diff --git a/calibrations/calorimeter/calo_emc_pi0_tbt/CaloCalibEmc_Pi0.cc b/calibrations/calorimeter/calo_emc_pi0_tbt/CaloCalibEmc_Pi0.cc index b1c6105afe..5a729a8851 100644 --- a/calibrations/calorimeter/calo_emc_pi0_tbt/CaloCalibEmc_Pi0.cc +++ b/calibrations/calorimeter/calo_emc_pi0_tbt/CaloCalibEmc_Pi0.cc @@ -5,15 +5,13 @@ #include #include #include +#include #include -#include +#include +#include -#include -#include - - -#include -#include +#include +#include #include #include diff --git a/calibrations/calorimeter/calo_emc_pi0_tbt/Makefile.am b/calibrations/calorimeter/calo_emc_pi0_tbt/Makefile.am index dde5a0691c..1de55f90c7 100644 --- a/calibrations/calorimeter/calo_emc_pi0_tbt/Makefile.am +++ b/calibrations/calorimeter/calo_emc_pi0_tbt/Makefile.am @@ -13,7 +13,7 @@ AM_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib64 \ -lHepMC \ -lCLHEP \ - -lg4vertex_io \ + -lglobalvertex_io \ -lcalo_io \ -lSubsysReco diff --git a/simulation/g4simulation/tpcresponse/Makefile.am b/calibrations/tpc/TPCPedestalCalibration/Makefile.am similarity index 68% rename from simulation/g4simulation/tpcresponse/Makefile.am rename to calibrations/tpc/TPCPedestalCalibration/Makefile.am index 25d7bd7140..0b48126b8f 100644 --- a/simulation/g4simulation/tpcresponse/Makefile.am +++ b/calibrations/tpc/TPCPedestalCalibration/Makefile.am @@ -8,25 +8,20 @@ AM_CPPFLAGS = \ AM_LDFLAGS = \ -L$(libdir) \ -L$(OFFLINE_MAIN)/lib \ - -L$(OFFLINE_MAIN)/lib64 \ - `root-config --libs` + -L$(OFFLINE_MAIN)/lib64 pkginclude_HEADERS = \ - TpcRS.h + TPCPedestalCalibration.h lib_LTLIBRARIES = \ - libtpcresponse.la + libTPCPedestalCalibration.la -libtpcresponse_la_SOURCES = \ - TpcRS.cc +libTPCPedestalCalibration_la_SOURCES = \ + TPCPedestalCalibration.cc -libtpcresponse_la_LIBADD = \ - -lphg4hit \ +libTPCPedestalCalibration_la_LIBADD = \ -lphool \ - -lSubsysReco \ - -ltpcrs \ - -lGeom \ - -lMathMore + -lSubsysReco BUILT_SOURCES = testexternals.cc @@ -34,7 +29,7 @@ noinst_PROGRAMS = \ testexternals testexternals_SOURCES = testexternals.cc -testexternals_LDADD = libtpcresponse.la +testexternals_LDADD = libTPCPedestalCalibration.la testexternals.cc: echo "//*** this is a generated file. Do not commit, do not edit" > $@ diff --git a/calibrations/tpc/TPCPedestalCalibration/TPCPedestalCalibration.cc b/calibrations/tpc/TPCPedestalCalibration/TPCPedestalCalibration.cc new file mode 100644 index 0000000000..ad14515976 --- /dev/null +++ b/calibrations/tpc/TPCPedestalCalibration/TPCPedestalCalibration.cc @@ -0,0 +1,197 @@ +#include "TPCPedestalCalibration.h" + +#include +#include +#include // for PHIODataNode +#include // for PHNodeIterator +#include // for PHObject +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/*************************************************************/ +/* TPC Pedestal Calibration */ +/* Thomas Marshall,Aditya Dash */ +/* rosstom@ucla.edu,aditya55@physics.ucla.edu */ +/*************************************************************/ + +TPCPedestalCalibration::TPCPedestalCalibration(const std::string &name) + :SubsysReco("TPCPedestalCalibration") + , m_fname(name) +{ + // reserve memory for max ADC samples + m_adcSamples.resize(1024, 0); + + for(int fee_no=0;fee_no<26;fee_no++) + { + for(int channel_no=0;channel_no<256;channel_no++) + { + m_aveADCFeeChannel[fee_no][channel_no]=0.0; + m_stdADCFeeChannel[fee_no][channel_no]=0.0; + m_countsADCFeeChannel[fee_no][channel_no]=0.0; + m_aliveArrayFeeChannel[fee_no][channel_no]=1; + } + } + +} + +int TPCPedestalCalibration::InitRun(PHCompositeNode *) +{ + m_file = TFile::Open(m_fname.c_str(), "recreate"); + assert(m_file->IsOpen()); + + m_pedestalTree = new TTree("pedestalTree", "Each entry is one TPC Channel"); + + m_pedestalTree->Branch("isAlive",&m_isAlive,"isAlive/I"); + m_pedestalTree->Branch("pedMean",&m_pedMean,"pedMean/F"); + m_pedestalTree->Branch("pedStd",&m_pedStd,"pedStd/F"); + m_pedestalTree->Branch("sector",&m_sector,"sector/I"); + m_pedestalTree->Branch("fee",&m_outFEE,"fee/I"); + m_pedestalTree->Branch("channel",&m_chan,"channel/I"); + m_pedestalTree->Branch("module",&m_module,"module/I"); + m_pedestalTree->Branch("slot",&m_slot,"slot/I"); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TPCPedestalCalibration::process_event(PHCompositeNode *topNode) +{ + Event *_event = findNode::getClass(topNode, "PRDF"); + if (_event == nullptr) + { + std::cout << "TPCRawDataTree::Process_Event - Event not found" << std::endl; + return -1; + } + if (_event->getEvtType() >= 8) /// special events + { + return Fun4AllReturnCodes::DISCARDEVENT; + } + + for (int packet : m_packets) + { + if (Verbosity()) + { + std::cout << __PRETTY_FUNCTION__ << " : decoding packet " << packet << std::endl; + } + + m_packet = packet; + + std::unique_ptr p (_event->getPacket(m_packet)); + if (!p) + { + if (Verbosity()) + { + std::cout << __PRETTY_FUNCTION__ << " : missing packet " << packet << std::endl; + } + + continue; + } + + m_nWaveormInFrame = p->iValue(0, "NR_WF"); + + for (int wf = 0; wf < m_nWaveormInFrame; wf++) + { + m_nSamples = p->iValue(wf, "SAMPLES"); + m_fee = p->iValue(wf, "FEE"); + m_Channel = p->iValue(wf, "CHANNEL"); + + if(m_nSamples==0) + { + m_aliveArrayFeeChannel[m_fee][m_Channel]=0; + continue; + } + + assert(m_nSamples < (int) m_adcSamples.size()); // no need for movements in memory allocation + for (int s = 0; s < m_nSamples; s++) + { + m_adcSamples[s] = p->iValue(wf, s); + } + + bool dead = false; + for(int adc_sam_no=0;adc_sam_no 200 || m_aveADCFeeChannel[fee_no][channel_no] < 10) + { + m_aliveArrayFeeChannel[fee_no][channel_no]=0; + } + + m_pedMean=m_aveADCFeeChannel[fee_no][channel_no]; + m_pedStd=sqrt(m_stdADCFeeChannel[fee_no][channel_no] - pow(m_aveADCFeeChannel[fee_no][channel_no],2)); + m_isAlive=m_aliveArrayFeeChannel[fee_no][channel_no]; + m_chan=channel_no; + m_outFEE=fee_no; + m_module=mod_arr[fee_no]; + m_slot=slot_arr[fee_no]; + m_pedestalTree->Fill(); + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TPCPedestalCalibration::End(PHCompositeNode *topNode) +{ + std::cout << "TPCPedestalCalibration::End(PHCompositeNode *topNode) This is the End..." << std::endl; + + m_file->Write(); + + std::cout << __PRETTY_FUNCTION__ << " : completed saving to " << m_file->GetName() << std::endl; + m_file->ls(); + + m_file->Close(); + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/calibrations/tpc/TPCPedestalCalibration/TPCPedestalCalibration.h b/calibrations/tpc/TPCPedestalCalibration/TPCPedestalCalibration.h new file mode 100644 index 0000000000..101bcde7a1 --- /dev/null +++ b/calibrations/tpc/TPCPedestalCalibration/TPCPedestalCalibration.h @@ -0,0 +1,74 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef TPCPedestalCalibration_H +#define TPCPedestalCalibration_H + +#include + +#include +#include + +class PHCompositeNode; +class TFile; +class TTree; + +class TPCPedestalCalibration : public SubsysReco +{ + public: + explicit TPCPedestalCalibration(const std::string &name = "TPCPedestalCalibration.root"); + + ~TPCPedestalCalibration() override {} + + int InitRun(PHCompositeNode *topNode) override; + + int process_event(PHCompositeNode *topNode) override; + + int EndRun(const int runnumber) override; + + int End(PHCompositeNode *topNode) override; + + void AddPacket(int packet) + { + m_packets.push_back(packet); + } + + void SetSector(int sectorNum) + { + m_sector = sectorNum; + } + + protected: + //! which packet to decode + std::vector m_packets{1001}; + + private: + std::string m_fname; + TFile * m_file = nullptr; + TTree * m_pedestalTree = nullptr; + + int m_packet = 0; + int m_nWaveormInFrame = 0; + int m_nSamples = 0; + int m_fee = 0; + int m_Channel = 0; + std::vector m_adcSamples; + + float m_aveADCFeeChannel[26][256]; + float m_stdADCFeeChannel[26][256]; + float m_countsADCFeeChannel[26][256]; + int m_aliveArrayFeeChannel[26][256]; + + int m_isAlive = 1; + float m_pedMean = 0; + float m_pedStd = 0; + int m_sector = 0; + int m_outFEE = 99; + int m_chan = 999; + int m_module = 9; + int m_slot = 99; + + int mod_arr[26]={2,2,1,1,1,3,3,3,3,3,3,2,2,1,2,2,1,1,2,2,3,3,3,3,3,3}; + int slot_arr[26] = {5,6,1,3,2,12,10,11,9,8,7,1,2,4,8,7,6,5,4,3,1,3,2,4,6,5}; +}; + +#endif // TPCPedestalCalibration_H diff --git a/simulation/g4simulation/tpcresponse/autogen.sh b/calibrations/tpc/TPCPedestalCalibration/autogen.sh similarity index 100% rename from simulation/g4simulation/tpcresponse/autogen.sh rename to calibrations/tpc/TPCPedestalCalibration/autogen.sh diff --git a/simulation/g4simulation/tpcresponse/configure.ac b/calibrations/tpc/TPCPedestalCalibration/configure.ac similarity index 78% rename from simulation/g4simulation/tpcresponse/configure.ac rename to calibrations/tpc/TPCPedestalCalibration/configure.ac index 82f255e112..a3d4486d54 100644 --- a/simulation/g4simulation/tpcresponse/configure.ac +++ b/calibrations/tpc/TPCPedestalCalibration/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(tpcresponse,[1.00]) +AC_INIT(tpcpedestalcalibration,[1.00]) AC_CONFIG_SRCDIR([configure.ac]) AM_INIT_AUTOMAKE @@ -9,7 +9,7 @@ LT_INIT([disable-static]) dnl no point in suppressing warnings people should dnl at least see them, so here we go for g++: -Wall if test $ac_cv_prog_gxx = yes; then - CXXFLAGS="$CXXFLAGS -Wall -Werror -Wextra" + CXXFLAGS="$CXXFLAGS -Wall -Werror" fi AC_CONFIG_FILES([Makefile]) diff --git a/calibrations/tpc/fillDigitalCurrentMaps/Files/TPCGainMaps.root b/calibrations/tpc/fillDigitalCurrentMaps/Files/TPCGainMaps.root new file mode 100644 index 0000000000..178e6d1a32 Binary files /dev/null and b/calibrations/tpc/fillDigitalCurrentMaps/Files/TPCGainMaps.root differ diff --git a/calibrations/tpc/fillDigitalCurrentMaps/Makefile.am b/calibrations/tpc/fillDigitalCurrentMaps/Makefile.am new file mode 100644 index 0000000000..f725870c48 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/Makefile.am @@ -0,0 +1,49 @@ +AUTOMAKE_OPTIONS = foreign + +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 + +pkginclude_HEADERS = \ + readDigitalCurrents.h + +lib_LTLIBRARIES = \ + libreadDigitalCurrents.la + +libreadDigitalCurrents_la_SOURCES = \ + readDigitalCurrents.cc + +libreadDigitalCurrents_la_LIBADD = \ + -lphool \ + -lfun4all \ + -lphg4hit \ + -ltrackbase_historic_io \ + -ltrack_io \ + -ltpc_io \ + -lg4detectors \ + -lg4testbench \ + -lSubsysReco + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libreadDigitalCurrents.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/calibrations/tpc/fillDigitalCurrentMaps/README.md b/calibrations/tpc/fillDigitalCurrentMaps/README.md new file mode 100644 index 0000000000..51f4426d0f --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/README.md @@ -0,0 +1,80 @@ +# SetUp +Start here for setting up environment: [Example_of_using_DST_nodes (Wiki)](https://wiki.bnl.gov/sPHENIX/index.php/Example_of_using_DST_nodes#Building%20a%20package) +- Setup local compilation for bash shel: + +``` +source /opt/sphenix/core/bin/sphenix_setup.sh -n +export MYINSTALL=/sphenix/user/shulga/tpc2019_install +source /opt/sphenix/core/bin/setup_local.sh $MYINSTALL +``` +**Do not forget to change the line:** ```export MYINSTALL=/sphenix/user/shulga/tpc2019_install``` + + + +- Compilation of the package: +``` +mkdir build +cd build +../autogen.sh --prefix=$MYINSTALL +make -j 4 +make install +``` +- reading first file: + + + + +# Workflow: +- DST files with TrkrHitSet containing ADCs from Hijing events used for the analysis: + - DST_TRKR_HIT_sHijing_0_20fm-0000000006--* + +- To get list of the files: +``` +CreateFileList.pl --run 6 --type 4 --nopileup DST_TRKR_HIT G4Hits +``` + +- File with bunchcrossing id and time (ns) assuming 106ns between bunches and 50kHz collision rate: __timestamps_50kHz.txt__. The file is used to mimic the bunchcrossing; + +- Running over containers in the files is performed with Fun4All environment. Main code is Fun4All_FillDCMap.C, it is run with run_files_AA.sh, which takes as an input the first and last file number: +``` +#This will run first 5 files with G4Hits (100 events per file in the MDC2) and create files +#with histograms: +source macros/run_files_AA.sh 1 2 1508071.0 +``` + +- As soon as files are available the histograms are inside; +- To create bunch of bash files and condor job files to start condor jobs scripts are available: +``` +#Creating folders to store all the files: + +mkdir Out +mkdir Files +mkdir condor_macros + +#Creating 1000s job files to run over G4Hits: +scripts/generate_files_AA.py +``` +**Do not forget to change the path to your repositories:** + +```export MYINSTALL=/sphenix/user/shulga/tpc2019_install``` + +```/sphenix/user/shulga/Work/...``` + +- Scripts above will also generate bash files to submit all jobs, *_all bash scripts created above should be provided executable rights before that_*: +``` +../run_all_jobs* +``` + +# Adding histograms from all files: +The files contain histograms for 100 events each. Full map is ~10000 events. Thus, maps have to be integrated. +To make files smaller the Sumw2 arrays/matrices for histograms should not be stored. +The tool to provide this functionality: +``` +add_histos.py +``` diff --git a/calibrations/tpc/fillDigitalCurrentMaps/autogen.sh b/calibrations/tpc/fillDigitalCurrentMaps/autogen.sh new file mode 100755 index 0000000000..dea267bbfd --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/calibrations/tpc/fillDigitalCurrentMaps/configure.ac b/calibrations/tpc/fillDigitalCurrentMaps/configure.ac new file mode 100644 index 0000000000..130d2b1b11 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/configure.ac @@ -0,0 +1,16 @@ +AC_INIT(readdigitalcurrents,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE +AC_PROG_CXX(CC g++) + +LT_INIT([disable-static]) + +dnl no point in suppressing warnings people should +dnl at least see them, so here we go for g++: -Wall +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Werror" +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT \ No newline at end of file diff --git a/calibrations/tpc/fillDigitalCurrentMaps/macros/Fun4All_FillDCMap.C b/calibrations/tpc/fillDigitalCurrentMaps/macros/Fun4All_FillDCMap.C new file mode 100644 index 0000000000..0eb99a4709 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/macros/Fun4All_FillDCMap.C @@ -0,0 +1,116 @@ +#pragma once +#include +#include +#include + +#include + +#include +//#include +#include + +#include + +// cppcheck-suppress unknownMacro +R__LOAD_LIBRARY(libfun4all.so) +// cppcheck-suppress unknownMacro +R__LOAD_LIBRARY(libreadDigitalCurrents.so) +// cppcheck-suppress unknownMacro +R__LOAD_LIBRARY(libg4dst.so) + +std::vector readBeamXings(); + +std::vector readBeamXings(){ + //cout << "fillSpaceChargeMaps::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << endl; + std::vector bXs; + string line; + string txt_file = "./data/timestamps_50kHz_1M.txt"; + ifstream InputFile (txt_file); + //std::map timestamps; + if (InputFile.is_open()){ + int n_line=0; + while ( getline (InputFile,line) ) + { + n_line++; + //cout << line << '\n'; + if(n_line>3){ + std::istringstream is( line ); + double n[2] = {0,0}; + int i = 0; + while( is >> n[i] ) { + i++; + } + //_timestamps[n[0]]=n[1]; + bXs.push_back(int(n[0])); + } + } + InputFile.close(); + } + return bXs; +} + +int closest(std::vector const& vec, int value) { + auto const it = std::lower_bound(vec.begin(), vec.end(), value); + if (it == vec.end()) { return -1; } + + return *it; +} + +void Fun4All_FillDCMap( const int nEvents = 1000, const int eventsInFileStart = 0, const int eventsBeamCrossing = 1508071, const string &fname = "/sphenix/user/shulga/Work/IBF/macros/detectors/sPHENIX/Files/DST_G4Hits_sHijing_0-12fm_005000_006000.root", const string &foutputname = "./Files/hists_G4Hits_sHijing_0-12fm_000000_001000.root" )//DST_G4sPHENIX_1000evt.root")//G4sPHENIX.root" ) +{ + // /sphenix/user/frawley/new_macros_april27/macros/detectors/sPHENIX/Reconstructed_DST_Hijing_50kHz_00000.root + + /////////////////////////////////////////// + // Make the Server + ////////////////////////////////////////// + std::vector bXs = readBeamXings(); + std::vector bXs_sel; + + std::vector::iterator it = std::find(bXs.begin(), bXs.end(), eventsBeamCrossing); + int index=0; + index = std::distance(bXs.begin(), it); + cout<<"Index="<registerSubsystem(dist_calc); + dist_calc->SetEvtStart(eventsInFileStart); + dist_calc->SetBeamXing(bXs_sel);// Set beam crosssing bias + //dist_calc->SetBeamXing(eventsBeamCrossing); // Set beam crosssing bias + dist_calc->SetCollSyst(0); //setting pp with = 1 + dist_calc->SetIBF(0.004); + dist_calc->SetCCGC(1);//to use PHG4CylinderCellGeom + + gSystem->Load("libFROG"); + FROG *fr = new FROG(); + string inputFileName = fr->location(fname); + cout << "Next file:" << inputFileName << endl; + // this (DST) input manager just drives the event loop + Fun4AllInputManager *in = new Fun4AllDstInputManager("DSTin"); + in->fileopen(inputFileName);//fname); + se->registerInputManager(in); + // events = 0 => run till end of input file + if (nEvents <= 0) + { + return; + } + cout << endl << "Running over " << nEvents << " Events" << endl; + se->run(nEvents); + //} + cout << endl << "Calling End in Fun4All_readDigitalCurrents.C" << endl; + se->End(); + + cout << endl << "All done, calling delete Fun4AllServer" << endl; + delete se; + + cout << endl << "gSystem->Exit(0)" << endl; + gSystem->Exit(0); +} diff --git a/calibrations/tpc/fillDigitalCurrentMaps/macros/add_histos.py b/calibrations/tpc/fillDigitalCurrentMaps/macros/add_histos.py new file mode 100755 index 0000000000..5d02f73dbe --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/macros/add_histos.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +from ROOT import TCanvas, TFile, TH1F,TH2F,TH3F, TF1, TGraph, gROOT +import os +import re + +gROOT.SetBatch(True) + +dirName = './Files/' +bXs = [1508071, 3016509, 4524020, 6032112, 7540028, 9048092, 10556072, 12064371, 13572143, 15080178, 16588072, 18096105] +h_names = ['_h_DC_E', + '_h_DC_SC', + '_h_DC_SC_XY', + '_h_R', + '_h_SC_ibf', + '_h_hits'] + +for bX in bXs: + print(bX) + name = 'hist_G4Hits_sHijing_0-12fm_bX{}'.format(bX) + outputName = './Files/Summary_ADC_NoW_hist_AA_event_0_bX{}.root'.format(bX) + files = [f for f in os.listdir(dirName) if re.match(name, f)] + n=0 + histos = [] + for file in files: + h=0 + f = TFile.Open(dirName+file) + for h_name in h_names: + newName=h_name+'_{}'.format(n) + if n==0: + newName=h_name + hist = f.Get(h_name).Clone() + hist.SetDirectory(0) + if n==0: + histos.append(hist) + if n>0: + histos[h].Add(hist) + h+=1 + n+=1 + + outfile = TFile(outputName, "RECREATE") + for hist in histos: + hist.Sumw2(False) + hist.Write() + outfile.Write() + outfile.Close() +#print(files) +# +# \ No newline at end of file diff --git a/calibrations/tpc/fillDigitalCurrentMaps/macros/add_histos_bX.py b/calibrations/tpc/fillDigitalCurrentMaps/macros/add_histos_bX.py new file mode 100755 index 0000000000..8bda346671 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/macros/add_histos_bX.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +from ROOT import TCanvas, TFile, TH1F,TH2F,TH3F, TF1, TGraph, gROOT +import os +import re +import glob +import sys + +gROOT.SetBatch(True) + +dirName = '/sphenix/user/shulga/Work/TpcPadPlane_phi_coresoftware/coresoftware/calibrations/tpc/fillDigitalCurrentMaps/Files/' +#bXs = [1508071, 3016509, 4524020, 6032112, 7540028, 9048092, 10556072, 12064371, 13572143, 15080178, 16588072, 18096105] +#bXs = [18096105] +h_names = []#'_h_hits','_h_R','_h_DC_E'] +for i in range(30): + h_names.append('_h_SC_ibf_{}'.format(i)) + + + +#sys.argv[0] +ib = sys.argv[1] +bX = sys.argv[2] + + +print(bX) +name = 'hist_G4Hits_sHijing_0-12fm_bX{}*'.format(bX) +outputName = './Files/Summary_hist_mdc2_UseFieldMaps_AA_event_{}_bX{}_new.root'.format(ib,bX) + +filePattern = dirName+name +files = sorted(glob.glob(filePattern)) +#print(files) +#n=0 +histos = [] +for n,file in enumerate(files): + #h=0 + f = TFile.Open(file) + print(file) + for h,h_name in enumerate(h_names): + newName=h_name+'_{}'.format(n) + if n==0: + newName=h_name + #print(h_name) + hist = f.Get(h_name).Clone(newName) + if n==0: + histos.append(hist) + if n>0: + histos[h].Add(hist) + hist.SetDirectory(0) + #h+=1 + #n+=1 + +outfile = TFile(outputName, "RECREATE") +for hist in histos: + hist.Sumw2(False) + hist.Write() +outfile.Write() +outfile.Close() + + +# Remove all the used files +for file in files : + if os.path.exists(file): + os.remove(file) + else: + print("Can not delete the file as it doesn't exist:{}",file) + diff --git a/calibrations/tpc/fillDigitalCurrentMaps/macros/run_DS.sh b/calibrations/tpc/fillDigitalCurrentMaps/macros/run_DS.sh new file mode 100755 index 0000000000..6269c3afb2 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/macros/run_DS.sh @@ -0,0 +1,10 @@ +#!/usr/bin/bash +#IN_FILE="/sphenix/user/shulga/Work/TpcPadPlane_v3_coresoftware/macros/detectors/sPHENIX/Files/G4sPHENIX_NewTestGeo_NewRLimits_1evt.root" +#OUT_FILE="/sphenix/user/shulga/Work/TpcPadPlane_v3_coresoftware/macros/detectors/sPHENIX/Files/DC_G4sPHENIX_NewTestGeo_NewRLimits_1evt.root" +#IN_FILE="/sphenix/user/shulga/Work/TpcPadPlane_v3_coresoftware/macros/detectors/sPHENIX/Files/G4sPHENIX_NewTestGeo_1evt.root" +#OUT_FILE="/sphenix/user/shulga/Work/TpcPadPlane_v3_coresoftware/macros/detectors/sPHENIX/Files/DC_G4sPHENIX_NewTestGeo_1evt.root" +#IN_FILE="/sphenix/user/shulga/Work/TpcPadPlane_v3_coresoftware/macros/detectors/sPHENIX/Files/G4sPHENIX_Default_1evts.root" +#OUT_FILE="/sphenix/user/shulga/Work/TpcPadPlane_v3_coresoftware/macros/detectors/sPHENIX/Files/DC_G4sPHENIX_Default_1evt.root" +IN_FILE="DST_TRKR_HIT_sHijing_0_20fm-0000000006-000001.root" +OUT_FILE="/sphenix/user/shulga/Work/IBF/readDigitalCurrents/Files/DC_G4sPHENIX_Default_1evt.root" +root -l -b -q ./macros/Fun4All_FillDCMap.C\(1000,0,1508071,\"$IN_FILE\",\"$OUT_FILE\"\) \ No newline at end of file diff --git a/calibrations/tpc/fillDigitalCurrentMaps/macros/run_files_AA.sh b/calibrations/tpc/fillDigitalCurrentMaps/macros/run_files_AA.sh new file mode 100755 index 0000000000..92fefe9a81 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/macros/run_files_AA.sh @@ -0,0 +1,26 @@ +#!/usr/bin/bash +start=${1?Error: no start file \# given} +stop=${2?Error: no stop file \# given} +bX=${3?Error: no beamX \# given} +source /opt/sphenix/core/bin/sphenix_setup.sh -n new +export MYINSTALL=/sphenix/user/shulga/tpc2019_install +source /opt/sphenix/core/bin/setup_local.sh $MYINSTALL + +for (( f=$start; f<$stop; f++ )); +do + #let Xstart=f*1000 Xend=(f+1)*1000; + #A=$( printf '%06d' $Xstart ) + #B=$( printf '%06d' $Xend ) + let Xstart=f*100 Xend=(f+1)*100; + A=$( printf '%05d' $f ) + B=$( printf '%06d' $Xend ) + #fname="/sphenix/user/shulga/Work/IBF/macros/detectors/sPHENIX/Files/DST_NoW_G4Hits_sHijing_0-12fm_"$A"_"$B".root" ; + #fname="DST_TRKR_HIT_sHijing_0_20fm_50kHz_bkg_0_20fm-0000000062-"$A".root" ; + fname="DST_TRKR_HIT_sHijing_0_20fm-0000000006-"$A".root" ; + foutputname="./Files/hist_G4Hits_sHijing_0-12fm_bX"$bX"_"$A"_"$B".root" ; + echo $fname ; + echo $foutputname ; + root -l -b -q ./macros/Fun4All_FillDCMap.C\(100,$Xstart,$bX,\"$fname\",\"$foutputname\"\) +done + +echo all done diff --git a/calibrations/tpc/fillDigitalCurrentMaps/readDigitalCurrents.cc b/calibrations/tpc/fillDigitalCurrentMaps/readDigitalCurrents.cc new file mode 100644 index 0000000000..9b51a66d9a --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/readDigitalCurrents.cc @@ -0,0 +1,554 @@ + +#include "readDigitalCurrents.h" + +#include +#include +#include // for SubsysReco + + +#include "trackbase/TpcDefs.h" +#include "trackbase/ActsGeometry.h" + +#include + +#include +#include + +#include +#include + + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +using namespace std; + +bool IsOverFrame(double r, double phi); + +bool IsOverFrame(double r, double phi){ + //these parameters are taken from Feb 12 drawings of frames. + double tpc_frame_side_gap=0.8;//mm //space between radial line and start of frame + double tpc_frame_side_width=2.6;//mm //thickness of frame + double tpc_margin=0.0;//mm // extra gap between edge of frame and start of GEM holes + + double tpc_frame_r3_outer=758.4;//mm inner edge of larger-r frame of r3 + double tpc_frame_r3_inner=583.5;//mm outer edge of smaller-r frame of r3 + + double tpc_frame_r2_outer=574.9;//mm inner edge of larger-r frame of r2 + double tpc_frame_r2_inner=411.4;//mm outer edge of smaller-r frame of r2 + + double tpc_frame_r1_outer=402.6;//mm inner edge of larger-r frame of r1 + double tpc_frame_r1_inner=221.0;//mm outer edge of smaller-r frame of r1 + + //double tpc_sec0_phi=0.0;//get_double_param("tpc_sec0_phi"); + + //if the coordinate is in the radial spaces of the frames, return true: + if (rtpc_frame_r1_outer-tpc_margin && rtpc_frame_r2_outer-tpc_margin && rtpc_frame_r3_outer-tpc_margin) + return true; + + //if the coordinate is within gap+width of a sector boundary, return true: + //note that this is not a line of constant radius, but a linear distance from a radius. + + //find the two spokes we're between: + + float sectorangle=(M_PI/6); + float nsectors=phi/sectorangle; + int nsec=floor(nsectors); + float reduced_phi=phi-nsec*sectorangle; //between zero and sixty degrees. + float dist_to_previous=r*sin(reduced_phi); + float dist_to_next=r*sin(sectorangle-reduced_phi); + if (dist_to_previousregisterHisto(_h_SC_ibf[iz]); + } + + hm->registerHisto(_h_R ); + hm->registerHisto(_h_hits ); + hm->registerHisto(_h_DC_SC ); + hm->registerHisto(_h_DC_SC_XY ); + hm->registerHisto(_h_hit_XY ); + hm->registerHisto(_h_DC_E ); + + _event_timestamp = 0; + + if(_fillCSVFile){ + myCSVFile.open ("./Files/example_1ms_120evts_AA.csv"); + myCSVFile << "Event," + << "T," + << "Pad," + << "Radius," + << "ADC" + <<"\n"; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int readDigitalCurrents::InitRun(PHCompositeNode *topNode) +{ + std::cout << "readDigitalCurrents::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl; + std::string line; + //AA collisions timestamps + //std::string txt_file = "/sphenix/user/shulga/Work/IBF/DistortionMap/timestamps_50kHz.txt"; + std::string txt_file = "/sphenix/user/shulga/Work/TpcPadPlane_phi_coresoftware/coresoftware/calibrations/tpc/fillSpaceChargeMaps/data/timestamps_50kHz_1M.txt"; + int start_line = 3; + if(_collSyst==1){ + //pp collisions timestamps + txt_file = "/phenix/u/hpereira/sphenix/work/g4simulations/timestamps_3MHz.txt"; + //txt_file = "/sphenix/user/shulga/Work/IBF/DistortionMap/timestamps_50kHz.txt"; + start_line = 2; + } + ifstream InputFile (txt_file); + if (InputFile.is_open()){ + int n_line=0; + while ( getline (InputFile,line) ) + { + n_line++; + if(n_line>start_line){ + std::istringstream is( line ); + double n[2] = {0,0}; + int i = 0; + while( is >> n[i] ) { + i++; + } + _timestamps[n[0]]=n[1]; + if(n_line<10){ + cout<IsOpen() ) printf("Gain/IBF Maps File opened successfully\n"); + //_h_modules_anode = (TH2F*)MapsFile ->Get("h_modules_anode") ->Clone("_h_modules_anode"); + _h_modules_measuredibf = (TH2F*)MapsFile ->Get("h_modules_measuredibf")->Clone("_h_modules_measuredibf"); + //} + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int readDigitalCurrents::process_event(PHCompositeNode *topNode) +{ + //double bX = _beamxing; + //float bX = 1508071; + //double z_bias_avg = 0; + //if (_fAvg==1){ + // z_bias_avg=1.05*(float) rand()/RAND_MAX; + //} + int bemxingsInFile = _keys.size(); + if (_evtstart>= bemxingsInFile) _evtstart=_evtstart-bemxingsInFile; + int key = _keys.at(_evtstart); + _event_timestamp = (float)_timestamps[key]*ns;//units in seconds + _event_bunchXing = key; + if(_evtstart%100==0) cout<<"_evtstart = "<<_evtstart<::const_iterator iter; + // //nodename << "G4HIT_TPC"; + nodename << "TRKR_HITSET"; + + // // SvtxEvaluator + // SvtxEvaluator *hits = findNode::getClass(topNode, nodename.str().c_str()); + // //int n_hits = 0; + // if (hits){ + // PHG4HitContainer::ConstRange hit_range = hits->getHits(); + // } + //=================================== + // get node containing the digitized hits + TrkrHitSetContainer* _hitmap = findNode::getClass(topNode, nodename.str().c_str()); + if (!_hitmap) + { + std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + ostringstream geo_nodename; + geo_nodename << "CYLINDERCELLGEOM_SVTX"; + + PHG4TpcCylinderGeomContainer* _geom_container_ccgc = nullptr; + PHG4CylinderCellGeomContainer* _geom_container_cgc = nullptr; + if(_f_ccgc==1){ + _geom_container_ccgc = findNode::getClass(topNode, geo_nodename.str().c_str()); + if (!_geom_container_ccgc) + { + std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + }else{ + _geom_container_cgc = findNode::getClass(topNode, geo_nodename.str().c_str()); + + if (!_geom_container_cgc) + { + std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + } + + + // loop over all the hits + // hits are stored in hitsets, so have to get the hitset first + int n_hits = 0; + //float _event_bunchXing = 1508071; + TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(); + for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first;iter != all_hitsets.second; ++iter){ + //checking that the object is inside TPC + if(TrkrDefs::getTrkrId(iter->first) == TrkrDefs::tpcId){ + TrkrDefs::hitsetkey hitsetkey = iter->first; + const unsigned int zside = TpcDefs::getSide(hitsetkey); + TrkrHitSet::ConstRange range = iter->second->getHits(); + unsigned int layer = TrkrDefs::getLayer(iter->first); + //if(layer>6){ + PHG4TpcCylinderGeom *layergeom_ccgc = nullptr; + PHG4CylinderCellGeom *layergeom_cgc = nullptr; + double radius = 0; + if(_f_ccgc==1){ + layergeom_ccgc = _geom_container_ccgc->GetLayerCellGeom(layer); + radius = layergeom_ccgc->get_radius()*cm; + }else{ + layergeom_cgc = _geom_container_cgc->GetLayerCellGeom(layer); + radius = layergeom_cgc->get_radius()*cm; + } + //PHG4TpcCylinderGeom *layergeom = _geom_container->GetLayerCellGeom(layer); + //double radius = layergeom->get_radius()*cm; // returns center of the layer + int min_phiBin=1e5; + int max_phiBin=-1; + for(TrkrHitSet::ConstIterator hit_iter = range.first; hit_iter != range.second; ++hit_iter){ + //int f_fill_ibf=0; + int f_fill_ibf[30] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + + unsigned short phibin = TpcDefs::getPad(hit_iter->first); + unsigned short zbin = TpcDefs::getTBin(hit_iter->first); + double _drift_velocity = 8.0e-3;//ActsGeometry::get_drift_velocity(); + double phi_center = 0; + if(_f_ccgc==1){ + phi_center = layergeom_ccgc->get_phicenter(phibin); + }else{ + phi_center = layergeom_cgc->get_phicenter(phibin); + } + if (phi_center<0) phi_center+=2*M_PI; + if(phi_centerM_PI/2-M_PI/12){ + if(min_phiBin>phibin)min_phiBin=phibin; + if(max_phiBinget_zcenter(zbin)*cm; + if(_f_ccgc==1){ + z = layergeom_ccgc->get_zcenter(zbin)*_drift_velocity*cm;//*cm/ns; + if(zside==0){ + z = -z; + } + }else{ + z = layergeom_cgc->get_zcenter(zbin)*cm; + } + TrkrHit *hit = hit_iter->second; + unsigned short adc = hit->getAdc()-adc_pedestal; + float E = hit->getEnergy(); + //double z = 0; + //double z_prim = -1*1e10; + //double z_ibf = -1*1e10; + double z_ibf[30] = {-1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, + -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, + -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10, -1 * 1e10}; + + int RBin=_h_R->GetXaxis()->FindBin(radius); + if((RBin>33 && RBin<50) && z>0){ + int nRBins = layergeom_ccgc->get_phibins(); + if(phibinget_zcenter(zbin) << "," + << phibin<<"," + << RBin-34<< "," + << adc <<"\n"; + } + _h_hit_XY->Fill( x, y); + } + + } + //if(!IsOverFrame(radius/mm,phi_center)){ + for (int iz = 0; iz < nFrames; iz++) + { + double bX = _beamxing[iz]; + if (_event_bunchXing <= bX) + { + if(z>=0 && z<1.055*m){ + z_ibf[iz] = 1.055 * m - (bX - _event_bunchXing) * 106 * vIon * ns; + if( z_ibf[iz]>0 && z_ibf[iz]<1.055*m){ + f_fill_ibf[iz]=1; + } + } + if(z<0 && z>-1.055*m){ + z_ibf[iz] = -1.055*m+(bX-_event_bunchXing)*106*vIon*ns; + if( z_ibf[iz]<0 && z_ibf[iz]>-1.055*m){ + f_fill_ibf[iz]=1; + } + } + } + + } + if(z>=0 && z<1.055*m){ + if(adc>=0)n_hits++; + if(adc>=0)_h_DC_E->Fill(adc,E); + + } + if(z<0 && z>-1.055*m){ + if(adc>=0)n_hits++; + if(adc>=0)_h_DC_E->Fill(adc,E); + + } + + //Reading IBF and Gain weights according to X-Y position + float w_ibf = 1.; + //float w_gain = 1.; + //if(_fUseIBFMap){ + int bin_x = _h_modules_measuredibf ->GetXaxis()->FindBin(x/mm); + int bin_y = _h_modules_measuredibf ->GetYaxis()->FindBin(y/mm); + w_ibf = _h_modules_measuredibf->GetBinContent(bin_x,bin_y); + //w_gain = _h_modules_anode->GetBinContent(bin_x,bin_y); + w_ibf = 1.; + //} + float w_adc = adc*w_ibf; + _h_DC_SC->Fill(phi_center,radius,z,w_adc); + _h_DC_SC_XY->Fill(x,y,w_adc); + if(f_fill_ibf[0]==1){ + + _h_R->Fill(radius); + } + for (int iz = 0; iz < nFrames; iz++) + { + if (f_fill_ibf[iz] == 1)_h_SC_ibf[iz] ->Fill(phi_center,radius,z_ibf[iz],w_adc); + } + //} + //if(n_hits%100==0) std::cout<Fill(n_hits); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int readDigitalCurrents::ResetEvent(PHCompositeNode *topNode) +{ + //std::cout << "readDigitalCurrents::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl; + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int readDigitalCurrents::EndRun(const int runnumber) +{ + std::cout << "readDigitalCurrents::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl; + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int readDigitalCurrents::End(PHCompositeNode *topNode) +{ + std::cout << "readDigitalCurrents::End(PHCompositeNode *topNode) This is the End..." << std::endl; + _h_R ->Sumw2( false ); + _h_hits ->Sumw2( false ); + _h_DC_E ->Sumw2( false ); + _h_DC_SC ->Sumw2( false ); + _h_hit_XY ->Sumw2( false ); + _h_DC_SC_XY ->Sumw2( false ); + for (int iz = 0; iz < nFrames; iz++) + { + _h_SC_ibf[iz]->Sumw2(false); + } + hm->dumpHistos(_filename, "RECREATE"); + if(_fillCSVFile)myCSVFile.close(); + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int readDigitalCurrents::Reset(PHCompositeNode *topNode) +{ + std::cout << "readDigitalCurrents::Reset(PHCompositeNode *topNode) being Reset" << std::endl; + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +void readDigitalCurrents::Print(const std::string &what) const +{ + std::cout << "readDigitalCurrents::Print(const std::string &what) const Printing info for " << what << std::endl; +} + +void readDigitalCurrents::SetEvtStart(int newEvtStart){ + _evtstart = newEvtStart; + cout<<"Start event is set to: "< &beamXs) +{ + _beamxing = beamXs; + std::cout << "Initial BeamXing is set to: " << _beamxing[0] << std::endl; +} +void readDigitalCurrents::SetCollSyst(int coll_syst){ + _collSyst = coll_syst; + std::string s_syst[2] = {"AA","pp"}; + cout<<"Collision system is set to: "< + +#include +#include +#include +#include + +#include // for sin, asin, cos, floor, M_PI + +class Fun4AllHistoManager; +class PHCompositeNode; + +//class PHG4CylinderCellGeom; + +//class TFile; +class TH1; +class TH2; +class TH3; + + +class readDigitalCurrents : public SubsysReco +{ + public: + + readDigitalCurrents(const std::string &name = "readDigitalCurrents", const std::string &filename = "DC_Hist_OnPlane_WIBF.root"); + + virtual ~readDigitalCurrents(); + + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + int Init(PHCompositeNode *topNode) override; + + /** Called for first event when run number is known. + Typically this is where you may want to fetch data from + database, because you know the run number. A place + to book histograms which have to know the run number. + */ + int InitRun(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode *topNode) override; + + /// Clean up internals after each event. + int ResetEvent(PHCompositeNode *topNode) override; + + /// Called at the end of each run. + int EndRun(const int runnumber) override; + + /// Called at the end of all processing. + int End(PHCompositeNode *topNode) override; + + /// Reset + int Reset(PHCompositeNode * /*topNode*/) override; + + void Print(const std::string &what = "ALL") const override; + + void SetBeamXing(const std::vector &beamXs); + void SetEvtStart(int newEvtStart); + void FillCSV(int fillCSVFile); + void SetCollSyst(int coll_syst=0); + void SetIBF(float ampIBFfrac=0.004); + void SetCCGC(float f_ccgc=0); + + //double pi = 3.14159265358979323846;//2 * acos(0.0); + + protected: + Fun4AllHistoManager *hm = nullptr; + std::string _filename; + //TFile *outfile = nullptr; + std::map _timestamps; + std::vector _keys; + float _ampIBFfrac = 0.02; + int _collSyst = 0; + std::ofstream myCSVFile; + + private: + std::vector _beamxing; + int _evtstart = 0; + + int _fillCSVFile = 0; + + int _f_ccgc = 0; + + TH2* _h_modules_measuredibf = nullptr; + + TH1* _h_R = nullptr; + TH1* _h_hits = nullptr; + TH3* _h_DC_SC = nullptr; + TH2* _h_DC_SC_XY = nullptr; + TH2* _h_hit_XY = nullptr; + TH2* _h_DC_E = nullptr; + //TH3* _h_SC_ibf = nullptr; + static const int nFrames = 30; + TH3 *_h_SC_ibf[nFrames] = {nullptr}; + + float _event_timestamp = 0; + float _event_bunchXing = 0; + + //double pi = 2 * acos(0.0); + double adc_pedestal=0.;//74.4; + double cm=1e1,m=1e3, mm=1; //changed to make 'm' 1.0, for convenience. + float ns=1e-9,us=1e-6,ms=1e-3,s=1; + float V=1; + //float ionMobility=3.37*cm*cm/V/s; + float ionMobility=1.65*cm*cm/V/s; + float vIon=ionMobility*400*V/cm; + + float f=0.5;//for now, just pick the middle of the hit. Do better later. +}; + +#endif // READDIGITALCURRENTS_H diff --git a/calibrations/tpc/fillDigitalCurrentMaps/scripts/generate_files_AA.py b/calibrations/tpc/fillDigitalCurrentMaps/scripts/generate_files_AA.py new file mode 100755 index 0000000000..757dce73d0 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/scripts/generate_files_AA.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python + +# coding=utf-8 + +introduction = [ + "# All local jobs are part of the vanilla universe.", + "Universe = vanilla", + "", + "# The requirement line specifies which machines we want to", + "# run this job on. Any arbitrary classad expression can", + "# be used.", + "#Requirements = (CPU_Speed >= 1)", + "", + "# Rank is an expression that states how to rank machines which ", + "# have already met the requirements expression. Essentially, ", + "# rank expresses preference. A higher numeric value equals better ", + "# rank. Condor will give the job the machine with the highest rank.", + "# Rank = CPU_Speed", + "", + "# Jobs by default get 1.4Gb of RAM allocated, ask for more if needed", + "# but if a job needs more than 2Gb it will not be able to run on the", + "# older nodes", + "request_memory = 7.1GB", + "", + "# If you need multiple cores you can ask for them, but the scheduling", + "# may take longer the \"larger\" a job you ask for", + "request_cpus = 1", + "", + "# This flag is used to order only one's own submitted jobs ", + "# The jobs with the highest numbers get considered for ", + "# scheduling first.", + "#Priority = 4", + "", + "# Copy all of the user's current shell environment variables ", + "# at the time of job submission.", + "#GetEnv = True", + "", + "# Used to give jobs a directory with respect to file input ", + "# and output.", + "Initialdir = /sphenix/user/shulga/Work/IBF/readDigitalCurrents/", + "", + "# Input file given to the job.", + "#Input = /dev/null", + "", + "", + "# This should be the last command and tells condor to queue the", + "# job. If a number is placed after the command (i.e. Queue 15)", + "# then the job will be submitted N times. Use the $(Process)", + "# macro to make your input/output and log files unique.", + "Queue" +] + +ff= open("./run_all_AA_jobs.sh","w+") +ff.write("#!/usr/bin/bash"+"\n"), +#evt_start = [0,8,16,23,31,39,47,55,63,71,79,87] +#evt_end = [9,17,24,32,40,48,56,64,72,80,88,96] +evt_start = [0, 75, 155, 233, 312, 392, 471, 551, 630, 712, 793, 873, 953, 1033, 1113, 1194, 1272, 1352, 1432, 1511, 1592, 1670, 1750, 1830, 1910, 1990, 2069, 2149, 2230, 2310, 2391, 2470, 2550, 2631, 2711, 2792, 2871, 2952, 3032, 3113, 3193, 3273, 3352, 3433, 3514, 3595, 3676, 3755, 3834, 3915, 3995, 4076, 4156, 4235, 4315, 4396, 4476, 4557, 4636, 4718, 4798, 4877, 4957, 5037, 5118, 5200, 5278, 5359, 5439, 5518, 5598, 5680, 5760, 5841, 5922, 6002, 6081, 6162, 6241, 6321, 6400, 6481, 6561, 6641, 6722, 6804, 6884, 6964, 7045, 7126, 7206, 7286, 7366, 7447, 7527, 7606, 7687, 7767, 7847, 7928, 8008, 8087, 8167, 8248, 8328, 8408, 8489, 8566, 8646, 8727, 8809, 8890, 8970, 9049, 9129, 9209, 9288, 9368, 9449, 9529, 9608, 9688, 9769, 9849] +evt_end = [ 170, 248, 327, 407, 486, 566, 645, 727, 808, 888, 968, 1048, 1128, 1209, 1287, 1367, 1447, 1526, 1607, 1685, 1765, 1845, 1925, 2005, 2084, 2164, 2245, 2325, 2406, 2485, 2565, 2646, 2726, 2807, 2886, 2967, 3047, 3128, 3208, 3288, 3367, 3448, 3529, 3610, 3691, 3770, 3849, 3930, 4010, 4091, 4171, 4250, 4330, 4411, 4491, 4572, 4651, 4733, 4813, 4892, 4972, 5052, 5133, 5215, 5293, 5374, 5454, 5533, 5613, 5695, 5775, 5856, 5937, 6017, 6096, 6177, 6256, 6336, 6415, 6496, 6576, 6656, 6737, 6819, 6899, 6979, 7060, 7141, 7221, 7301, 7381, 7462, 7542, 7621, 7702, 7782, 7862, 7943, 8023, 8102, 8182, 8263, 8343, 8423, 8504, 8581, 8661, 8742, 8824, 8905, 8985, 9064, 9144, 9224, 9303, 9383, 9464, 9544, 9623, 9703, 9784, 9864, 9943, 10000] +evt_bX = [1508071.0, 3016509.0, 4524020.0, 6032112.0, 7540028.0, 9048092.0, 10556072.0, 12064371.0, 13572143.0, 15080178.0, 16588072.0, 18096105.0] +for j, (start,end) in enumerate(zip(evt_start,evt_end)): + for i in range(start,end): + filename = "./run_macros/run_files_AA_{}_{}.sh".format(j,i) + f= open(filename,"w+") + f.write("#!/usr/bin/bash"+"\n") + f.write("source macros/run_files_AA.sh {} {} {}".format(i,i+1,evt_bX[j])+"\n") + f.close + filename_job = "./run_macros/condor_run_files_AA_{}_{}.job".format(j,i) + ff.write("condor_submit {}".format(filename_job)+"\n") + f_job= open(filename_job,"w+") + n_line = 0 + for lines in introduction: + f_job.write(lines+"\n") + if n_line==3: + f_job.write("# The executable we want to run."+"\n") + f_job.write("Executable = run_macros/run_files_AA_{}_{}.sh".format(j,i)+"\n") + f_job.write(""+"\n") + f_job.write(""+"\n") + f_job.write("# The argument to pass to the executable."+"\n") + f_job.write("Arguments = \"run DST HISTO job AA {} {}\"".format(j,i)+"\n") + if n_line==38: + f_job.write("# The job's stdout is sent to this file."+"\n") + f_job.write("Output = /sphenix/user/shulga/Work/IBF/readDigitalCurrents/Out/myjob_AA_{}_{}.out".format(j,i)+"\n") + f_job.write(""+"\n") + f_job.write("# The job's stderr is sent to this file."+"\n") + f_job.write("Error = /sphenix/user/shulga/Work/IBF/readDigitalCurrents/Out/myjob_AA_{}_{}.err".format(j,i)+"\n") + f_job.write(""+"\n") + f_job.write("# The condor log file for this job, useful when debugging."+"\n") + f_job.write("Log = /sphenix/user/shulga/Work/IBF/readDigitalCurrents/Out/condor_AA_{}_{}.log".format(j,i)+"\n") + f_job.write(""+"\n") + + n_line+=1 + f_job.close +ff.close diff --git a/calibrations/tpc/fillDigitalCurrentMaps/scripts/generate_files_AA_dag.py b/calibrations/tpc/fillDigitalCurrentMaps/scripts/generate_files_AA_dag.py new file mode 100755 index 0000000000..52c9affce2 --- /dev/null +++ b/calibrations/tpc/fillDigitalCurrentMaps/scripts/generate_files_AA_dag.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 + +# coding=utf-8 + +from pathlib import Path +import stat + +def chmod_px(name): + f = Path(name) + f.chmod(f.stat().st_mode | stat.S_IEXEC) + return 0 + +work_dir = "/sphenix/user/shulga/Work/TpcPadPlane_phi_coresoftware/coresoftware/calibrations/tpc/fillDigitalCurrentMaps/" +init_str = "Initialdir = "+work_dir + +introduction = [ + "# All local jobs are part of the vanilla universe.", + "Universe = vanilla", + "", + "# The requirement line specifies which machines we want to", + "# run this job on. Any arbitrary classad expression can", + "# be used.", + "#Requirements = (CPU_Speed >= 1)", + "", + "# Rank is an expression that states how to rank machines which ", + "# have already met the requirements expression. Essentially, ", + "# rank expresses preference. A higher numeric value equals better ", + "# rank. Condor will give the job the machine with the highest rank.", + "# Rank = CPU_Speed", + "", + "# Jobs by default get 1.4Gb of RAM allocated, ask for more if needed", + "# but if a job needs more than 2Gb it will not be able to run on the", + "# older nodes", + "request_memory = 7.1GB", + "", + "# If you need multiple cores you can ask for them, but the scheduling", + "# may take longer the \"larger\" a job you ask for", + "request_cpus = 1", + "", + "# This flag is used to order only one's own submitted jobs ", + "# The jobs with the highest numbers get considered for ", + "# scheduling first.", + "#Priority = 4", + "", + "# Copy all of the user's current shell environment variables ", + "# at the time of job submission.", + "#GetEnv = True", + "", + "# Used to give jobs a directory with respect to file input ", + "# and output.", + init_str, + "", + "# Input file given to the job.", + "#Input = /dev/null", + "", + "", + "# This should be the last command and tells condor to queue the", + "# job. If a number is placed after the command (i.e. Queue 15)", + "# then the job will be submitted N times. Use the $(Process)", + "# macro to make your input/output and log files unique.", + "Queue" +] + +ff= open("./run_all_AA_jobs.sh","w+") +ff.write("#!/usr/bin/bash"+"\n") +ff_all_dag= open("./run_all_AA_jobs_dag.sh","w+") +ff_all_dag.write("#!/usr/bin/bash"+"\n") +evt_start = [0, 75, 155, 233, 312, 392, 471, 551, 630, 712, 793, 873, 953, 1033, 1113, 1194, 1272, 1352, 1432, 1511, 1592, 1670, 1750, 1830, 1910, 1990, 2069, 2149, 2230, 2310, 2391, 2470, 2550, 2631, 2711, 2792, 2871, 2952, 3032, 3113, 3193, 3273, 3352, 3433, 3514, 3595, 3676, 3755, 3834, 3915, 3995, 4076, 4156, 4235, 4315, 4396, 4476, 4557, 4636, 4718, 4798, 4877, 4957, 5037, 5118, 5200, 5278, 5359, 5439, 5518, 5598, 5680, 5760, 5841, 5922, 6002, 6081, 6162, 6241, 6321, 6400, 6481, 6561, 6641, 6722, 6804, 6884, 6964, 7045, 7126, 7206, 7286, 7366, 7447, 7527, 7606, 7687, 7767, 7847, 7928, 8008, 8087, 8167, 8248, 8328, 8408, 8489, 8566, 8646, 8727, 8809, 8890, 8970, 9049, 9129, 9209, 9288, 9368, 9449, 9529, 9608, 9688, 9769, 9849] +evt_end = [ 170, 248, 327, 407, 486, 566, 645, 727, 808, 888, 968, 1048, 1128, 1209, 1287, 1367, 1447, 1526, 1607, 1685, 1765, 1845, 1925, 2005, 2084, 2164, 2245, 2325, 2406, 2485, 2565, 2646, 2726, 2807, 2886, 2967, 3047, 3128, 3208, 3288, 3367, 3448, 3529, 3610, 3691, 3770, 3849, 3930, 4010, 4091, 4171, 4250, 4330, 4411, 4491, 4572, 4651, 4733, 4813, 4892, 4972, 5052, 5133, 5215, 5293, 5374, 5454, 5533, 5613, 5695, 5775, 5856, 5937, 6017, 6096, 6177, 6256, 6336, 6415, 6496, 6576, 6656, 6737, 6819, 6899, 6979, 7060, 7141, 7221, 7301, 7381, 7462, 7542, 7621, 7702, 7782, 7862, 7943, 8023, 8102, 8182, 8263, 8343, 8423, 8504, 8581, 8661, 8742, 8824, 8905, 8985, 9064, 9144, 9224, 9303, 9383, 9464, 9544, 9623, 9703, 9784, 9864, 9943, 10000] +evt_bX = [1508071.0, 3016509.0, 4524020.0, 6032112.0, 7540028.0, 9048092.0, 10556072.0, 12064371.0, 13572143.0, 15080178.0, 16588072.0, 18096105.0, 19604092.0, 21112166.0, 22620146.0, 24128151.0, 25636093.0, 27144133.0, 28652094.0, 30160125.0, 31668120.0, 33176312.0, 34684455.0, 36192201.0, 37700299.0, 39208338.0, 40716228.0, 42224205.0, 43732346.0, 45240219.0, 46748391.0, 48256211.0, 49764321.0, 51272217.0, 52780276.0, 54288364.0, 55796155.0, 57304180.0, 58812172.0, 60320612.0, 61828166.0, 63336720.0, 64844207.0, 66352327.0, 67860452.0, 69368220.0, 70876499.0, 72384379.0, 73892278.0, 75400246.0, 76908483.0, 78416343.0, 79924240.0, 81432250.0, 82940306.0, 84449218.0, 85956368.0, 87464432.0, 88972282.0, 90480292.0, 91988279.0, 93496320.0, 95004286.0, 96512289.0, 98020429.0, 99528306.0, 101036272.0, 102544367.0, 104052284.0, 105560289.0, 107068427.0, 108576408.0, 110084415.0, 111592686.0, 113100369.0, 114608368.0, 116116420.0, 117624429.0, 119132375.0, 120640371.0, 122148359.0, 123656423.0, 125164763.0, 126673264.0, 128180360.0, 129688558.0, 131196596.0, 132704683.0, 134212939.0, 135720446.0, 137228683.0, 138736381.0, 140244545.0, 141752581.0, 143260466.0, 144768499.0, 146276523.0, 147784726.0, 149292502.0, 150800480.0, 152308621.0, 153816539.0, 155324424.0, 156832627.0, 158340668.0, 159848664.0, 161356504.0, 162864630.0, 164372489.0, 165880652.0, 167388456.0, 168896455.0, 170404493.0, 171912555.0, 173421358.0, 174928568.0, 176436571.0, 177945044.0, 179452976.0, 180961051.0, 182468742.0, 183976536.0, 185484542.0, 186992509.0] + +for j, (start,end) in enumerate(zip(evt_start,evt_end)): + filename_bx = "./condor_macros/run_all_AA_jobs_{}.sh".format(int(evt_bX[j])) + filename_dag = "./condor_macros/run_all_AA_jobs_{}.dag".format(int(evt_bX[j])) + ff_bx= open(filename_bx,"w+") + ff_dag= open(filename_dag,"w+") + ff_bx.write("#!/usr/bin/bash"+"\n") + ff.write("source {}\n".format(filename_bx)) + ff_all_dag.write("condor_submit_dag {}\n".format(filename_dag)) + parent_str = "PARENT" + for i in range(start,end+10): + filename = "./condor_macros/run_files_AA_{}_{}.sh".format(j,i) + f= open(filename,"w+") + f.write("#!/usr/bin/bash"+"\n") + f.write("source macros/run_files_AA.sh {} {} {}".format(i,i+1,evt_bX[j])+"\n") + f.close + chmod_px(filename) + filename_job = "./condor_macros/condor_run_files_AA_{}_{}.job".format(j,i) + ff_bx.write("condor_submit {}".format(filename_job)+"\n") + ff_dag.write("JOB A_{} {}\n".format(i,filename_job )) + parent_str += " A_{}".format(i) + f_job= open(filename_job,"w+") + n_line = 0 + for lines in introduction: + f_job.write(lines+"\n") + if n_line==3: + f_job.write("# The executable we want to run."+"\n") + f_job.write("Executable = condor_macros/run_files_AA_{}_{}.sh".format(j,i)+"\n") + f_job.write(""+"\n") + f_job.write(""+"\n") + f_job.write("# The argument to pass to the executable."+"\n") + f_job.write("Arguments = \"run job 300 evts AA {} {}\"".format(j,i)+"\n") + if n_line==38: + f_job.write("# The job's stdout is sent to this file."+"\n") + f_job.write("Output = " + work_dir + "Out/myjob_300evts_AA_{}_{}.out".format(j,i)+"\n") + f_job.write(""+"\n") + f_job.write("# The job's stderr is sent to this file."+"\n") + f_job.write("Error = " + work_dir + "Out/myjob_300evts_AA_{}_{}.err".format(j,i)+"\n") + f_job.write(""+"\n") + f_job.write("# The condor log file for this job, useful when debugging."+"\n") + f_job.write("Log = " + work_dir + "Out/condor_300evts_AA_{}_{}.log".format(j,i)+"\n") + f_job.write(""+"\n") + + n_line+=1 + + f_job.close + ff_bx.close + chmod_px(filename_bx) + + #chmod_px(filename) + filename_B = "./condor_macros/add_hist_{}.job".format(int(evt_bX[j])) + ff_dag.write("JOB B {}\n".format(filename_B )) + ff_dag.write(parent_str + " CHILD B") + ff_dag.close + chmod_px(filename_dag) + + # files for adding histos + # - .sh: + filename_B_sh = "./condor_macros/add_hist_{}.sh".format(int(evt_bX[j])) + ff_B_sh = open(filename_B_sh,"w+") + + ff_B_sh.write("#!/usr/bin/bash"+"\n") + ff_B_sh.write("source /opt/sphenix/core/bin/sphenix_setup.sh -n new"+"\n") + ff_B_sh.write("./macros/add_histos_bX.py {} {} \n".format(j,int(evt_bX[j]))) + + ff_B_sh.close + chmod_px(filename_B_sh) + + # - .job: + add_file_content = [ + "Universe = vanilla", + "Executable = {}".format(filename_B_sh), + "Arguments = \"run job add histos AA {}\"".format(int(evt_bX[j])), + "request_memory = 7.1GB", + init_str, + "# The job's stdout is sent to this file.", + "Output = ./Out/myjob_add_histos_AA_{}.out".format(int(evt_bX[j])), + "# The job's stderr is sent to this file.", + "Error = ./Out/myjob_add_histos_AA_{}.err".format(int(evt_bX[j])), + "# The condor log file for this job, useful when debugging.", + "Log = ./Out/condor_add_histos_AA_{}.log".format(int(evt_bX[j])), + "Queue" + ] + ff_B = open(filename_B,"w+") + for line in add_file_content: + ff_B.write(line+"\n") + ff_B.close + + +ff.close +ff_all_dag.close diff --git a/calibrations/tpc/fillSpaceChargeMaps/Makefile.am b/calibrations/tpc/fillSpaceChargeMaps/Makefile.am index 1d25e8cc1b..ae1a48d25e 100644 --- a/calibrations/tpc/fillSpaceChargeMaps/Makefile.am +++ b/calibrations/tpc/fillSpaceChargeMaps/Makefile.am @@ -7,7 +7,7 @@ AM_CPPFLAGS = \ AM_LDFLAGS = \ -L$(libdir) \ - -L$(OFFLINE_MAIN)/lib + -L$(OFFLINE_MAIN)/lib pkginclude_HEADERS = \ fillSpaceChargeMaps.h \ @@ -26,6 +26,7 @@ libfillSpaceChargeMaps_la_LIBADD = \ -lphg4hit \ -lg4detectors \ -lg4testbench \ + -lg4tpc \ -lSubsysReco BUILT_SOURCES = testexternals.cc diff --git a/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.cc b/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.cc index c208f52a01..bcae25440b 100644 --- a/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.cc +++ b/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.cc @@ -10,6 +10,10 @@ #include // for SubsysReco #include +#include + +//#include +//#include #include // for TAxis #include @@ -92,18 +96,20 @@ int fillSpaceChargeMaps::Init(PHCompositeNode * /*topNode*/) z_bins[z] = -z_rdo + z_rdo / nz * z; } - _h_R = new TH1F("_h_R", "_h_R;R, [m]", r_bins_N+2, r_bins_edges); + _h_R = new TH1F("_h_R", "_h_R;R, [mm]", r_bins_N+2, r_bins_edges); _h_hits = new TH1F("_h_hits", "_h_hits;N, [hit]", 1000, 0, 1e6); _h_DC_E = new TH2F("_h_DC_E", "_h_DC_E;SC;E#times10^{6}", 2000, -100, 2e5 - 100, 1000, -50, 1e3 - 50); + _h_SC_XY = new TH2F("_h_SC_XY" ,"_h_SC_XY;X, [mm];Y, [mm];ADC;" ,4*159,-1*78*cm,78*cm,4*159,-1*78*cm,78*cm); + char name[100]; char name_ax[100]; for (int iz = 0; iz < 30; iz++) { sprintf(name, "_h_SC_ibf_%d", iz); - sprintf(name_ax, "_h_SC_ibf_%d;#phi, [rad];R, [m];Z, [m]", iz); + sprintf(name_ax, "_h_SC_ibf_%d;#phi, [rad];R, [mm];Z, [mm]", iz); _h_SC_ibf[iz] = new TH3F(name, name_ax, nphi, phi_bins, r_bins_N, r_bins, 2 * nz, z_bins); sprintf(name, "_h_SC_prim_%d", iz); - sprintf(name_ax, "_h_SC_prim_%d;#phi, [rad];R, [m];Z, [m]", iz); + sprintf(name_ax, "_h_SC_prim_%d;#phi, [rad];R, [mm];Z, [mm]", iz); _h_SC_prim[iz] = new TH3F(name, name_ax, nphi, phi_bins, r_bins_N, r_bins, 2 * nz, z_bins); hm->registerHisto(_h_SC_prim[iz]); @@ -112,7 +118,7 @@ int fillSpaceChargeMaps::Init(PHCompositeNode * /*topNode*/) hm->registerHisto(_h_hits); hm->registerHisto(_h_R); hm->registerHisto(_h_DC_E); - + hm->registerHisto(_h_SC_XY); //_event_timestamp = 0; _hit_eion = 0; _hit_r = 0; @@ -134,6 +140,8 @@ int fillSpaceChargeMaps::Init(PHCompositeNode * /*topNode*/) _rawHits->Branch("event_timestamp", &_event_timestamp); _rawHits->Branch("event_bunchXing", &_event_bunchXing); } + //padplane = new PHG4TpcPadPlaneReadout; + //seggeo = new PHG4TpcCylinderGeomContainer(); return 0; } @@ -192,7 +200,7 @@ int fillSpaceChargeMaps::InitRun(PHCompositeNode * /*topNode*/) _mbRate = _freqKhz * kHz; _xingRate = 9.383 * MHz; _mean = mbRate / xingRate; - + //padplane->CreateReadoutGeometry( PHCompositeNode *, seggeo); return 0; } @@ -407,11 +415,13 @@ int fillSpaceChargeMaps::process_event(PHCompositeNode *topNode) _ibf_vol = N_electrons * w_gain_tmp * _ampGain * w_ibf_tmp * _ampIBFfrac; _h_SC_ibf[iz]->Fill(_hit_phi, _hit_r, z_ibf[iz], _ibf_vol); + if(iz==0)_h_SC_XY->Fill(_hit_r * cos(_hit_phi),_hit_r * sin(_hit_phi));//,_ibf_vol); } else { _h_SC_ibf[iz]->Fill(new_phi, new_r, z_ibf[iz], _ibf_vol); + if(iz==0)_h_SC_XY->Fill(new_r * cos(new_phi),new_r * sin(new_phi));//,_ibf_vol); } } } @@ -447,6 +457,7 @@ int fillSpaceChargeMaps::End(PHCompositeNode * /*topNode*/) _h_SC_ibf[iz]->Sumw2(false); } + _h_SC_XY->Sumw2(false); _h_hits->Sumw2(false); _h_DC_E->Sumw2(false); _h_R->Sumw2(false); diff --git a/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.h b/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.h index 93d4f55acd..576034c74a 100644 --- a/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.h +++ b/calibrations/tpc/fillSpaceChargeMaps/fillSpaceChargeMaps.h @@ -5,6 +5,9 @@ #include +//#include +//#include + #include #include #include @@ -102,9 +105,13 @@ class fillSpaceChargeMaps : public SubsysReco TH1 *_h_hits = nullptr; TH1 *_h_R = nullptr; TH2 *_h_DC_E = nullptr; + TH2 *_h_SC_XY = nullptr; static const int nFrames = 30; TH3 *_h_SC_prim[nFrames] = {nullptr}; TH3 *_h_SC_ibf[nFrames] = {nullptr}; + + //PHG4TpcPadPlaneReadout *padplane = nullptr; + //PHG4TpcCylinderGeomContainer *seggeo = nullptr; float f = 0.5; //for now, just pick the middle of the hit. Do better later. float ns = 1e-9, s = 1.0; // us=1e-6,ms=1e-3, diff --git a/calibrations/tpc/fillSpaceChargeMaps/macros/add_histos_bX.py b/calibrations/tpc/fillSpaceChargeMaps/macros/add_histos_bX.py index 1334717d53..1bb7db003e 100755 --- a/calibrations/tpc/fillSpaceChargeMaps/macros/add_histos_bX.py +++ b/calibrations/tpc/fillSpaceChargeMaps/macros/add_histos_bX.py @@ -23,7 +23,7 @@ print(bX) name = 'mdc2_ADCBins_UseFieldMaps_hist_G4Hits_sHijing_0-12fm_bX{}*'.format(bX) -outputName = './Files/Summary_hist_mdc2_UseFieldMaps_AA_event_{}_bX{}.root'.format(ib,bX) +outputName = './Files/Summary_hist_mdc2_UseFieldMaps_AA_event_{}_bX{}_new.root'.format(ib,bX) filePattern = dirName+name files = sorted(glob.glob(filePattern)) diff --git a/calibrations/tpc/fillSpaceChargeMaps/macros/run_files_300evts_AA_MDC2.sh b/calibrations/tpc/fillSpaceChargeMaps/macros/run_files_300evts_AA_MDC2.sh index 1413fe0460..e0225eff56 100755 --- a/calibrations/tpc/fillSpaceChargeMaps/macros/run_files_300evts_AA_MDC2.sh +++ b/calibrations/tpc/fillSpaceChargeMaps/macros/run_files_300evts_AA_MDC2.sh @@ -12,12 +12,12 @@ do A=$( printf '%05d' $Xstart ) #B=$( printf '%06d' $Xend ) #fname="G4Hits_sHijing_0_20fm-0000000002-"$A".root" ; - fname="G4Hits_sHijing_0_20fm-0000000040-"$A".root" ; + fname="G4Hits_sHijing_0_20fm-0000000006-"$A".root" ; foutputname="./Files/mdc2_ADCBins_UseFieldMaps_hist_G4Hits_sHijing_0-12fm_bX"$bX"_"$A".root" ; #foutputname="./Files/mdc2_ADCBins_NoFieldMaps_hist_G4Hits_sHijing_0-12fm_bX"$bX"_"$A".root" ; echo $fname ; echo $foutputname ; - root -l -b -q ./macros/Fun4All_FillChargesMap_300evts_MDC2.C\(1,$XevtStart,$bX,\"$fname\",\"$foutputname\"\) + root -l -b -q ./macros/Fun4All_FillChargesMap_300evts_MDC2.C\(100,$XevtStart,$bX,\"$fname\",\"$foutputname\"\) done echo all done diff --git a/calibrations/tpc/generator/AnnularFieldSim.cc b/calibrations/tpc/generator/AnnularFieldSim.cc index d36ce0dbb0..4f11c14f9a 100644 --- a/calibrations/tpc/generator/AnnularFieldSim.cc +++ b/calibrations/tpc/generator/AnnularFieldSim.cc @@ -2597,7 +2597,7 @@ void AnnularFieldSim::PlotFieldSlices(const char *filebase, TVector3 pos, char w return; } -void AnnularFieldSim::GenerateSeparateDistortionMaps(const char *filebase, int r_subsamples, int p_subsamples, int z_subsamples, int /*z_substeps*/, bool andCartesian) +void AnnularFieldSim::GenerateSeparateDistortionMaps(const char *filebase, int nSteps, int r_subsamples, int p_subsamples, int z_subsamples, int /*z_substeps*/, bool andCartesian) { //generates the distortion map for one or both sides of the detector, separating them so //they do not try to interpolate across the CM. @@ -2609,7 +2609,7 @@ void AnnularFieldSim::GenerateSeparateDistortionMaps(const char *filebase, int r float deltap = s.Phi(); //(pf-pi)/np; float deltaz = s.Z(); //(zf-zi)/nz; TVector3 stepzvec(0, 0, deltaz); - int nSteps = 500; //how many steps to take in the particle path. hardcoded for now. Think about this later. + //int nSteps = 500; //how many steps to take in the particle path. hardcoded for now. Think about this later. int nSides = 1; if (hasTwin) nSides = 2; diff --git a/calibrations/tpc/generator/AnnularFieldSim.h b/calibrations/tpc/generator/AnnularFieldSim.h index a8665dfb9c..1938736a6b 100644 --- a/calibrations/tpc/generator/AnnularFieldSim.h +++ b/calibrations/tpc/generator/AnnularFieldSim.h @@ -236,7 +236,7 @@ class AnnularFieldSim //file-writing functions for complex mapping questions: void GenerateDistortionMaps(const char *filebase, int r_subsamples = 1, int p_subsamples = 1, int z_subsamples = 1, int z_substeps = 1, bool andCartesian = false); - void GenerateSeparateDistortionMaps(const char *filebase, int r_subsamples = 1, int p_subsamples = 1, int z_subsamples = 1, int z_substeps = 1, bool andCartesian = false); + void GenerateSeparateDistortionMaps(const char *filebase, int nSteps = 500, int r_subsamples = 1, int p_subsamples = 1, int z_subsamples = 1, int z_substeps = 1, bool andCartesian = false); void PlotFieldSlices(const char *filebase, TVector3 pos, char which = 'E'); void load_spacecharge(const std::string &filename, const std::string &histname, float zoffset = 0, float chargescale = 1, float cmscale = 1, bool isChargeDensity = true); diff --git a/calibrations/tpc/generator/generate_distortion_map.C b/calibrations/tpc/generator/generate_distortion_map.C index 77c5a50c93..6a082d4337 100644 --- a/calibrations/tpc/generator/generate_distortion_map.C +++ b/calibrations/tpc/generator/generate_distortion_map.C @@ -16,7 +16,7 @@ void SurveyFiles(TFileCollection* filelist); -void generate_distortion_map(const char *inputname, const char* gainName, const char *outputname, const char *ibfName, const char *primName, bool hasSpacecharge=true, bool isAdc=false){ +void generate_distortion_map(const char *inputname, const char* gainName, const char *outputname, const char *ibfName, const char *primName, bool hasSpacecharge=true, bool isAdc=false, int nSteps=500){ printf("generating single distortion map. Caution: This is vastly less efficient than re-using the tpc model once it is set up\n"); bool hasTwin=true; //this flag prompts the code to build both a positive-half and a negative-half for the TPC, reusing as much of the calculations as possible. It is more efficient to 'twin' one half of the TPC than to recalculate/store the greens functions for both. @@ -206,7 +206,7 @@ void generate_distortion_map(const char * inputpattern="./evgeny_apr/Smooth*.roo //TestSpotDistortion(tpc); //tpc->GenerateDistortionMaps(outputfilename,2,2,2,1,true); - tpc->GenerateSeparateDistortionMaps(outputfilename,2,2,2,1,true); + tpc->GenerateSeparateDistortionMaps(outputfilename,500,2,2,2,1,true); printf("distortions mapped.\n"); tpc->PlotFieldSlices(outputfilename.Data(),pos); tpc->PlotFieldSlices(outputfilename.Data(),pos,'B'); diff --git a/generators/FermiMotionAfterburner/Makefile.am b/generators/FermiMotionAfterburner/Makefile.am index 10d15395ea..f2683ce1ac 100644 --- a/generators/FermiMotionAfterburner/Makefile.am +++ b/generators/FermiMotionAfterburner/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ - -I$(ROOTSYS)/include + -isystem$(ROOTSYS)/include AM_LDFLAGS = \ -L$(libdir) \ diff --git a/offline/QA/modules/Makefile.am b/offline/QA/modules/Makefile.am index c6720b9c78..f7d946d665 100644 --- a/offline/QA/modules/Makefile.am +++ b/offline/QA/modules/Makefile.am @@ -34,6 +34,7 @@ libqa_modules_la_LIBADD = \ pkginclude_HEADERS = \ QAG4SimulationCalorimeter.h \ QAG4SimulationCalorimeterSum.h \ + QAG4SimulationDistortions.h \ QAG4SimulationIntt.h \ QAG4SimulationJet.h \ QAG4SimulationKFParticle.h \ @@ -53,6 +54,7 @@ libqa_kfparticle_la_SOURCES = \ libqa_modules_la_SOURCES = \ QAG4SimulationCalorimeter.cc \ QAG4SimulationCalorimeterSum.cc \ + QAG4SimulationDistortions.cc \ QAG4SimulationIntt.cc \ QAG4SimulationJet.cc \ QAG4SimulationMicromegas.cc \ diff --git a/offline/QA/modules/QAG4SimulationDistortions.cc b/offline/QA/modules/QAG4SimulationDistortions.cc new file mode 100644 index 0000000000..d9f89c9135 --- /dev/null +++ b/offline/QA/modules/QAG4SimulationDistortions.cc @@ -0,0 +1,372 @@ + +#include "QAG4SimulationDistortions.h" +#include "QAHistManagerDef.h" + +#include +#include + +#include +#include +#include // for PHWHERE + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include // for map +#include // for pair + +namespace +{ + + // square + template + inline constexpr T square(const T& x) + { + return x * x; + } + + // radius + template + T get_r(const T& x, const T& y) + { + return std::sqrt(square(x) + square(y)); + } + + template + inline constexpr T deltaPhi(const T& phi) + { + if (phi > M_PI) + return phi - 2. * M_PI; + else if (phi <= -M_PI) + return phi + 2. * M_PI; + else + return phi; + } + + /// return number of clusters of a given type that belong to a tracks + template + int count_clusters(const std::vector& keys) + { + return std::count_if(keys.begin(), keys.end(), + [](const TrkrDefs::cluskey& key) + { return TrkrDefs::getTrkrId(key) == type; }); + } +} // namespace + +//____________________________________________________________________________.. +QAG4SimulationDistortions::QAG4SimulationDistortions(const std::string& name) + : SubsysReco(name) +{ +} + +//____________________________________________________________________________.. +QAG4SimulationDistortions::~QAG4SimulationDistortions() +{ +} + +//____________________________________________________________________________.. +int QAG4SimulationDistortions::Init(PHCompositeNode*) +{ + Fun4AllHistoManager* hm = QAHistManagerDef::getHistoManager(); + assert(hm); + + TH1* h(nullptr); + + h = new TH2F(TString(get_histo_prefix()) + "betadz", ";tan#beta; #Deltaz [cm]", 100, -0.5, 0.5, 100, -0.5, 0.5); + + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "alphardphi", ";tan#alpha; r#Delta#phi [cm]", 100, -0.5, 0.5, 100, -0.5, 0.5); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "rphiResid", ";r [cm]; #Deltar#phi [cm]", 60, 20, 80, 500, -2, 2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "zResid", ";z [cm]; #Deltaz [cm]", 200, -100, 100, 1000, -2, 2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "etaResid", ";#eta;#Delta#eta", 20, -1, 1, 500, -0.2, 0.2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "etaResidLayer", ";r [cm]; #Delta#eta", 60, 20, 80, 500, -0.2, 0.2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "zResidLayer", ";r [cm]; #Deltaz [cm]", 60, 20, 80, 1000, -2, 2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "deltarphi_layer", ";layer; r.#Delta#phi_{track-cluster} (cm)", 57, 0, 57, 500, -2, 2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "deltaz_layer", ";layer; #Deltaz_{track-cluster} (cm)", 57, 0, 57, 100, -2, 2); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "statez_pulls", "layer; #Deltaz_{track-cluster}/#sigma_{z}^{state}", 57, 0, 57, 100, -5, 5); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "staterphi_pulls", "layer; #Deltar#phi_{track-cluster}/#sigma_{rphi}^{state}", 57, 0, 57, 100, -5, 5); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "clusz_pulls", "layer; #Deltaz_{track-cluster}/#sigma_{z}^{clus}", 57, 0, 57, 100, -5, 5); + hm->registerHisto(h); + + h = new TH2F(TString(get_histo_prefix()) + "clusrphi_pulls", "layer; #Deltar#phi_{track-cluster}/#sigma_{r#phi}^{clus}", 57, 0, 57, 100, -5, 5); + hm->registerHisto(h); + + TTree* t(nullptr); + + t = new TTree(TString(get_histo_prefix()) + "residTree", "tpc residual info"); + t->Branch("tanAlpha", &m_tanAlpha, "tanAlpha/D"); + t->Branch("tanBeta", &m_tanBeta, "tanBeta/D"); + t->Branch("drphi", &m_drphi, "drphi/D"); + t->Branch("dz", &m_dz, "dz/D"); + t->Branch("clusR", &m_clusR, "clusR/D"); + t->Branch("clusPhi", &m_clusPhi, "clusPhi/D"); + t->Branch("clusZ", &m_clusZ, "clusZ/D"); + t->Branch("statePhi", &m_statePhi, "statePhi/D"); + t->Branch("stateZ", &m_stateZ, "stateZ/D"); + t->Branch("stateR", &m_stateR, "stateR/D"); + t->Branch("stateRPhiErr", &m_stateRPhiErr, "stateRPhiErr/D"); + t->Branch("stateZErr", &m_stateZErr, "stateZErr/D"); + t->Branch("clusRPhiErr", &m_clusRPhiErr, "clusRPhiErr/D"); + t->Branch("clusZErr", &m_clusZErr, "clusZErr/D"); + t->Branch("cluskey", &m_cluskey, "cluskey/l"); + t->Branch("event", &m_event, "event/I"); + + hm->registerHisto(t); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int QAG4SimulationDistortions::InitRun(PHCompositeNode* topNode) +{ + m_trackMap = findNode::getClass(topNode, "SvtxSiliconMMTrackMap"); + m_clusterContainer = findNode::getClass(topNode, "TRKR_CLUSTER"); + + m_tGeometry = findNode::getClass(topNode, "ActsGeometry"); + + if (not m_trackMap or not m_clusterContainer or not m_tGeometry) + { + std::cout << PHWHERE << "Necessary distortion container not on node tree. Bailing." + << std::endl; + + return Fun4AllReturnCodes::ABORTRUN; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int QAG4SimulationDistortions::process_event(PHCompositeNode*) +{ + Fun4AllHistoManager* hm = QAHistManagerDef::getHistoManager(); + assert(hm); + + auto h_beta = dynamic_cast(hm->getHisto(get_histo_prefix() + "betadz")); + assert(h_beta); + + auto h_alpha = dynamic_cast(hm->getHisto(get_histo_prefix() + "alphardphi")); + assert(h_alpha); + + auto h_rphiResid = dynamic_cast(hm->getHisto(get_histo_prefix() + "rphiResid")); + assert(h_rphiResid); + + auto h_zResid = dynamic_cast(hm->getHisto(get_histo_prefix() + "zResid")); + assert(h_zResid); + + auto h_etaResid = dynamic_cast(hm->getHisto(get_histo_prefix() + "etaResid")); + assert(h_etaResid); + + auto h_etaResidLayer = dynamic_cast(hm->getHisto(get_histo_prefix() + "etaResidLayer")); + assert(h_etaResidLayer); + + auto h_zResidLayer = dynamic_cast(hm->getHisto(get_histo_prefix() + "zResidLayer")); + assert(h_zResidLayer); + + auto h_deltarphi_layer = dynamic_cast(hm->getHisto(get_histo_prefix() + "deltarphi_layer")); + assert(h_deltarphi_layer); + + auto h_deltaz_layer = dynamic_cast(hm->getHisto(get_histo_prefix() + "deltaz_layer")); + assert(h_deltaz_layer); + + auto h_statez_pulls = dynamic_cast(hm->getHisto(get_histo_prefix() + "statez_pulls")); + assert(h_statez_pulls); + + auto h_staterphi_pulls = dynamic_cast(hm->getHisto(get_histo_prefix() + "staterphi_pulls")); + assert(h_staterphi_pulls); + + auto h_clusz_pulls = dynamic_cast(hm->getHisto(get_histo_prefix() + "clusz_pulls")); + assert(h_clusz_pulls); + + auto h_clusrphi_pulls = dynamic_cast(hm->getHisto(get_histo_prefix() + "clusrphi_pulls")); + assert(h_clusrphi_pulls); + + auto t_tree = dynamic_cast(hm->getHisto(get_histo_prefix() + "residTree")); + assert(t_tree); + + for (const auto& [key, track] : *m_trackMap) + { + if (!checkTrack(track)) + { + continue; + } + auto tpcSeed = track->get_tpc_seed(); + auto siliconSeed = track->get_silicon_seed(); + + /// Should have never been added to the map... + if (not tpcSeed or not siliconSeed) + { + continue; + } + + for (auto iter = track->begin_states(); iter != track->end_states(); ++iter) + { + auto state = iter->second; + + /// If the state name wasn't set to the ckey, it wasn't analyzed + /// in PHTpcResiduals (i.e. it isn't in the tpc) + if ((state->get_name()).find("UNKNOWN") != std::string::npos) + { + continue; + } + + TrkrDefs::cluskey key = std::stoll(state->get_name()); + + auto cluster = m_clusterContainer->findCluster(key); + + const auto clusGlobPosition = m_tGeometry->getGlobalPosition(key, cluster); + + const float clusR = get_r(clusGlobPosition(0), clusGlobPosition(1)); + const float clusPhi = std::atan2(clusGlobPosition(1), clusGlobPosition(0)); + const float clusZ = clusGlobPosition(2); + + // cluster errors + const float clusRPhiErr = cluster->getRPhiError(); + const float clusZErr = cluster->getZError(); + + const Acts::Vector3 stateGlobPosition = Acts::Vector3(state->get_x(), + state->get_y(), + state->get_z()); + const Acts::Vector3 stateGlobMom = Acts::Vector3(state->get_px(), + state->get_py(), + state->get_pz()); + + const float stateRPhiErr = state->get_rphi_error(); + const float stateZErr = state->get_z_error(); + + const float stateR = get_r(stateGlobPosition(0), stateGlobPosition(1)); + + const auto dr = clusR - stateR; + const auto trackDrDt = (stateGlobPosition(0) * stateGlobMom(0) + stateGlobPosition(1) * stateGlobMom(1)) / stateR; + const auto trackDxDr = stateGlobMom(0) / trackDrDt; + const auto trackDyDr = stateGlobMom(1) / trackDrDt; + const auto trackDzDr = stateGlobMom(2) / trackDrDt; + + const auto trackX = stateGlobPosition(0) + dr * trackDxDr; + const auto trackY = stateGlobPosition(1) + dr * trackDyDr; + const auto trackZ = stateGlobPosition(2) + dr * trackDzDr; + const float statePhi = std::atan2(trackY, trackX); + const float stateZ = trackZ; + + // Calculate residuals + const float drphi = clusR * deltaPhi(clusPhi - statePhi); + const float dz = clusZ - stateZ; + + const auto trackPPhi = -stateGlobMom(0) * std::sin(statePhi) + stateGlobMom(1) * std::cos(statePhi); + const auto trackPR = stateGlobMom(0) * std::cos(statePhi) + stateGlobMom(1) * std::sin(statePhi); + const auto trackPZ = stateGlobMom(2); + + const auto trackAlpha = -trackPPhi / trackPR; + const auto trackBeta = -trackPZ / trackPR; + const auto trackEta = std::atanh(stateGlobMom(2) / stateGlobMom.norm()); + const auto clusEta = std::atanh(clusZ / clusGlobPosition.norm()); + + h_alpha->Fill(trackAlpha, drphi); + h_beta->Fill(trackBeta, dz); + h_rphiResid->Fill(clusR, drphi); + h_zResid->Fill(stateZ, dz); + h_etaResid->Fill(trackEta, clusEta - trackEta); + h_zResidLayer->Fill(clusR, dz); + h_etaResidLayer->Fill(clusR, clusEta - trackEta); + + const auto layer = TrkrDefs::getLayer(key); + h_deltarphi_layer->Fill(layer, drphi); + h_deltaz_layer->Fill(layer, dz); + + h_statez_pulls->Fill(layer, dz / stateZErr); + h_staterphi_pulls->Fill(layer, drphi / stateRPhiErr); + h_clusz_pulls->Fill(layer, dz / clusZErr); + h_clusrphi_pulls->Fill(layer, drphi / clusRPhiErr); + + m_tanAlpha = trackAlpha; + m_tanBeta = trackBeta; + m_drphi = drphi; + m_dz = dz; + m_clusR = clusR; + m_clusPhi = clusPhi; + m_clusZ = clusZ; + m_statePhi = statePhi; + m_stateZ = stateZ; + m_stateR = stateR; + m_stateRPhiErr = stateRPhiErr; + m_stateZErr = stateZErr; + m_clusRPhiErr = clusRPhiErr; + m_clusZErr = clusZErr; + m_cluskey = key; + t_tree->Fill(); + } + } + + m_event++; + + return Fun4AllReturnCodes::EVENT_OK; +} + +bool QAG4SimulationDistortions::checkTrack(SvtxTrack* track) +{ + if (track->get_pt() < 0.5) + { + return false; + } + + // ignore tracks with too few mvtx, intt and micromegas hits + const auto cluster_keys(get_cluster_keys(track)); + if (count_clusters(cluster_keys) < 2) return false; + if (count_clusters(cluster_keys) < 2) return false; + if (count_clusters(cluster_keys) < 2) + { + return false; + } + + return true; +} + +std::vector QAG4SimulationDistortions::get_cluster_keys(SvtxTrack* track) +{ + std::vector out; + for (const auto& seed : {track->get_silicon_seed(), track->get_tpc_seed()}) + { + if (seed) + { + std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out)); + } + } + return out; +} diff --git a/offline/QA/modules/QAG4SimulationDistortions.h b/offline/QA/modules/QAG4SimulationDistortions.h new file mode 100644 index 0000000000..e2da48f59f --- /dev/null +++ b/offline/QA/modules/QAG4SimulationDistortions.h @@ -0,0 +1,60 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef QAG4SIMULATIONDISTORTIONS_H +#define QAG4SIMULATIONDISTORTIONS_H + +#include +#include + +#include +#include +#include + +class PHCompositeNode; +class SvtxTrackMap; +class TrkrClusterContainer; +class SvtxTrack; +class ActsGeometry; + +class QAG4SimulationDistortions : public SubsysReco +{ + public: + QAG4SimulationDistortions(const std::string& name = "QAG4SimulationDistortions"); + + ~QAG4SimulationDistortions() override; + + int Init(PHCompositeNode*) override; + int InitRun(PHCompositeNode* topNode) override; + int process_event(PHCompositeNode*) override; + + private: + std::string get_histo_prefix() + { + return std::string("h_") + Name() + std::string("_"); + } + + std::vector get_cluster_keys(SvtxTrack* track); + bool checkTrack(SvtxTrack* track); + SvtxTrackMap* m_trackMap = nullptr; + TrkrClusterContainer* m_clusterContainer = nullptr; + ActsGeometry* m_tGeometry = nullptr; + + int m_event = 0; + float m_tanAlpha = NAN; + float m_tanBeta = NAN; + float m_drphi = NAN; + float m_dz = NAN; + float m_clusR = NAN; + float m_clusPhi = NAN; + float m_clusZ = NAN; + float m_statePhi = NAN; + float m_stateZ = NAN; + float m_stateR = NAN; + float m_stateRPhiErr = NAN; + float m_stateZErr = NAN; + float m_clusRPhiErr = NAN; + float m_clusZErr = NAN; + TrkrDefs::cluskey m_cluskey = TrkrDefs::CLUSKEYMAX; +}; + +#endif // QAG4SIMULATIONDISTORTIONS_H diff --git a/offline/QA/modules/QAG4SimulationMicromegas.cc b/offline/QA/modules/QAG4SimulationMicromegas.cc index 320a4bd025..c5301858d9 100644 --- a/offline/QA/modules/QAG4SimulationMicromegas.cc +++ b/offline/QA/modules/QAG4SimulationMicromegas.cc @@ -272,10 +272,10 @@ int QAG4SimulationMicromegas::load_nodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } - m_hitsets = findNode::getClass(topNode, "TRKR_HITSET"); + m_hitsets = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); if (!m_hitsets) { - std::cout << PHWHERE << " ERROR: Can't find TrkrHitSetContainer." << std::endl; + std::cout << PHWHERE << " ERROR: Can't find TrkrHitSetContainer TRKR_HITSET_MICROMEGAS." << std::endl; } m_cluster_map = findNode::getClass(topNode, "TRKR_CLUSTER"); diff --git a/offline/database/PHParameter/PHParameters.cc b/offline/database/PHParameter/PHParameters.cc index 5ea4ffc9b1..4957b0bd9d 100644 --- a/offline/database/PHParameter/PHParameters.cc +++ b/offline/database/PHParameter/PHParameters.cc @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include @@ -502,11 +502,12 @@ int PHParameters::ReadFromDB() int PHParameters::ReadFromCDB(const std::string &domain) { - std::string url = XploadInterface::instance()->getUrl(domain); + std::string url = CDBInterface::instance()->getUrl(domain); TFile *f = TFile::Open(url.c_str()); if (!f) { - std::cout << "could not open " << url << std::endl; + std::cout << "could not open " << url + << " for domain " << domain << std::endl; gSystem->Exit(1); } PdbParameterMap *myparm = static_cast(f->Get("PdbParameterMap")); diff --git a/offline/database/sphenixnpc/CDBUtils.cc b/offline/database/sphenixnpc/CDBUtils.cc new file mode 100644 index 0000000000..2528c90f4c --- /dev/null +++ b/offline/database/sphenixnpc/CDBUtils.cc @@ -0,0 +1,208 @@ +#include "CDBUtils.h" + +#include "SphenixClient.h" + +#include + +#include +#include + +CDBUtils::CDBUtils() + : cdbclient(new SphenixClient()) +{ +} + +CDBUtils::CDBUtils(const std::string &globaltag) + : cdbclient(new SphenixClient(globaltag)) +{ +} + +int CDBUtils::createGlobalTag(const std::string &tagname) +{ + nlohmann::json resp = cdbclient->createGlobalTag(tagname); + int iret = resp["code"]; + nlohmann::json msgcont = resp["msg"]; + std::cout << msgcont << std::endl; + return iret; +} + +int CDBUtils::deleteGlobalTag(const std::string &tagname) +{ + nlohmann::json resp = cdbclient->deleteGlobalTag(tagname); + int iret = resp["code"]; + nlohmann::json msgcont = resp["msg"]; + std::cout << msgcont << std::endl; + return iret; +} + +int CDBUtils::lockGlobalTag(const std::string &tagname) +{ + nlohmann::json resp = cdbclient->lockGlobalTag(tagname); + int iret = resp["code"]; + nlohmann::json msgcont = resp["msg"]; + std::cout << msgcont << std::endl; + return iret; +} + +int CDBUtils::unlockGlobalTag(const std::string &tagname) +{ + nlohmann::json resp = cdbclient->unlockGlobalTag(tagname); + int iret = resp["code"]; + nlohmann::json msgcont = resp["msg"]; + std::cout << "message: " << msgcont << std::endl; + return iret; +} + +void CDBUtils::clearCache() +{ + cdbclient->clearCache(); +} + +std::string CDBUtils::getUrl(const std::string &type, uint64_t iov) +{ + nlohmann::json resp = cdbclient->getUrl(type, iov); + return resp["msg"]; +} + +int CDBUtils::createPayloadType(const std::string &pt) +{ + int iret = -1; + nlohmann::json resp; + if (m_PayloadTypeCache.empty()) + { + resp = cdbclient->getPayloadTypes(); + nlohmann::json msgcont = resp["msg"]; + for (auto &it : msgcont.items()) + { + std::string existent_pt = it.value().at("name"); + m_PayloadTypeCache.insert(existent_pt); + } + } + if (m_PayloadTypeCache.find(pt) == m_PayloadTypeCache.end()) + { + resp = cdbclient->createPayloadType(pt); + iret = resp["code"]; + if (iret == 0) + { + m_PayloadTypeCache.insert(pt); + } + } + else + { + std::cout << "PayloadTypeCache " << pt << " exists already" << std::endl; + iret = 0; + } + return iret; +} + +void CDBUtils::listGlobalTags() +{ + nlohmann::json resp = cdbclient->getGlobalTags(); + nlohmann::json msgcont = resp["msg"]; + for (auto &it : msgcont.items()) + { + std::string exist_gt = it.value().at("name"); + std::cout << "global tag: " << exist_gt << std::endl; + } + return; +} + +void CDBUtils::listPayloadTypes() +{ + nlohmann::json resp = cdbclient->getPayloadTypes(); + nlohmann::json msgcont = resp["msg"]; + for (auto &it : msgcont.items()) + { + std::string exist_pl = it.value().at("name"); + std::cout << "payload type: " << exist_pl << std::endl; + } + return; +} + +int CDBUtils::insertPayload(const std::string &pl_type, const std::string &file_url, uint64_t iov_start) +{ + if (!isGlobalTagSet()) + { + std::cout << "No Global Tag set" << std::endl; + return -1; + } + nlohmann::json resp = cdbclient->insertPayload(pl_type, file_url, iov_start); + int iret = resp["code"]; + if (iret != 0) + { + std::cout << "Error inserting payload " << file_url << ", msg: " << resp["msg"] << std::endl; + } + else + { + std::cout << resp["msg"] << std::endl; + } + return iret; +} + +int CDBUtils::insertPayload(const std::string &pl_type, const std::string &file_url, uint64_t iov_start, uint64_t iov_end) +{ + if (!isGlobalTagSet()) + { + std::cout << "No Global Tag set" << std::endl; + return -1; + } + nlohmann::json resp = cdbclient->insertPayload(pl_type, file_url, iov_start, iov_end); + int iret = resp["code"]; + if (iret != 0) + { + std::cout << "Error inserting payload " << file_url << ", msg: " << resp["msg"] << std::endl; + } + else + { + std::cout << resp["msg"] << std::endl; + } + return iret; +} + +int CDBUtils::setGlobalTag(const std::string &tagname) +{ + nlohmann::json resp = cdbclient->setGlobalTag(tagname); + int iret = resp["code"]; + std::cout << "message: " << resp["msg"] << std::endl; + return iret; +} + +bool CDBUtils::isGlobalTagSet() +{ + return cdbclient->isGlobalTagSet(); +} + +/* +int CDBUtils::createPayloadType(const std::string& pl_type) +{ + if (! isGlobalTagSet()) + { + std::cout << "No Global Tag Set to add payload " << pl_type << " to" << std::endl; + return -1; + } + nlohmann::json resp = cdbclient->createPayloadType(pl_type); + nlohmann::json msgcont = resp["msg"]; + for (auto &it : msgcont.items()) + { + std::cout << it.value() << std::endl; + // std::string exist_pl = it.value().at("name"); + // std::cout << "payload type: " << exist_pl << std::endl; + } + + int iret = 0;//resp["code"]; + if (iret != 0) + { + std::cout << "Error setting global tag, msg: " << resp["msg"] << std::endl; + } + return iret; +} +*/ + +void CDBUtils::Verbosity(int i) +{ + if (cdbclient) + { + cdbclient->Verbosity(i); + } + m_Verbosity = i; +} diff --git a/offline/database/sphenixnpc/CDBUtils.h b/offline/database/sphenixnpc/CDBUtils.h new file mode 100644 index 0000000000..1fe25d02f0 --- /dev/null +++ b/offline/database/sphenixnpc/CDBUtils.h @@ -0,0 +1,45 @@ +#ifndef SPHENIXNPC_CDBUTILS_H +#define SPHENIXNPC_CDBUTILS_H + +#include +#include +#include +#include + +class SphenixClient; + +class CDBUtils +{ + public: + CDBUtils(); + explicit CDBUtils(const std::string &globaltag); + + // delete copy ctor and assignment operator (cppcheck) + explicit CDBUtils(const CDBUtils&) = delete; + CDBUtils& operator=(const CDBUtils&) = delete; + + virtual ~CDBUtils() = default; + int createGlobalTag(const std::string &tagname); + int setGlobalTag(const std::string &tagname); + int lockGlobalTag(const std::string &tagname); + int unlockGlobalTag(const std::string &tagname); + int createPayloadType(const std::string &domain); + std::string getUrl(const std::string &type, uint64_t iov); + int insertPayload(const std::string &pl_type, const std::string &file_url, uint64_t iov_start); + int insertPayload(const std::string &pl_type, const std::string &file_url, uint64_t iov_start, uint64_t iov_end); + int deleteGlobalTag(const std::string &); + void listGlobalTags(); + void listPayloadTypes(); + void clearCache(); + bool isGlobalTagSet(); + void Verbosity(int i); + int Verbosity() const { return m_Verbosity; } + + private: + int m_Verbosity = 0; + SphenixClient *cdbclient = nullptr; + std::string m_CachedGlobalTag; + std::set m_PayloadTypeCache; +}; + +#endif // SPHENIXNPC_CDBUTILS_H diff --git a/offline/database/sphenixnpc/Makefile.am b/offline/database/sphenixnpc/Makefile.am new file mode 100644 index 0000000000..10b7d1188f --- /dev/null +++ b/offline/database/sphenixnpc/Makefile.am @@ -0,0 +1,54 @@ +AUTOMAKE_OPTIONS = foreign + +# List of shared libraries to produce +lib_LTLIBRARIES = \ + libsphenixnpc.la + +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 + +libsphenixnpc_la_SOURCES = \ + CDBUtils.cc \ + SphenixClient.cc + + +libsphenixnpc_la_LIBADD = \ + -lnopayloadclient + +############################################## +# please add new classes in alphabetical order + +pkginclude_HEADERS = \ + CDBUtils.h \ + SphenixClient.h + +################################################ +# linking tests + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libsphenixnpc.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +############################################## +# please add new classes in alphabetical order + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/offline/database/sphenixnpc/SphenixClient.cc b/offline/database/sphenixnpc/SphenixClient.cc new file mode 100644 index 0000000000..31646df659 --- /dev/null +++ b/offline/database/sphenixnpc/SphenixClient.cc @@ -0,0 +1,175 @@ +#include "SphenixClient.h" + +#include + +#include +#include +#include + +SphenixClient::SphenixClient(const std::string& gt_name) + : nopayloadclient::NoPayloadClient(gt_name) + , m_CachedGlobalTag(gt_name) +{} + +nlohmann::json SphenixClient::getPayloadIOVs(long long iov) +{ + return nopayloadclient::NoPayloadClient::getPayloadIOVs(0, iov); +} + +nlohmann::json SphenixClient::getUrl(const std::string& pl_type, long long iov) +{ + nlohmann::json resp = getPayloadIOVs(iov); + if (resp["code"] != 0) + { + return resp; + } + nlohmann::json payload_iovs = resp["msg"]; + if (!payload_iovs.contains(pl_type)) + { + return nopayloadclient::DataBaseException("No valid payload with type " + pl_type).jsonify(); + } + nlohmann::json payload_iov = payload_iovs[pl_type]; + if (payload_iov["minor_iov_end"] < iov) + { + return nopayloadclient::DataBaseException("No valid payload with type " + pl_type).jsonify(); + } + return makeResp(payload_iov["payload_url"]); +} + +std::string SphenixClient::getCalibration(const std::string& pl_type, long long iov) +{ + nlohmann::json resp = getUrl(pl_type, iov); + if (resp["code"] != 0) + { + if (m_Verbosity> 0) + { + std::cout << resp["msg"] << std::endl; + } + return ""; + } + return resp["msg"]; +} + +nlohmann::json SphenixClient::insertPayload(const std::string& pl_type, const std::string& file_url, + long long iov_start) +{ + return nopayloadclient::NoPayloadClient::insertPayload(pl_type, file_url, 0, iov_start); +} + +nlohmann::json SphenixClient::insertPayload(const std::string& pl_type, const std::string& file_url, + long long iov_start, long long iov_end) +{ + return nopayloadclient::NoPayloadClient::insertPayload(pl_type, file_url, 0, iov_start, 0, iov_end); +} + +nlohmann::json SphenixClient::setGlobalTag(const std::string& gt_name) +{ + if (m_CachedGlobalTag == gt_name) + { + std::string message = "global tag already set to " + gt_name; + return {{"code", 0}, {"msg", message}}; + } + // check if the global tag exists before switching + bool found_gt = false; + nlohmann::json resp = nopayloadclient::NoPayloadClient::getGlobalTags(); + nlohmann::json msgcont = resp["msg"]; + for (auto& it : msgcont.items()) + { + std::string exist_gt = it.value().at("name"); + if (exist_gt == gt_name) + { + found_gt = true; + break; + } + } + if (found_gt) + { + m_CachedGlobalTag = gt_name; + return nopayloadclient::NoPayloadClient::setGlobalTag(gt_name); + } + + std::string message = "global tag " + gt_name + " does not exist"; + return {{"code", -1}, {"msg", message}}; +} + +nlohmann::json SphenixClient::clearCache() +{ + return nopayloadclient::NoPayloadClient::clearCache(); +} + +int SphenixClient::cache_set_GlobalTag(const std::string& tagname) +{ + int iret = 0; + if (tagname == m_CachedGlobalTag) // global tag already set + { + return iret; + } + m_CachedGlobalTag = tagname; + nopayloadclient::NoPayloadClient::setGlobalTag(tagname); + bool found_gt = false; + nlohmann::json resp = nopayloadclient::NoPayloadClient::getGlobalTags(); + nlohmann::json msgcont = resp["msg"]; + for (auto& it : msgcont.items()) + { + std::string exist_gt = it.value().at("name"); + std::cout << "global tag: " << exist_gt << std::endl; + if (exist_gt == tagname) + { + found_gt = true; + break; + } + } + if (!found_gt) + { + resp = nopayloadclient::NoPayloadClient::createGlobalTag(); + iret = resp["code"]; + if (iret != 0) + { + std::cout << "Error creating global tag, msg: " << resp["msg"] << std::endl; + } + else + { + std::cout << "SphenixClient: Created new global tag " << tagname << std::endl; + } + } + return iret; +} + +int SphenixClient::createDomain(const std::string& domain) +{ + int iret = -1; + nlohmann::json resp; + if (m_DomainCache.empty()) + { + resp = nopayloadclient::NoPayloadClient::getPayloadTypes(); + nlohmann::json msgcont = resp["msg"]; + for (auto& it : msgcont.items()) + { + std::string existent_domain = it.value().at("name"); + m_DomainCache.insert(existent_domain); + } + } + if (m_DomainCache.find(domain) == m_DomainCache.end()) + { + resp = nopayloadclient::NoPayloadClient::createPayloadType(domain); + iret = resp["code"]; + if (iret == 0) + { + m_DomainCache.insert(domain); + } + } + else + { + iret = 0; + } + return iret; +} + +bool SphenixClient::isGlobalTagSet() +{ + if (m_CachedGlobalTag.empty()) + { + return false; + } + return true; +} diff --git a/offline/database/sphenixnpc/SphenixClient.h b/offline/database/sphenixnpc/SphenixClient.h new file mode 100644 index 0000000000..f0d55e5141 --- /dev/null +++ b/offline/database/sphenixnpc/SphenixClient.h @@ -0,0 +1,45 @@ +#ifndef SPHENIXNPC_SPHENIXCLIENT_H +#define SPHENIXNPC_SPHENIXCLIENT_H + +#include + +#include + +#include +#include +#include +#include + +class SphenixClient : public nopayloadclient::NoPayloadClient +{ + public: + SphenixClient() = default; + explicit SphenixClient(const std::string& globaltag); + virtual ~SphenixClient() = default; + // make clang happy, since we use our own without overriding the base class methods + using nopayloadclient::NoPayloadClient::getPayloadIOVs; + + nlohmann::json getPayloadIOVs(long long iov); + nlohmann::json getUrl(const std::string& pl_type, long long iov); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Woverloaded-virtual" + nlohmann::json insertPayload(const std::string& pl_type, const std::string& file_url, long long iov_start); +#pragma GCC diagnostic pop + nlohmann::json insertPayload(const std::string& pl_type, const std::string& file_url, long long iov_start, long long iov_end); + nlohmann::json setGlobalTag(const std::string& name); + nlohmann::json clearCache(); + std::string getCalibration(const std::string& pl_type, long long iov); + + int createDomain(const std::string& domain); + int cache_set_GlobalTag(const std::string& name); + bool isGlobalTagSet(); + void Verbosity(int i) { m_Verbosity = i; } + int Verbosity() const { return m_Verbosity; } + + private: + int m_Verbosity = 0; + std::string m_CachedGlobalTag; + std::set m_DomainCache; +}; + +#endif // SPHENIXNPC_SPHENIXCLIENT_H diff --git a/offline/database/sphenixnpc/autogen.sh b/offline/database/sphenixnpc/autogen.sh new file mode 100755 index 0000000000..be614cda0c --- /dev/null +++ b/offline/database/sphenixnpc/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/offline/database/sphenixnpc/configure.ac b/offline/database/sphenixnpc/configure.ac new file mode 100644 index 0000000000..75794b946c --- /dev/null +++ b/offline/database/sphenixnpc/configure.ac @@ -0,0 +1,13 @@ +AC_INIT(sphenixnpc,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE +AC_PROG_CXX(CC g++) +LT_INIT([disable-static]) + +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Werror -Wextra -Wshadow" +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/offline/framework/ffamodules/XploadInterface.cc b/offline/framework/ffamodules/CDBInterface.cc similarity index 68% rename from offline/framework/ffamodules/XploadInterface.cc rename to offline/framework/ffamodules/CDBInterface.cc index ff78249d6f..b9773a82e9 100644 --- a/offline/framework/ffamodules/XploadInterface.cc +++ b/offline/framework/ffamodules/CDBInterface.cc @@ -1,4 +1,6 @@ -#include "XploadInterface.h" +#include "CDBInterface.h" + +#include #include #include @@ -15,27 +17,27 @@ #include #include -#include +#include #include // for uint64_t #include // for operator<<, basic_ostream, endl #include // for pair #include // for vector -XploadInterface *XploadInterface::__instance = nullptr; +CDBInterface *CDBInterface::__instance = nullptr; -XploadInterface *XploadInterface::instance() +CDBInterface *CDBInterface::instance() { if (__instance) { return __instance; } - __instance = new XploadInterface(); + __instance = new CDBInterface(); return __instance; } //____________________________________________________________________________.. -XploadInterface::XploadInterface(const std::string &name) +CDBInterface::CDBInterface(const std::string &name) : SubsysReco(name) { Fun4AllServer *se = Fun4AllServer::instance(); @@ -43,7 +45,14 @@ XploadInterface::XploadInterface(const std::string &name) } //____________________________________________________________________________.. -int XploadInterface::End(PHCompositeNode *topNode) + +CDBInterface::~CDBInterface() +{ + delete cdbclient; +} + +//____________________________________________________________________________.. +int CDBInterface::End(PHCompositeNode *topNode) { PHNodeIterator iter(topNode); PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); @@ -93,7 +102,7 @@ int XploadInterface::End(PHCompositeNode *topNode) } //____________________________________________________________________________.. -void XploadInterface::Print(const std::string & /* what */) const +void CDBInterface::Print(const std::string & /* what */) const { for (auto &iter : m_UrlVector) { @@ -103,15 +112,30 @@ void XploadInterface::Print(const std::string & /* what */) const } } -std::string XploadInterface::getUrl(const std::string &domain, const std::string &filename) +std::string CDBInterface::getUrl(const std::string &domain, const std::string &filename) { - std::string return_url = filename; recoConsts *rc = recoConsts::instance(); - uint64_t timestamp = rc->get_uint64Flag("TIMESTAMP", 12345678912345); - xpload::Result result = xpload::fetch(rc->get_StringFlag("XPLOAD_TAG", "TEST"), domain, timestamp, xpload::Configurator(rc->get_StringFlag("XPLOAD_CONFIG", "sPHENIX_cdb"))); - if (!result.payload.empty()) + if (! rc->FlagExist("CDB_GLOBALTAG")) + { + std::cout << "CDB_GLOBALTAG flag needs to be set via" << std::endl; + std::cout << "rc->set_StringFlag(\"CDB_GLOBALTAG\",)" << std::endl; + gSystem->Exit(1); + } + if (! rc->FlagExist("TIMESTAMP")) + { + std::cout << "TIMESTAMP flag needs to be set via" << std::endl; + std::cout << "rc->set_uint64Flag(\"TIMESTAMP\",<64 bit timestamp>)" << std::endl; + gSystem->Exit(1); + } + if (cdbclient == nullptr) + { + cdbclient = new SphenixClient(rc->get_StringFlag("CDB_GLOBALTAG")); + } + uint64_t timestamp = rc->get_uint64Flag("TIMESTAMP"); + std::string return_url = cdbclient->getCalibration(domain,timestamp); + if (return_url.empty()) { - return_url = result.payload; + return_url = filename; } auto pret = m_UrlVector.insert(make_tuple(domain, return_url, timestamp)); if (!pret.second && Verbosity() > 1) diff --git a/offline/framework/ffamodules/XploadInterface.h b/offline/framework/ffamodules/CDBInterface.h similarity index 60% rename from offline/framework/ffamodules/XploadInterface.h rename to offline/framework/ffamodules/CDBInterface.h index 92093b1d53..41dd293586 100644 --- a/offline/framework/ffamodules/XploadInterface.h +++ b/offline/framework/ffamodules/CDBInterface.h @@ -1,7 +1,7 @@ // Tell emacs that this is a C++ source // -*- C++ -*-. -#ifndef FFAMODULES_XPLOADINTERFACE_H -#define FFAMODULES_XPLOADINTERFACE_H +#ifndef FFAMODULES_CDBINTERFACE_H +#define FFAMODULES_CDBINTERFACE_H #include @@ -11,13 +11,14 @@ #include // for tuple class PHCompositeNode; +class SphenixClient; -class XploadInterface : public SubsysReco +class CDBInterface : public SubsysReco { public: - static XploadInterface *instance(); + static CDBInterface *instance(); - ~XploadInterface() override {} + ~CDBInterface() override; /// Called at the end of all processing. int End(PHCompositeNode *topNode) override; @@ -27,11 +28,11 @@ class XploadInterface : public SubsysReco std::string getUrl(const std::string &domain, const std::string &filename = ""); private: - XploadInterface(const std::string &name = "XploadInterface"); - - static XploadInterface *__instance; + CDBInterface(const std::string &name = "CDBInterface"); + static CDBInterface *__instance; + SphenixClient *cdbclient = nullptr; std::set> m_UrlVector; }; -#endif // FFAMODULES_XPLOADINTERFACE_H +#endif // FFAMODULES_CDBINTERFACE_H diff --git a/offline/framework/ffamodules/Makefile.am b/offline/framework/ffamodules/Makefile.am index 2716fbe047..8f926fb419 100644 --- a/offline/framework/ffamodules/Makefile.am +++ b/offline/framework/ffamodules/Makefile.am @@ -6,7 +6,7 @@ lib_LTLIBRARIES = \ AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ - -I$(ROOTSYS)/include + -isystem$(ROOTSYS)/include AM_LDFLAGS = \ -L$(libdir) \ @@ -17,21 +17,20 @@ libffamodules_la_LIBADD = \ -lfun4all \ -lffaobjects \ -lphhepmc_io \ - -lSubsysReco \ - -lxpload \ - -lstdc++fs + -lsphenixnpc \ + -lSubsysReco pkginclude_HEADERS = \ + CDBInterface.h \ FlagHandler.h \ HeadReco.h \ - SyncReco.h \ - XploadInterface.h + SyncReco.h libffamodules_la_SOURCES = \ + CDBInterface.cc \ FlagHandler.cc \ HeadReco.cc \ - SyncReco.cc \ - XploadInterface.cc + SyncReco.cc BUILT_SOURCES = testexternals.cc diff --git a/offline/framework/ffaobjects/CdbUrlSavev1.h b/offline/framework/ffaobjects/CdbUrlSavev1.h index ca8da58a00..0138c339c0 100644 --- a/offline/framework/ffaobjects/CdbUrlSavev1.h +++ b/offline/framework/ffaobjects/CdbUrlSavev1.h @@ -11,6 +11,8 @@ #include #include // for vector<>::const_iterator, vector +class PHObject; + /// class CdbUrlSavev1 : public CdbUrlSave { diff --git a/offline/framework/ffaobjects/Makefile.am b/offline/framework/ffaobjects/Makefile.am index bc0c547333..1c569ef9b0 100644 --- a/offline/framework/ffaobjects/Makefile.am +++ b/offline/framework/ffaobjects/Makefile.am @@ -6,7 +6,7 @@ lib_LTLIBRARIES = \ AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ - -I$(ROOTSYS)/include + -isystem$(ROOTSYS)/include AM_LDFLAGS = \ -L$(libdir) \ diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 3890aa4093..a091eaa2f3 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -28,6 +28,12 @@ unlink $listfile; } } +my %exclude_these = ( + "DST_JOBA" => "Test PanDa", + "DST_MDC2_GLOBAL" => "Test PanDa", + "DST_PASS1_CLUSTERS" => "Test PanDa", + "DST_RECO_CLUSTER" => "Test PanDa" + ); my %proddesc = ( # "1" => "hijing (0-12fm) pileup 0-12fm DELETED", @@ -47,7 +53,10 @@ "15" => "Special Productions", "16" => "HF pythia8 D0 Jets", "17" => "HF pythia8 D0 pi-k Jets ptmin = 5GeV ", - "18" => "HF pythia8 D0 pi-k Jets ptmin = 12GeV" + "18" => "HF pythia8 D0 pi-k Jets ptmin = 12GeV", + "19" => "JS pythia8 Jet ptmin = 40GeV", + "20" => "hijing pAu (0-10fm) pileup 0-10fm", + "21" => "JS pythia8 Jet ptmin = 20GeV" ); my %pileupdesc = ( @@ -70,14 +79,16 @@ my $pmin; my $pmax; my $production; - -GetOptions('embed' => \$embed, 'l:i' => \$last_segment, 'n:i' => \$nEvents, "nopileup" => \$nopileup, "particle:s" => \$particle, 'pileup:i' => \$pileup, "pmin:i" => \$pmin, "pmax:i"=>\$pmax, "production:s"=>\$production, 'rand' => \$randomize, 'run:i' => \$runnumber, 's:i' => \$start_segment, 'type:i' =>\$prodtype, "verbose" =>\$verbose); +my $momentum; +GetOptions('embed:s' => \$embed, 'l:i' => \$last_segment, 'momentum:s' => \$momentum, 'n:i' => \$nEvents, "nopileup" => \$nopileup, "particle:s" => \$particle, 'pileup:i' => \$pileup, "pmin:i" => \$pmin, "pmax:i"=>\$pmax, "production:s"=>\$production, 'rand' => \$randomize, 'run:i' => \$runnumber, 's:i' => \$start_segment, 'type:i' =>\$prodtype, "verbose" =>\$verbose); my $filenamestring; my %filetypes = (); my %notlike = (); -my $pileupstring; +my $AuAu_pileupstring; my $pp_pileupstring; +my $pAu_pileupstring; +my $pileupstring; if (defined $embed && defined $nopileup) { @@ -86,16 +97,17 @@ } if ($pileup == 1) { - $pileupstring = sprintf("50kHz"); + $AuAu_pileupstring = sprintf("50kHz"); $pp_pileupstring = sprintf("3MHz"); + $pAu_pileupstring = sprintf("500kHz"); } elsif ($pileup == 2) { - $pileupstring = sprintf("25kHz"); + $AuAu_pileupstring = sprintf("25kHz"); } elsif ($pileup == 3) { - $pileupstring = sprintf("10kHz"); + $AuAu_pileupstring = sprintf("10kHz"); } else { @@ -109,13 +121,13 @@ { if ($prodtype == 1) { - $filenamestring = sprintf("sHijing_0_12fm_%s_bkg_0_12fm",$pileupstring); + $filenamestring = sprintf("sHijing_0_12fm_%s_bkg_0_12fm",$AuAu_pileupstring); die "This dataset has been deleted\n"; &commonfiletypes(); } elsif ($prodtype == 2) { - $filenamestring = sprintf("sHijing_0_488fm_%s_bkg_0_12fm",$pileupstring); + $filenamestring = sprintf("sHijing_0_488fm_%s_bkg_0_12fm",$AuAu_pileupstring); die "Dataset $prodtype has been deleted\n"; &commonfiletypes(); } @@ -126,6 +138,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 4) @@ -136,20 +149,22 @@ } else { - $filenamestring = sprintf("sHijing_0_20fm_%s_bkg_0_20fm",$pileupstring); + $filenamestring = sprintf("sHijing_0_20fm_%s_bkg_0_20fm",$AuAu_pileupstring); } $notlike{$filenamestring} = ["pythia8" ,"single", "special"]; + $pileupstring = $AuAu_pileupstring; &commonfiletypes(); } elsif ($prodtype == 5) { - $filenamestring = sprintf("sHijing_0_12fm_%s_bkg_0_20fm",$pileupstring); + $filenamestring = sprintf("sHijing_0_12fm_%s_bkg_0_20fm",$AuAu_pileupstring); die "Dataset $prodtype has been deleted\n"; &commonfiletypes(); } elsif ($prodtype == 6) { - $filenamestring = sprintf("sHijing_0_488fm_%s_bkg_0_20fm",$pileupstring); + $filenamestring = sprintf("sHijing_0_488fm_%s_bkg_0_20fm",$AuAu_pileupstring); + $pileupstring = $AuAu_pileupstring; &commonfiletypes(); } elsif ($prodtype == 7) @@ -159,6 +174,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 8) @@ -168,6 +184,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 9) @@ -177,6 +194,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 10) @@ -186,6 +204,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 11) @@ -196,13 +215,14 @@ { if (defined $embed) { - $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $pileupstring); + $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $AuAu_pileupstring); } else { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 12) @@ -213,13 +233,22 @@ { if (defined $embed) { - $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $pileupstring); + print "embed is $embed\n"; + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm_%s_bkg_0_10fm",$filenamestring, $pAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $AuAu_pileupstring); + } } else { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 13) @@ -230,13 +259,14 @@ { if (defined $embed) { - $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $pileupstring); + $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $AuAu_pileupstring); } else { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 14) @@ -258,7 +288,15 @@ } if (defined $pmin && defined $pmax) { - $filenamestring = sprintf("%s_%s_%d_%dMeV",$filenamestring, $particle, $pmin, $pmax); + if (defined $momentum) + { + $filenamestring = sprintf("%s_%s_%s_%d_%dMeV",$filenamestring, $particle, $momentum, $pmin, $pmax); + } + else + { + $filenamestring = sprintf("%s_%s_%d_%dMeV",$filenamestring, $particle, $pmin, $pmax); + } + if (defined $embed) { $filenamestring = sprintf("%s_sHijing_0_20fm_50kHz_bkg_0_20fm",$filenamestring); @@ -302,6 +340,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 17) @@ -311,6 +350,7 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } elsif ($prodtype == 18) @@ -320,6 +360,65 @@ { $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 19) + { + $embedok = 1; + $filenamestring = "pythia8_Jet40"; + if (! defined $nopileup) + { + if (defined $embed) + { + $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 20) + { + if (defined $nopileup) + { + $filenamestring = sprintf("sHijing_pAu_0_10fm"); + } + else + { + $filenamestring = sprintf("sHijing_pAu_0_10fm_%s_bkg_0_10fm",$pAu_pileupstring); + } + $notlike{$filenamestring} = ["pythia8" ,"single", "special"]; + $pileupstring = $pAu_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 21) + { + $embedok = 1; + $filenamestring = "pythia8_Jet20"; + if (! defined $nopileup) + { + if (defined $embed) + { + print "embed is $embed\n"; + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm_%s_bkg_0_10fm",$filenamestring, $pAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm_%s_bkg_0_20fm",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s_%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; &commonfiletypes(); } else @@ -335,6 +434,13 @@ print "Embedding not implemented for type $prodtype\n"; exit(1); } +if (defined $embed) +{ + if ($embed ne "pau" && $embed ne "auau") + { + push(@ARGV,$embed); + } +} my $filenamestring_with_runnumber = sprintf("%s\-%010d-",$filenamestring,$runnumber); if ($#ARGV < 0) @@ -343,7 +449,8 @@ { print "usage: CreateFileLists.pl -type \n"; print "parameters:\n"; - print "-embed : pp embedded into hijing (only for pp types)\n"; + print "-embed : pp embedded into AuAu hijing (only for pp types)\n"; + print "-embed pau : embedded into pAu (only for pp types\n"; print "-l : last segment\n"; print "-n : \n"; print "-nopileup : without pileup\n"; @@ -362,6 +469,7 @@ } print "\n Single particle mandatory options:\n"; print "-particle : G4 particle name\n"; + print "-mom : (optional) p or pt\n"; print "-pmin : minimum momentum (in MeV/c)\n"; print "-pmax : maximum momentum (in MeV/c)\n"; @@ -371,7 +479,10 @@ print "\navailable file types (choose at least one, --> means: written to):\n"; foreach my $tp (sort keys %dsttype) { - print "$tp --> $dsttype{$tp}\n"; + if (! exists $exclude_these{$tp}) + { + print "$tp --> $dsttype{$tp}\n"; + } } } else @@ -504,20 +615,9 @@ } else { - my @sp1 = split(/_/,$filenamestring_with_runnumber); - if ($#sp1 == 3 || $#sp1 == 6 ) - { - $newfilenamestring = sprintf("%s_%s_%s\-%010d-",$sp1[0],$sp1[1],$sp1[2],$runnumber); - } - elsif ($#sp1 == 2) - { - $newfilenamestring = sprintf("%s_%s\-%010d-",$sp1[0],$sp1[1],$runnumber); - } - else - { - print "splitting $filenamestring_with_runnumber gave bad number of _: $#sp1\n"; - die; - } + my $splitstring = sprintf("_%s",$pileupstring); + my @sp2 = split(/$splitstring/,$filenamestring_with_runnumber); + $newfilenamestring = sprintf("%s-%010d-",$sp2[0],$runnumber); } my $newgetfilesql = $getfilesql; $newgetfilesql =~ s/$filenamestring_with_runnumber/$newfilenamestring/; @@ -739,17 +839,34 @@ sub print_single_types { if ($name =~ /(\S+)\_(\d+)\_(\d+).*/ ) { - print "CreateFileList.pl -type 14 $types{$name} -run $runnumber -particle $1 -pmin $2 -pmax $3\n"; - } - else - { - print "CreateFileList.pl -type 14 $types{$name} -run $runnumber -particle $name\n"; + my $part = $1; + my $mom; + my $minp = $2; + my $maxp = $3; + if ($part =~ /(\S+)_(\S+)/) + { + $part = $1; + $mom = $2; + } + if (defined $mom) + { + print "CreateFileList.pl -type 14 $types{$name} -run $runnumber -particle $part -mom $mom -pmin $minp -pmax $maxp\n"; + } + else + { + print "CreateFileList.pl -type 14 $types{$name} -run $runnumber -particle $part -pmin $minp -pmax $maxp\n"; + } } + else + { + print "CreateFileList.pl -type 14 $types{$name} -run $runnumber -particle $name\n"; + + } } print "\nDST types:\n"; foreach my $name (sort keys %dsts) { - print "$name\n"; + print "$name\n"; } } diff --git a/offline/framework/fun4all/Fun4AllBase.cc b/offline/framework/fun4all/Fun4AllBase.cc index 002d07f598..eb6811fd9c 100644 --- a/offline/framework/fun4all/Fun4AllBase.cc +++ b/offline/framework/fun4all/Fun4AllBase.cc @@ -1,5 +1,6 @@ #include "Fun4AllBase.h" +#include #include #include diff --git a/offline/framework/fun4all/Fun4AllBase.h b/offline/framework/fun4all/Fun4AllBase.h index 9b92a70852..164275e1a9 100644 --- a/offline/framework/fun4all/Fun4AllBase.h +++ b/offline/framework/fun4all/Fun4AllBase.h @@ -8,13 +8,13 @@ /** Base class for all Fun4All Classes * - * It implements the Name, the Verbosity and the print method + * It implements the Name, the Verbosity and the print method */ class Fun4AllBase { public: - /** dtor. + /** dtor. Does nothing as this is a base class only. */ virtual ~Fun4AllBase(); @@ -25,7 +25,7 @@ class Fun4AllBase /// Sets the name of this module. virtual void Name(const std::string &name) { m_ThisName = name; } - /** Print out some info about this module. + /** Print out some info about this module. @param what can be used to specify what to print exactly. */ virtual void Print(const std::string &what = "ALL") const; @@ -66,7 +66,7 @@ class Fun4AllBase protected: /** ctor. - */ + */ Fun4AllBase(const std::string &name = "NONAME"); private: diff --git a/offline/framework/fun4all/Fun4AllDstInputManager.cc b/offline/framework/fun4all/Fun4AllDstInputManager.cc index ab3ce3d1e3..4a6a00ad4c 100644 --- a/offline/framework/fun4all/Fun4AllDstInputManager.cc +++ b/offline/framework/fun4all/Fun4AllDstInputManager.cc @@ -41,8 +41,8 @@ Fun4AllDstInputManager::Fun4AllDstInputManager(const std::string &name, const st Fun4AllDstInputManager::~Fun4AllDstInputManager() { - delete IManager; - delete runNodeSum; + delete m_IManager; + delete m_RunNodeSum; return; } @@ -65,78 +65,78 @@ int Fun4AllDstInputManager::fileopen(const std::string &filenam) } // sanity check - the IManager must be nullptr when this method is executed // if not something is very very wrong and we must not continue - if (IManager) + if (m_IManager) { - std::cout << PHWHERE << " IManager pointer is not nullptr but " << IManager + std::cout << PHWHERE << " IManager pointer is not nullptr but " << m_IManager << std::endl; std::cout << "Send mail to off-l with this printout and the macro you used" << std::endl; std::cout << "Trying to execute IManager->print() to display more info" << std::endl; std::cout << "Code will probably segfault now" << std::endl; - IManager->print(); + m_IManager->print(); std::cout << "Have someone look into this problem - Exiting now" << std::endl; exit(1); } // first read the runnode if not disabled if (m_ReadRunTTree) { - IManager = new PHNodeIOManager(fullfilename, PHReadOnly, PHRunTree); - if (IManager->isFunctional()) + m_IManager = new PHNodeIOManager(fullfilename, PHReadOnly, PHRunTree); + if (m_IManager->isFunctional()) { - runNode = se->getNode(RunNode, TopNodeName()); - IManager->read(runNode); + m_RunNode = se->getNode(RunNode, TopNodeName()); + m_IManager->read(m_RunNode); // get the current run number - RunHeader *runheader = findNode::getClass(runNode, "RunHeader"); + RunHeader *runheader = findNode::getClass(m_RunNode, "RunHeader"); if (runheader) { SetRunNumber(runheader->get_RunNumber()); } // delete our internal copy of the runnode when opening subsequent files - if (runNodeCopy) + if (m_RunNodeCopy) { std::cout << PHWHERE << " The impossible happened, we have a valid copy of the run node " - << runNodeCopy->getName() << " which should be a nullptr" + << m_RunNodeCopy->getName() << " which should be a nullptr" << std::endl; gSystem->Exit(1); } - runNodeCopy = new PHCompositeNode("RUNNODECOPY"); - if (!runNodeSum) + m_RunNodeCopy = new PHCompositeNode("RUNNODECOPY"); + if (!m_RunNodeSum) { - runNodeSum = new PHCompositeNode("RUNNODESUM"); + m_RunNodeSum = new PHCompositeNode("RUNNODESUM"); } PHNodeIOManager *tmpIman = new PHNodeIOManager(fullfilename, PHReadOnly, PHRunTree); - tmpIman->read(runNodeCopy); + tmpIman->read(m_RunNodeCopy); delete tmpIman; PHNodeIntegrate integrate; - integrate.RunNode(runNode); - integrate.RunSumNode(runNodeSum); + integrate.RunNode(m_RunNode); + integrate.RunSumNode(m_RunNodeSum); // run recursively over internal run node copy and integrate objects - PHNodeIterator mainIter(runNodeCopy); + PHNodeIterator mainIter(m_RunNodeCopy); mainIter.forEach(integrate); // we do not need to keep the internal copy, keeping it would crate // problems in case a subsequent file does not contain all the // runwise objects from the previous file. Keeping this copy would then // integrate the missing object again with the old copy - delete runNodeCopy; - runNodeCopy = nullptr; + delete m_RunNodeCopy; + m_RunNodeCopy = nullptr; } // DLW: move the delete outside the if block to cover the case where isFunctional() fails - delete IManager; + delete m_IManager; } // now open the dst node dstNode = se->getNode(InputNode(), TopNodeName()); - IManager = new PHNodeIOManager(fullfilename, PHReadOnly); - if (IManager->isFunctional()) + m_IManager = new PHNodeIOManager(fullfilename, PHReadOnly); + if (m_IManager->isFunctional()) { IsOpen(1); events_thisfile = 0; setBranches(); // set branch selections AddToFileOpened(FileName()); // add file to the list of files which were opened // check if our input file has a sync object or not - if (IManager->NodeExist(syncdefs::SYNCNODENAME)) + if (m_IManager->NodeExist(syncdefs::SYNCNODENAME)) { m_HaveSyncObject = 1; } @@ -151,8 +151,8 @@ int Fun4AllDstInputManager::fileopen(const std::string &filenam) { std::cout << PHWHERE << ": " << Name() << " Could not open file " << FileName() << std::endl; - delete IManager; - IManager = nullptr; + delete m_IManager; + m_IManager = nullptr; return -1; } } @@ -185,7 +185,7 @@ int Fun4AllDstInputManager::run(const int nevents) readagain: PHCompositeNode *dummy; int ncount = 0; - dummy = IManager->read(dstNode); + dummy = m_IManager->read(dstNode); while (dummy) { ncount++; @@ -193,7 +193,7 @@ int Fun4AllDstInputManager::run(const int nevents) { break; } - dummy = IManager->read(dstNode); + dummy = m_IManager->read(dstNode); } if (!dummy) { @@ -222,8 +222,8 @@ int Fun4AllDstInputManager::fileclose() std::cout << Name() << ": fileclose: No Input file open" << std::endl; return -1; } - delete IManager; - IManager = nullptr; + delete m_IManager; + m_IManager = nullptr; IsOpen(0); UpdateFileList(); m_HaveSyncObject = 0; @@ -372,7 +372,7 @@ int Fun4AllDstInputManager::SyncIt(const SyncObject *mastersync) // Here the event counter and segment number and run number do agree - we found the right match // now read the full event (previously we only read the sync object) PHCompositeNode *dummy; - dummy = IManager->read(dstNode); + dummy = m_IManager->read(dstNode); if (!dummy) { std::cout << PHWHERE << " " << Name() << " Could not read full Event" << std::endl; @@ -413,7 +413,7 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() { readnextsync: static int readfull = 0; // for some reason all the input managers need to see the same (I think, should look at this at some point) - if (!IManager) // in case the old file was exhausted and there is no new file opened + if (!m_IManager) // in case the old file was exhausted and there is no new file opened { return Fun4AllReturnCodes::SYNC_FAIL; } @@ -421,7 +421,7 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() { readfull = 1; // we need to read a full event to set the root branches to phool nodes right when a new file has been opened std::map::const_iterator bIter; - for (bIter = IManager->GetBranchMap()->begin(); bIter != IManager->GetBranchMap()->end(); ++bIter) + for (bIter = m_IManager->GetBranchMap()->begin(); bIter != m_IManager->GetBranchMap()->end(); ++bIter) { if (Verbosity() > 2) { @@ -430,7 +430,7 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() std::string delimeters = phooldefs::branchpathdelim; // + phooldefs::legacypathdelims; std::vector splitvec; boost::split(splitvec, bIter->first, boost::is_any_of(delimeters)); - for (auto & ia : splitvec) // -1 so we skip the node name + for (auto &ia : splitvec) // -1 so we skip the node name { if (ia == syncdefs::SYNCNODENAME) { @@ -448,7 +448,7 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() std::cout << PHWHERE << "Could not locate Sync Branch" << std::endl; std::cout << "Please check for it in the following list of branch names and" << std::endl; std::cout << "PLEASE NOTIFY PHENIX-OFF-L and post the macro you used" << std::endl; - for (bIter = IManager->GetBranchMap()->begin(); bIter != IManager->GetBranchMap()->end(); ++bIter) + for (bIter = m_IManager->GetBranchMap()->begin(); bIter != m_IManager->GetBranchMap()->end(); ++bIter) { std::cout << bIter->first << std::endl; } @@ -461,10 +461,10 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() { // if all files are exhausted, the IManager is deleted and set to nullptr // so check if IManager is valid before getting a new event - if (IManager) + if (m_IManager) { - EventOnDst = IManager->getEventNumber(); // this returns the next number of the event - itest = IManager->readSpecific(EventOnDst, syncbranchname.c_str()); + EventOnDst = m_IManager->getEventNumber(); // this returns the next number of the event + itest = m_IManager->readSpecific(EventOnDst, syncbranchname.c_str()); } else { @@ -477,7 +477,7 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() } else { - if (IManager->read(dstNode)) + if (m_IManager->read(dstNode)) { itest = 1; } @@ -503,7 +503,7 @@ int Fun4AllDstInputManager::ReadNextEventSyncObject() if (!readfull) { EventOnDst++; - IManager->setEventNumber(EventOnDst); // update event number in phool io manager + m_IManager->setEventNumber(EventOnDst); // update event number in phool io manager } else { @@ -556,14 +556,14 @@ int Fun4AllDstInputManager::BranchSelect(const std::string &branch, const int if int Fun4AllDstInputManager::setBranches() { - if (IManager) + if (m_IManager) { if (!branchread.empty()) { std::map::const_iterator branchiter; for (branchiter = branchread.begin(); branchiter != branchread.end(); ++branchiter) { - IManager->selectObjectToRead(branchiter->first.c_str(), branchiter->second); + m_IManager->selectObjectToRead(branchiter->first.c_str(), branchiter->second); if (Verbosity() > 0) { std::cout << branchiter->first << " set to " << branchiter->second << std::endl; @@ -571,7 +571,7 @@ int Fun4AllDstInputManager::setBranches() } // protection against switching off the sync variables // only implemented in the Sync Manager - setSyncBranches(IManager); + setSyncBranches(m_IManager); } } else @@ -586,7 +586,7 @@ int Fun4AllDstInputManager::setBranches() int Fun4AllDstInputManager::setSyncBranches(PHNodeIOManager *IMan) { // protection against switching off the sync variables - for (auto & i : syncdefs::SYNCVARS) + for (auto &i : syncdefs::SYNCVARS) { IMan->selectObjectToRead(i, true); } @@ -617,13 +617,13 @@ void Fun4AllDstInputManager::Print(const std::string &what) const std::cout << std::endl; } } - if ((what == "ALL" || what == "PHOOL") && IManager) + if ((what == "ALL" || what == "PHOOL") && m_IManager) { // loop over the map and print out the content (name and location in memory) std::cout << "--------------------------------------" << std::endl << std::endl; std::cout << "PHNodeIOManager print in Fun4AllDstInputManager " << Name() << ":" << std::endl; - IManager->print(); + m_IManager->print(); } Fun4AllInputManager::Print(what); return; @@ -631,11 +631,11 @@ void Fun4AllDstInputManager::Print(const std::string &what) const int Fun4AllDstInputManager::PushBackEvents(const int i) { - if (IManager) + if (m_IManager) { - unsigned EventOnDst = IManager->getEventNumber(); + unsigned EventOnDst = m_IManager->getEventNumber(); EventOnDst -= static_cast(i); - IManager->setEventNumber(EventOnDst); + m_IManager->setEventNumber(EventOnDst); return 0; } std::cout << PHWHERE << Name() << ": could not push back events, Imanager is NULL" diff --git a/offline/framework/fun4all/Fun4AllDstInputManager.h b/offline/framework/fun4all/Fun4AllDstInputManager.h index 5346497adf..825b2e63a2 100644 --- a/offline/framework/fun4all/Fun4AllDstInputManager.h +++ b/offline/framework/fun4all/Fun4AllDstInputManager.h @@ -24,7 +24,7 @@ class Fun4AllDstInputManager : public Fun4AllInputManager int SyncIt(const SyncObject *mastersync) override; int BranchSelect(const std::string &branch, const int iflag) override; int setBranches() override; - virtual int setSyncBranches(PHNodeIOManager *IManager); + virtual int setSyncBranches(PHNodeIOManager *iman); void Print(const std::string &what = "ALL") const override; int PushBackEvents(const int i) override; int HasSyncObject() const override; @@ -32,6 +32,16 @@ class Fun4AllDstInputManager : public Fun4AllInputManager protected: int ReadNextEventSyncObject(); void ReadRunTTree(const int i) { m_ReadRunTTree = i; } + void IManager(PHNodeIOManager *iman) { m_IManager = iman; } + PHNodeIOManager *IManager() { return m_IManager; } + void runNode(PHCompositeNode *node) { m_RunNode = node; } + PHCompositeNode *runNode() { return m_RunNode; } + void runNodeCopy(PHCompositeNode *node) { m_RunNodeCopy = node; } + PHCompositeNode *runNodeCopy() { return m_RunNodeCopy; } + void runNodeSum(PHCompositeNode *node) { m_RunNodeSum = node; } + PHCompositeNode *runNodeSum() { return m_RunNodeSum; } + std::string RunNodeName() const { return RunNode; } + std::string fullfilename; private: int m_ReadRunTTree = 1; @@ -39,16 +49,15 @@ class Fun4AllDstInputManager : public Fun4AllInputManager int events_thisfile = 0; int events_skipped_during_sync = 0; int m_HaveSyncObject = 0; - std::string fullfilename; - std::string RunNode = "RUN"; std::map branchread; std::string syncbranchname; PHCompositeNode *dstNode = nullptr; - PHCompositeNode *runNode = nullptr; - PHCompositeNode *runNodeCopy = nullptr; - PHCompositeNode *runNodeSum = nullptr; - PHNodeIOManager *IManager = nullptr; + PHCompositeNode *m_RunNode = nullptr; + PHCompositeNode *m_RunNodeCopy = nullptr; + PHCompositeNode *m_RunNodeSum = nullptr; + PHNodeIOManager *m_IManager = nullptr; SyncObject *syncobject = nullptr; + std::string RunNode = "RUN"; }; #endif /* __FUN4ALLDSTINPUTMANAGER_H__ */ diff --git a/offline/framework/fun4all/Fun4AllDstOutputManager.cc b/offline/framework/fun4all/Fun4AllDstOutputManager.cc index 03df89c09e..2f555f9df1 100644 --- a/offline/framework/fun4all/Fun4AllDstOutputManager.cc +++ b/offline/framework/fun4all/Fun4AllDstOutputManager.cc @@ -118,6 +118,10 @@ void Fun4AllDstOutputManager::Print(const std::string &what) const // that everything is written out), those nodes are declared transient int Fun4AllDstOutputManager::Write(PHCompositeNode *startNode) { + if (!m_SaveDstNodeFlag) + { + return 0; + } PHNodeIterator nodeiter(startNode); if (savenodes.empty()) { diff --git a/offline/framework/fun4all/Fun4AllDstOutputManager.h b/offline/framework/fun4all/Fun4AllDstOutputManager.h index 52a40758c2..e2f5166a85 100644 --- a/offline/framework/fun4all/Fun4AllDstOutputManager.h +++ b/offline/framework/fun4all/Fun4AllDstOutputManager.h @@ -25,6 +25,7 @@ class Fun4AllDstOutputManager : public Fun4AllOutputManager int StripNode(const std::string &nodename) override; int StripRunNode(const std::string &nodename) override; void SaveRunNode(const int i) override { m_SaveRunNodeFlag = i; } + void SaveDstNode(const int i) override { m_SaveDstNodeFlag = i; } int outfileopen(const std::string &fname) override; void Print(const std::string &what = "ALL") const override; @@ -35,6 +36,7 @@ class Fun4AllDstOutputManager : public Fun4AllOutputManager private: PHNodeIOManager *dstOut = nullptr; int m_SaveRunNodeFlag = 1; + int m_SaveDstNodeFlag = 1; std::set savenodes; std::set saverunnodes; std::set stripnodes; diff --git a/offline/framework/fun4all/Fun4AllHistoManager.cc b/offline/framework/fun4all/Fun4AllHistoManager.cc index b8dd36d252..696021ffcf 100644 --- a/offline/framework/fun4all/Fun4AllHistoManager.cc +++ b/offline/framework/fun4all/Fun4AllHistoManager.cc @@ -175,11 +175,15 @@ bool Fun4AllHistoManager::registerHisto(const std::string &hname, TNamed *h1d, c // reset directory for TTree if (h1d->InheritsFrom("TTree")) + { static_cast(h1d)->SetDirectory(nullptr); + } // For histograms, enforce error calculation and propagation if (h1d->InheritsFrom("TH1")) + { static_cast(h1d)->Sumw2(); + } return true; } @@ -285,11 +289,13 @@ void Fun4AllHistoManager::Reset() { TNamed *h = hiter->second; if (h->InheritsFrom("TH1")) + { (dynamic_cast(h))->Reset(); -#if HAS_THNSPARSE + } else if (h->InheritsFrom("THnSparse")) + { (dynamic_cast(h))->Reset(); -#endif + } } return; } diff --git a/offline/framework/fun4all/Fun4AllMemoryTracker.cc b/offline/framework/fun4all/Fun4AllMemoryTracker.cc index 80a7a01ae1..da81de21a1 100644 --- a/offline/framework/fun4all/Fun4AllMemoryTracker.cc +++ b/offline/framework/fun4all/Fun4AllMemoryTracker.cc @@ -111,7 +111,7 @@ void Fun4AllMemoryTracker::PrintMemoryTracker(const std::string &name) const { std::cout << iter->first << ": "; std::vector memvec = iter->second; - for (int & vit : memvec) + for (int &vit : memvec) { std::cout << vit << " "; } @@ -125,7 +125,7 @@ void Fun4AllMemoryTracker::PrintMemoryTracker(const std::string &name) const { std::cout << "SubsysReco/OutputManager: " << iter->first << std::endl; std::vector memvec = iter->second; - for (int & vit : memvec) + for (int &vit : memvec) { std::cout << vit << " "; } diff --git a/offline/framework/fun4all/Fun4AllOutputManager.h b/offline/framework/fun4all/Fun4AllOutputManager.h index 941eceb9f6..b270fe8cb2 100644 --- a/offline/framework/fun4all/Fun4AllOutputManager.h +++ b/offline/framework/fun4all/Fun4AllOutputManager.h @@ -47,6 +47,7 @@ class Fun4AllOutputManager : public Fun4AllBase } virtual void SaveRunNode(const int) { return; } + virtual void SaveDstNode(const int) { return; } /*! \brief add an event selector to the outputmanager. @@ -100,7 +101,7 @@ class Fun4AllOutputManager : public Fun4AllBase void OutFileName(const std::string &name) { m_OutFileName = name; } protected: - /*! + /*! constructor. is protected since we do not want the class to be created in root macros */ diff --git a/offline/framework/fun4all/Fun4AllRunNodeInputManager.cc b/offline/framework/fun4all/Fun4AllRunNodeInputManager.cc new file mode 100644 index 0000000000..80ed6abca9 --- /dev/null +++ b/offline/framework/fun4all/Fun4AllRunNodeInputManager.cc @@ -0,0 +1,103 @@ +#include "Fun4AllRunNodeInputManager.h" + +#include "Fun4AllReturnCodes.h" +#include "Fun4AllServer.h" + +#include + +#include + +#include +#include +#include +#include +#include // for PHWHERE, PHReadOnly, PHRunTree +#include + +#include + +#include +#include + +Fun4AllRunNodeInputManager::Fun4AllRunNodeInputManager(const std::string &name, + const std::string &nodename, + const std::string &topnodename) + : Fun4AllDstInputManager(name, nodename, topnodename) +{ + return; +} + +int Fun4AllRunNodeInputManager::fileopen(const std::string &filenam) +{ + Fun4AllServer *se = Fun4AllServer::instance(); + if (IsOpen()) + { + std::cout << "Closing currently open file " + << FileName() + << " and opening " << filenam << std::endl; + fileclose(); + } + FileName(filenam); + FROG frog; + fullfilename = frog.location(FileName()); + if (Verbosity() > 0) + { + std::cout << Name() << ": opening file " << fullfilename << std::endl; + } + // sanity check - the IManager must be nullptr when this method is executed + // if not something is very very wrong and we must not continue + if (IManager()) + { + std::cout << PHWHERE << " IManager pointer is not nullptr but " << IManager() + << std::endl; + std::cout << "Send mail to off-l with this printout and the macro you used" + << std::endl; + std::cout << "Trying to execute IManager->print() to display more info" + << std::endl; + std::cout << "Code will probably segfault now" << std::endl; + IManager()->print(); + std::cout << "Have someone look into this problem - Exiting now" << std::endl; + exit(1); + } + IManager(new PHNodeIOManager(fullfilename, PHReadOnly, PHRunTree)); + if (IManager()->isFunctional()) + { + runNode(se->getNode(RunNodeName(), TopNodeName())); + IManager()->read(runNode()); + // get the current run number from an existing run noder + RunHeader *runheader = findNode::getClass(runNode(), "RunHeader"); + if (runheader) + { + SetRunNumber(runheader->get_RunNumber()); + } + } + // DLW: move the delete outside the if block to cover the case where isFunctional() fails + delete IManager(); + IManager(nullptr); + IsOpen(1); + return 0; +} + +int Fun4AllRunNodeInputManager::run(const int /*nevents*/) +{ + if (!IsOpen()) + { + if (FileListEmpty()) + { + if (Verbosity() > 0) + { + std::cout << Name() << ": No Input file open" << std::endl; + } + return -1; + } + else + { + if (OpenNextFile()) + { + std::cout << Name() << ": No Input file from filelist opened" << std::endl; + return -1; + } + } + } + return 0; +} diff --git a/offline/framework/fun4all/Fun4AllRunNodeInputManager.h b/offline/framework/fun4all/Fun4AllRunNodeInputManager.h new file mode 100644 index 0000000000..b35c0eb85f --- /dev/null +++ b/offline/framework/fun4all/Fun4AllRunNodeInputManager.h @@ -0,0 +1,38 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef FUN4ALL_FUN4ALLRUNNODEINPUTMANAGER_H +#define FUN4ALL_FUN4ALLRUNNODEINPUTMANAGER_H + +#include "Fun4AllDstInputManager.h" + +#include "Fun4AllReturnCodes.h" + +#include // for string + +class PHNodeIOManager; +class SyncObject; + +class Fun4AllRunNodeInputManager : public Fun4AllDstInputManager +{ + public: + Fun4AllRunNodeInputManager(const std::string& name = "DUMMY", const std::string& nodename = "DST", const std::string& topnodename = "TOP"); + + ~Fun4AllRunNodeInputManager() override {} + + int fileopen(const std::string& filenam) override; + int run(const int /*nevents*/) override; + + // Effectivly turn off the synchronization checking + // + int SyncIt(const SyncObject* /*mastersync*/) override { return Fun4AllReturnCodes::SYNC_OK; } + int GetSyncObject(SyncObject** /*mastersync*/) override { return Fun4AllReturnCodes::SYNC_NOOBJECT; } + int NoSyncPushBackEvents(const int nevt) override { return PushBackEvents(nevt); } + /* // no sync object we don't need to enable the sync variables */ + int setSyncBranches(PHNodeIOManager* /*IManager*/) override { return 0; } + int PushBackEvents(const int /*i*/) override { return 0; } + int SkipForThisManager(const int nevents) override { return PushBackEvents(nevents); } + int HasSyncObject() const override { return 0; } + +}; + +#endif // FUN4ALL_FUN4ALLRUNNODEINPUTMANAGER_H diff --git a/offline/framework/fun4all/Fun4AllServer.cc b/offline/framework/fun4all/Fun4AllServer.cc index d6a5867a6f..31be25ebd2 100644 --- a/offline/framework/fun4all/Fun4AllServer.cc +++ b/offline/framework/fun4all/Fun4AllServer.cc @@ -1480,9 +1480,13 @@ int Fun4AllServer::run(const int nevnts, const bool require_nevents) if (std::find(RetCodes.begin(), RetCodes.end(), static_cast(Fun4AllReturnCodes::ABORTEVENT)) == RetCodes.end()) + { icnt_good++; + } if (iret || (nevnts > 0 && icnt_good >= nevnts)) + { break; + } } else if (iret || (nevnts > 0 && icnt >= nevnts)) { diff --git a/offline/framework/fun4all/Fun4AllServer.h b/offline/framework/fun4all/Fun4AllServer.h index 09a1c5cfc4..154ff4d212 100644 --- a/offline/framework/fun4all/Fun4AllServer.h +++ b/offline/framework/fun4all/Fun4AllServer.h @@ -83,8 +83,8 @@ class Fun4AllServer : public Fun4AllBase //! run n events (0 means up to end of file) int run(const int nevnts = 0, const bool require_nevents = false); - /*! - \brief skip n events (0 means up to the end of file). + /*! + \brief skip n events (0 means up to the end of file). Skip means read, don't process. */ int skip(const int nevnts = 0); diff --git a/offline/framework/fun4all/Fun4AllSyncManager.cc b/offline/framework/fun4all/Fun4AllSyncManager.cc index 0f638b0a27..80a1871b5a 100644 --- a/offline/framework/fun4all/Fun4AllSyncManager.cc +++ b/offline/framework/fun4all/Fun4AllSyncManager.cc @@ -94,7 +94,7 @@ int Fun4AllSyncManager::run(const int nevnts) unsigned iman = 0; int ifirst = 0; int hassync = 0; - for (auto & iter : m_InManager) + for (auto &iter : m_InManager) { m_iretInManager[iman] = iter->run(1); iret += m_iretInManager[iman]; @@ -238,7 +238,7 @@ int Fun4AllSyncManager::run(const int nevnts) if (!resetnodetree) // all syncing is done and no read errors --> we have a good event in memory { m_CurrentRun = 0; // reset current run to 0 - for (auto & iter : m_InManager) + for (auto &iter : m_InManager) { int runno = iter->RunNumber(); if (Verbosity() > 2) @@ -256,7 +256,7 @@ int Fun4AllSyncManager::run(const int nevnts) { if (m_CurrentRun != runno) { - std::cout << "Mixing run numbers (except runnumber=0 which means no valid runnumber) is not supported" << std::endl; + std::cout << PHWHERE << "Mixing run numbers (except runnumber=0 which means no valid runnumber) is not supported" << std::endl; std::cout << "Here are the list of input managers and runnumbers:" << std::endl; for (Fun4AllInputManager *inman : m_InManager) { diff --git a/offline/framework/fun4all/Fun4AllSyncManager.h b/offline/framework/fun4all/Fun4AllSyncManager.h index c7f9f4ffba..1601b8958d 100644 --- a/offline/framework/fun4all/Fun4AllSyncManager.h +++ b/offline/framework/fun4all/Fun4AllSyncManager.h @@ -26,8 +26,8 @@ class Fun4AllSyncManager : public Fun4AllBase //! run n events (0 means up to end of file int run(const int nevnts = 0); - /*! - \brief skip n events (0 means up to the end of file). + /*! + \brief skip n events (0 means up to the end of file). Skip means read, don't process. */ int skip(const int nevnts = 0); @@ -53,8 +53,8 @@ class Fun4AllSyncManager : public Fun4AllBase void PushBackInputMgrsEvents(const int i); int ResetEvent(); const std::vector GetInputManagers() const { return m_InManager; } - bool MixRunsOk() const {return m_MixRunsOkFlag;} - void MixRunsOk(bool b) {m_MixRunsOkFlag = b;} + bool MixRunsOk() const { return m_MixRunsOkFlag; } + void MixRunsOk(bool b) { m_MixRunsOkFlag = b; } private: void PrintSyncProblem() const; diff --git a/offline/framework/fun4all/Makefile.am b/offline/framework/fun4all/Makefile.am index 385432189f..96fafbe817 100644 --- a/offline/framework/fun4all/Makefile.am +++ b/offline/framework/fun4all/Makefile.am @@ -23,6 +23,7 @@ pkginclude_HEADERS = \ Fun4AllNoSyncDstInputManager.h \ Fun4AllOutputManager.h \ Fun4AllReturnCodes.h \ + Fun4AllRunNodeInputManager.h \ Fun4AllServer.h \ Fun4AllSyncManager.h \ Fun4AllUtils.h \ @@ -51,6 +52,7 @@ libfun4all_la_SOURCES = \ Fun4AllMemoryTracker.cc \ Fun4AllNoSyncDstInputManager.cc \ Fun4AllOutputManager.cc \ + Fun4AllRunNodeInputManager.cc \ Fun4AllServer.cc \ Fun4AllSyncManager.cc \ Fun4AllUtils.cc \ diff --git a/offline/framework/fun4all/PHTFileServer.cc b/offline/framework/fun4all/PHTFileServer.cc index 4fe0459274..86f41862ec 100644 --- a/offline/framework/fun4all/PHTFileServer.cc +++ b/offline/framework/fun4all/PHTFileServer.cc @@ -1,5 +1,5 @@ ////////////////////////////////////////////////////////////////// -/*! +/*! \file PHTFileServer.cc \brief TFile clean handling \author Hugo Pereira @@ -22,7 +22,10 @@ PHTFileServer::SafeTFile::TFileMap PHTFileServer::SafeTFile::_map; //_________________________________________________ PHTFileServer::~PHTFileServer() { - if (!SafeTFile::file_map().empty()) close(); + if (!SafeTFile::file_map().empty()) + { + close(); + } } //_________________________________________________ @@ -47,7 +50,10 @@ void PHTFileServer::open(const std::string& filename, const std::string& type) // create new SafeTFile; insert in map; change TDirectory SafeTFile* file(new SafeTFile(filename, type)); - if (!file->IsOpen()) std::cout << ("PHTFileServer::open - error opening TFile") << std::endl; + if (!file->IsOpen()) + { + std::cout << ("PHTFileServer::open - error opening TFile") << std::endl; + } SafeTFile::file_map().insert(make_pair(filename, file)); file->cd(); } @@ -58,7 +64,9 @@ bool PHTFileServer::flush(const std::string& filename) { SafeTFile::TFileMap::iterator iter(SafeTFile::file_map().find(filename)); if (iter != SafeTFile::file_map().end()) + { iter->second->Flush(); + } else { std::ostringstream what; @@ -75,7 +83,9 @@ bool PHTFileServer::cd(const std::string& filename) { SafeTFile::TFileMap::iterator iter(SafeTFile::file_map().find(filename)); if (iter != SafeTFile::file_map().end()) + { iter->second->cd(); + } else { std::ostringstream what; @@ -132,7 +142,7 @@ void PHTFileServer::close() { // close // MUTOO::TRACE( "PHTFileServer::close" ); - for (auto & iter : SafeTFile::file_map()) + for (auto& iter : SafeTFile::file_map()) { if (iter.second->IsOpen()) { @@ -177,7 +187,7 @@ PHTFileServer::SafeTFile::~SafeTFile() Close(); } - /* + /* remove this filename from the make to make sure that PHTFileServer does not try to write/close this TFile during the destructor */ diff --git a/offline/framework/fun4all/PHTFileServer.h b/offline/framework/fun4all/PHTFileServer.h index a1d0d0989c..4880ee6933 100644 --- a/offline/framework/fun4all/PHTFileServer.h +++ b/offline/framework/fun4all/PHTFileServer.h @@ -1,7 +1,7 @@ // Tell emacs that this is a C++ source // -*- C++ -*-. ////////////////////////////////////////////////////////////////// -/*! +/*! \file PHTFileServer.h \brief TFile clean handling \author Hugo Pereira @@ -19,10 +19,10 @@ #include #include -/*! +/*! \brief TFile clean handling. It allow independant classes to access the same TFile and write ntuple to it. TFiles get written only when as many - write request are achieved as open request. + write request are achieved as open request. It get closed when the server is deleted */ class PHTFileServer @@ -38,7 +38,7 @@ class PHTFileServer //! destructor. All non close TFiles are closed, with a warning. virtual ~PHTFileServer(); - /*! \brief + /*! \brief open a SafeTFile. If filename is not found in the map, create a new TFile and append to the map; increment counter otherwise */ @@ -51,7 +51,7 @@ class PHTFileServer bool cd(const std::string& filename); /*! \brief - if TFile is found in map and counter is 0, close the TFile, + if TFile is found in map and counter is 0, close the TFile, decrement counter otherwise */ bool write(const std::string& filename); diff --git a/offline/framework/fun4all/SubsysReco.h b/offline/framework/fun4all/SubsysReco.h index 807d897f7a..3d6bc13df0 100644 --- a/offline/framework/fun4all/SubsysReco.h +++ b/offline/framework/fun4all/SubsysReco.h @@ -16,14 +16,14 @@ class PHCompositeNode; * from this base class and you have to implement this class methods. * None of these are strictly required as far as C++ is concerned, but as * far as your job is concerned, at least process_event(), to do the - * job, and InitRun(), to initialize, should be implemented. - * + * job, and InitRun(), to initialize, should be implemented. + * */ class SubsysReco : public Fun4AllBase { public: - /** dtor. + /** dtor. Does nothing as this is a base class only. */ ~SubsysReco() override {} diff --git a/offline/framework/fun4all/TDirectoryHelper.cc b/offline/framework/fun4all/TDirectoryHelper.cc index 8bb6c304d2..103c2524ef 100644 --- a/offline/framework/fun4all/TDirectoryHelper.cc +++ b/offline/framework/fun4all/TDirectoryHelper.cc @@ -126,7 +126,7 @@ bool TDirectoryHelper::mkpath(TDirectory* dir, const std::string& pathin) TDirectory* currentdir = dir; - for (auto & path : paths) + for (auto& path : paths) { currentdir->cd(); diff --git a/offline/packages/CaloBase/Makefile.am b/offline/packages/CaloBase/Makefile.am index 42db43b099..698a87c1ac 100644 --- a/offline/packages/CaloBase/Makefile.am +++ b/offline/packages/CaloBase/Makefile.am @@ -11,14 +11,25 @@ libcalo_io_la_LDFLAGS = \ -L$(libdir) \ -L$(OFFLINE_MAIN)/lib -libcalo_io_la_LIBADD = \ - -lphool - AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ -isystem$(ROOTSYS)/include +# List of shared libraries to produce +if USE_ONLINE +pkginclude_HEADERS = \ + RawTowerDefs.h \ + TowerInfoDefs.h + +libcalo_io_la_SOURCES = \ + TowerInfoDefs.cc + +else + +libcalo_io_la_LIBADD = \ + -lphool + pkginclude_HEADERS = \ RawClusterUtility.h \ RawCluster.h \ @@ -113,7 +124,9 @@ libcalo_io_la_SOURCES = \ RawTowerGeomContainerv1.cc \ RawTowerGeomContainer_Cylinderv1.cc \ TowerInfov1.cc \ + TowerInfoDefs.cc \ TowerInfoContainerv1.cc +endif # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h diff --git a/offline/packages/CaloBase/TowerInfoContainer.h b/offline/packages/CaloBase/TowerInfoContainer.h index bf6b87f78c..d5ae275e5e 100644 --- a/offline/packages/CaloBase/TowerInfoContainer.h +++ b/offline/packages/CaloBase/TowerInfoContainer.h @@ -20,6 +20,7 @@ class TowerInfoContainer : public PHObject EMCAL = 0, HCAL = 1, SEPD = 2, + MBD = 3, DETECTOR_INVALID = 9999 }; @@ -37,10 +38,12 @@ class TowerInfoContainer : public PHObject virtual unsigned int encode_epd(unsigned int /*towerIndex*/) { return UINT_MAX; } virtual unsigned int encode_hcal(unsigned int /*towerIndex*/) { return UINT_MAX; } virtual unsigned int encode_emcal(unsigned int /*towerIndex*/) { return UINT_MAX; } + virtual unsigned int encode_mbd(unsigned int /*towerIndex*/) { return UINT_MAX; } virtual unsigned int decode_epd(unsigned int /*towerIndex*/) { return UINT_MAX; } virtual unsigned int decode_hcal(unsigned int /*towerIndex*/) { return UINT_MAX; } virtual unsigned int decode_emcal(unsigned int /*towerIndex*/) { return UINT_MAX; } + virtual unsigned int decode_mbd(unsigned int /*towerIndex*/) { return UINT_MAX; } virtual unsigned int getTowerPhiBin(unsigned int /*towerIndex*/) { return UINT_MAX; } diff --git a/offline/packages/CaloBase/TowerInfoContainerv1.cc b/offline/packages/CaloBase/TowerInfoContainerv1.cc index f1557df6af..655aac66b1 100644 --- a/offline/packages/CaloBase/TowerInfoContainerv1.cc +++ b/offline/packages/CaloBase/TowerInfoContainerv1.cc @@ -1,5 +1,6 @@ #include "TowerInfoContainerv1.h" #include "TowerInfov1.h" +#include "TowerInfoDefs.h" #include #include @@ -8,25 +9,6 @@ #include -int emcadc[8][8] = { - {62, 60, 46, 44, 30, 28, 14, 12}, - {63, 61, 47, 45, 31, 29, 15, 13}, - {58, 56, 42, 40, 26, 24, 10, 8}, - {59, 57, 43, 41, 27, 25, 11, 9}, - {54, 52, 38, 36, 22, 20, 6, 4}, - {55, 53, 39, 37, 23, 21, 7, 5}, - {50, 48, 34, 32, 18, 16, 2, 0}, - {51, 49, 35, 33, 19, 17, 3, 1}}; - -int hcaladc[8][2] = { - {0, 1}, - {2, 3}, - {4, 5}, - {6, 7}, - {8, 9}, - {10, 11}, - {12, 13}, - {14, 15}}; TowerInfoContainerv1::TowerInfoContainerv1(DETECTOR detec) : _detector(detec) @@ -44,11 +26,13 @@ TowerInfoContainerv1::TowerInfoContainerv1(DETECTOR detec) { nchannels = 1536; } + else if (_detector == DETECTOR::MBD) + { + nchannels = 256; + } _clones = new TClonesArray("TowerInfov1", nchannels); - _clones->SetOwner(); _clones->SetName("TowerInfoContainerv1"); - for (int i = 0; i < nchannels; ++i) { // as tower numbers are fixed per event @@ -80,7 +64,6 @@ void TowerInfoContainerv1::Reset() } assert(obj); - // same as TClonesArray::Clear() but only clear but not to erase all towers obj->Clear(); obj->ResetBit(kHasUUID); @@ -89,7 +72,6 @@ void TowerInfoContainerv1::Reset() } } - TowerInfov1* TowerInfoContainerv1::get_tower_at_channel(int pos) { return (TowerInfov1*) _clones->At(pos); @@ -102,108 +84,27 @@ TowerInfov1* TowerInfoContainerv1::get_tower_at_key(int pos) return (TowerInfov1*) _clones->At(index); } - - - - - unsigned int TowerInfoContainerv1::encode_epd(unsigned int towerIndex) { - int channels_per_sector = 31; - int supersector = channels_per_sector * 12; - unsigned int supersectornumber = towerIndex / supersector; - int sector = ((towerIndex % supersector)) / channels_per_sector; - int channel = ((towerIndex % supersector)) % channels_per_sector; - int rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; - int phimap_sepd[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; - unsigned int globalphi = phimap_sepd[channel] + 2 * sector; - unsigned int r = rmap[channel]; - unsigned int key = globalphi + (r << 10U) + (supersectornumber << 20U); + unsigned int key = TowerInfoDefs::encode_epd(towerIndex); return key; } - - unsigned int TowerInfoContainerv1::encode_emcal(unsigned int towerIndex) { - int phimap[64] = {0}; - int etamap[64] = {0}; - for (int j = 0; j < 8; j++) - { - for (int k = 0; k < 8; k++) - { - etamap[emcadc[j][k]] = j; - phimap[emcadc[j][k]] = k; - } - } - int channels_per_sector = 64; - int supersector = 64 * 12; - int nchannelsperpacket = 64 * 3; - int maxphibin = 7; - int maxetabin = 23; - int etabinoffset[4] = {24,0,48,72}; - int supersectornumber = towerIndex / supersector; - int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta| - if (packet < 0 || packet > 3 ) - { - std::cout << PHWHERE << "Attempting to access channel with invalid value in EMCal " << packet << std::endl; - exit(1); - } - int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector; - int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector; - int localphibin = phimap[interfaceboard_channel]; - if (packet == 0 || packet == 1) - { - localphibin = maxphibin - localphibin; - } - int localetabin = etamap[interfaceboard_channel]; - int packet_etabin = localetabin + 8 * interfaceboard; - if (packet == 0 || packet == 1) - { - packet_etabin = maxetabin - packet_etabin; - } - unsigned int globaletabin = packet_etabin + etabinoffset[packet]; - unsigned int globalphibin = localphibin + supersectornumber * 8; - unsigned int key = globalphibin + (globaletabin << 16U); - return key; + unsigned int key = TowerInfoDefs::encode_emcal(towerIndex); + return key; } - - - unsigned int TowerInfoContainerv1::encode_hcal(unsigned int towerIndex) { - int phimap[64] = {0}; - int etamap[64] = {0}; - for (int j = 0; j < 8; j++) - { - for (int k = 0; k < 2; k++) - { - etamap[hcaladc[j][k]] = j; - phimap[hcaladc[j][k]] = k; - } - } - int channels_per_sector = 16; - int supersector = 16 * 4 * 3; - int nchannelsperpacket = channels_per_sector * 4; - int etabinoffset[4] = {0,8,16,0}; - int phibinoffset[4] = {0,2,4,6}; - int supersectornumber = towerIndex / supersector; - int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta| - if (packet < 0 || packet > 3 ) - { - std::cout << PHWHERE << "Attempting to access channel with invalid value ih HCAL " << packet << std::endl; - exit(1); - } + unsigned int key = TowerInfoDefs::encode_hcal(towerIndex); + return key; +} - int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector; - int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector; - int localphibin = phimap[interfaceboard_channel] + phibinoffset[interfaceboard]; - int localetabin = etamap[interfaceboard_channel]; - int packet_etabin = localetabin; - unsigned int globaletabin = packet_etabin + etabinoffset[packet]; - unsigned int globalphibin = localphibin + supersectornumber * 8; - unsigned int key = globalphibin + (globaletabin << 16U); +unsigned int TowerInfoContainerv1::encode_mbd(unsigned int towerIndex) +{ + unsigned int key = TowerInfoDefs::encode_mbd(towerIndex); return key; } @@ -222,100 +123,37 @@ unsigned int TowerInfoContainerv1::encode_key(unsigned int towerIndex) { key = TowerInfoContainerv1::encode_epd(towerIndex); } + else if (_detector == DETECTOR::MBD) + { + key = TowerInfoContainerv1::encode_mbd(towerIndex); + } return key; } - - - unsigned int TowerInfoContainerv1::decode_epd(unsigned int tower_key) { - int channels_per_sector = 31; - int supersector = channels_per_sector * 12; - unsigned int ns_sector = tower_key >> 20U; - unsigned int rbin = (tower_key - (ns_sector << 20U)) >> 10U; - unsigned int phibin = tower_key - (ns_sector << 20U) - (rbin << 10U); - int epdchnlmap[16][2] = {{0, 0}, {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, {19, 20}, {21, 22}, {23, 24}, {25, 26}, {27, 28}, {29, 30}}; - int sector = phibin / 2; - int channel = 0; - if (rbin > 0) - { - channel = epdchnlmap[rbin][phibin - 2 * sector]; - } - else - { - channel = 0; - } - unsigned int index = 0; - index = ns_sector * supersector + sector * channels_per_sector + channel; + unsigned int index = TowerInfoDefs::decode_epd(tower_key); return index; } unsigned int TowerInfoContainerv1::decode_emcal(unsigned int tower_key) { - int etabinoffset[4] = {0}; - int etabinmap[4] = {0}; - int channels_per_sector = 64; - int supersector = 64 * 12; - int nchannelsperpacket = 64 * 3; - int maxphibin = 7; - int maxetabin = 23; - etabinoffset[0] = 24; - etabinoffset[1] = 0; - etabinoffset[2] = 48; - etabinoffset[3] = 72; - etabinmap[0] = 1; - etabinmap[1] = 0; - etabinmap[2] = 2; - etabinmap[3] = 3; - unsigned int etabin = tower_key >> 16U; - unsigned int phibin = tower_key - (etabin << 16U); - int packet = etabinmap[(int) etabin / 24]; - int localetabin = etabin - etabinoffset[packet]; - int localphibin = phibin % 8; - int supersectornumber = phibin / 8; - int ib = 0; - if (packet == 0 || packet == 1) - { - localetabin = maxetabin - localetabin; - } - ib = localetabin / 8; - unsigned int index = 0; - if (packet == 0 || packet == 1) - { - localphibin = maxphibin - localphibin; - } - localetabin = localetabin % 8; - unsigned int localindex = emcadc[localetabin][localphibin]; - index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber; + unsigned int index = TowerInfoDefs::decode_emcal(tower_key); return index; } - - unsigned int TowerInfoContainerv1::decode_hcal(unsigned int tower_key) { - int channels_per_sector = 16; - int supersector = 16 * 4 * 3; - int nchannelsperpacket = channels_per_sector * 4; - int etabinoffset[3] = {0,8,16}; - int phibinoffset[4] = {0,2,4,6}; - unsigned int etabin = tower_key >> 16U; - unsigned int phibin = tower_key - (etabin << 16U); - int packet = etabin / 8; - int localetabin = etabin - etabinoffset[packet]; - int localphibin = phibin % 8; - int supersectornumber = phibin / 8; - int ib = localphibin / 2; - unsigned int index = 0; - localphibin = localphibin - phibinoffset[ib]; - unsigned int localindex = hcaladc[localetabin][localphibin]; - index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber; + unsigned int index = TowerInfoDefs::decode_hcal(tower_key); return index; } - +unsigned int TowerInfoContainerv1::decode_mbd(unsigned int tower_key) +{ + unsigned int index = TowerInfoDefs::decode_mbd(tower_key); + return index; +} unsigned int TowerInfoContainerv1::decode_key(unsigned int tower_key) { @@ -333,18 +171,21 @@ unsigned int TowerInfoContainerv1::decode_key(unsigned int tower_key) { index = TowerInfoContainerv1::decode_epd(tower_key); } + else if (_detector == DETECTOR::MBD) + { + index = TowerInfoContainerv1::decode_mbd(tower_key); + } return index; } unsigned int TowerInfoContainerv1::getTowerPhiBin(unsigned int key) { - unsigned int etabin = key >> 16U; - unsigned int phibin = key - (etabin << 16U); + unsigned int phibin = TowerInfoDefs::getCaloTowerPhiBin(key); return phibin; } unsigned int TowerInfoContainerv1::getTowerEtaBin(unsigned int key) { - unsigned int etabin = key >> 16U; + unsigned int etabin = TowerInfoDefs::getCaloTowerEtaBin(key); return etabin; } diff --git a/offline/packages/CaloBase/TowerInfoContainerv1.h b/offline/packages/CaloBase/TowerInfoContainerv1.h index 3d9fe88b11..44d8e53123 100644 --- a/offline/packages/CaloBase/TowerInfoContainerv1.h +++ b/offline/packages/CaloBase/TowerInfoContainerv1.h @@ -29,10 +29,12 @@ class TowerInfoContainerv1 : public TowerInfoContainer unsigned int encode_epd(unsigned int towerIndex) override; unsigned int encode_hcal(unsigned int towerIndex) override; unsigned int encode_emcal(unsigned int towerIndex) override; + unsigned int encode_mbd(unsigned int towerIndex) override; unsigned int decode_epd(unsigned int towerIndex) override; unsigned int decode_hcal(unsigned int towerIndex) override; unsigned int decode_emcal(unsigned int towerIndex) override; + unsigned int decode_mbd(unsigned int towerIndex) override; size_t size() override { return _clones->GetEntries(); } diff --git a/offline/packages/CaloBase/TowerInfoDefs.cc b/offline/packages/CaloBase/TowerInfoDefs.cc new file mode 100644 index 0000000000..d7101af09a --- /dev/null +++ b/offline/packages/CaloBase/TowerInfoDefs.cc @@ -0,0 +1,532 @@ +#include "TowerInfoDefs.h" +#include "RawTowerDefs.h" + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +static const int emcadc[8][8] = { + {62, 60, 46, 44, 30, 28, 14, 12}, + {63, 61, 47, 45, 31, 29, 15, 13}, + {58, 56, 42, 40, 26, 24, 10, 8}, + {59, 57, 43, 41, 27, 25, 11, 9}, + {54, 52, 38, 36, 22, 20, 6, 4}, + {55, 53, 39, 37, 23, 21, 7, 5}, + {50, 48, 34, 32, 18, 16, 2, 0}, + {51, 49, 35, 33, 19, 17, 3, 1}}; + +static const int hcaladc[8][2] = { + {0, 1}, + {2, 3}, + {4, 5}, + {6, 7}, + {8, 9}, + {10, 11}, + {12, 13}, + {14, 15}}; +static const int epdchnlmap[16][2] = { + {0, 0}, + {1, 2}, + {3, 4}, + {5, 6}, + {7, 8}, + {9, 10}, + {11, 12}, + {13, 14}, + {15, 16}, + {17, 18}, + {19, 20}, + {21, 22}, + {23, 24}, + {25, 26}, + {27, 28}, + {29, 30}}; + +static const int epd_phimap[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; +static const int epd_rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +unsigned int TowerInfoDefs::encode_emcal(const unsigned int towerIndex) +{ + static int phimap[64]; + static int etamap[64]; + static int etabinoffset[4]; + static int ifirst = 1; + if (ifirst == 1) + { + for (int j = 0; j < 8; j++) + { + for (int k = 0; k < 8; k++) + { + etamap[emcadc[j][k]] = j; + phimap[emcadc[j][k]] = k; + } + } + etabinoffset[0] = 24; + etabinoffset[1] = 0; + etabinoffset[2] = 48; + etabinoffset[3] = 72; + ifirst = 0; + } + const int channels_per_sector = 64; + const int supersector = 64 * 12; + const int nchannelsperpacket = 64 * 3; + const int maxphibin = 7; + const int maxetabin = 23; + int supersectornumber = towerIndex / supersector; + int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta| + if (packet < 0 || packet > 3) + { + std::cout << "Attempting to access channel with invalid value in EMCal " << packet << std::endl; + exit(1); + } + int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector; + int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector; + int localphibin = phimap[interfaceboard_channel]; + if (packet == 0 || packet == 1) + { + localphibin = maxphibin - localphibin; + } + int localetabin = etamap[interfaceboard_channel]; + int packet_etabin = localetabin + 8 * interfaceboard; + if (packet == 0 || packet == 1) + { + packet_etabin = maxetabin - packet_etabin; + } + unsigned int globaletabin = packet_etabin + etabinoffset[packet]; + unsigned int globalphibin = localphibin + supersectornumber * 8; + unsigned int key = globalphibin + (globaletabin << 16U); + return key; +} + +unsigned int TowerInfoDefs::encode_emcal(const unsigned int etabin, const unsigned int phibin) +{ + unsigned int key = phibin + (etabin << 16U); + return key; +} + +unsigned int TowerInfoDefs::decode_emcal(const unsigned int tower_key) +{ + const int etabinoffset[4] = {24, 0, 48, 72}; + const int etabinmap[4] = {1, 0, 2, 3}; + const int channels_per_sector = 64; + const int supersector = 64 * 12; + const int nchannelsperpacket = 64 * 3; + const int maxphibin = 7; + const int maxetabin = 23; + + unsigned int etabin = tower_key >> 16U; + unsigned int phibin = tower_key - (etabin << 16U); + int packet = etabinmap[(int) etabin / 24]; + int localetabin = etabin - etabinoffset[packet]; + int localphibin = phibin % 8; + int supersectornumber = phibin / 8; + int ib = 0; + if (packet == 0 || packet == 1) + { + localetabin = maxetabin - localetabin; + } + ib = localetabin / 8; + unsigned int index = 0; + if (packet == 0 || packet == 1) + { + localphibin = maxphibin - localphibin; + } + localetabin = localetabin % 8; + unsigned int localindex = emcadc[localetabin][localphibin]; + index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber; + return index; +} + +unsigned int TowerInfoDefs::encode_hcal(const unsigned int towerIndex) +{ + static int phimap[64]; + static int etamap[64]; + static int etabinoffset[4]; + static int phibinoffset[4]; + static int ifirst = 1; + if (ifirst == 1) + { + for (int j = 0; j < 8; j++) + { + for (int k = 0; k < 2; k++) + { + etamap[hcaladc[j][k]] = j; + phimap[hcaladc[j][k]] = k; + } + } + etabinoffset[0] = 0; + etabinoffset[1] = 8; + etabinoffset[2] = 16; + etabinoffset[3] = 0; + + phibinoffset[0] = 0; + phibinoffset[1] = 2; + phibinoffset[2] = 4; + phibinoffset[3] = 6; + ifirst = 0; + } + + const int channels_per_sector = 16; + const int supersector = 16 * 4 * 3; + const int nchannelsperpacket = channels_per_sector * 4; + // const int etabinoffset[4] = {0,8,16,0}; + // const int phibinoffset[4] = {0,2,4,6}; + int supersectornumber = towerIndex / supersector; + int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta| + if (packet < 0 || packet > 3) + { + std::cout << "Attempting to access channel with invalid value ih HCAL " << packet << std::endl; + exit(1); + } + int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector; + int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector; + int localphibin = phimap[interfaceboard_channel] + phibinoffset[interfaceboard]; + int localetabin = etamap[interfaceboard_channel]; + int packet_etabin = localetabin; + unsigned int globaletabin = packet_etabin + etabinoffset[packet]; + unsigned int globalphibin = localphibin + supersectornumber * 8; + unsigned int key = globalphibin + (globaletabin << 16U); + return key; +} + +// convert from etabin-phibin to key +unsigned int TowerInfoDefs::encode_hcal(const unsigned int etabin, const unsigned int phibin) +{ + unsigned int key = phibin + (etabin << 16U); + return key; +} + +unsigned int TowerInfoDefs::decode_hcal(const unsigned int tower_key) +{ + int channels_per_sector = 16; + int supersector = 16 * 4 * 3; + int nchannelsperpacket = channels_per_sector * 4; + int etabinoffset[3] = {0, 8, 16}; + int phibinoffset[4] = {0, 2, 4, 6}; + unsigned int etabin = tower_key >> 16U; + unsigned int phibin = tower_key - (etabin << 16U); + int packet = etabin / 8; + int localetabin = etabin - etabinoffset[packet]; + int localphibin = phibin % 8; + int supersectornumber = phibin / 8; + int ib = localphibin / 2; + unsigned int index = 0; + localphibin = localphibin - phibinoffset[ib]; + unsigned int localindex = hcaladc[localetabin][localphibin]; + index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber; + return index; +} + +// convert from calorimeter key to phi bin +unsigned int TowerInfoDefs::getCaloTowerPhiBin(const unsigned int key) +{ + unsigned int etabin = key >> 16U; + unsigned int phibin = key - (etabin << 16U); + return phibin; +} + +// convert from calorimeter key to eta bin +unsigned int TowerInfoDefs::getCaloTowerEtaBin(const unsigned int key) +{ + unsigned int etabin = key >> 16U; + return etabin; +} + +unsigned int TowerInfoDefs::encode_epd(const unsigned int towerIndex) // convert from tower index to key +{ + int channels_per_sector = 31; + int supersector = channels_per_sector * 12; + unsigned int supersectornumber = towerIndex / supersector; + int sector = ((towerIndex % supersector)) / channels_per_sector; + int channel = ((towerIndex % supersector)) % channels_per_sector; + unsigned int key = channel + (sector << 5U) + (supersectornumber << 9U); + return key; +} + +// convert from arm-rbin-phibin to key +unsigned int TowerInfoDefs::encode_epd(const unsigned int arm, const unsigned int rbin, const unsigned int phibin) +{ + if (rbin == 0 && phibin > 11) + { + std::cout << __PRETTY_FUNCTION__ << " encode_epd invalid phibin value: " << phibin << " where max valid phibin is 11" << std::endl; + exit(1); + } + + unsigned int sector = phibin / 2; + if (rbin == 0) + { + sector = phibin; + } + + int channel = 0; + if (rbin != 0) + { + channel = epdchnlmap[rbin][phibin - 2 * sector]; + } + + unsigned int key = channel + (sector << 5U) + (arm << 9U); + return key; +} + +unsigned int TowerInfoDefs::decode_epd(const unsigned int tower_key) +{ + int channels_per_sector = 31; + int supersector = channels_per_sector * 12; + unsigned int ns_sector = tower_key >> 9U; + unsigned int sector = (tower_key - (ns_sector << 9U)) >> 5U; + unsigned int channel = tower_key - (ns_sector << 9U) - (sector << 5U); + unsigned int index = ns_sector * supersector + sector * channels_per_sector + channel; + return index; +} + +// convert from epd key to arm bin +unsigned int TowerInfoDefs::get_epd_arm(unsigned int key) +{ + unsigned int arm = key >> 9U; + return arm; +} +// convert from epd key to sector number +unsigned int TowerInfoDefs::get_epd_sector(unsigned int key) +{ + unsigned int arm = get_epd_arm(key); + unsigned int sector = (key - (arm << 9U)) >> 5U; + return sector; +} +// convert from epd key to r bin +unsigned int TowerInfoDefs::get_epd_rbin(unsigned int key) +{ + unsigned int arm = get_epd_arm(key); + unsigned int sector = get_epd_sector(key); + unsigned int channel = key - (sector << 5U) - (arm << 9U); + unsigned int rbin = epd_rmap[channel]; + return rbin; +} +// convert from epd key to phi bin +unsigned int TowerInfoDefs::get_epd_phibin(unsigned int key) +{ + unsigned int arm = get_epd_arm(key); + unsigned int rbin = get_epd_rbin(key); + unsigned int sector = get_epd_sector(key); + unsigned int channel = key - (sector << 5U) - (arm << 9U); + unsigned int phibin = epd_phimap[channel] + 2 * sector; + if (rbin == 0) + { + phibin = sector; + } + + return phibin; +} + +unsigned int TowerInfoDefs::encode_zdc(const unsigned int towerIndex) +{ + if (towerIndex > 5) + { + std::cout << "Attempting to access zdc channel with invalid number " << towerIndex << std::endl; + exit(1); + } + // 3 bits: one for pos/neg z and 2 for the 3 modules + unsigned int key; + if (towerIndex == 0) key = 0; + if (towerIndex == 1) key = 1; + if (towerIndex == 2) key = 2; + // negative side + if (towerIndex == 3) + { + key = 1 << 2; + key += 0; + } + if (towerIndex == 4) + { + key = 1 << 2; + key += 1; + } + if (towerIndex == 5) + { + key = 1 << 2; + key += 2; + } + return key; +} + +// convert from channel number to smd tower key +unsigned int TowerInfoDefs::encode_smd(const unsigned int towerIndex) +{ + // 3 bits: one for pos/neg z and 2 for the 3 modules + if (towerIndex > 29) + { + std::cout << "Attempting to access smd channel with invalid number " << towerIndex << std::endl; + exit(1); + } + unsigned int Xpos[2] = {0, 6}; + unsigned int Ypos[2] = {7, 14}; + unsigned int Xneg[2] = {15, 23}; + unsigned int Yneg[2] = {22, 29}; + unsigned int xyBit = 0; + unsigned int fingerIndex = UINT_MAX; + unsigned int sideBit = 0; + if (towerIndex >= Xpos[0] && towerIndex <= Xpos[1]) + { + xyBit = 0; + fingerIndex = towerIndex - Xpos[0]; + sideBit = 1; + } + if (towerIndex >= Ypos[0] && towerIndex <= Ypos[1]) + { + xyBit = 1; + fingerIndex = towerIndex - Ypos[0]; + sideBit = 1; + } + if (towerIndex >= Xneg[0] && towerIndex <= Xneg[1]) + { + xyBit = 0; + fingerIndex = towerIndex - Xneg[0]; + sideBit = 0; + } + if (towerIndex >= Yneg[0] && towerIndex <= Yneg[1]) + { + xyBit = 1; + fingerIndex = towerIndex - Yneg[0]; + sideBit = 0; + } + unsigned int key = (sideBit << 4) + (xyBit << 3) + fingerIndex; + // key += (sideBit << 4) + (xyBit << 3) + fingerIndex; + return key; +} + +unsigned int TowerInfoDefs::decode_smd(const unsigned int key) +{ + unsigned int index = 999; + for (unsigned int i = 0; i < 30; i++) + { + if (encode_smd(i) == key) + { + index = i; + break; + } + } + return index; +} + +// convert from zdc tower key to channel number +unsigned int TowerInfoDefs::decode_zdc(const unsigned int key) +{ + unsigned int index = 999; + for (unsigned int i = 0; i < 6; i++) + { + if (encode_zdc(i) == key) + { + index = i; + break; + } + } + return index; +} + +// convert from calorimeter key to zdc side +int TowerInfoDefs::get_zdc_side(const unsigned int key) +{ + if (key & 4) return 1; + if (!(key & 4)) return -1; + return -999; +} + +// convert from calorimeter key to zdc module number +unsigned int TowerInfoDefs::get_zdc_module_index(const unsigned int key) +{ + return key & 3; +} + +// convert from calorimeter key to smd side +int TowerInfoDefs::get_smd_side(const unsigned int key) +{ + if (key & (1 << 4)) return 1; + if (!(key & (1 << 4))) return -1; + return -999; +} +// convert from calorimeter key to smd xy bin +int TowerInfoDefs::get_smd_xy(const unsigned int key) +{ + if (key & (1 << 3)) return 0; + if (!(key & (1 << 3))) return 1; + return -999; +} +// convert from calorimeter key to smd finger +int TowerInfoDefs::get_smd_finger_index(const unsigned int key) +{ + return key & 7; +} + +// 128 channels per side, goes 8 times and 8 charges and so on +unsigned int TowerInfoDefs::encode_mbd(const unsigned int towerIndex) +{ + unsigned int side = towerIndex / 128; + unsigned int type = (towerIndex % 16) / 8; + unsigned int channel = (towerIndex % 8) + ((towerIndex / 16) * 8); + if (channel > 63) channel -= 64; + + unsigned int key = (side << 7) | (type << 6) | channel; + + return key; +} + +unsigned int TowerInfoDefs::decode_mbd(const unsigned int key) +{ + unsigned int side = (key >> 7) & 1; + unsigned int type = (key >> 6) & 1; + unsigned int channel = key & 63; + + unsigned int index = (side * 128) + (type * 8) + (channel % 8) + (channel / 8) * 16; + + return index; +} + +unsigned int TowerInfoDefs::get_mbd_side(const unsigned int key) +{ + return (key >> 7) & 1; +} + +unsigned int TowerInfoDefs::get_mbd_type(const unsigned int key) +{ + return (key >> 6) & 1; +} + +unsigned int TowerInfoDefs::get_mbd_channel(const unsigned int key) +{ + return key & 63; +} + +// convienent for interface to geometry class +RawTowerDefs::keytype TowerInfoDefs::get_emcal_geokey_at_channel(const unsigned int towerIndex) +{ + unsigned int towerkey = encode_emcal(towerIndex); + unsigned int etabin = getCaloTowerEtaBin(towerkey); + unsigned int phibin = getCaloTowerPhiBin(towerkey); + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::CEMC, etabin, phibin); + return key; +} + +// convienent for interface to geometry class +RawTowerDefs::keytype TowerInfoDefs::get_hcalin_geokey_at_channel(const unsigned int towerIndex) +{ + unsigned int towerkey = encode_hcal(towerIndex); + unsigned int etabin = getCaloTowerEtaBin(towerkey); + unsigned int phibin = getCaloTowerPhiBin(towerkey); + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, etabin, phibin); + return key; +} + +// convienent for interface to geometry class +RawTowerDefs::keytype TowerInfoDefs::get_hcalout_geokey_at_channel(const unsigned int towerIndex) +{ + unsigned int towerkey = encode_hcal(towerIndex); + unsigned int etabin = getCaloTowerEtaBin(towerkey); + unsigned int phibin = getCaloTowerPhiBin(towerkey); + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, etabin, phibin); + return key; +} + +#pragma GCC diagnostic pop diff --git a/offline/packages/CaloBase/TowerInfoDefs.h b/offline/packages/CaloBase/TowerInfoDefs.h index 0a80adf756..aa7298f3b4 100644 --- a/offline/packages/CaloBase/TowerInfoDefs.h +++ b/offline/packages/CaloBase/TowerInfoDefs.h @@ -2,430 +2,57 @@ #define CALOBASE_TOWERINFODEFS_H #include "RawTowerDefs.h" -#include -#include -#include -#include -/*! Namespace with functions to encode / decode calo information. - */ -int emcadc[8][8] = { - {62, 60, 46, 44, 30, 28, 14, 12}, - {63, 61, 47, 45, 31, 29, 15, 13}, - {58, 56, 42, 40, 26, 24, 10, 8}, - {59, 57, 43, 41, 27, 25, 11, 9}, - {54, 52, 38, 36, 22, 20, 6, 4}, - {55, 53, 39, 37, 23, 21, 7, 5}, - {50, 48, 34, 32, 18, 16, 2, 0}, - {51, 49, 35, 33, 19, 17, 3, 1}}; - -int hcaladc[8][2] = { - {0, 1}, - {2, 3}, - {4, 5}, - {6, 7}, - {8, 9}, - {10, 11}, - {12, 13}, - {14, 15}}; - - - -namespace TowerInfoDefs +namespace TowerInfoDefs { - // convert from tower index to key - inline unsigned int encode_emcal(const unsigned int towerIndex) - { - int phimap[64] = {0}; - int etamap[64] = {0}; - for (int j = 0; j < 8; j++) - { - for (int k = 0; k < 8; k++) - { - etamap[emcadc[j][k]] = j; - phimap[emcadc[j][k]] = k; - } - } - int channels_per_sector = 64; - int supersector = 64 * 12; - int nchannelsperpacket = 64 * 3; - int maxphibin = 7; - int maxetabin = 23; - int etabinoffset[4] = {24,0,48,72}; - int supersectornumber = towerIndex / supersector; - int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta| - if (packet < 0 || packet > 3 ) - { - std::cout << "Attempting to access channel with invalid value in EMCal " << packet << std::endl; - exit(1); - } - int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector; - int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector; - int localphibin = phimap[interfaceboard_channel]; - if (packet == 0 || packet == 1) - { - localphibin = maxphibin - localphibin; - } - int localetabin = etamap[interfaceboard_channel]; - int packet_etabin = localetabin + 8 * interfaceboard; - if (packet == 0 || packet == 1) - { - packet_etabin = maxetabin - packet_etabin; - } - unsigned int globaletabin = packet_etabin + etabinoffset[packet]; - unsigned int globalphibin = localphibin + supersectornumber * 8; - unsigned int key = globalphibin + (globaletabin << 16U); - return key; - } - - inline unsigned int encode_emcal (const unsigned int etabin, const unsigned int phibin) - { - unsigned int key = phibin + (etabin << 16U); - return key; - } - - // convert from tower index to hcal key - inline unsigned int encode_hcal(const unsigned int towerIndex) - { - int phimap[64] = {0}; - int etamap[64] = {0}; - for (int j = 0; j < 8; j++) - { - for (int k = 0; k < 2; k++) - { - etamap[hcaladc[j][k]] = j; - phimap[hcaladc[j][k]] = k; - } - } - int channels_per_sector = 16; - int supersector = 16 * 4 * 3; - int nchannelsperpacket = channels_per_sector * 4; - int etabinoffset[4] = {0,8,16,0}; - int phibinoffset[4] = {0,2,4,6}; - int supersectornumber = towerIndex / supersector; - int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta| - if (packet < 0 || packet > 3 ) - { - std::cout << "Attempting to access channel with invalid value ih HCAL " << packet << std::endl; - exit(1); - } - int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector; - int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector; - int localphibin = phimap[interfaceboard_channel] + phibinoffset[interfaceboard]; - int localetabin = etamap[interfaceboard_channel]; - int packet_etabin = localetabin; - unsigned int globaletabin = packet_etabin + etabinoffset[packet]; - unsigned int globalphibin = localphibin + supersectornumber * 8; - unsigned int key = globalphibin + (globaletabin << 16U); - return key; - } - - // convert from etabin-phibin to key - inline unsigned int encode_hcal (const unsigned int etabin, const unsigned int phibin) - { - unsigned int key = phibin + (etabin << 16U); - return key; - } - - // convert from channel index to EPD key - inline unsigned int encode_epd(const unsigned int towerIndex) // convert from tower index to key - { - int channels_per_sector = 31; - int supersector = channels_per_sector * 12; - unsigned int supersectornumber = towerIndex / supersector; - int sector = ((towerIndex % supersector)) / channels_per_sector; - int channel = ((towerIndex % supersector)) % channels_per_sector; - int rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; - int phimap_sepd[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; - unsigned int globalphi = phimap_sepd[channel] + 2 * sector; - unsigned int r = rmap[channel]; - unsigned int key = globalphi + (r << 10U) + (supersectornumber << 20U); - return key; - } - - // convert from arm-rbin-phibin to key - inline unsigned int encode_epd (const unsigned int arm, const unsigned int rbin, const unsigned int phibin) - { - unsigned int key = phibin + (rbin << 10U) + (arm << 20U); - return key; - } - - // convert from channel number to zdc tower key - inline unsigned int encode_zdc(const unsigned int towerIndex) - { - if (towerIndex > 5) - { - std::cout << "Attempting to access zdc channel with invalid number " << towerIndex << std::endl; - exit(1); - } - // 3 bits: one for pos/neg z and 2 for the 3 modules - - unsigned int key; - if(towerIndex==0) key = 0; - if(towerIndex==1) key = 1; - if(towerIndex==2) key = 2; - //negative side - if(towerIndex==3) {key = 1 << 2; key += 0;} - if(towerIndex==4) {key = 1 << 2; key += 1;} - if(towerIndex==5) {key = 1 << 2; key += 2;} - return key; - } - - - // convert from channel number to smd tower key - inline unsigned int encode_smd(const unsigned int towerIndex) - { - // 3 bits: one for pos/neg z and 2 for the 3 modules - if (towerIndex > 29) - { - std::cout << "Attempting to access smd channel with invalid number " << towerIndex << std::endl; - exit(1); - } - int Xpos[2] = {0,6}; - int Ypos[2] = {7,14}; - int Xneg[2] = {15,23}; - int Yneg[2] = {22,29}; - unsigned int xyBit = 0; - unsigned int fingerIndex; - unsigned int sideBit = 0; - if (towerIndex >= Xpos[0] && towerIndex <= Xpos[1] ) - { - xyBit = 0; - fingerIndex = towerIndex -Xpos[0]; - sideBit = 1; - } - if (towerIndex >= Ypos[0] && towerIndex <= Ypos[1] ) - { - xyBit = 1; - fingerIndex = towerIndex -Ypos[0]; - sideBit = 1; - } - if (towerIndex >= Xneg[0] && towerIndex <= Xneg[1] ) - { - xyBit = 0; - fingerIndex = towerIndex - Xneg[0]; - sideBit = 0; - } - if (towerIndex >= Yneg[0] && towerIndex <= Yneg[1] ) - { - xyBit = 1; - fingerIndex = towerIndex - Yneg[0]; - sideBit = 0; - } - unsigned int key = (sideBit << 4) + (xyBit << 3) + fingerIndex; - return key; - } - - - // convert from smd tower key to channel number - inline unsigned int decode_smd(const unsigned int key) - { - unsigned int index=999; - for (unsigned int i=0; i<30; i++) - { - if (encode_smd(i) == key) {index=i; break;} - } - return index; - } - - - // convert from zdc tower key to channel number - inline unsigned int decode_zdc(const unsigned int key) - { - unsigned int index=999; - for (unsigned int i=0; i<6; i++) - { - if (encode_zdc(i) == key) {index=i; break;} - } - return index; - } - - - - // convert from EPD tower key to channel index - inline unsigned int decode_epd(const unsigned int tower_key) - { - int channels_per_sector = 31; - int supersector = channels_per_sector * 12; - unsigned int ns_sector = tower_key >> 20U; - unsigned int rbin = (tower_key - (ns_sector << 20U)) >> 10U; - unsigned int phibin = tower_key - (ns_sector << 20U) - (rbin << 10U); - int epdchnlmap[16][2] = {{0, 0}, {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, {19, 20}, {21, 22}, {23, 24}, {25, 26}, {27, 28}, {29, 30}}; - int sector = phibin / 2; - int channel = 0; - if (rbin > 0) - { - channel = epdchnlmap[rbin][phibin - 2 * sector]; - } - else - { - channel = 0; - } - unsigned int index = 0; - index = ns_sector * supersector + sector * channels_per_sector + channel; - return index; - } - - - // convert from EMCAL tower key to channel index - inline unsigned int decode_emcal(const unsigned int tower_key) - { - int etabinoffset[4] = {0}; - int etabinmap[4] = {0}; - int channels_per_sector = 64; - int supersector = 64 * 12; - int nchannelsperpacket = 64 * 3; - int maxphibin = 7; - int maxetabin = 23; - etabinoffset[0] = 24; - etabinoffset[1] = 0; - etabinoffset[2] = 48; - etabinoffset[3] = 72; - - etabinmap[0] = 1; - etabinmap[1] = 0; - etabinmap[2] = 2; - etabinmap[3] = 3; - unsigned int etabin = tower_key >> 16U; - unsigned int phibin = tower_key - (etabin << 16U); - int packet = etabinmap[(int) etabin / 24]; - int localetabin = etabin - etabinoffset[packet]; - int localphibin = phibin % 8; - int supersectornumber = phibin / 8; - int ib = 0; - if (packet == 0 || packet == 1) - { - localetabin = maxetabin - localetabin; - } - ib = localetabin / 8; - unsigned int index = 0; - if (packet == 0 || packet == 1) - { - localphibin = maxphibin - localphibin; - } - localetabin = localetabin % 8; - unsigned int localindex = emcadc[localetabin][localphibin]; - index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber; - return index; - } - - // convert from HCAL tower key to channel index - inline unsigned int decode_hcal(const unsigned int tower_key) - { - int channels_per_sector = 16; - int supersector = 16 * 4 * 3; - int nchannelsperpacket = channels_per_sector * 4; - int etabinoffset[3] = {0,8,16}; - int phibinoffset[4] = {0,2,4,6}; - unsigned int etabin = tower_key >> 16U; - unsigned int phibin = tower_key - (etabin << 16U); - int packet = etabin / 8; - int localetabin = etabin - etabinoffset[packet]; - int localphibin = phibin % 8; - int supersectornumber = phibin / 8; - int ib = localphibin / 2; - unsigned int index = 0; - localphibin = localphibin - phibinoffset[ib]; - unsigned int localindex = hcaladc[localetabin][localphibin]; - index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber; - return index; - } - - // convert from calorimeter key to phi bin - inline unsigned int getCaloTowerPhiBin(const unsigned int key) - { - unsigned int etabin = key >> 16U; - unsigned int phibin = key - (etabin << 16U); - return phibin; - } - - // convert from calorimeter key to eta bin - inline unsigned int getCaloTowerEtaBin(const unsigned int key) - { - unsigned int etabin = key >> 16U; - return etabin; - } - - - - - - - // convert from calorimeter key to zdc side - inline int get_zdc_side(const unsigned int key) - { - if (key&4) return 1; - if (!(key&4)) return -1; - return -999; - } - - // convert from calorimeter key to zdc module number - inline unsigned int get_zdc_module_index(const unsigned int key) - { - return key&3; - } - + unsigned int encode_emcal(const unsigned int towerIndex); + unsigned int encode_emcal (const unsigned int etabin, const unsigned int phibin); + unsigned int decode_emcal(const unsigned int tower_key); + unsigned int encode_hcal(const unsigned int towerIndex); + unsigned int encode_hcal (const unsigned int etabin, const unsigned int phibin); + unsigned int decode_hcal(const unsigned int tower_key); + unsigned int encode_epd(const unsigned int towerIndex); + unsigned int encode_epd (const unsigned int arm, const unsigned int rbin, const unsigned int phibin); + unsigned int decode_epd(const unsigned int tower_key); - // convert from calorimeter key to smd side - inline int get_smd_side(const unsigned int key) - { - if (key&(1<<4)) return 1; - if ( !(key&(1<<4)) ) return -1; - return -999; - } - // convert from calorimeter key to smd xy bin - inline int get_smd_xy(const unsigned int key) - { - if (key&(1<<3)) return 0; - if ( !(key&(1<<3)) ) return 1; - return -999; - } - // convert from calorimeter key to smd finger - inline int get_smd_finger_index(const unsigned int key) - { - return key&7; - } - // convienent for interface to geometry class - inline RawTowerDefs::keytype get_emcal_geokey_at_channel(const unsigned int towerIndex) - { - unsigned int towerkey = encode_emcal(towerIndex); - unsigned int etabin = getCaloTowerEtaBin(towerkey); - unsigned int phibin = getCaloTowerPhiBin(towerkey); - const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::CEMC, etabin, phibin); - return key; - } + unsigned int get_epd_arm(unsigned int key); + unsigned int get_epd_sector(unsigned int key); + unsigned int get_epd_rbin(unsigned int key); + unsigned int get_epd_phibin(unsigned int key); + unsigned int getCaloTowerPhiBin(const unsigned int key); + unsigned int getCaloTowerEtaBin(const unsigned int key) ; - // convienent for interface to geometry class - inline RawTowerDefs::keytype get_hcalin_geokey_at_channel(const unsigned int towerIndex) - { - unsigned int towerkey = encode_hcal(towerIndex); - unsigned int etabin = getCaloTowerEtaBin(towerkey); - unsigned int phibin = getCaloTowerPhiBin(towerkey); - const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, etabin, phibin); - return key; - } + int get_zdc_side(const unsigned int key) ; + unsigned int get_zdc_module_index(const unsigned int key); + int get_smd_side(const unsigned int key); + int get_smd_xy(const unsigned int key); + int get_smd_finger_index(const unsigned int key); - // convienent for interface to geometry class - inline RawTowerDefs::keytype get_hcalout_geokey_at_channel(const unsigned int towerIndex) - { - unsigned int towerkey = encode_hcal(towerIndex); - unsigned int etabin = getCaloTowerEtaBin(towerkey); - unsigned int phibin = getCaloTowerPhiBin(towerkey); - const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, etabin, phibin); - return key; - } + unsigned int get_mbd_side(const unsigned int key); + // 0 for time 1 for charge + unsigned int get_mbd_type(const unsigned int key); + unsigned int get_mbd_channel(const unsigned int key); + unsigned int encode_zdc(const unsigned int towerIndex); + unsigned int encode_smd(const unsigned int towerIndex); + unsigned int decode_smd(const unsigned int key); + unsigned int decode_zdc(const unsigned int key); + unsigned int encode_mbd(const unsigned int towerIndex); + unsigned int decode_mbd(const unsigned int key); + RawTowerDefs::keytype get_emcal_geokey_at_channel(const unsigned int towerIndex); + RawTowerDefs::keytype get_hcalin_geokey_at_channel(const unsigned int towerIndex) ; + RawTowerDefs::keytype get_hcalout_geokey_at_channel(const unsigned int towerIndex) ; diff --git a/offline/packages/CaloBase/configure.ac b/offline/packages/CaloBase/configure.ac index 5dcd946757..0c8dd5cd01 100644 --- a/offline/packages/CaloBase/configure.ac +++ b/offline/packages/CaloBase/configure.ac @@ -17,5 +17,15 @@ esac CINTDEFS=" -noIncludePaths -inlineInputHeader " AC_SUBST(CINTDEFS) +AC_ARG_ENABLE(online, + [ --enable-online build using for online [default=no]], + [case "${enableval}" in + yes) online=true ;; + no) online=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-online) ;; + esac], + online=false) +AM_CONDITIONAL(USE_ONLINE, test "x$online" = xtrue) + AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index e801587e0e..93930a8b12 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -26,6 +26,19 @@ //____________________________________________________________________________.. CaloTowerBuilder::CaloTowerBuilder(const std::string &name) : SubsysReco(name) + , WaveformProcessing(nullptr) + , m_dettype(CaloTowerBuilder::CEMC) + , m_CaloInfoContainer(nullptr) + , m_detector("CEMC") + , m_packet_low(INT_MIN) + , m_packet_high(INT_MIN) + , m_nsamples(16) + , m_nchannels(192) + , m_nzerosuppsamples(2) + , m_isdata(true) + , _nsoftwarezerosuppression(40) + , _bdosoftwarezerosuppression(false) + , _processingtype(CaloWaveformProcessing::NONE) { WaveformProcessing = new CaloWaveformProcessing(); } @@ -39,36 +52,66 @@ CaloTowerBuilder::~CaloTowerBuilder() //____________________________________________________________________________.. int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) { - WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); + WaveformProcessing->set_processing_type(_processingtype); + WaveformProcessing->set_softwarezerosuppression(_bdosoftwarezerosuppression, _nsoftwarezerosuppression); if (m_dettype == CaloTowerBuilder::CEMC) { m_detector = "CEMC"; - m_packet_low = 6017; - m_packet_high = 6032; - // 6001, 60128 + m_packet_low = 6001; + m_packet_high = 6128; + m_nchannels = 192; WaveformProcessing->set_template_file("testbeam_cemc_template.root"); + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); + } } else if (m_dettype == CaloTowerBuilder::HCALIN) { m_packet_low = 7001; m_packet_high = 7008; m_detector = "HCALIN"; + m_nchannels = 192; WaveformProcessing->set_template_file("testbeam_ihcal_template.root"); + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); + } } else if (m_dettype == CaloTowerBuilder::HCALOUT) { m_detector = "HCALOUT"; m_packet_low = 8001; m_packet_high = 8008; + m_nchannels = 192; WaveformProcessing->set_template_file("testbeam_ohcal_template.root"); + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); + } } else if (m_dettype == CaloTowerBuilder::EPD) { m_detector = "EPD"; m_packet_low = 9001; - m_packet_high = 9016; - WaveformProcessing->set_template_file("testbeam_cemc_template.root"); // place holder until we have EPD templates + m_packet_high = 9005; + m_nchannels = 186; + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::FAST); // default the EPD to fast processing + } + } + else if (m_dettype == CaloTowerBuilder::MBD) + { + m_detector = "MBD"; + m_packet_low = 1001; + m_packet_high = 1002; + m_nchannels = 128; + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::FAST); + } } WaveformProcessing->initialize_processing(); CreateNodeTree(topNode); @@ -95,22 +138,54 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) for (int pid = m_packet_low; pid <= m_packet_high; pid++) { Packet *packet = _event->getPacket(pid); - if (!packet) + if (packet) { - return Fun4AllReturnCodes::DISCARDEVENT; + int nchannels = packet->iValue(0, "CHANNELS"); + if (nchannels > m_nchannels) // packet is corrupted and reports too many channels + { + return Fun4AllReturnCodes::DISCARDEVENT; + } + for (int channel = 0; channel < nchannels; channel++) + { + std::vector waveform; + waveform.reserve(m_nsamples); + for (int samp = 0; samp < m_nsamples; samp++) + { + waveform.push_back(packet->iValue(samp, channel)); + } + waveforms.push_back(waveform); + waveform.clear(); + } + if (nchannels < m_nchannels) + { + for (int channel = 0; channel < m_nchannels - nchannels; channel++) + { + std::vector waveform; + waveform.reserve(m_nsamples); + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { + waveform.push_back(0); + } + waveforms.push_back(waveform); + waveform.clear(); + } + } + delete packet; } - for (int channel = 0; channel < packet->iValue(0, "CHANNELS"); channel++) + else // if the packet is missing treat constitutent channels as zero suppressed { - std::vector waveform; - waveform.reserve(m_nsamples); - for (int samp = 0; samp < m_nsamples; samp++) + for (int channel = 0; channel < m_nchannels; channel++) { - waveform.push_back(packet->iValue(samp, channel)); + std::vector waveform; + waveform.reserve(2); + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { + waveform.push_back(0); + } + waveforms.push_back(waveform); + waveform.clear(); } - waveforms.push_back(waveform); - waveform.clear(); } - delete packet; } } else // placeholder for adding simulation @@ -152,6 +227,10 @@ void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) { m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::SEPD); } + else if (m_dettype == MBD) + { + m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::MBD); + } else { m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL); diff --git a/offline/packages/CaloReco/CaloTowerBuilder.h b/offline/packages/CaloReco/CaloTowerBuilder.h index 3ce5e78af3..fbf03e249e 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.h +++ b/offline/packages/CaloReco/CaloTowerBuilder.h @@ -4,6 +4,7 @@ #define CALOTOWERBUILDER_H #include +#include "CaloWaveformProcessing.h" #include #include @@ -27,7 +28,8 @@ class CaloTowerBuilder : public SubsysReco CEMC = 0, HCALIN = 1, HCALOUT = 2, - EPD = 3 + EPD = 3, + MBD = 4 }; void set_detector_type(CaloTowerBuilder::DetectorSystem dettype) @@ -47,15 +49,32 @@ class CaloTowerBuilder : public SubsysReco return; } + void set_processing_type( CaloWaveformProcessing::process processingtype) + { + _processingtype = processingtype; + } + + void set_softwarezerosuppression(bool usezerosuppression,int softwarezerosuppression) + { + _nsoftwarezerosuppression = softwarezerosuppression; + _bdosoftwarezerosuppression = usezerosuppression; + } + private: - CaloWaveformProcessing *WaveformProcessing = nullptr; - CaloTowerBuilder::DetectorSystem m_dettype = CaloTowerBuilder::CEMC; - TowerInfoContainer *m_CaloInfoContainer = nullptr; //! Calo info - std::string m_detector = "CEMC"; - int m_packet_low = INT_MIN; - int m_packet_high = INT_MIN; - int m_nsamples = 16; - bool m_isdata = true; + CaloWaveformProcessing *WaveformProcessing; + CaloTowerBuilder::DetectorSystem m_dettype; + TowerInfoContainer *m_CaloInfoContainer; //! Calo info + std::string m_detector; + int m_packet_low; + int m_packet_high; + int m_nsamples; + int m_nchannels; + int m_nzerosuppsamples; + bool m_isdata; + int _nsoftwarezerosuppression; + bool _bdosoftwarezerosuppression; + CaloWaveformProcessing::process _processingtype; + }; #endif // CALOTOWERBUILDER_H diff --git a/offline/packages/CaloReco/CaloTowerCalib.cc b/offline/packages/CaloReco/CaloTowerCalib.cc index 1fb87aa684..ce6dab159b 100644 --- a/offline/packages/CaloReco/CaloTowerCalib.cc +++ b/offline/packages/CaloReco/CaloTowerCalib.cc @@ -19,7 +19,7 @@ #include #include -#include +#include #include //____________________________________________________________________________.. @@ -58,11 +58,8 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) std::cout << "at run" << m_runNumber << std::endl; if (m_dettype == CaloTowerCalib::CEMC) { - recoConsts *rc = recoConsts::instance(); // place holder - rc->set_StringFlag("CDB_GLOBALTAG", "CEMCCalibTest"); - ReadCalib *rb = new ReadCalib(); - std::string calibdir = rb->getCalibrationFile("TestBeginValidity", m_runNumber); + std::string calibdir = CDBInterface::instance()->getUrl("TestBeginValidity"); m_detector = "CEMC"; m_DETECTOR = TowerInfoContainer::EMCAL; m_fieldname = "cemc_abscalib_mip"; @@ -78,10 +75,7 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) } else if (m_dettype == CaloTowerCalib::HCALIN) { - recoConsts *rc = recoConsts::instance(); - rc->set_StringFlag("CDB_GLOBALTAG", "HCalCalibTest"); - ReadCalib *rb = new ReadCalib(); - std::string calibdir = rb->getCalibrationFile("TestBeginValidity", m_runNumber); + std::string calibdir = CDBInterface::instance()->getUrl("TestBeginValidity"); m_detector = "HCALIN"; m_DETECTOR = TowerInfoContainer::HCAL; m_fieldname = "ihcal_abscalib_mip"; @@ -97,10 +91,7 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) } else if (m_dettype == CaloTowerCalib::HCALOUT) { - recoConsts *rc = recoConsts::instance(); - rc->set_StringFlag("CDB_GLOBALTAG", "HCalCalibTest"); - ReadCalib *rb = new ReadCalib(); - std::string calibdir = rb->getCalibrationFile("TestBeginValidity", m_runNumber); + std::string calibdir = CDBInterface::instance()->getUrl("TestBeginValidity"); m_detector = "HCALOUT"; m_DETECTOR = TowerInfoContainer::HCAL; m_fieldname = "ohcal_abscalib_mip"; @@ -116,11 +107,7 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) } else if (m_dettype == CaloTowerCalib::EPD) { - recoConsts *rc = recoConsts::instance(); - // place holder - rc->set_StringFlag("CDB_GLOBALTAG", "EPDCalibTest"); - ReadCalib *rb = new ReadCalib(); - std::string calibdir = rb->getCalibrationFile("TestBeginValidity", m_runNumber); + std::string calibdir = CDBInterface::instance()->getUrl("TestBeginValidity"); m_detector = "EPD"; m_DETECTOR = TowerInfoContainer::SEPD; m_fieldname = "EPD_abscalib_mip"; diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 725157aafd..cf2f2f51c6 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -19,9 +19,6 @@ #include #include -// Define some items that must be defined globally in the .cc file -TProfile *CaloWaveformFitting::h_template = nullptr; - double CaloWaveformFitting::template_function(double *x, double *par) { Double_t v1 = par[0] * h_template->Interpolate(x[0] - par[1]) + par[2]; @@ -54,50 +51,72 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit auto func = [&](std::vector &v) { int size1 = v.size() - 1; - auto h = new TH1F(Form("h_%d", (int) round(v.at(size1))), "", size1, 0, size1); - float maxheight = 0; - int maxbin = 0; - for (int i = 0; i < size1; i++) - { - h->SetBinContent(i + 1, v.at(i)); - if (v.at(i) > maxheight) + + if (size1 == _nzerosuppresssamples) { - maxheight = v.at(i); - maxbin = i; + v.push_back(v.at(0) - v.at(1)); //returns peak sample - pedestal sample + v.push_back(-1); // set time to -1 to indicate zero suppressed + v.push_back(v.at(1)); } - } - float pedestal = 1500; - if (maxbin > 4) - { - pedestal = 0.5 * (v.at(maxbin - 4) + v.at(maxbin - 5)); - } - else if (maxbin > 3) - { - pedestal = (v.at(maxbin - 4)); - } else - { - pedestal = 0.5 * (v.at(size1 - 3) + v.at(size1 - 2)); - } - auto f = new TF1(Form("f_%d", (int) round(v.at(size1))), template_function, 0, 31, 3); - ROOT::Math::WrappedMultiTF1 *fitFunction = new ROOT::Math::WrappedMultiTF1(*f, 3); - ROOT::Fit::BinData data(v.size() - 1, 1); - ROOT::Fit::FillData(data, h); - ROOT::Fit::Chi2Function *EPChi2 = new ROOT::Fit::Chi2Function(data, *fitFunction); - ROOT::Fit::Fitter *fitter = new ROOT::Fit::Fitter(); - fitter->Config().MinimizerOptions().SetMinimizerType("GSLMultiFit"); - double params[] = {static_cast(maxheight), static_cast(maxbin - 5), static_cast(pedestal)}; - fitter->Config().SetParamsSettings(3, params); - fitter->FitFCN(*EPChi2, nullptr, data.Size(), true); - for (int i = 0; i < 3; i++) - { - v.push_back(f->GetParameter(i)); - } - h->Delete(); - f->Delete(); - delete fitFunction; - delete fitter; - delete EPChi2; + { + auto h = new TH1F(Form("h_%d", (int) round(v.at(size1))), "", size1, 0, size1); + float maxheight = 0; + int maxbin = 0; + for (int i = 0; i < size1; i++) + { + h->SetBinContent(i + 1, v.at(i)); + if (v.at(i) > maxheight) + { + maxheight = v.at(i); + maxbin = i; + } + } + float pedestal = 1500; + if (maxbin > 4) + { + pedestal = 0.5 * (v.at(maxbin - 4) + v.at(maxbin - 5)); + } + else if (maxbin > 3) + { + pedestal = (v.at(maxbin - 4)); + } + else + { + pedestal = 0.5 * (v.at(size1 - 3) + v.at(size1 - 2)); + } + + if (_bdosoftwarezerosuppression && maxheight - pedestal < _nsoftwarezerosuppression) + { + // std::cout << "software zero suppression happened " << std::endl; + h->Delete(); + v.push_back(v.at(6) - pedestal); + v.push_back(-1); + v.push_back(pedestal); + } + else + { + auto f = new TF1(Form("f_%d", (int) round(v.at(size1))), this,&CaloWaveformFitting::template_function, 0, 31, 3,"CaloWaveformFitting","template_function"); + ROOT::Math::WrappedMultiTF1 *fitFunction = new ROOT::Math::WrappedMultiTF1(*f, 3); + ROOT::Fit::BinData data(v.size() - 1, 1); + ROOT::Fit::FillData(data, h); + ROOT::Fit::Chi2Function *EPChi2 = new ROOT::Fit::Chi2Function(data, *fitFunction); + ROOT::Fit::Fitter *fitter = new ROOT::Fit::Fitter(); + fitter->Config().MinimizerOptions().SetMinimizerType("GSLMultiFit"); + double params[] = {static_cast(maxheight), static_cast(maxbin - 5), static_cast(pedestal)}; + fitter->Config().SetParamsSettings(3, params); + fitter->FitFCN(*EPChi2, nullptr, data.Size(), true); + for (int i = 0; i < 3; i++) + { + v.push_back(f->GetParameter(i)); + } + h->Delete(); + f->Delete(); + delete fitFunction; + delete fitter; + delete EPChi2; + } + } }; t.Foreach(func, chnlvector); diff --git a/offline/packages/CaloReco/CaloWaveformFitting.h b/offline/packages/CaloReco/CaloWaveformFitting.h index 1259b85d6c..0703892d6d 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.h +++ b/offline/packages/CaloReco/CaloWaveformFitting.h @@ -24,7 +24,13 @@ class CaloWaveformFitting return; } - int get_nthreads() + void set_softwarezerosuppression(bool usezerosuppression,int softwarezerosuppression) + { + _nsoftwarezerosuppression = softwarezerosuppression; + _bdosoftwarezerosuppression = usezerosuppression; + } + + int get_nthreads() { return _nthreads; } @@ -37,9 +43,12 @@ class CaloWaveformFitting private: void FastMax(float x0, float x1, float x2, float y0, float y1, float y2, float &xmax, float &ymax); - static TProfile *h_template; - static double template_function(double *x, double *par); + TProfile *h_template = nullptr; + double template_function(double *x, double *par); int _nthreads = 1; + int _nzerosuppresssamples = 2; + int _nsoftwarezerosuppression = 40; + bool _bdosoftwarezerosuppression = false; std::string m_template_input_file; std::string url_template; diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index e8487ee035..aa7d0e005d 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -1,7 +1,7 @@ #include "CaloWaveformProcessing.h" #include "CaloWaveformFitting.h" -#include +#include #include @@ -18,15 +18,20 @@ void CaloWaveformProcessing::initialize_processing() if (m_processingtype == CaloWaveformProcessing::TEMPLATE) { std::string calibrations_repo_template = std::string(calibrationsroot) + "/WaveformProcessing/templates/" + m_template_input_file; - url_template = XploadInterface::instance()->getUrl(m_template_input_file, calibrations_repo_template); + url_template = CDBInterface::instance()->getUrl(m_template_name, calibrations_repo_template); m_Fitter = new CaloWaveformFitting(); m_Fitter->initialize_processing(url_template); m_Fitter->set_nthreads(get_nthreads()); + + if (_bdosoftwarezerosuppression == true) + { + m_Fitter->set_softwarezerosuppression(_bdosoftwarezerosuppression,_nsoftwarezerosuppression); + } } - if (m_processingtype == CaloWaveformProcessing::ONNX) + else if (m_processingtype == CaloWaveformProcessing::ONNX) { std::string calibrations_repo_model = std::string(calibrationsroot) + "/WaveformProcessing/models/" + m_model_name; - url_onnx = XploadInterface::instance()->getUrl(m_model_name, calibrations_repo_model); + url_onnx = CDBInterface::instance()->getUrl(m_model_name, calibrations_repo_model); onnxmodule = onnxSession(url_onnx); } } diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.h b/offline/packages/CaloReco/CaloWaveformProcessing.h index cf184bf018..c79dd99d1c 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.h +++ b/offline/packages/CaloReco/CaloWaveformProcessing.h @@ -20,10 +20,7 @@ class CaloWaveformProcessing : public SubsysReco FAST = 3, }; - CaloWaveformProcessing() - : m_processingtype(CaloWaveformProcessing::TEMPLATE) - , m_template_input_file("CEMC_TEMPLATE") - , m_model_name("CEMC_ONNX"){}; + CaloWaveformProcessing() {} ~CaloWaveformProcessing() override {} void set_processing_type(CaloWaveformProcessing::process modelno) @@ -42,6 +39,12 @@ class CaloWaveformProcessing : public SubsysReco m_template_input_file = template_input_file; return; } + + void set_template_name(const std::string &template_name) + { + m_template_name = template_name; + return; + } void set_model_file(const std::string &model_name) { m_model_name = model_name; @@ -52,6 +55,13 @@ class CaloWaveformProcessing : public SubsysReco int get_nthreads(); + void set_softwarezerosuppression(bool usezerosuppression,int softwarezerosuppression) + { + _nsoftwarezerosuppression = softwarezerosuppression; + _bdosoftwarezerosuppression = usezerosuppression; + } + + std::vector> process_waveform(std::vector> waveformvector); std::vector> calo_processing_ONNX(std::vector> chnlvector); @@ -60,13 +70,16 @@ class CaloWaveformProcessing : public SubsysReco private: CaloWaveformFitting *m_Fitter = nullptr; - CaloWaveformProcessing::process m_processingtype = CaloWaveformProcessing::NONE; + CaloWaveformProcessing::process m_processingtype = CaloWaveformProcessing::TEMPLATE; int _nthreads = 1; + int _nsoftwarezerosuppression = 40; + bool _bdosoftwarezerosuppression = false; std::string m_template_input_file; std::string url_template; + std::string m_template_name = "NONE"; std::string url_onnx; - std::string m_model_name; + std::string m_model_name = "CEMC_ONNX"; }; #endif diff --git a/offline/packages/CaloReco/Makefile.am b/offline/packages/CaloReco/Makefile.am index d0777c79e1..8963aa0ef8 100644 --- a/offline/packages/CaloReco/Makefile.am +++ b/offline/packages/CaloReco/Makefile.am @@ -18,18 +18,17 @@ if USE_ONLINE else libcalo_reco_la_LIBADD = \ + -lcalo_io \ + -lcdbobjects \ -lCLHEP \ - -lphool \ - -lSubsysReco \ + -lffamodules \ -lgsl \ -lgslcblas \ - -lg4vertex_io \ - -lcalo_io \ + -lglobalvertex_io \ -lsph_onnx \ - -lcaloCalibDBFile \ - -lcdbobjects \ - -ldbtools \ - -lphparameter + -lphparameter \ + -lphool \ + -lSubsysReco endif AM_CPPFLAGS = \ diff --git a/offline/packages/CaloReco/RawClusterBuilderTemplate.cc b/offline/packages/CaloReco/RawClusterBuilderTemplate.cc index 59e2256e6e..127027c387 100644 --- a/offline/packages/CaloReco/RawClusterBuilderTemplate.cc +++ b/offline/packages/CaloReco/RawClusterBuilderTemplate.cc @@ -6,8 +6,8 @@ #include "BEmcRecEEMC.h" #include "BEmcRecFEMC.h" -#include -#include +#include +#include #include #include @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -99,8 +99,7 @@ void RawClusterBuilderTemplate::Detector(const std::string &d) void RawClusterBuilderTemplate::LoadProfile(const std::string &fname) { - std::string url = XploadInterface::instance()->getUrl("EMCPROFILE", fname); - + std::string url = CDBInterface::instance()->getUrl("EMCPROFILE", fname); bemc->LoadProfile(url); } diff --git a/offline/packages/CaloReco/RawClusterBuilderTopo.cc b/offline/packages/CaloReco/RawClusterBuilderTopo.cc index d939506436..2c3071d303 100644 --- a/offline/packages/CaloReco/RawClusterBuilderTopo.cc +++ b/offline/packages/CaloReco/RawClusterBuilderTopo.cc @@ -3,10 +3,11 @@ #include #include #include -#include -#include #include #include +#include +#include +#include #include #include @@ -57,14 +58,8 @@ float RawClusterBuilderTopo::calculate_dR(float eta1, float eta2, float phi1, fl { float deta = eta1 - eta2; float dphi = phi1 - phi2; - while (dphi > M_PI) - { - dphi -= 2 * M_PI; - } - while (dphi < -M_PI) - { - dphi += 2 * M_PI; - } + while (dphi > M_PI) dphi -= 2 * M_PI; + while (dphi < -M_PI) dphi += 2 * M_PI; return sqrt(pow(deta, 2) + pow(dphi, 2)); } @@ -85,10 +80,7 @@ std::vector RawClusterBuilderTopo::get_adjacent_towers_by_ID(int ID) { for (int delta_phi = -1; delta_phi <= 1; delta_phi++) { - if (delta_layer == 0 && delta_eta == 0 && delta_phi == 0) - { - continue; // this is the same tower - } + if (delta_layer == 0 && delta_eta == 0 && delta_phi == 0) continue; // this is the same tower int test_eta = this_eta + delta_eta; if (test_eta < 0 || test_eta >= _HCAL_NETA) @@ -102,10 +94,7 @@ std::vector RawClusterBuilderTopo::get_adjacent_towers_by_ID(int ID) // disallow "corner" adjacency (diagonal in eta/phi plane and in different layer) if this option not enabled if (!_allow_corner_neighbor && delta_layer == 1 && abs(delta_phi) == 1 && abs(delta_eta) == 1) { - if (Verbosity() > 20) - { - std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : corner growth not allowed " << std::endl; - } + if (Verbosity() > 20) std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : corner growth not allowed " << std::endl; continue; } @@ -130,10 +119,7 @@ std::vector RawClusterBuilderTopo::get_adjacent_towers_by_ID(int ID) int new_phi = (EMCal_phi_start + delta_phi + _EMCAL_NPHI) % _EMCAL_NPHI; int EMCal_tower = get_ID(2, new_eta, new_phi); - if (Verbosity() > 20) - { - std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : HCal tower with eta / phi = " << this_eta << " / " << this_phi << ", adding EMCal tower with eta / phi = " << new_eta << " / " << new_phi << std::endl; - } + if (Verbosity() > 20) std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : HCal tower with eta / phi = " << this_eta << " / " << this_phi << ", adding EMCal tower with eta / phi = " << new_eta << " / " << new_phi << std::endl; adjacent_towers.push_back(EMCal_tower); } } @@ -147,10 +133,7 @@ std::vector RawClusterBuilderTopo::get_adjacent_towers_by_ID(int ID) { for (int delta_phi = -1; delta_phi <= 1; delta_phi++) { - if (delta_eta == 0 && delta_phi == 0) - { - continue; // this is the same tower - } + if (delta_eta == 0 && delta_phi == 0) continue; // this is the same tower int test_eta = this_eta + delta_eta; if (test_eta < 0 || test_eta >= _EMCAL_NETA) @@ -174,18 +157,12 @@ std::vector RawClusterBuilderTopo::get_adjacent_towers_by_ID(int ID) if (HCal_eta >= 0) { int IHCal_tower = get_ID(0, HCal_eta, HCal_phi); - if (Verbosity() > 20) - { - std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : EMCal tower with eta / phi = " << this_eta << " / " << this_phi << ", adding IHCal tower with eta / phi = " << HCal_eta << " / " << HCal_phi << std::endl; - } + if (Verbosity() > 20) std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : EMCal tower with eta / phi = " << this_eta << " / " << this_phi << ", adding IHCal tower with eta / phi = " << HCal_eta << " / " << HCal_phi << std::endl; adjacent_towers.push_back(IHCal_tower); } else { - if (Verbosity() > 20) - { - std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : EMCal tower with eta / phi = " << this_eta << " / " << this_phi << ", does not have matching IHCal due to large eta " << std::endl; - } + if (Verbosity() > 20) std::cout << "RawClusterBuilderTopo::get_adjacent_towers_by_ID : EMCal tower with eta / phi = " << this_eta << " / " << this_phi << ", does not have matching IHCal due to large eta " << std::endl; } } } @@ -215,9 +192,7 @@ void RawClusterBuilderTopo::export_clusters(const std::vector &original_tow if (n_clusters != 1) // if we didn't just pass down from export_single_cluster { if (Verbosity() > 2) - { std::cout << "RawClusterBuilderTopo::export_clusters called on an initial cluster with " << n_clusters << " final clusters " << std::endl; - } } // build a RawCluster for output std::vector clusters; @@ -386,26 +361,28 @@ int RawClusterBuilderTopo::InitRun(PHCompositeNode *topNode) int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) { - RawTowerContainer *towersEM = findNode::getClass(topNode, "TOWER_CALIB_CEMC"); - RawTowerContainer *towersIH = findNode::getClass(topNode, "TOWER_CALIB_HCALIN"); - RawTowerContainer *towersOH = findNode::getClass(topNode, "TOWER_CALIB_HCALOUT"); + TowerInfoContainer *towerinfosEM = findNode::getClass(topNode, "TOWERINFO_CALIB_CEMC"); + TowerInfoContainer *towerinfosIH = findNode::getClass(topNode, "TOWERINFO_CALIB_HCALIN"); + TowerInfoContainer *towerinfosOH = findNode::getClass(topNode, "TOWERINFO_CALIB_HCALOUT"); - if (!towersEM) + if (!towerinfosEM) { - std::cout << " RawClusterBuilderTopo::process_event : container TOWER_CALIB_CEMC does not exist, aborting " << std::endl; + std::cout << " RawClusterBuilderTopo::process_event : container TOWERINFO_CALIB_CEMC does not exist, aborting " << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - if (!towersIH) + if (!towerinfosIH) { - std::cout << " RawClusterBuilderTopo::process_event : container TOWER_CALIB_HCALIN does not exist, aborting " << std::endl; + std::cout << " RawClusterBuilderTopo::process_event : container TOWERINFO_CALIB_HCALIN does not exist, aborting " << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - if (!towersOH) + if (!towerinfosOH) { - std::cout << " RawClusterBuilderTopo::process_event : container TOWER_CALIB_HCALOUT does not exist, aborting " << std::endl; + std::cout << " RawClusterBuilderTopo::process_event : container TOWERINFO_CALIB_HCALOUT does not exist, aborting " << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } + + _geom_containers[0] = findNode::getClass(topNode, "TOWERGEOM_HCALIN"); _geom_containers[1] = findNode::getClass(topNode, "TOWERGEOM_HCALOUT"); _geom_containers[2] = findNode::getClass(topNode, "TOWERGEOM_CEMC"); @@ -428,9 +405,9 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) if (Verbosity() > 10) { - std::cout << "RawClusterBuilderTopo::process_event: " << towersEM->size() << " TOWER_CALIB_CEMC towers" << std::endl; - std::cout << "RawClusterBuilderTopo::process_event: " << towersIH->size() << " TOWER_CALIB_HCALIN towers" << std::endl; - std::cout << "RawClusterBuilderTopo::process_event: " << towersOH->size() << " TOWER_CALIB_HCALOUT towers" << std::endl; + std::cout << "RawClusterBuilderTopo::process_event: " << towerinfosEM->size() << " TOWERINFO_CALIB_CEMC towers" << std::endl; + std::cout << "RawClusterBuilderTopo::process_event: " << towerinfosIH->size() << " TOWERINFO_CALIB_HCALIN towers" << std::endl; + std::cout << "RawClusterBuilderTopo::process_event: " << towerinfosOH->size() << " TOWERINFO_CALIB_HCALOUT towers" << std::endl; std::cout << "RawClusterBuilderTopo::process_event: pointer to TOWERGEOM_CEMC: " << _geom_containers[2] << std::endl; std::cout << "RawClusterBuilderTopo::process_event: pointer to TOWERGEOM_HCALIN: " << _geom_containers[0] << std::endl; @@ -487,19 +464,26 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) // translate towers to our internal representation if (_enable_EMCal) { - RawTowerContainer::ConstRange begin_end_EM = towersEM->getTowers(); - for (RawTowerContainer::ConstIterator rtiter = begin_end_EM.first; rtiter != begin_end_EM.second; ++rtiter) + TowerInfo *towerInfo = nullptr; + for(unsigned int iEM = 0; iEM < towerinfosEM->size(); iEM++) { - RawTower *tower = rtiter->second; - RawTowerGeom *tower_geom = _geom_containers[2]->get_tower_geometry(tower->get_key()); + towerInfo = towerinfosEM->get_tower_at_channel(iEM); + unsigned int towerinfo_key = towerinfosEM->encode_key(iEM); + int ti_ieta = towerinfosEM->getTowerEtaBin(towerinfo_key); + int ti_iphi = towerinfosEM->getTowerPhiBin(towerinfo_key); + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::CEMC, ti_ieta, ti_iphi); + + RawTowerGeom *tower_geom = _geom_containers[2]->get_tower_geometry(key); int ieta = _geom_containers[2]->get_etabin(tower_geom->get_eta()); int iphi = _geom_containers[2]->get_phibin(tower_geom->get_phi()); - float this_E = tower->get_energy(); + float this_E = towerInfo->get_energy(); + + if(this_E < 1.E-10) continue; _EMTOWERMAP_STATUS_ETA_PHI[ieta][iphi] = -1; // change status to unknown _EMTOWERMAP_E_ETA_PHI[ieta][iphi] = this_E; - _EMTOWERMAP_KEY_ETA_PHI[ieta][iphi] = tower->get_key(); + _EMTOWERMAP_KEY_ETA_PHI[ieta][iphi] = key; if (this_E > _sigma_seed * _noise_LAYER[2]) { @@ -517,19 +501,26 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) // translate towers to our internal representation if (_enable_HCal) { - RawTowerContainer::ConstRange begin_end_IH = towersIH->getTowers(); - for (RawTowerContainer::ConstIterator rtiter = begin_end_IH.first; rtiter != begin_end_IH.second; ++rtiter) + TowerInfo *towerInfo = nullptr; + for(unsigned int iIH = 0; iIH < towerinfosIH->size(); iIH++) { - RawTower *tower = rtiter->second; - RawTowerGeom *tower_geom = _geom_containers[0]->get_tower_geometry(tower->get_key()); + towerInfo = towerinfosIH->get_tower_at_channel(iIH); + unsigned int towerinfo_key = towerinfosIH->encode_key(iIH); + int ti_ieta = towerinfosIH->getTowerEtaBin(towerinfo_key); + int ti_iphi = towerinfosIH->getTowerPhiBin(towerinfo_key); + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, ti_ieta, ti_iphi); + + RawTowerGeom *tower_geom = _geom_containers[0]->get_tower_geometry(key); int ieta = _geom_containers[0]->get_etabin(tower_geom->get_eta()); int iphi = _geom_containers[0]->get_phibin(tower_geom->get_phi()); - float this_E = tower->get_energy(); + float this_E = towerInfo->get_energy(); + + if(this_E < 1.E-10) continue; _TOWERMAP_STATUS_LAYER_ETA_PHI[0][ieta][iphi] = -1; // change status to unknown _TOWERMAP_E_LAYER_ETA_PHI[0][ieta][iphi] = this_E; - _TOWERMAP_KEY_LAYER_ETA_PHI[0][ieta][iphi] = tower->get_key(); + _TOWERMAP_KEY_LAYER_ETA_PHI[0][ieta][iphi] = key; if (this_E > _sigma_seed * _noise_LAYER[0]) { @@ -543,19 +534,25 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) } } - RawTowerContainer::ConstRange begin_end_OH = towersOH->getTowers(); - for (RawTowerContainer::ConstIterator rtiter = begin_end_OH.first; rtiter != begin_end_OH.second; ++rtiter) + for(unsigned int iOH = 0; iOH < towerinfosOH->size(); iOH++) { - RawTower *tower = rtiter->second; - RawTowerGeom *tower_geom = _geom_containers[1]->get_tower_geometry(tower->get_key()); + towerInfo = towerinfosOH->get_tower_at_channel(iOH); + unsigned int towerinfo_key = towerinfosOH->encode_key(iOH); + int ti_ieta = towerinfosOH->getTowerEtaBin(towerinfo_key); + int ti_iphi = towerinfosOH->getTowerPhiBin(towerinfo_key); + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, ti_ieta, ti_iphi); + + RawTowerGeom *tower_geom = _geom_containers[1]->get_tower_geometry(key); int ieta = _geom_containers[1]->get_etabin(tower_geom->get_eta()); int iphi = _geom_containers[1]->get_phibin(tower_geom->get_phi()); - float this_E = tower->get_energy(); + float this_E = towerInfo->get_energy(); + + if(this_E < 1.E-10) continue; _TOWERMAP_STATUS_LAYER_ETA_PHI[1][ieta][iphi] = -1; // change status to unknown _TOWERMAP_E_LAYER_ETA_PHI[1][ieta][iphi] = this_E; - _TOWERMAP_KEY_LAYER_ETA_PHI[1][ieta][iphi] = tower->get_key(); + _TOWERMAP_KEY_LAYER_ETA_PHI[1][ieta][iphi] = key; if (this_E > _sigma_seed * _noise_LAYER[1]) { @@ -589,9 +586,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) } if (Verbosity() > 0) - { std::cout << "RawClusterBuilderTopo::process_event: initialized with " << list_of_seeds.size() << " seeds with E > 4*sigma " << std::endl; - } int cluster_index = 0; // begin counting clusters @@ -667,30 +662,21 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) // if tower is owned by THIS cluster already, continue if (get_status_from_ID(this_adjacent_tower_ID) == cluster_index) { - if (Verbosity() > 10) - { - std::cout << "already owned by this cluster index " << cluster_index << std::endl; - } + if (Verbosity() > 10) std::cout << "already owned by this cluster index " << cluster_index << std::endl; continue; } // if tower has < 2*sigma energy, continue if (get_E_from_ID(this_adjacent_tower_ID) < _sigma_grow * _noise_LAYER[test_layer]) { - if (Verbosity() > 10) - { - std::cout << "E = " << get_E_from_ID(this_adjacent_tower_ID) << " under 2*sigma threshold " << std::endl; - } + if (Verbosity() > 10) std::cout << "E = " << get_E_from_ID(this_adjacent_tower_ID) << " under 2*sigma threshold " << std::endl; continue; } // if tower is owned by somebody else, continue (although should this really happen?) if (get_status_from_ID(this_adjacent_tower_ID) > -1) { - if (Verbosity() > 10) - { - std::cout << "ERROR! in growth stage, encountered >2sigma tower which is already owned?!" << std::endl; - } + if (Verbosity() > 10) std::cout << "ERROR! in growth stage, encountered >2sigma tower which is already owned?!" << std::endl; continue; } @@ -698,16 +684,10 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) grow_tower_ID.push_back(this_adjacent_tower_ID); cluster_tower_ID.push_back(this_adjacent_tower_ID); set_status_by_ID(this_adjacent_tower_ID, cluster_index); - if (Verbosity() > 10) - { - std::cout << "add this tower ( ID " << this_adjacent_tower_ID << " ) to grow list " << std::endl; - } + if (Verbosity() > 10) std::cout << "add this tower ( ID " << this_adjacent_tower_ID << " ) to grow list " << std::endl; } - if (Verbosity() > 5) - { - std::cout << " --> after examining neighbors, grow list is now " << grow_tower_ID.size() << ", # of towers in cluster = " << cluster_tower_ID.size() << std::endl; - } + if (Verbosity() > 5) std::cout << " --> after examining neighbors, grow list is now " << grow_tower_ID.size() << ", # of towers in cluster = " << cluster_tower_ID.size() << std::endl; } // done growing cluster, now add on perimeter towers with E > 0 * sigma @@ -730,56 +710,40 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (Verbosity() > 10) - { - std::cout << " --> --> --> checking possible adjacent tower with ID " << this_adjacent_tower_ID << " : "; - } + if (Verbosity() > 10) std::cout << " --> --> --> checking possible adjacent tower with ID " << this_adjacent_tower_ID << " : "; int test_layer = get_ilayer_from_ID(this_adjacent_tower_ID); // if tower does not exist, continue if (get_status_from_ID(this_adjacent_tower_ID) == -2) { - if (Verbosity() > 10) - { - std::cout << "does not exist " << std::endl; - } + if (Verbosity() > 10) std::cout << "does not exist " << std::endl; continue; } // if tower is owned by somebody else (including current cluster), continue. ( allowed during perimeter fixing state ) if (get_status_from_ID(this_adjacent_tower_ID) > -1) { - if (Verbosity() > 10) - { - std::cout << "already owned by other cluster index " << get_status_from_ID(this_adjacent_tower_ID) << std::endl; - } + if (Verbosity() > 10) std::cout << "already owned by other cluster index " << get_status_from_ID(this_adjacent_tower_ID) << std::endl; continue; } // if tower has < 0*sigma energy, continue if (get_E_from_ID(this_adjacent_tower_ID) < _sigma_peri * _noise_LAYER[test_layer]) { - if (Verbosity() > 10) - { - std::cout << "E = " << get_E_from_ID(this_adjacent_tower_ID) << " under 0*sigma threshold " << std::endl; - } + if (Verbosity() > 10) std::cout << "E = " << get_E_from_ID(this_adjacent_tower_ID) << " under 0*sigma threshold " << std::endl; continue; } // perimeter tower good to be added to cluster cluster_tower_ID.push_back(this_adjacent_tower_ID); set_status_by_ID(this_adjacent_tower_ID, cluster_index); - if (Verbosity() > 10) - { - std::cout << "add this tower ( ID " << this_adjacent_tower_ID << " ) to cluster " << std::endl; - } + if (Verbosity() > 10) std::cout << "add this tower ( ID " << this_adjacent_tower_ID << " ) to cluster " << std::endl; } - if (Verbosity() > 5) - { - std::cout << " --> after examining perimeter neighbors, # of towers in cluster is now = " << cluster_tower_ID.size() << std::endl; - } + + + if (Verbosity() > 5) std::cout << " --> after examining perimeter neighbors, # of towers in cluster is now = " << cluster_tower_ID.size() << std::endl; } // keep track of these @@ -789,13 +753,12 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) cluster_index++; } - if (Verbosity() > 0) - { - std::cout << "RawClusterBuilderTopo::process_event: " << cluster_index << " topo-clusters initially reconstructed, entering splitting step" << std::endl; - } + if (Verbosity() > 0) std::cout << "RawClusterBuilderTopo::process_event: " << cluster_index << " topo-clusters initially reconstructed, entering splitting step" << std::endl; - // now entering cluster splitting stage int original_cluster_index = cluster_index; // since it may be updated + + // now entering cluster splitting stage + for (int cl = 0; cl < original_cluster_index; cl++) { std::vector original_towers = all_cluster_towers.at(cl); @@ -803,10 +766,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) if (!_do_split) { // don't run splitting, just export entire cluster as it is - if (Verbosity() > 2) - { - std::cout << "RawClusterBuilderTopo::process_event: splitting step disabled, cluster " << cluster_index << " is final" << std::endl; - } + if (Verbosity() > 2) std::cout << "RawClusterBuilderTopo::process_event: splitting step disabled, cluster " << cluster_index << " is final" << std::endl; export_single_cluster(original_towers); continue; } @@ -816,18 +776,12 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) // iterate through each tower, looking for maxima for (int tower_ID : original_towers) { - if (Verbosity() > 10) - { - std::cout << " -> examining tower ID " << tower_ID << " for possible local maximum " << std::endl; - } + if (Verbosity() > 10) std::cout << " -> examining tower ID " << tower_ID << " for possible local maximum " << std::endl; // check minimum energy if (get_E_from_ID(tower_ID) < _local_max_minE_LAYER[get_ilayer_from_ID(tower_ID)]) { - if (Verbosity() > 10) - { - std::cout << " -> -> energy E = " << get_E_from_ID(tower_ID) << " < " << _local_max_minE_LAYER[get_ilayer_from_ID(tower_ID)] << " too low" << std::endl; - } + if (Verbosity() > 10) std::cout << " -> -> energy E = " << get_E_from_ID(tower_ID) << " < " << _local_max_minE_LAYER[get_ilayer_from_ID(tower_ID)] << " too low" << std::endl; continue; } @@ -839,36 +793,24 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) bool has_higher_neighbor = false; for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (get_status_from_ID(this_adjacent_tower_ID) != cl) - { - continue; // only consider neighbors in cluster, obviously - } + if (get_status_from_ID(this_adjacent_tower_ID) != cl) continue; // only consider neighbors in cluster, obviously neighbors_in_cluster++; if (get_E_from_ID(this_adjacent_tower_ID) > get_E_from_ID(tower_ID)) { - if (Verbosity() > 10) - { - std::cout << " -> -> has higher-energy neighbor ID / E = " << this_adjacent_tower_ID << " / " << get_E_from_ID(this_adjacent_tower_ID) << std::endl; - } + if (Verbosity() > 10) std::cout << " -> -> has higher-energy neighbor ID / E = " << this_adjacent_tower_ID << " / " << get_E_from_ID(this_adjacent_tower_ID) << std::endl; has_higher_neighbor = true; // at this point we can break -- we won't need to count the number of good neighbors, since we won't even pass the E_neighbor test break; } } - if (has_higher_neighbor) - { - continue; // if we broke out, now continue - } + if (has_higher_neighbor) continue; // if we broke out, now continue // check number of neighbors if (neighbors_in_cluster < 4) { - if (Verbosity() > 10) - { - std::cout << " -> -> too few neighbors N = " << neighbors_in_cluster << std::endl; - } + if (Verbosity() > 10) std::cout << " -> -> too few neighbors N = " << neighbors_in_cluster << std::endl; continue; } @@ -876,21 +818,14 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) } // check for possible EMCal-OHCal seed overlaps - for (unsigned int n = 0; n < local_maxima_ID.size(); n++) { // only look at I/OHCal local maxima std::pair this_LM = local_maxima_ID.at(n); - if (get_ilayer_from_ID(this_LM.first) == 2) - { - continue; - } + if (get_ilayer_from_ID(this_LM.first) == 2) continue; float this_phi = _geom_containers[get_ilayer_from_ID(this_LM.first)]->get_phicenter(get_iphi_from_ID(this_LM.first)); - if (this_phi > M_PI) - { - this_phi -= 2 * M_PI; - } + if (this_phi > M_PI) this_phi -= 2 * M_PI; float this_eta = _geom_containers[get_ilayer_from_ID(this_LM.first)]->get_etacenter(get_ieta_from_ID(this_LM.first)); bool has_EM_overlap = false; @@ -898,23 +833,14 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) // check all other local maxima for overlaps for (unsigned int n2 = 0; n2 < local_maxima_ID.size(); n2++) { - if (n == n2) - { - continue; // don't check the same one - } + if (n == n2) continue; // don't check the same one // only look at EMCal local mazima std::pair this_LM2 = local_maxima_ID.at(n2); - if (get_ilayer_from_ID(this_LM2.first) != 2) - { - continue; - } + if (get_ilayer_from_ID(this_LM2.first) != 2) continue; float this_phi2 = _geom_containers[get_ilayer_from_ID(this_LM2.first)]->get_phicenter(get_iphi_from_ID(this_LM2.first)); - if (this_phi2 > M_PI) - { - this_phi -= 2 * M_PI; - } + if (this_phi2 > M_PI) this_phi -= 2 * M_PI; float this_eta2 = _geom_containers[get_ilayer_from_ID(this_LM2.first)]->get_etacenter(get_ieta_from_ID(this_LM2.first)); // calculate geometric dR @@ -950,10 +876,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) int tower_ID = this_LM.first; std::cout << "RawClusterBuilderTopo::process_event in cluster " << cl << ", tower ID " << tower_ID << " is LOCAL MAXIMUM with layer / E = " << get_ilayer_from_ID(tower_ID) << " / " << get_E_from_ID(tower_ID) << ", "; float this_phi = _geom_containers[get_ilayer_from_ID(tower_ID)]->get_phicenter(get_iphi_from_ID(tower_ID)); - if (this_phi > M_PI) - { - this_phi -= 2 * M_PI; - } + if (this_phi > M_PI) this_phi -= 2 * M_PI; std::cout << " eta / phi = " << _geom_containers[get_ilayer_from_ID(tower_ID)]->get_etacenter(get_ieta_from_ID(tower_ID)) << " / " << this_phi << std::endl; } } @@ -961,10 +884,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) // do we have only 1 or 0 local maxima? if (local_maxima_ID.size() <= 1) { - if (Verbosity() > 2) - { - std::cout << "RawClusterBuilderTopo::process_event cluster " << cl << " has only " << local_maxima_ID.size() << " local maxima, not splitting " << std::endl; - } + if (Verbosity() > 2) std::cout << "RawClusterBuilderTopo::process_event cluster " << cl << " has only " << local_maxima_ID.size() << " local maxima, not splitting " << std::endl; export_single_cluster(original_towers); continue; @@ -1046,12 +966,11 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) } // look over all towers THIS one is adjacent to, and count up... std::vector adjacent_tower_IDs = get_adjacent_towers_by_ID(neighbor_ID); + for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (get_status_from_ID(this_adjacent_tower_ID) != cl) - { - continue; - } + if (get_status_from_ID(this_adjacent_tower_ID) != cl) continue; + if (tower_ownership[this_adjacent_tower_ID].first > -1) { if (Verbosity() > 20) @@ -1143,10 +1062,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (get_status_from_ID(this_adjacent_tower_ID) != cl) - { - continue; - } + if (get_status_from_ID(this_adjacent_tower_ID) != cl) continue; if (tower_ownership[this_adjacent_tower_ID].first == -1) { new_neighbor_list.push_back(this_adjacent_tower_ID); @@ -1195,10 +1111,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (get_status_from_ID(this_adjacent_tower_ID) != cl) - { - continue; - } + if (get_status_from_ID(this_adjacent_tower_ID) != cl) continue; std::cout << " -> adjacent to add tower " << this_adjacent_tower_ID << " , which has status " << tower_ownership[this_adjacent_tower_ID].first << std::endl; } } @@ -1227,7 +1140,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) pseudocluster_sumE[the_pair.first] += get_E_from_ID(this_ID); float this_eta = _geom_containers[get_ilayer_from_ID(this_ID)]->get_etacenter(get_ieta_from_ID(this_ID)); float this_phi = _geom_containers[get_ilayer_from_ID(this_ID)]->get_phicenter(get_iphi_from_ID(this_ID)); - // float this_phi = ( get_ilayer_from_ID( this_ID ) == 2 ? geomEM->get_phicenter( get_iphi_from_ID( this_ID ) ) : geomOH->get_phicenter( get_iphi_from_ID( this_ID ) ) ); + //float this_phi = ( get_ilayer_from_ID( this_ID ) == 2 ? geomEM->get_phicenter( get_iphi_from_ID( this_ID ) ) : geomOH->get_phicenter( get_iphi_from_ID( this_ID ) ) ); pseudocluster_sumeta[the_pair.first] += this_eta; pseudocluster_sumphi[the_pair.first] += this_phi; pseudocluster_ntower[the_pair.first] += 1; @@ -1268,10 +1181,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (get_status_from_ID(this_adjacent_tower_ID) != cl) - { - continue; - } + if (get_status_from_ID(this_adjacent_tower_ID) != cl) continue; if (tower_ownership[this_adjacent_tower_ID].first > -1) { pseudocluster_adjacency[tower_ownership[this_adjacent_tower_ID].first] = true; @@ -1301,10 +1211,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) for (unsigned int n = 0; n < pseudocluster_adjacency.size(); n++) { - if (!pseudocluster_adjacency[n]) - { - continue; - } + if (!pseudocluster_adjacency[n]) continue; if (pseudocluster_sumE[n] > highest_pseudocluster_E) { @@ -1343,10 +1250,7 @@ int RawClusterBuilderTopo::process_event(PHCompositeNode *topNode) for (int this_adjacent_tower_ID : adjacent_tower_IDs) { - if (get_status_from_ID(this_adjacent_tower_ID) != cl) - { - continue; - } + if (get_status_from_ID(this_adjacent_tower_ID) != cl) continue; std::cout << " -> adjacent to add tower " << this_adjacent_tower_ID << " , which has status " << tower_ownership[this_adjacent_tower_ID].first << std::endl; } } diff --git a/offline/packages/CaloReco/RawTowerCalibration.cc b/offline/packages/CaloReco/RawTowerCalibration.cc index 093f5bc79c..f65888ba97 100644 --- a/offline/packages/CaloReco/RawTowerCalibration.cc +++ b/offline/packages/CaloReco/RawTowerCalibration.cc @@ -11,12 +11,12 @@ #include #include -#include -#include -#include - #include +#include + +#include + #include #include @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include @@ -40,7 +42,7 @@ RawTowerCalibration::RawTowerCalibration(const std::string &name) : SubsysReco(name) , _calib_algorithm(kNo_calibration) - , detector("NONE") + , m_Detector("NONE") , _calib_tower_node_prefix("CALIB") , _raw_tower_node_prefix("RAW") , _tower_calib_params(name) @@ -48,6 +50,11 @@ RawTowerCalibration::RawTowerCalibration(const std::string &name) //_tower_type = -1; } +RawTowerCalibration::~RawTowerCalibration() +{ + delete m_CDBTTree; +} + int RawTowerCalibration::InitRun(PHCompositeNode *topNode) { PHNodeIterator iter(topNode); @@ -58,7 +65,7 @@ int RawTowerCalibration::InitRun(PHCompositeNode *topNode) "DST")); if (!dstNode) { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "DST Node missing, doing nothing." << std::endl; exit(1); } @@ -75,23 +82,10 @@ int RawTowerCalibration::InitRun(PHCompositeNode *topNode) if (_calib_algorithm == kDbfile_tbt_gain_corr) { - if (detector.c_str()[0] == 'H') - { - _cal_dbfile = (CaloCalibSimpleCorrFile *) new HcalCaloCalibSimpleCorrFilev1(); - } - else if (detector.c_str()[0] == 'C') - { - _cal_dbfile = (CaloCalibSimpleCorrFile *) new CEmcCaloCalibSimpleCorrFilev1(); - } - else - { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ - << "kDbfile_tbt_gain_corr chosen but Detector Name not HCALOUT/IN or CEMC" + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ + << "kDbfile_tbt_gain_corr chosen but not implemented" << std::endl; - return -999; - } - - _cal_dbfile->Open(m_CalibrationFileName.c_str()); + return Fun4AllReturnCodes::ABORTRUN; } return Fun4AllReturnCodes::EVENT_OK; @@ -101,7 +95,7 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) { if (Verbosity()) { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "Process event entered" << std::endl; } @@ -201,9 +195,33 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) // else if // eventally this will be done exclusively of tow_by_tow else if (_calib_algorithm == kDbfile_tbt_gain_corr) { - if (!_cal_dbfile) + if (m_Detector.c_str()[0] == 'H') + { + std::string url = CDBInterface::instance()->getUrl("HCALTBYTCORR"); + if (url.empty()) + { + std::cout << PHWHERE << " Could not get Hcal Calibration for domain HCALTBYTCORR" << std::endl; + gSystem->Exit(1); + exit(1); + } + + m_CDBTTree = new CDBTTree(url); + } + else if (m_Detector.c_str()[0] == 'C') + { + std::string url = CDBInterface::instance()->getUrl("CEMCTBYTCORR"); + if (url.empty()) + { + std::cout << PHWHERE << " Could not get Cemc Calibration for domain CEMCTBYTCORR" << std::endl; + gSystem->Exit(1); + exit(1); + } + + m_CDBTTree = new CDBTTree(url); + } + if (!m_CDBTTree) { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "kDbfile_tbt_gain_corr chosen but no file loaded" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } @@ -213,8 +231,10 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) const int eta = raw_tower->get_bineta(); const int phi = raw_tower->get_binphi(); + unsigned int etaphikey = phi; + etaphikey = (etaphikey << 16U) + eta; - gain_factor = _cal_dbfile->getCorr(eta, phi); + gain_factor = m_CDBTTree->GetFloatValue(etaphikey,"etaphi"); const double raw_energy = raw_tower->get_energy(); RawTower *calib_tower = new RawTowerv2(*raw_tower); @@ -228,7 +248,7 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) } else { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << " invalid calibration algorithm #" << _calib_algorithm << std::endl; @@ -286,9 +306,9 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) } else if (_calib_algorithm == kDbfile_tbt_gain_corr) { - if (!_cal_dbfile) + if (!m_CDBTTree) { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "kDbfile_tbt_gain_corr chosen but no file loaded" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } @@ -296,15 +316,17 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) float gain_factor = -888; const int eta = _raw_towerinfos->getTowerEtaBin(key); const int phi = _raw_towerinfos->getTowerPhiBin(key); + unsigned int etaphikey = phi; + etaphikey = (etaphikey << 16U) + eta; - gain_factor = _cal_dbfile->getCorr(eta, phi); + gain_factor = m_CDBTTree->GetFloatValue(etaphikey,"etaphi"); const double raw_energy = raw_tower->get_energy(); float corr_energy = raw_energy * gain_factor * _calib_const_GeV_ADC; calib_tower->set_energy(corr_energy); } else { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << " invalid calibration algorithm #" << _calib_algorithm << std::endl; @@ -344,7 +366,7 @@ int RawTowerCalibration::process_event(PHCompositeNode * /*topNode*/) if (Verbosity()) { - std::cout << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "input sum energy = " << _raw_towers->getTotalEdep() << ", output sum digitalized value = " << _calib_towers->getTotalEdep() << std::endl; @@ -364,18 +386,18 @@ void RawTowerCalibration::CreateNodes(PHCompositeNode *topNode) "PHCompositeNode", "RUN")); if (!runNode) { - std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "Run Node missing, doing nothing." << std::endl; throw std::runtime_error( "Failed to find Run node in RawTowerCalibration::CreateNodes"); } - TowerGeomNodeName = "TOWERGEOM_" + detector; + TowerGeomNodeName = "TOWERGEOM_" + m_Detector; rawtowergeom = findNode::getClass(topNode, TowerGeomNodeName); if (!rawtowergeom) { - std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << " " << TowerGeomNodeName << " Node missing, doing bail out!" << std::endl; throw std::runtime_error( @@ -391,7 +413,7 @@ void RawTowerCalibration::CreateNodes(PHCompositeNode *topNode) "PHCompositeNode", "DST")); if (!dstNode) { - std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << "DST Node missing, doing nothing." << std::endl; throw std::runtime_error( "Failed to find DST node in RawTowerCalibration::CreateNodes"); @@ -399,12 +421,12 @@ void RawTowerCalibration::CreateNodes(PHCompositeNode *topNode) if (m_UseTowerInfo != 1) { - RawTowerNodeName = "TOWER_" + _raw_tower_node_prefix + "_" + detector; + RawTowerNodeName = "TOWER_" + _raw_tower_node_prefix + "_" + m_Detector; _raw_towers = findNode::getClass(dstNode, RawTowerNodeName); if (!_raw_towers) { - std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << " " << RawTowerNodeName << " Node missing, doing bail out!" << std::endl; throw std::runtime_error( @@ -413,11 +435,11 @@ void RawTowerCalibration::CreateNodes(PHCompositeNode *topNode) } if (m_UseTowerInfo > 0) { - RawTowerInfoNodeName = "TOWERINFO_" + _raw_tower_node_prefix + "_" + detector; + RawTowerInfoNodeName = "TOWERINFO_" + _raw_tower_node_prefix + "_" + m_Detector; _raw_towerinfos = findNode::getClass(dstNode, RawTowerInfoNodeName); if (!_raw_towerinfos) { - std::cerr << Name() << "::" << detector << "::" << __PRETTY_FUNCTION__ + std::cout << Name() << "::" << m_Detector << "::" << __PRETTY_FUNCTION__ << " " << RawTowerInfoNodeName << " Node missing, doing bail out!" << std::endl; throw std::runtime_error( @@ -428,17 +450,17 @@ void RawTowerCalibration::CreateNodes(PHCompositeNode *topNode) // Create the tower nodes on the tree PHNodeIterator dstiter(dstNode); PHCompositeNode *DetNode = dynamic_cast(dstiter.findFirst( - "PHCompositeNode", detector)); + "PHCompositeNode", m_Detector)); if (!DetNode) { - DetNode = new PHCompositeNode(detector); + DetNode = new PHCompositeNode(m_Detector); dstNode->addNode(DetNode); } // Be careful as a previous calibrator may have been registered for this detector if (m_UseTowerInfo != 1) { - CaliTowerNodeName = "TOWER_" + _calib_tower_node_prefix + "_" + detector; + CaliTowerNodeName = "TOWER_" + _calib_tower_node_prefix + "_" + m_Detector; _calib_towers = findNode::getClass(DetNode, CaliTowerNodeName); if (!_calib_towers) @@ -450,16 +472,16 @@ void RawTowerCalibration::CreateNodes(PHCompositeNode *topNode) } if (m_UseTowerInfo > 0) { - CaliTowerInfoNodeName = "TOWERINFO_" + _calib_tower_node_prefix + "_" + detector; + CaliTowerInfoNodeName = "TOWERINFO_" + _calib_tower_node_prefix + "_" + m_Detector; _calib_towerinfos = findNode::getClass(DetNode, CaliTowerInfoNodeName); if (!_calib_towerinfos) { TowerInfoContainerv1::DETECTOR detec; - if (detector == "CEMC") + if (m_Detector == "CEMC") { detec = TowerInfoContainer::DETECTOR::EMCAL; } - else if (detector == "HCALIN" || detector == "HCALOUT") + else if (m_Detector == "HCALIN" || m_Detector == "HCALOUT") { detec = TowerInfoContainer::DETECTOR::HCAL; } diff --git a/offline/packages/CaloReco/RawTowerCalibration.h b/offline/packages/CaloReco/RawTowerCalibration.h index f464dc449e..edeab81e43 100644 --- a/offline/packages/CaloReco/RawTowerCalibration.h +++ b/offline/packages/CaloReco/RawTowerCalibration.h @@ -9,7 +9,7 @@ #include #include -class CaloCalibSimpleCorrFile; +class CDBTTree; class PHCompositeNode; class RawTowerContainer; class TowerInfoContainerv1; @@ -22,21 +22,17 @@ class RawTowerCalibration : public SubsysReco { public: RawTowerCalibration(const std::string &name = "RawTowerCalibration"); - ~RawTowerCalibration() override - { - } + ~RawTowerCalibration() override; int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - void - Detector(const std::string &d) + void Detector(const std::string &d) { - detector = d; + m_Detector = d; _tower_calib_params.set_name(d); } - void - TowerType(const int type) + void TowerType(const int type) { _tower_type = type; } @@ -62,80 +58,67 @@ class RawTowerCalibration : public SubsysReco kBothTowers = 2 }; - enu_calib_algorithm - get_calib_algorithm() const + enu_calib_algorithm get_calib_algorithm() const { return _calib_algorithm; } - void - set_calib_algorithm(enu_calib_algorithm calibAlgorithm) + void set_calib_algorithm(enu_calib_algorithm calibAlgorithm) { _calib_algorithm = calibAlgorithm; } - double - get_calib_const_GeV_ADC() const + double get_calib_const_GeV_ADC() const { return _calib_const_GeV_ADC; } - void - set_calib_const_GeV_ADC(double calibConstGeVAdc) + void set_calib_const_GeV_ADC(double calibConstGeVAdc) { _calib_const_GeV_ADC = calibConstGeVAdc; } - void - set_variable_GeV_ADC(const bool value) + void set_variable_GeV_ADC(const bool value) { _GeV_ADC_file = value; } - std::string - get_calib_tower_node_prefix() const + std::string get_calib_tower_node_prefix() const { return _calib_tower_node_prefix; } - void - set_calib_tower_node_prefix(const std::string &calibTowerNodePrefix) + void set_calib_tower_node_prefix(const std::string &calibTowerNodePrefix) { _calib_tower_node_prefix = calibTowerNodePrefix; } - double - get_pedstal_ADC() const + double get_pedstal_ADC() const { return _pedstal_ADC; } - void - set_pedstal_ADC(double pedstalAdc) + void set_pedstal_ADC(double pedstalAdc) { _pedstal_ADC = pedstalAdc; } - void - set_variable_pedestal(const bool value) + void set_variable_pedestal(const bool value) { _pedestal_file = value; } - std::string - get_raw_tower_node_prefix() const + std::string get_raw_tower_node_prefix() const { return _raw_tower_node_prefix; } - void - set_raw_tower_node_prefix(const std::string &rawTowerNodePrefix) + void set_raw_tower_node_prefix(const std::string &rawTowerNodePrefix) { _raw_tower_node_prefix = rawTowerNodePrefix; } - void - set_zero_suppression_GeV(double) + void set_zero_suppression_GeV(double) { std::cout << "RawTowerCalibration::set_zero_suppression_GeV is deprecated!" << std::endl << " See discussion at https://github.com/sPHENIX-Collaboration/coresoftware/pull/867" << std::endl @@ -143,8 +126,7 @@ class RawTowerCalibration : public SubsysReco } //! Get the parameters for update. Useful fields are listed in SetDefaultParameters(); - PHParameters & - GetCalibrationParameters() + PHParameters &GetCalibrationParameters() { return _tower_calib_params; } @@ -164,10 +146,8 @@ class RawTowerCalibration : public SubsysReco } protected: - void - CreateNodes(PHCompositeNode *topNode); + void CreateNodes(PHCompositeNode *topNode); - enu_calib_algorithm _calib_algorithm; RawTowerContainer *_calib_towers = nullptr; RawTowerContainer *_raw_towers = nullptr; @@ -177,7 +157,9 @@ class RawTowerCalibration : public SubsysReco RawTowerGeomContainer *rawtowergeom = nullptr; - std::string detector; + enu_calib_algorithm _calib_algorithm; + + std::string m_Detector; std::string RawTowerNodeName; std::string RawTowerInfoNodeName; std::string CaliTowerNodeName; @@ -208,7 +190,7 @@ class RawTowerCalibration : public SubsysReco std::string m_CalibrationFileName; bool m_UseConditionsDB = false; - CaloCalibSimpleCorrFile *_cal_dbfile = nullptr; + CDBTTree *m_CDBTTree = nullptr; RawTowerCalibration::ProcessTowerType m_UseTowerInfo = RawTowerCalibration::ProcessTowerType::kBothTowers; // 0 just produce RawTowers, 1 just produce TowerInfo objects, and 2 produce both }; diff --git a/offline/packages/ClusterIso/ClusterIso.cc b/offline/packages/ClusterIso/ClusterIso.cc index 4945b0d3f3..e7a5127820 100644 --- a/offline/packages/ClusterIso/ClusterIso.cc +++ b/offline/packages/ClusterIso/ClusterIso.cc @@ -17,8 +17,8 @@ #include #include -#include -#include +#include +#include #include // for Fun4AllBase::VERBOSITY_MORE #include diff --git a/offline/packages/ClusterIso/Makefile.am b/offline/packages/ClusterIso/Makefile.am index b4800ea48d..68b1670569 100644 --- a/offline/packages/ClusterIso/Makefile.am +++ b/offline/packages/ClusterIso/Makefile.am @@ -21,7 +21,7 @@ libclusteriso_la_SOURCES = \ libclusteriso_la_LIBADD = \ -lcalo_io \ - -lg4vertex_io \ + -lglobalvertex_io \ -lSubsysReco \ -lCLHEP diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc index 9867be931d..0fa6857fe2 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc @@ -81,7 +81,7 @@ int HFTrackEfficiency::process_event(PHCompositeNode *topNode) if (Verbosity() >= VERBOSITY_MORE) std::cout << __FILE__ << ": Missing node G4TruthInfo" << std::endl; } - if (m_decay_descriptor.empty()) + if (m_decay_descriptor.empty() && !m_decayMap->empty()) { getDecayDescriptor(); getNDaughters(); @@ -140,27 +140,32 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) std::vector selectedTracks; CLHEP::HepLorentzVector motherRecoLV; + CLHEP::HepLorentzVector *motherTrueLV = new CLHEP::HepLorentzVector(); + CLHEP::HepLorentzVector *daughterTrueLV = new CLHEP::HepLorentzVector(); - m_genevt = m_geneventmap->get(decay[0].first.first); - assert(m_genevt); + HepMC::GenEvent *theEvent = nullptr; + if (m_geneventmap) + { + m_genevt = m_geneventmap->get(decay[0].first.first); + assert(m_genevt); - HepMC::GenEvent *theEvent = m_genevt->getEvent(); - HepMC::GenParticle *mother = theEvent->barcode_to_particle(decay[0].first.second); - assert(mother); - if (Verbosity() >= VERBOSITY_MORE) mother->print(); + theEvent = m_genevt->getEvent(); + HepMC::GenParticle *mother = theEvent->barcode_to_particle(decay[0].first.second); + assert(mother); + if (Verbosity() >= VERBOSITY_MORE) mother->print(); - m_true_mother_pT = mother->momentum().perp(); - m_true_mother_eta = mother->momentum().eta(); + m_true_mother_pT = mother->momentum().perp(); + m_true_mother_eta = mother->momentum().eta(); + } for (unsigned int i = 1; i < decay.size(); ++i) { if (std::find(std::begin(trackableParticles), std::end(trackableParticles), std::abs(decay[i].second)) != std::end(trackableParticles)) { - HepMC::GenParticle *daughterHepMC = theEvent->barcode_to_particle(decay[i].first.second); - CLHEP::HepLorentzVector *daughterTrueLV = new CLHEP::HepLorentzVector(); - if (daughterHepMC) + if (theEvent && decay[i].first.second > -1) { + HepMC::GenParticle *daughterHepMC = theEvent->barcode_to_particle(decay[i].first.second); if (Verbosity() >= VERBOSITY_MORE) daughterHepMC->print(); daughterTrueLV->setVectM(CLHEP::Hep3Vector(daughterHepMC->momentum().px(), daughterHepMC->momentum().py(), daughterHepMC->momentum().pz()), getParticleMass(decay[i].second)); @@ -185,6 +190,10 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) { if (Verbosity() >= VERBOSITY_MORE) daughterG4->identify(); + motherTrueLV->setVectM(CLHEP::Hep3Vector(motherG4->get_px(), motherG4->get_py(), motherG4->get_pz()), getParticleMass(decay[0].second)); + m_true_mother_pT = motherTrueLV->perp(); + m_true_mother_eta = motherTrueLV->pseudoRapidity(); + daughterTrueLV->setVectM(CLHEP::Hep3Vector(daughterG4->get_px(), daughterG4->get_py(), daughterG4->get_pz()), getParticleMass(decay[i].second)); m_true_track_PID[i - 1] = daughterG4->get_pid(); @@ -213,7 +222,14 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_reco_track_exists[i - 1] = true; m_reco_track_pT[i - 1] = m_dst_track->get_pt(); m_reco_track_chi2nDoF[i - 1] = m_dst_track->get_chisq() / m_dst_track->get_ndf(); - m_reco_track_silicon_seeds[i - 1] = static_cast(m_dst_track->get_silicon_seed()->size_cluster_keys()); + if (m_dst_track->get_silicon_seed()) + { + m_reco_track_silicon_seeds[i - 1] = static_cast(m_dst_track->get_silicon_seed()->size_cluster_keys()); + } + else + { + m_reco_track_silicon_seeds[i - 1] = 0; + } m_reco_track_tpc_seeds[i - 1] = static_cast(m_dst_track->get_tpc_seed()->size_cluster_keys()); m_min_reco_track_pT = std::min(m_reco_track_pT[i - 1], m_min_reco_track_pT); m_max_reco_track_pT = std::max(m_reco_track_pT[i - 1], m_max_reco_track_pT); @@ -248,6 +264,9 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) selectedTracks.clear(); + delete motherTrueLV; + delete daughterTrueLV; + return foundDecay; } diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc index 7feb1e2077..e4080d1280 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc @@ -32,6 +32,9 @@ #include #include +#include +#include + #include //KFParticle stuff @@ -111,7 +114,7 @@ KFParticle KFParticle_Tools::makeVertex(PHCompositeNode * /*topNode*/) return kfp_vertex; } -std::vector KFParticle_Tools::makeAllPrimaryVertices(PHCompositeNode *topNode, std::string vertexMapName) +std::vector KFParticle_Tools::makeAllPrimaryVertices(PHCompositeNode *topNode, const std::string &vertexMapName) { std::string vtxMN; if (vertexMapName.empty()) @@ -121,14 +124,26 @@ std::vector KFParticle_Tools::makeAllPrimaryVertices(PHCompositeNode std::vector primaryVertices; m_dst_vertexmap = findNode::getClass(topNode, vtxMN); + auto globalvertexmap = findNode::getClass(topNode,"GlobalVertexMap"); + if(!globalvertexmap) { + std::cout << "Can't continue in KFParticle_Tools::makeAllPrimaryVertices" << std::endl; + } + unsigned int vertexID = 0; - for (SvtxVertexMap::ConstIter iter = m_dst_vertexmap->begin(); iter != m_dst_vertexmap->end(); ++iter) + for (GlobalVertexMap::ConstIter iter = globalvertexmap->begin(); iter != globalvertexmap->end(); ++iter) { - m_dst_vertex = iter->second; + GlobalVertex *gvertex = iter->second; + auto svtxv = gvertex->find_vtxids(GlobalVertex::SVTX); + // check that it contains a track vertex + if(svtxv == gvertex->end_vtxids()) + { continue; } + + auto svtxvertexid = svtxv->second; + m_dst_vertex = m_dst_vertexmap->find(svtxvertexid)->second; primaryVertices.push_back(makeVertex(topNode)); - primaryVertices[vertexID].SetId(iter->first); + primaryVertices[vertexID].SetId(gvertex->get_id()); ++vertexID; } @@ -211,7 +226,7 @@ std::vector KFParticle_Tools::makeAllDaughterParticles(PHCompositeNo return daughterParticles; } -int KFParticle_Tools::getTracksFromVertex(PHCompositeNode *topNode, KFParticle vertex, std::string vertexMapName) +int KFParticle_Tools::getTracksFromVertex(PHCompositeNode *topNode, KFParticle vertex, const std::string &vertexMapName) { std::string vtxMN; if (vertexMapName.empty()) @@ -221,8 +236,10 @@ int KFParticle_Tools::getTracksFromVertex(PHCompositeNode *topNode, KFParticle v SvtxVertex *associatedVertex = NULL; m_dst_vertexmap = findNode::getClass(topNode, vtxMN); - - associatedVertex = m_dst_vertexmap->find(vertex.Id())->second; + auto globalvertexmap = findNode::getClass(topNode, "GlobalVertexMap"); + GlobalVertex *associatedgvertex = globalvertexmap->find(vertex.Id())->second; + auto svtxvtx_id = associatedgvertex->find_vtxids(GlobalVertex::SVTX)->second; + associatedVertex = m_dst_vertexmap->find(svtxvtx_id)->second; return associatedVertex->size_tracks(); } @@ -601,7 +618,7 @@ void KFParticle_Tools::constrainToVertex(KFParticle &particle, bool &goodCandida goodCandidate = false; - const float speed = 2.99792458e-1; + const float speed = 2.99792458e-2; calculated_decayTime /= speed; if (calculated_fdchi2 >= m_fdchi2 && calculated_ipchi2 <= m_mother_ipchi2 && isInRange(m_dira_min, calculated_dira, m_dira_max) && isInRange(m_min_decayTime, calculated_decayTime, m_max_decayTime) && isInRange(m_min_decayLength, calculated_decayLength, m_max_decayLength)) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h index 6d60915024..e3023e79ef 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h @@ -48,13 +48,13 @@ class KFParticle_Tools : protected KFParticle_MVA KFParticle makeVertex(PHCompositeNode *topNode); - std::vector makeAllPrimaryVertices(PHCompositeNode *topNode, std::string vertexMapName); + std::vector makeAllPrimaryVertices(PHCompositeNode *topNode, const std::string &vertexMapName); KFParticle makeParticle(PHCompositeNode *topNode); std::vector makeAllDaughterParticles(PHCompositeNode *topNode); - int getTracksFromVertex(PHCompositeNode *topNode, KFParticle vertex, std::string vertexMapName); + int getTracksFromVertex(PHCompositeNode *topNode, KFParticle vertex, const std::string &vertexMapName); /*const*/ bool isGoodTrack(KFParticle particle, const std::vector &primaryVertices); diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.cc index 1042d98c4d..2ba5b47fa8 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.cc @@ -26,9 +26,9 @@ /*****************/ #include "KFParticle_eventReconstruction.h" -#include "KFParticle_Tools.h" +#include "KFParticle_Tools.h" -//KFParticle stuff +// KFParticle stuff #include #include @@ -56,9 +56,6 @@ void KFParticle_eventReconstruction::createDecay(PHCompositeNode* topNode, std:: std::vector>& selectedIntermediates, int& nPVs, int& multiplicity) { - //ALICE field is 0.5T but they set it to -5 in KFParticle? Checked momentum sums and -1.4 is more accurate - KFParticle::SetField(-1.4e0); - std::vector primaryVertices; if (m_use_fake_pv) primaryVertices.push_back(createFakePV()); @@ -137,9 +134,9 @@ void KFParticle_eventReconstruction::buildChain(std::vector& selecte for (int i = 0; i < m_num_intermediate_states; ++i) num_tracks_used_by_intermediates += m_num_tracks_from_intermediate[i]; int num_remaining_tracks = m_num_tracks - num_tracks_used_by_intermediates; - unsigned int num_pot_inter_a, num_pot_inter_b, num_pot_inter_c, num_pot_inter_d; //Number of potential intermediates found + unsigned int num_pot_inter_a, num_pot_inter_b, num_pot_inter_c, num_pot_inter_d; // Number of potential intermediates found num_pot_inter_a = potentialIntermediates[0].size(); - num_pot_inter_b = m_num_intermediate_states < 2 ? 1 : potentialIntermediates[1].size(); //Ensure the code inside the loop below is executed + num_pot_inter_b = m_num_intermediate_states < 2 ? 1 : potentialIntermediates[1].size(); // Ensure the code inside the loop below is executed num_pot_inter_c = m_num_intermediate_states < 3 ? 1 : potentialIntermediates[2].size(); num_pot_inter_d = m_num_intermediate_states < 4 ? 1 : potentialIntermediates[3].size(); @@ -174,7 +171,8 @@ void KFParticle_eventReconstruction::buildChain(std::vector& selecte int trackElement_to_remove = -1; auto it = std::find_if(daughterParticlesAdv.begin(), daughterParticlesAdv.end(), - [&trackID_to_remove](const KFParticle& obj) { return obj.Id() == trackID_to_remove; }); + [&trackID_to_remove](const KFParticle& obj) + { return obj.Id() == trackID_to_remove; }); if (it != daughterParticlesAdv.end()) { @@ -200,7 +198,7 @@ void KFParticle_eventReconstruction::buildChain(std::vector& selecte required_unique_vertexID += m_daughter_charge[i] * kfp_Tools_evtReco.getParticleMass(m_daughter_name[i].c_str()); } - uniqueCombinations = findUniqueDaughterCombinations(num_tracks_used_by_intermediates, m_num_tracks); //Unique comb of remaining trackIDs + uniqueCombinations = findUniqueDaughterCombinations(num_tracks_used_by_intermediates, m_num_tracks); // Unique comb of remaining trackIDs listOfTracksToAppend = appendTracksToIntermediates(motherDecayProducts, daughterParticlesAdv, goodTrackIndexAdv_withoutIntermediates, num_remaining_tracks); @@ -237,7 +235,7 @@ void KFParticle_eventReconstruction::buildChain(std::vector& selecte for (int k = 0; k < m_num_intermediate_states; ++k) goodIntermediates[k].push_back(motherDecayProducts[k]); for (int k = 0; k < num_tracks_used_by_intermediates; ++k) goodDaughters[k].push_back(finalTracks[k]); for (int k = 0; k < num_remaining_tracks; ++k) - { //Need to deal with track mass and PID assignment for extra tracks + { // Need to deal with track mass and PID assignment for extra tracks int trackArrayID = k + m_num_intermediate_states; KFParticle slowTrack; slowTrack.Create(motherDecayProducts[trackArrayID].Parameters(), @@ -272,10 +270,10 @@ void KFParticle_eventReconstruction::buildChain(std::vector& selecte for (int j = 0; j < m_num_intermediate_states; ++j) goodIntermediates[j].clear(); for (int j = 0; j < m_num_tracks; ++j) goodDaughters[j].clear(); } - } //Close forth intermediate - } //Close third intermediate - } //Close second intermediate - } //Close first intermediate + } // Close forth intermediate + } // Close third intermediate + } // Close second intermediate + } // Close first intermediate } void KFParticle_eventReconstruction::getCandidateDecay(std::vector& selectedMotherCand, @@ -297,18 +295,18 @@ void KFParticle_eventReconstruction::getCandidateDecay(std::vector& float required_unique_vertexID = 0; for (int i = n_track_start; i < n_track_stop; ++i) required_unique_vertexID += m_daughter_charge[i] * kfp_Tools_evtReco.getParticleMass(m_daughter_name[i].c_str()); - for (unsigned int i_comb = 0; i_comb < goodTracksThatMeetCand.size(); ++i_comb) //Loop over all good track combinations + for (unsigned int i_comb = 0; i_comb < goodTracksThatMeetCand.size(); ++i_comb) // Loop over all good track combinations { KFParticle daughterTracks[nTracks]; for (int i_track = 0; i_track < nTracks; ++i_track) { daughterTracks[i_track] = daughterParticlesCand[goodTracksThatMeetCand[i_comb][i_track]]; - } //Build array of the good tracks in that combination + } // Build array of the good tracks in that combination - for (unsigned int i_uc = 0; i_uc < uniqueCombinations.size(); ++i_uc) //Loop over unique track PID assignments + for (unsigned int i_uc = 0; i_uc < uniqueCombinations.size(); ++i_uc) // Loop over unique track PID assignments { - for (unsigned int i_pv = 0; i_pv < primaryVerticesCand.size(); ++i_pv) //Loop over all PVs in the event + for (unsigned int i_pv = 0; i_pv < primaryVerticesCand.size(); ++i_pv) // Loop over all PVs in the event { std::string* names = &uniqueCombinations[i_uc][0]; std::tie(candidate, isGood) = getCombination(daughterTracks, names, primaryVerticesCand[i_pv], m_constrain_to_vertex, @@ -405,3 +403,8 @@ KFParticle KFParticle_eventReconstruction::createFakePV() return kfp_vertex; } + +void KFParticle_eventReconstruction::setBz(double Bz_Tesla) +{ + KFParticle::SetField(Bz_Tesla); +} diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.h b/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.h index f1b33a71bf..4a3e854a02 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.h @@ -50,7 +50,7 @@ class KFParticle_eventReconstruction : public KFParticle_Tools std::vector>& selectedIntermediates, int& nPVs, int& multiplicity); - ///Used to reconstruct simple decays with no intermediate states + /// Used to reconstruct simple decays with no intermediate states void buildBasicChain(std::vector& selectedMotherBasic, std::vector& selectedVertexBasic, std::vector>& selectedDaughtersBasic, @@ -58,7 +58,7 @@ class KFParticle_eventReconstruction : public KFParticle_Tools const std::vector& goodTrackIndexBasic, const std::vector& primaryVerticesBasic); - ///Used to reconstruct more complicated decays with up to four intermediate states + /// Used to reconstruct more complicated decays with up to four intermediate states void buildChain(std::vector& selectedMotherAdv, std::vector& selectedVertexAdv, std::vector>& selectedDaughtersAdv, @@ -67,7 +67,7 @@ class KFParticle_eventReconstruction : public KFParticle_Tools const std::vector& goodTrackIndexAdv, const std::vector& primaryVerticesAdv); - ///Basic building block for event reconstruction and selection + /// Basic building block for event reconstruction and selection void getCandidateDecay(std::vector& selectedMotherCand, std::vector& selectedVertexCand, std::vector>& selectedDaughtersCand, @@ -77,19 +77,20 @@ class KFParticle_eventReconstruction : public KFParticle_Tools int n_track_start, int n_track_stop, bool isIntermediate, int intermediateNumber, bool constrainMass); - ///Method to chose best candidate from a selection of common SV's + /// Method to chose best candidate from a selection of common SV's int selectBestCombination(bool PVconstraint, bool isAnInterMother, std::vector possibleCandidates, std::vector possibleVertex); KFParticle createFakePV(); + void setBz(double Bz_Tesla); protected: bool m_constrain_to_vertex; bool m_constrain_int_mass; bool m_use_fake_pv; - //private: + // private: }; -#endif //KFPARTICLESPHENIX_KFPARTICLEEVENTRECONSTRUCTION_H +#endif // KFPARTICLESPHENIX_KFPARTICLEEVENTRECONSTRUCTION_H diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc index 694aae38a0..dcac3ecfcd 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc @@ -27,6 +27,7 @@ KFParticle_Tools kfpTupleTools; KFParticle_nTuple::KFParticle_nTuple() : m_has_intermediates_nTuple(false) + , m_extrapolateTracksToSV_nTuple(true) , m_constrain_to_vertex_nTuple(false) , m_get_all_PVs(false) , m_truth_matching(false) @@ -282,7 +283,7 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, std::vector intermediates, int nPVs, int multiplicity) { - const float speedOfLight = 2.99792458e-1; + const float speedOfLight = 2.99792458e-2; KFParticle temp; KFParticle* daughterArray = &daughters[0]; @@ -348,6 +349,14 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, } } + if (m_extrapolateTracksToSV_nTuple) + { + for (unsigned int i = 0; i < daughters.size(); ++i) + { + daughterArray[i].SetProductionVertex(motherParticle); + } + } + if (m_constrain_to_vertex_nTuple) { m_calculated_mother_dira = kfpTupleTools.eventDIRA(motherParticle, vertex); diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h index 133aa48a3f..9e7738a584 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h @@ -38,6 +38,7 @@ class KFParticle_nTuple : public KFParticle_truthAndDetTools protected: bool m_has_intermediates_nTuple; + bool m_extrapolateTracksToSV_nTuple; bool m_constrain_to_vertex_nTuple; bool m_get_all_PVs; //int m_num_intermediate_states_nTuple; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index ee78c0e0d3..9c311334c8 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -29,17 +29,20 @@ #include #include +#include // for obtaining the B field value +#include // for getting the TTree from the file #include // for KFParticle #include // for Fun4AllBase::VERBOSITY... #include // for SubsysReco -#include // for toupper -#include // for sqrt -#include // for size_t, exit -#include // for operator<<, endl, basi... -#include // for map -#include // for tie, tuple +#include // for accessing the field map file from the CDB +#include // for toupper +#include // for sqrt +#include // for size_t, exit +#include // for operator<<, endl, basi... +#include // for map +#include // for tie, tuple class PHCompositeNode; @@ -94,6 +97,46 @@ int KFParticle_sPHENIX::Init(PHCompositeNode *topNode) return returnCode; } +int KFParticle_sPHENIX::InitRun(PHCompositeNode *topNode) +{ + assert(topNode); + + // Load the official offline B-field map that is also used in tracking, basically copying the codes from: https://github.com/sPHENIX-Collaboration/coresoftware/blob/master/offline/packages/trackreco/MakeActsGeometry.cc#L478-L483, provide by Joe Osborn. + char *calibrationsroot = getenv("CALIBRATIONROOT"); + std::string m_magField = "sphenix3dtrackingmapxyz.root"; + + if (calibrationsroot != nullptr) + { + m_magField = std::string(calibrationsroot) + std::string("/Field/Map/") + m_magField; + } + + m_magField = CDBInterface::instance()->getUrl("FIELDMAPTRACKING", m_magField); // Joe's New Implementation to get the field map file name on 05/10/2023 + + TFile *fin = new TFile(m_magField.c_str()); + fin->cd(); + + TTree *fieldmap = (TTree *) fin->Get("fieldmap"); + + TH1F *BzHist = new TH1F("BzHist", "", 100, 0, 10); + + int NBFieldEntries = fieldmap->Project("BzHist", "bz", "x==0 && y==0 && z==0"); + + if (NBFieldEntries != 1) + { // Validate exactly 1 B field value at (0,0,0) in the field map + std::cout << "Not a single B field value at (0,0,0) in the field map, need to check why" << std::endl; + exit(1); + } + + // The actual unit of KFParticle is in kilo Gauss (kG), which is equivalent to 0.1 T, instead of Tesla (T). The positive value indicates the B field is in the +z direction + m_Bz = BzHist->GetMean() * 10; // Factor of 10 to convert the B field unit from kG to T + + fieldmap->Delete(); + BzHist->Delete(); + fin->Close(); + + return 0; +} + int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::vector mother, vertex; @@ -117,6 +160,8 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } + setBz(m_Bz); // Set the Magnetic Field for KFParticle + createDecay(topNode, mother, vertex, daughters, intermediates, nPVs, multiplicity); if (!m_has_intermediates_sPHENIX) intermediates = daughters; @@ -165,8 +210,8 @@ int KFParticle_sPHENIX::End(PHCompositeNode * /*topNode*/) return 0; } -void KFParticle_sPHENIX::printParticles(const KFParticle motherParticle, - const KFParticle chosenVertex, +void KFParticle_sPHENIX::printParticles(const KFParticle &motherParticle, + const KFParticle &chosenVertex, const std::vector &daughterParticles, const std::vector &intermediateParticles, const int numPVs, const int numTracks) @@ -233,33 +278,34 @@ int KFParticle_sPHENIX::parseDecayDescriptor() std::string startIntermediate = "{"; std::string endIntermediate = "}"; - //These tracks require a + or - after their name for TDatabasePDG + // These tracks require a + or - after their name for TDatabasePDG std::string specialTracks[] = {"e", "mu", "pi", "K"}; std::string manipulateDecayDescriptor = m_decayDescriptor; - //Remove all white space before we begin + // Remove all white space before we begin size_t pos; while ((pos = manipulateDecayDescriptor.find(" ")) != std::string::npos) manipulateDecayDescriptor.replace(pos, 1, ""); - //Check for charge conjugate requirement + // Check for charge conjugate requirement std::string checkForCC = manipulateDecayDescriptor.substr(0, 1) + manipulateDecayDescriptor.substr(manipulateDecayDescriptor.size() - 3, 3); - std::for_each(checkForCC.begin(), checkForCC.end(), [](char &c) { c = ::toupper(c); }); + std::for_each(checkForCC.begin(), checkForCC.end(), [](char &c) + { c = ::toupper(c); }); - //Remove the CC check if needed + // Remove the CC check if needed if (checkForCC == "[]CC") { manipulateDecayDescriptor = manipulateDecayDescriptor.substr(1, manipulateDecayDescriptor.size() - 4); getChargeConjugate(true); } - //Find the initial particle + // Find the initial particle size_t findMotherEndPoint = manipulateDecayDescriptor.find(decayArrow); mother = manipulateDecayDescriptor.substr(0, findMotherEndPoint); if (!findParticle(mother)) ddCanBeParsed = false; manipulateDecayDescriptor.erase(0, findMotherEndPoint + decayArrow.length()); - //Try and find the intermediates + // Try and find the intermediates while ((pos = manipulateDecayDescriptor.find(startIntermediate)) != std::string::npos) { size_t findIntermediateStartPoint = manipulateDecayDescriptor.find(startIntermediate, pos); @@ -272,7 +318,7 @@ int KFParticle_sPHENIX::parseDecayDescriptor() else ddCanBeParsed = false; - //Now find the daughters associated to this intermediate + // Now find the daughters associated to this intermediate int nDaughters = 0; intermediateDecay.erase(0, intermediateDecay.find(decayArrow) + decayArrow.length()); while ((daughterLocator = intermediateDecay.find(chargeIndicator)) != std::string::npos) @@ -315,7 +361,7 @@ int KFParticle_sPHENIX::parseDecayDescriptor() nTracks += nDaughters; } - //Now find any remaining reconstructable tracks from the mother + // Now find any remaining reconstructable tracks from the mother while ((daughterLocator = manipulateDecayDescriptor.find(chargeIndicator)) != std::string::npos) { daughter = manipulateDecayDescriptor.substr(0, daughterLocator); diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index 78d4d050de..98f3dd52c7 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -33,10 +33,10 @@ #include "KFParticle_DST.h" #include "KFParticle_nTuple.h" -//sPHENIX stuff +// sPHENIX stuff #include -//KFParticle stuff +// KFParticle stuff #include #include // for max @@ -59,6 +59,8 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K int Init(PHCompositeNode *topNode); + int InitRun(PHCompositeNode *topNode); + int process_event(PHCompositeNode *topNode); int End(PHCompositeNode *topNode); @@ -68,15 +70,15 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K * masses, momenta and positions for mothers, intermediates and final state tracks, * PV position, number of vertices and number of tracks in the event (multiplicity) */ - void printParticles(const KFParticle motherParticle, - const KFParticle chosenVertex, + void printParticles(const KFParticle &motherParticle, + const KFParticle &chosenVertex, const std::vector &daughterParticles, const std::vector &intermediateParticles, const int numPVs, const int numTracks); int parseDecayDescriptor(); - ///Parameters for the user to vary + /// Parameters for the user to vary void setDecayDescriptor(const std::string &decayDescriptor) { m_decayDescriptor = decayDescriptor; } @@ -199,7 +201,11 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K void allowZeroMassTracks(bool allow) { m_allowZeroMassTracks = allow; } - void extraolateTracksToSV(bool extrapolate) { m_extrapolateTracksToSV = extrapolate; } + void extraolateTracksToSV(bool extrapolate) + { + m_extrapolateTracksToSV = extrapolate; + m_extrapolateTracksToSV_nTuple = extrapolate; + } void constrainIntermediateMasses(bool constrain_int_mass) { m_constrain_int_mass = constrain_int_mass; } @@ -286,10 +292,10 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K void getAllPVInfo(bool pvinfo) { m_get_all_PVs = pvinfo; } - ///Use alternate vertex and track fitters + /// Use alternate vertex and track fitters void setVertexMapNodeName(const std::string &vtx_map_node_name) { m_vtx_map_node_name = m_vtx_map_node_name_nTuple = vtx_map_node_name; } - ///Use alternate vertex and track fitters + /// Use alternate vertex and track fitters void setTrackMapNodeName(const std::string &trk_map_node_name) { m_trk_map_node_name = m_trk_map_node_name_nTuple = trk_map_node_name; } private: @@ -298,9 +304,10 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K bool m_require_mva; bool m_save_dst; bool m_save_output; + float m_Bz = 0; std::string m_outfile_name; TFile *m_outfile; std::string m_decayDescriptor; }; -#endif //KFPARTICLESPHENIX_KFPARTICLESPHENIX_H +#endif // KFPARTICLESPHENIX_KFPARTICLESPHENIX_H diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc index 81f4c966fe..c60ab315cb 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc @@ -19,6 +19,9 @@ #include // for SvtxVertex #include // for SvtxVertexMap, SvtxVer... +#include +#include + #include // for PHG4Particle #include // for PHG4TruthInfoContainer #include // for PHG4VtxPoint @@ -84,9 +87,9 @@ SvtxTrack *KFParticle_truthAndDetTools::getTrack(unsigned int track_id, SvtxTrac return matched_track; } -SvtxVertex *KFParticle_truthAndDetTools::getVertex(unsigned int vertex_id, SvtxVertexMap *vertexmap) +GlobalVertex *KFParticle_truthAndDetTools::getVertex(unsigned int vertex_id, GlobalVertexMap *vertexmap) { - SvtxVertex *matched_vertex = vertexmap->get(vertex_id); + GlobalVertex *matched_vertex = vertexmap->get(vertex_id); return matched_vertex; } @@ -197,7 +200,10 @@ void KFParticle_truthAndDetTools::fillTruthBranch(PHCompositeNode *topNode, TTre { std::cout << "KFParticle truth matching: " << m_vtx_map_node_name_nTuple << " does not exist" << std::endl; } - + auto globalvertexmap = findNode::getClass(topNode, "GlobalVertexMap"); + if(!globalvertexmap) { + std::cout << "KFParticle truth matching: GlobalVertexMap does not exist" << std::endl; + } track = getTrack(daughter.Id(), dst_trackmap); g4particle = getTruthTrack(track, topNode); @@ -238,8 +244,15 @@ void KFParticle_truthAndDetTools::fillTruthBranch(PHCompositeNode *topNode, TTre if (m_constrain_to_vertex_truthMatch) { //Calculate true DCA - SvtxVertex *recoVertex = getVertex(vertex.Id(), dst_vertexmap); - PHG4VtxPoint *truePoint = vertexeval->max_truth_point_by_ntracks(recoVertex); + GlobalVertex *recoVertex = getVertex(vertex.Id(), globalvertexmap); + auto svtxv = recoVertex->find_vtxids(GlobalVertex::SVTX); + if(svtxv == recoVertex->end_vtxids()) + { + std::cout << "Have a global vertex with no track vertex... shouldn't happen in KFParticle_truthAndDetTools::fillTruthBranch..." << std::endl; + } + + SvtxVertex* svtxvertex = dst_vertexmap->find(svtxv->second)->second; + PHG4VtxPoint *truePoint = vertexeval->max_truth_point_by_ntracks(svtxvertex); KFParticle trueKFParticleVertex; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.h b/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.h index 2316f8e934..7022f32531 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.h @@ -23,6 +23,8 @@ class SvtxVertexEval; class TrkrClusterContainer; class TTree; class KFParticle; +class GlobalVertex; +class GlobalVertexMap; namespace HepMC { @@ -37,7 +39,7 @@ class KFParticle_truthAndDetTools virtual ~KFParticle_truthAndDetTools(); //Destructor SvtxTrack *getTrack(unsigned int track_id, SvtxTrackMap *trackmap); - SvtxVertex *getVertex(unsigned int vertex_id, SvtxVertexMap *vertexmap); + GlobalVertex *getVertex(unsigned int vertex_id, GlobalVertexMap *vertexmap); PHG4Particle *getTruthTrack(SvtxTrack *thisTrack, PHCompositeNode *topNode); void initializeTruthBranches(TTree *m_tree, int daughter_id, std::string daughter_number, bool m_constrain_to_vertex_truthMatch); diff --git a/offline/packages/NodeDump/DumpBbcOut.cc b/offline/packages/NodeDump/DumpBbcOut.cc new file mode 100644 index 0000000000..ac8b81bb8c --- /dev/null +++ b/offline/packages/NodeDump/DumpBbcOut.cc @@ -0,0 +1,41 @@ +#include "DumpBbcOut.h" + +#include + +#include + +#include +#include + +using MyNode_t = PHIODataNode; + +DumpBbcOut::DumpBbcOut(const std::string &NodeName) + : DumpObject(NodeName) +{ + return; +} + +int DumpBbcOut::process_Node(PHNode *myNode) +{ + BbcOut *bbcout = nullptr; + MyNode_t *thisNode = static_cast(myNode); + if (thisNode) + { + bbcout = thisNode->getData(); + } + if (bbcout && bbcout->isValid()) + { + *fout << "BbcOut->get_VertexPoint: " << bbcout->get_VertexPoint() << std::endl; + *fout << "BbcOut->get_dVertexPoint: " << bbcout->get_dVertexPoint() << std::endl; + *fout << "BbcOut->get_TimeZero: " << bbcout->get_TimeZero() << std::endl; + *fout << "BbcOut->get_dTimeZero: " << bbcout->get_dTimeZero() << std::endl; + + for (int j = 0; j < 2; j++) + { + *fout << "BbcOut->get_nPMT(" << j << "): " << bbcout->get_nPMT(j) << std::endl; + *fout << "BbcOut->get_nCharge(" << j << "): " << bbcout->get_nCharge(j) << std::endl; + *fout << "BbcOut->get_Timing(" << j << "): " << bbcout->get_Timing(j) << std::endl; + } + } + return 0; +} diff --git a/offline/packages/NodeDump/DumpBbcOut.h b/offline/packages/NodeDump/DumpBbcOut.h new file mode 100644 index 0000000000..d748adf64a --- /dev/null +++ b/offline/packages/NodeDump/DumpBbcOut.h @@ -0,0 +1,20 @@ +#ifndef NODEDUMP_DUMPBBCOUT_H +#define NODEDUMP_DUMPBBCOUT_H + +#include "DumpObject.h" + +#include + +class PHNode; + +class DumpBbcOut : public DumpObject +{ + public: + explicit DumpBbcOut(const std::string &NodeName); + virtual ~DumpBbcOut() {} + + protected: + int process_Node(PHNode *mynode) override; +}; + +#endif diff --git a/offline/packages/NodeDump/DumpBbcPmtContainer.cc b/offline/packages/NodeDump/DumpBbcPmtContainer.cc new file mode 100644 index 0000000000..227f867b1c --- /dev/null +++ b/offline/packages/NodeDump/DumpBbcPmtContainer.cc @@ -0,0 +1,38 @@ +#include "DumpBbcPmtContainer.h" + +#include + +#include + +#include +#include + +using MyNode_t = PHIODataNode; + +DumpBbcPmtContainer::DumpBbcPmtContainer(const std::string &NodeName) + : DumpObject(NodeName) +{ + return; +} + +int DumpBbcPmtContainer::process_Node(PHNode *myNode) +{ + BbcPmtContainer *bbcpmtcontainer = nullptr; + MyNode_t *thisNode = static_cast(myNode); + if (thisNode) + { + bbcpmtcontainer = thisNode->getData(); + } + if (bbcpmtcontainer && bbcpmtcontainer->isValid()) + { + *fout << "BbcPmtContainer->get_npmt: " << bbcpmtcontainer->get_npmt() << std::endl; + for (int j = 0; j < bbcpmtcontainer->get_npmt(); j++) + { + *fout << "BbcPmtContainer->get_pmt(" << j << "): " << bbcpmtcontainer->get_pmt(j) << std::endl; + *fout << "BbcPmtContainer->get_adc(" << j << "): " << bbcpmtcontainer->get_adc(j) << std::endl; + *fout << "BbcPmtContainer->get_tdc0(" << j << "): " << bbcpmtcontainer->get_tdc0(j) << std::endl; + *fout << "BbcPmtContainer->get_tdc1(" << j << "): " << bbcpmtcontainer->get_tdc1(j) << std::endl; + } + } + return 0; +} diff --git a/offline/packages/NodeDump/DumpBbcPmtContainer.h b/offline/packages/NodeDump/DumpBbcPmtContainer.h new file mode 100644 index 0000000000..6c2f12453a --- /dev/null +++ b/offline/packages/NodeDump/DumpBbcPmtContainer.h @@ -0,0 +1,20 @@ +#ifndef NODEDUMP_DUMPBBCPMTCONTAINER_H +#define NODEDUMP_DUMPBBCPMTCONTAINER_H + +#include "DumpObject.h" + +#include + +class PHNode; + +class DumpBbcPmtContainer : public DumpObject +{ + public: + explicit DumpBbcPmtContainer(const std::string &NodeName); + virtual ~DumpBbcPmtContainer() {} + + protected: + int process_Node(PHNode *mynode) override; +}; + +#endif diff --git a/offline/packages/NodeDump/DumpBbcVertexMap.cc b/offline/packages/NodeDump/DumpBbcVertexMap.cc index e511e209cb..32d59e7a7c 100644 --- a/offline/packages/NodeDump/DumpBbcVertexMap.cc +++ b/offline/packages/NodeDump/DumpBbcVertexMap.cc @@ -1,7 +1,7 @@ #include "DumpBbcVertexMap.h" -#include -#include +#include +#include #include diff --git a/offline/packages/NodeDump/DumpEpdGeom.cc b/offline/packages/NodeDump/DumpEpdGeom.cc new file mode 100644 index 0000000000..e7bef54183 --- /dev/null +++ b/offline/packages/NodeDump/DumpEpdGeom.cc @@ -0,0 +1,50 @@ +#include "DumpEpdGeom.h" + +#include + +#include +#include + +#include +#include +#include + +using MyNode_t = PHIODataNode; + +DumpEpdGeom::DumpEpdGeom(const std::string &NodeName) + : DumpObject(NodeName) +{ + return; +} + +int DumpEpdGeom::process_Node(PHNode *myNode) +{ + EpdGeom *epdgeom = nullptr; + MyNode_t *thisNode = static_cast(myNode); + if (thisNode) + { + epdgeom = thisNode->getData(); + } + if (epdgeom) + { + for (int iarm = 0; iarm < 2; iarm++) + { + for (int irad = 0; irad < 16; irad++) + { + for (int iphi = 0; iphi < 24; iphi++) + { + if (irad == 0 && iphi > 11) + { + continue; + } + unsigned int key = TowerInfoDefs::encode_epd(iarm, irad, iphi); + *fout << "tile key: 0x" << std::hex << key << std::dec << std::endl; + *fout << "get_r: " << epdgeom->get_r(key) << std::endl; + *fout << "get_phi: " << epdgeom->get_phi(key) << std::endl; + *fout << "get_z: " << epdgeom->get_z(key) << std::endl; + } + } + } + } + return 0; +} diff --git a/offline/packages/NodeDump/DumpEpdGeom.h b/offline/packages/NodeDump/DumpEpdGeom.h new file mode 100644 index 0000000000..9ae3e8af77 --- /dev/null +++ b/offline/packages/NodeDump/DumpEpdGeom.h @@ -0,0 +1,20 @@ +#ifndef NODEDUMP_DUMPEPDGEOM_H +#define NODEDUMP_DUMPEPDGEOM_H + +#include "DumpObject.h" + +#include + +class PHNode; + +class DumpEpdGeom : public DumpObject +{ + public: + explicit DumpEpdGeom(const std::string &NodeName); + ~DumpEpdGeom() override {} + + protected: + int process_Node(PHNode *mynode) override; +}; + +#endif diff --git a/offline/packages/NodeDump/DumpGlobalVertexMap.cc b/offline/packages/NodeDump/DumpGlobalVertexMap.cc index b7fd965420..a312ae70bc 100644 --- a/offline/packages/NodeDump/DumpGlobalVertexMap.cc +++ b/offline/packages/NodeDump/DumpGlobalVertexMap.cc @@ -1,7 +1,7 @@ #include "DumpGlobalVertexMap.h" -#include -#include +#include +#include #include diff --git a/offline/packages/NodeDump/DumpObject.h b/offline/packages/NodeDump/DumpObject.h index c5d760be1d..38624ce8dd 100644 --- a/offline/packages/NodeDump/DumpObject.h +++ b/offline/packages/NodeDump/DumpObject.h @@ -10,7 +10,7 @@ class PHNodeDump; class DumpObject { public: - DumpObject(const std::string &NodeName = "DUMMY"); + explicit DumpObject(const std::string &NodeName = "DUMMY"); virtual ~DumpObject() {} virtual int Init(); // called during intialization diff --git a/offline/packages/NodeDump/DumpPHG4CylinderGeomContainer.cc b/offline/packages/NodeDump/DumpPHG4CylinderGeomContainer.cc index a95c594fc3..11bdf0eb36 100644 --- a/offline/packages/NodeDump/DumpPHG4CylinderGeomContainer.cc +++ b/offline/packages/NodeDump/DumpPHG4CylinderGeomContainer.cc @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -49,6 +50,64 @@ int DumpPHG4CylinderGeomContainer::process_Node(PHNode *myNode) *fout << "pixel_z: " << hiter->second->get_pixel_z() << std::endl; *fout << "pixel_x: " << hiter->second->get_pixel_x() << std::endl; *fout << "pixel_thickness: " << hiter->second->get_pixel_thickness() << std::endl; + PHG4CylinderGeom_Spacalv1 *layergeomv1 = dynamic_cast(hiter->second); + if (layergeomv1) + { + const PHG4CylinderGeom_Spacalv3::sector_map_t §or_map = layergeomv1->get_sector_map(); + *fout << "xpos: " << layergeomv1->get_xpos() << std::endl; + *fout << "ypos: " << layergeomv1->get_ypos() << std::endl; + *fout << "zpos: " << layergeomv1->get_zpos() << std::endl; + *fout << "fiber_clading_thickness: " << layergeomv1->get_fiber_clading_thickness() << std::endl; + *fout << "fiber_core_diameter: " << layergeomv1->get_fiber_core_diameter() << std::endl; + *fout << "fiber_distance: " << layergeomv1->get_fiber_distance() << std::endl; + *fout << "absorber_mat: " << layergeomv1->get_absorber_mat() << std::endl; + *fout << "fiber_clading_mat: " << layergeomv1->get_fiber_clading_mat() << std::endl; + *fout << "fiber_core_mat: " << layergeomv1->get_fiber_core_mat() << std::endl; + *fout << "virualize_fiber: " << layergeomv1->is_virualize_fiber() << std::endl; + for (auto sectormapiter : sector_map) + { + *fout << "sector " << sectormapiter.first << ", rotation: " << sectormapiter.second << std::endl; + } + } + PHG4CylinderGeom_Spacalv3 *layergeomv3 = dynamic_cast(hiter->second); + if (layergeomv3) + { + *fout << "sidewall_outer_torr: " << layergeomv3->get_sidewall_outer_torr() << std::endl; + *fout << "sidewall_thickness: " << layergeomv3->get_sidewall_thickness() << std::endl; + *fout << "sidewall_mat: " << layergeomv3->get_sidewall_mat() << std::endl; + *fout << "max_phi_bin_in_sec: " << layergeomv3->get_max_phi_bin_in_sec() << std::endl; + *fout << "divider_mat: " << layergeomv3->get_divider_mat() << std::endl; + *fout << "divider_width: " << layergeomv3->get_divider_width() << std::endl; + + const PHG4CylinderGeom_Spacalv3::tower_map_t &tower_map = layergeomv3->get_sector_tower_map(); + for (const auto &towermapiter : tower_map) + { + *fout << "tower " << towermapiter.first << ", id: " << towermapiter.second.id << std::endl; + *fout << "tower " << towermapiter.first << ", pDz: " << towermapiter.second.pDz << std::endl; + *fout << "tower " << towermapiter.first << ", pDy1: " << towermapiter.second.pDy1 << std::endl; + *fout << "tower " << towermapiter.first << ", pDx1: " << towermapiter.second.pDx1 << std::endl; + *fout << "tower " << towermapiter.first << ", pDx2: " << towermapiter.second.pDx2 << std::endl; + *fout << "tower " << towermapiter.first << ", pDy2: " << towermapiter.second.pDy2 << std::endl; + *fout << "tower " << towermapiter.first << ", pDx3: " << towermapiter.second.pDx3 << std::endl; + *fout << "tower " << towermapiter.first << ", pDx4: " << towermapiter.second.pDx4 << std::endl; + *fout << "tower " << towermapiter.first << ", pTheta: " << towermapiter.second.pTheta << std::endl; + *fout << "tower " << towermapiter.first << ", pPhi: " << towermapiter.second.pPhi << std::endl; + *fout << "tower " << towermapiter.first << ", pAlp1: " << towermapiter.second.pAlp1 << std::endl; + *fout << "tower " << towermapiter.first << ", pAlp2: " << towermapiter.second.pAlp2 << std::endl; + *fout << "tower " << towermapiter.first << ", pRotationAngleX: " << towermapiter.second.pRotationAngleX << std::endl; + *fout << "tower " << towermapiter.first << ", centralX: " << towermapiter.second.centralX << std::endl; + *fout << "tower " << towermapiter.first << ", centralY: " << towermapiter.second.centralY << std::endl; + *fout << "tower " << towermapiter.first << ", centralZ: " << towermapiter.second.centralZ << std::endl; + *fout << "tower " << towermapiter.first << ", ModuleSkinThickness: " << towermapiter.second.ModuleSkinThickness << std::endl; + *fout << "tower " << towermapiter.first << ", NFiberX: " << towermapiter.second.NFiberX << std::endl; + *fout << "tower " << towermapiter.first << ", NFiberY: " << towermapiter.second.NFiberY << std::endl; + *fout << "tower " << towermapiter.first << ", NSubtowerX: " << towermapiter.second.NSubtowerX << std::endl; + *fout << "tower " << towermapiter.first << ", NSubtowerY: " << towermapiter.second.NSubtowerY << std::endl; + *fout << "tower " << towermapiter.first << ", LightguideHeight: " << towermapiter.second.LightguideHeight << std::endl; + *fout << "tower " << towermapiter.first << ", LightguideTaperRatio: " << towermapiter.second.LightguideTaperRatio << std::endl; + *fout << "tower " << towermapiter.first << ", LightguideMaterial: " << towermapiter.second.LightguideMaterial << std::endl; + } + } } } return 0; diff --git a/offline/packages/NodeDump/DumpPHG4ParticleSvtxMap.cc b/offline/packages/NodeDump/DumpPHG4ParticleSvtxMap.cc index 9b18889146..6c5db18c32 100644 --- a/offline/packages/NodeDump/DumpPHG4ParticleSvtxMap.cc +++ b/offline/packages/NodeDump/DumpPHG4ParticleSvtxMap.cc @@ -29,11 +29,11 @@ int DumpPHG4ParticleSvtxMap::process_Node(PHNode *myNode) if (phg4particlesvtxmap) { *fout << "size " << phg4particlesvtxmap->size() << std::endl; - for (auto &iter : *phg4particlesvtxmap) + for (auto const &iter : *phg4particlesvtxmap) { *fout << "Cluster: " << std::hex << iter.first << std::dec << std::endl; - for (auto &iter2 : iter.second) + for (auto const &iter2 : iter.second) { *fout << "weight: " << iter2.first << std::endl; for (unsigned int iter3 : iter2.second) diff --git a/offline/packages/NodeDump/DumpSvtxPHG4ParticleMap.cc b/offline/packages/NodeDump/DumpSvtxPHG4ParticleMap.cc index dbe4c54561..6d0994e2f2 100644 --- a/offline/packages/NodeDump/DumpSvtxPHG4ParticleMap.cc +++ b/offline/packages/NodeDump/DumpSvtxPHG4ParticleMap.cc @@ -29,11 +29,11 @@ int DumpSvtxPHG4ParticleMap::process_Node(PHNode *myNode) if (svtxphg4particlemap) { *fout << "size " << svtxphg4particlemap->size() << std::endl; - for (auto &iter : *svtxphg4particlemap) + for (auto const &iter : *svtxphg4particlemap) { *fout << "Cluster: " << std::hex << iter.first << std::dec << std::endl; - for (auto &iter2 : iter.second) + for (auto const &iter2 : iter.second) { *fout << "weight: " << iter2.first << std::endl; for (int iter3 : iter2.second) diff --git a/offline/packages/NodeDump/DumpTowerInfoContainer.cc b/offline/packages/NodeDump/DumpTowerInfoContainer.cc index 22ffbb552f..14cfa2a2f0 100644 --- a/offline/packages/NodeDump/DumpTowerInfoContainer.cc +++ b/offline/packages/NodeDump/DumpTowerInfoContainer.cc @@ -30,9 +30,9 @@ int DumpTowerInfoContainer::process_Node(PHNode *myNode) { unsigned int nchannels = towerinfocontainer->size(); *fout << "size: " << towerinfocontainer->size() << std::endl; - for ( unsigned int channel = 0; channel < nchannels;channel++ ) - { - TowerInfo *rawtwr = towerinfocontainer->get_tower_at_channel(channel); + for (unsigned int channel = 0; channel < nchannels; channel++) + { + TowerInfo *rawtwr = towerinfocontainer->get_tower_at_channel(channel); *fout << "time: " << rawtwr->get_time() << std::endl; *fout << "energy: " << rawtwr->get_energy() << std::endl; } diff --git a/offline/packages/NodeDump/Dumper.h b/offline/packages/NodeDump/Dumper.h index 90a523229e..ccccad34c2 100644 --- a/offline/packages/NodeDump/Dumper.h +++ b/offline/packages/NodeDump/Dumper.h @@ -11,7 +11,7 @@ class PHNodeDump; class Dumper : public SubsysReco { public: - Dumper(const std::string &name = "DUMPER"); + explicit Dumper(const std::string &name = "DUMPER"); ~Dumper() override; int End(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; diff --git a/offline/packages/NodeDump/Makefile.am b/offline/packages/NodeDump/Makefile.am index f5438f1971..23c8ba264e 100644 --- a/offline/packages/NodeDump/Makefile.am +++ b/offline/packages/NodeDump/Makefile.am @@ -14,10 +14,13 @@ pkginclude_HEADERS = \ libphnodedump_la_SOURCES = \ Dumper.cc \ + DumpBbcOut.cc \ + DumpBbcPmtContainer.cc \ DumpBbcVertexMap.cc \ DumpCaloTriggerInfo.cc \ DumpCdbUrlSave.cc \ DumpCentralityInfo.cc \ + DumpEpdGeom.cc \ DumpEpInfo.cc \ DumpEventHeader.cc \ DumpFlagSave.cc \ @@ -65,16 +68,18 @@ libphnodedump_la_SOURCES = \ AM_LDFLAGS = -L$(libdir) -L$(OFFLINE_MAIN)/lib libphnodedump_la_LIBADD = \ - -lg4bbc_io \ + -lbbc_io \ -lcalo_io \ -lcalotrigger_io \ + -lepd_io \ -leventplane_io \ -lffaobjects \ -lg4detectors_io \ - -lphfield_io \ + -lg4bbc_io \ -lg4jets_io \ -lHepMC \ -lparticleflow_io \ + -lphfield_io \ -lphg4hit \ -lSubsysReco \ -ltrackbase_historic_io \ diff --git a/offline/packages/NodeDump/PHNodeDump.cc b/offline/packages/NodeDump/PHNodeDump.cc index a924a73a6d..6ee801a464 100644 --- a/offline/packages/NodeDump/PHNodeDump.cc +++ b/offline/packages/NodeDump/PHNodeDump.cc @@ -1,11 +1,14 @@ #include "PHNodeDump.h" #include "DumpObject.h" +#include "DumpBbcOut.h" +#include "DumpBbcPmtContainer.h" #include "DumpBbcVertexMap.h" #include "DumpCaloTriggerInfo.h" #include "DumpCdbUrlSave.h" #include "DumpCentralityInfo.h" #include "DumpEpInfo.h" +#include "DumpEpdGeom.h" #include "DumpEventHeader.h" #include "DumpFlagSave.h" #include "DumpGlobalVertexMap.h" @@ -157,7 +160,6 @@ int PHNodeDump::CloseOutputFiles() int PHNodeDump::AddDumpObject(const std::string &NodeName, PHNode *node) { DumpObject *newdump; - const std::string &newnode = NodeName; if (!exclusive.empty()) { if (exclusive.find(NodeName) == exclusive.end()) @@ -165,13 +167,14 @@ int PHNodeDump::AddDumpObject(const std::string &NodeName, PHNode *node) std::cout << "Exclusive find: Ignoring " << NodeName << std::endl; newdump = new DumpObject(NodeName); newdump->NoOutput(); - goto initdump; + return initdump(NodeName, newdump); } } if (ignore.find(NodeName) != ignore.end()) { std::cout << "Ignoring " << NodeName << std::endl; newdump = new DumpObject(NodeName); + newdump->NoOutput(); } else { @@ -180,7 +183,15 @@ int PHNodeDump::AddDumpObject(const std::string &NodeName, PHNode *node) // need a static cast since only from DST these guys are of type PHIODataNode // when created they are normally PHIODataNode but can be anything else as well TObject *tmp = static_cast((static_cast *>(node))->getData()); - if (tmp->InheritsFrom("BbcVertexMap")) + if (tmp->InheritsFrom("BbcOut")) + { + newdump = new DumpBbcOut(NodeName); + } + else if (tmp->InheritsFrom("BbcPmtContainer")) + { + newdump = new DumpBbcPmtContainer(NodeName); + } + else if (tmp->InheritsFrom("BbcVertexMap")) { newdump = new DumpBbcVertexMap(NodeName); } @@ -196,6 +207,10 @@ int PHNodeDump::AddDumpObject(const std::string &NodeName, PHNode *node) { newdump = new DumpCentralityInfo(NodeName); } + else if (tmp->InheritsFrom("EpdGeom")) + { + newdump = new DumpEpdGeom(NodeName); + } else if (tmp->InheritsFrom("EpInfo")) { newdump = new DumpEpInfo(NodeName); @@ -374,12 +389,15 @@ int PHNodeDump::AddDumpObject(const std::string &NodeName, PHNode *node) } } newdump->PrintEvtSeq(print_evtseq); + return initdump(NodeName, newdump); +} -initdump: - newdump->SetParentNodeDump(this); - newdump->SetOutDir(outdir); - newdump->SetPrecision(fp_precision); - newdump->Init(); - dumpthis[newnode] = newdump; +int PHNodeDump::initdump(const std::string &newnode, DumpObject *dmp) +{ + dmp->SetParentNodeDump(this); + dmp->SetOutDir(outdir); + dmp->SetPrecision(fp_precision); + dmp->Init(); + dumpthis[newnode] = dmp; return 0; } diff --git a/offline/packages/NodeDump/PHNodeDump.h b/offline/packages/NodeDump/PHNodeDump.h index 5a469c1e3f..7ce4312568 100644 --- a/offline/packages/NodeDump/PHNodeDump.h +++ b/offline/packages/NodeDump/PHNodeDump.h @@ -31,6 +31,7 @@ class PHNodeDump : public PHNodeOperation private: void perform(PHNode *) override; int AddDumpObject(const std::string &NodeName, PHNode *node); + int initdump(const std::string &newnode, DumpObject *dmp); std::map dumpthis; std::set ignore; std::set exclusive; diff --git a/offline/packages/NodeDump/macro/run_dump.C b/offline/packages/NodeDump/macro/run_dump.C index db735d5331..f596812d53 100644 --- a/offline/packages/NodeDump/macro/run_dump.C +++ b/offline/packages/NodeDump/macro/run_dump.C @@ -6,10 +6,12 @@ #include #include +// cppcheck-suppress unknownMacro R__LOAD_LIBRARY(libfun4all.so) +// cppcheck-suppress unknownMacro R__LOAD_LIBRARY(libphnodedump.so) -void run_dump(const char *infile, const int evts=100) +void run_dump(const std::string &infile, const int evts=100) { gSystem->Load("libg4dst.so"); Fun4AllServer* se = Fun4AllServer::instance(); diff --git a/offline/packages/PHField/PHField2D.cc b/offline/packages/PHField/PHField2D.cc index fae8e159d4..15570a3f0d 100644 --- a/offline/packages/PHField/PHField2D.cc +++ b/offline/packages/PHField/PHField2D.cc @@ -1,19 +1,13 @@ #include "PHField2D.h" -//root framework +// root framework #include #include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" #include #include -#pragma GCC diagnostic pop #include -#include - #include #include #include @@ -22,9 +16,7 @@ #include #include -using namespace std; - -PHField2D::PHField2D(const string &filename, const int verb, const float magfield_rescale) +PHField2D::PHField2D(const std::string &filename, const int verb, const float magfield_rescale) : PHField(verb) , r_index0_cache(0) , r_index1_cache(0) @@ -33,19 +25,19 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel { if (Verbosity() > 0) { - cout << " ------------- PHField2D::PHField2D() ------------------" << endl; + std::cout << " ------------- PHField2D::PHField2D() ------------------" << std::endl; } // open file TFile *rootinput = TFile::Open(filename.c_str()); if (!rootinput) { - cout << " could not open " << filename << " exiting now" << endl; + std::cout << " could not open " << filename << " exiting now" << std::endl; gSystem->Exit(1); exit(1); } if (Verbosity() > 0) { - cout << " Field grid file: " << filename << endl; + std::cout << " Field grid file: " << filename << std::endl; } rootinput->cd(); @@ -62,7 +54,7 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel field_map = (TNtuple *) gDirectory->Get("map"); if (!field_map) { - cout << "PHField2D: could not locate ntuple of name map or fieldmap, exiting now" << endl; + std::cout << "PHField2D: could not locate ntuple of name map or fieldmap, exiting now" << std::endl; exit(1); } magfield_unit = gauss; @@ -81,21 +73,21 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel // run checks on entries if (Verbosity() > 0) { - cout << " The field grid contained " << NENTRIES << " entries" << endl; + std::cout << " The field grid contained " << NENTRIES << " entries" << std::endl; } if (Verbosity() > 1) { - cout << "\n NENTRIES should be the same as the following values:" - << "\n [ Number of values r,z: " - << nr << " " << nz << " ]! " << endl; + std::cout << "\n NENTRIES should be the same as the following values:" + << "\n [ Number of values r,z: " + << nr << " " << nz << " ]! " << std::endl; } if (nz != nr) { - cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - << "\n The file you entered is not a \"table\" of values" - << "\n Something very likely went oh so wrong" - << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + << "\n The file you entered is not a \"table\" of values" + << "\n Something very likely went oh so wrong" + << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; } // Keep track of the unique z, r, phi values in the grid using sets @@ -108,7 +100,7 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel // phi. if (Verbosity() > 1) { - cout << " --> Sorting Entries..." << endl; + std::cout << " --> Sorting Entries..." << std::endl; } std::map sorted_map; for (int i = 0; i < field_map->GetEntries(); i++) @@ -122,17 +114,17 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel r_set.insert(ROOT_R * cm); } - // couts for assurance + // std::couts for assurance if (Verbosity() > 4) { - map::iterator it = sorted_map.begin(); + std::map::iterator it = sorted_map.begin(); print_map(it); - float last_z = it->first.get<0>(); + float last_z = std::get<0>(it->first); for (it = sorted_map.begin(); it != sorted_map.end(); ++it) { - if (it->first.get<0>() != last_z) + if (std::get<0>(it->first) != last_z) { - last_z = it->first.get<0>(); + last_z = std::get<0>(it->first); print_map(it); } } @@ -140,7 +132,7 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel if (Verbosity() > 1) { - cout << " --> Putting entries into containers... " << endl; + std::cout << " --> Putting entries into containers... " << std::endl; } // grab the minimum and maximum z values @@ -159,19 +151,19 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel std::copy(r_set.begin(), r_set.end(), r_map_.begin()); // initialize the field map vectors to the correct sizes - BFieldR_.resize(nz, vector(nr, 0)); - BFieldZ_.resize(nz, vector(nr, 0)); + BFieldR_.resize(nz, std::vector(nr, 0)); + BFieldZ_.resize(nz, std::vector(nr, 0)); // all of this assumes that z_prev < z , i.e. the table is ordered (as of right now) unsigned int ir = 0, iz = 0; // useful indexes to keep track of - map::iterator iter = sorted_map.begin(); + std::map::iterator iter = sorted_map.begin(); for (; iter != sorted_map.end(); ++iter) { // equivalent to ->GetEntry(iter) - float z = iter->first.get<0>() * cm; - float r = iter->first.get<1>() * cm; - float Bz = iter->second.get<0>() * magfield_unit; - float Br = iter->second.get<1>() * magfield_unit; + float z = std::get<0>(iter->first) * cm; + float r = std::get<1>(iter->first) * cm; + float Bz = std::get<0>(iter->second) * magfield_unit; + float Br = std::get<1>(iter->second) * magfield_unit; if (z > maxz_) { @@ -196,7 +188,7 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel // shouldn't happen if (iz > 0 && z < z_map_[iz - 1]) { - cout << "!!!!!!!!! Your map isn't ordered.... z: " << z << " zprev: " << z_map_[iz - 1] << endl; + std::cout << "!!!!!!!!! Your map isn't ordered.... z: " << z << " zprev: " << z_map_[iz - 1] << std::endl; } BFieldR_[iz][ir] = Br * magfield_rescale; @@ -204,16 +196,16 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel // you can change this to check table values for correctness // print_map prints the values in the root table, and the - // couts print the values entered into the vectors - if (fabs(z) < 10 && ir < 10 /*&& iphi==2*/ && Verbosity() > 3) + // std::couts print the values entered into the vectors + if (std::fabs(z) < 10 && ir < 10 /*&& iphi==2*/ && Verbosity() > 3) { print_map(iter); - cout << " B(" - << r_map_[ir] << ", " - << z_map_[iz] << "): (" - << BFieldR_[iz][ir] << ", " - << BFieldZ_[iz][ir] << ")" << endl; + std::cout << " B(" + << r_map_[ir] << ", " + << z_map_[iz] << "): (" + << BFieldR_[iz][ir] << ", " + << BFieldZ_[iz][ir] << ")" << std::endl; } } // end loop over root field map file @@ -222,16 +214,16 @@ PHField2D::PHField2D(const string &filename, const int verb, const float magfiel if (Verbosity() > 0) { - cout << " Mag field z boundaries (min,max): (" << minz_ / cm << ", " << maxz_ / cm << ") cm" << endl; + std::cout << " Mag field z boundaries (min,max): (" << minz_ / cm << ", " << maxz_ / cm << ") cm" << std::endl; } if (Verbosity() > 0) { - cout << " Mag field r max boundary: " << r_map_.back() / cm << " cm" << endl; + std::cout << " Mag field r max boundary: " << r_map_.back() / cm << " cm" << std::endl; } if (Verbosity() > 0) { - cout << " -----------------------------------------------------------" << endl; + std::cout << " -----------------------------------------------------------" << std::endl; } } @@ -239,7 +231,7 @@ void PHField2D::GetFieldValue(const double point[4], double *Bfield) const { if (Verbosity() > 2) { - cout << "\nPHField2D::GetFieldValue" << endl; + std::cout << "\nPHField2D::GetFieldValue" << std::endl; } double x = point[0]; double y = point[1]; @@ -277,15 +269,15 @@ void PHField2D::GetFieldValue(const double point[4], double *Bfield) const Bfield[2] = 0.0; if (Verbosity() > 2) { - cout << "!!!!!!!!!! Field point not in defined region (outside of z bounds)" << endl; + std::cout << "!!!!!!!!!! Field point not in defined region (outside of z bounds)" << std::endl; } } if (Verbosity() > 2) { - cout << "END PHField2D::GetFieldValue\n" - << " ---> {Bx, By, Bz} : " - << "< " << Bfield[0] << ", " << Bfield[1] << ", " << Bfield[2] << " >" << endl; + std::cout << "END PHField2D::GetFieldValue\n" + << " ---> {Bx, By, Bz} : " + << "< " << Bfield[0] << ", " << Bfield[1] << ", " << Bfield[2] << " >" << std::endl; } return; @@ -302,14 +294,14 @@ void PHField2D::GetFieldCyl(const double CylPoint[4], double *BfieldCyl) const if (Verbosity() > 2) { - cout << "GetFieldCyl@ : {" << z << "," << r << "}" << endl; + std::cout << "GetFieldCyl@ : {" << z << "," << r << "}" << std::endl; } if (z < z_map_[0] || z > z_map_[z_map_.size() - 1]) { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << endl; + std::cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << std::endl; } return; } @@ -324,13 +316,13 @@ void PHField2D::GetFieldCyl(const double CylPoint[4], double *BfieldCyl) const if (!((r > r_map_[r_index0]) && (r < r_map_[r_index1]))) { // if miss cached r values, search through the lookup table - vector::const_iterator riter = upper_bound(r_map_.begin(), r_map_.end(), r); + std::vector::const_iterator riter = upper_bound(r_map_.begin(), r_map_.end(), r); r_index0 = distance(r_map_.begin(), riter) - 1; if (r_index0 >= r_map_.size()) { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << endl; + std::cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << std::endl; } return; } @@ -340,7 +332,7 @@ void PHField2D::GetFieldCyl(const double CylPoint[4], double *BfieldCyl) const { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << endl; + std::cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << std::endl; } return; } @@ -356,14 +348,14 @@ void PHField2D::GetFieldCyl(const double CylPoint[4], double *BfieldCyl) const if (!((z > z_map_[z_index0]) && (z < z_map_[z_index1]))) { // if miss cached z values, search through the lookup table - vector::const_iterator ziter = upper_bound(z_map_.begin(), z_map_.end(), z); + std::vector::const_iterator ziter = upper_bound(z_map_.begin(), z_map_.end(), z); z_index0 = distance(z_map_.begin(), ziter) - 1; z_index1 = z_index0 + 1; if (z_index1 >= z_map_.size()) { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (z too large in specific r-plane)" << endl; + std::cout << "!!!! Point not in defined region (z too large in specific r-plane)" << std::endl; } return; } @@ -410,22 +402,22 @@ void PHField2D::GetFieldCyl(const double CylPoint[4], double *BfieldCyl) const if (Verbosity() > 2) { - cout << "End GFCyl Call: : {" - << BfieldCyl[0] / gauss << "," << BfieldCyl[1] / gauss << "," << BfieldCyl[2] / gauss << "}" - << endl; + std::cout << "End GFCyl Call: : {" + << BfieldCyl[0] / gauss << "," << BfieldCyl[1] / gauss << "," << BfieldCyl[2] / gauss << "}" + << std::endl; } return; } // debug function to print key/value pairs in map -void PHField2D::print_map(map::iterator &it) const +void PHField2D::print_map(std::map::iterator &it) const { - cout << " Key: <" - << it->first.get<0>() / cm << "," - << it->first.get<1>() / cm << ">" + std::cout << " Key: <" + << std::get<0>(it->first) / cm << "," + << std::get<1>(it->first) / cm << ">" - << " Value: <" - << it->second.get<0>() / magfield_unit << "," - << it->second.get<1>() / magfield_unit << ">\n"; + << " Value: <" + << std::get<0>(it->second) / magfield_unit << "," + << std::get<1>(it->second) / magfield_unit << ">" << std::endl; } diff --git a/offline/packages/PHField/PHField2D.h b/offline/packages/PHField/PHField2D.h index aead61ff51..62794a9db1 100644 --- a/offline/packages/PHField/PHField2D.h +++ b/offline/packages/PHField/PHField2D.h @@ -4,15 +4,14 @@ #include "PHField.h" -#include - #include #include +#include #include class PHField2D : public PHField { - typedef boost::tuple trio; + typedef std::tuple trio; public: PHField2D(const std::string &filename, const int verb = 0, const float magfield_rescale = 1.0); diff --git a/offline/packages/PHField/PHField3DCartesian.cc b/offline/packages/PHField/PHField3DCartesian.cc index 0686ede794..389f1ab833 100644 --- a/offline/packages/PHField/PHField3DCartesian.cc +++ b/offline/packages/PHField/PHField3DCartesian.cc @@ -4,12 +4,8 @@ #include // for TDirectory, gDirectory #include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" #include #include -#pragma GCC diagnostic pop #include @@ -27,7 +23,6 @@ #include #include - PHField3DCartesian::PHField3DCartesian(const std::string &fname, const float magfield_rescale, const float innerradius, const float outerradius, const float size_z) : filename(fname) { @@ -68,7 +63,7 @@ PHField3DCartesian::PHField3DCartesian(const std::string &fname, const float mag if (field_map == nullptr) { std::cout << PHWHERE << " Could not load fieldmap ntuple from " - << filename << " exiting now" << std::endl; + << filename << " exiting now" << std::endl; gSystem->Exit(1); exit(1); } @@ -89,8 +84,8 @@ PHField3DCartesian::PHField3DCartesian(const std::string &fname, const float mag yvals.insert(ROOT_Y * cm); zvals.insert(ROOT_Z * cm); if ((std::sqrt(ROOT_X * cm * ROOT_X * cm + ROOT_Y * cm * ROOT_Y * cm) >= innerradius && - std::sqrt(ROOT_X * cm * ROOT_X * cm + ROOT_Y * cm * ROOT_Y * cm) <= outerradius) || - std::abs(ROOT_Z * cm) > size_z ) + std::sqrt(ROOT_X * cm * ROOT_X * cm + ROOT_Y * cm * ROOT_Y * cm) <= outerradius) || + std::abs(ROOT_Z * cm) > size_z) { fieldmap[coord_key] = field_val; } @@ -238,7 +233,7 @@ void PHField3DCartesian::GetFieldValue(const double point[4], double *Bfield) co ykey_save = ykey[0]; zkey_save = zkey[0]; - std::map, boost::tuple >::const_iterator magval; + std::map, std::tuple >::const_iterator magval; trio key; for (int i = 0; i < 2; i++) { @@ -246,22 +241,22 @@ void PHField3DCartesian::GetFieldValue(const double point[4], double *Bfield) co { for (int k = 0; k < 2; k++) { - key = boost::make_tuple(xkey[i], ykey[j], zkey[k]); + key = std::make_tuple(xkey[i], ykey[j], zkey[k]); magval = fieldmap.find(key); if (magval == fieldmap.end()) { std::cout << PHWHERE << " could not locate key in " << filename - << " value: x: " << xkey[i] / cm + << " value: x: " << xkey[i] / cm << ", y: " << ykey[j] / cm << ", z: " << zkey[k] / cm << std::endl; return; } - xyz[i][j][k][0] = (magval->first).get<0>(); - xyz[i][j][k][1] = (magval->first).get<1>(); - xyz[i][j][k][2] = (magval->first).get<2>(); - bf[i][j][k][0] = (magval->second).get<0>(); - bf[i][j][k][1] = (magval->second).get<1>(); - bf[i][j][k][2] = (magval->second).get<2>(); + xyz[i][j][k][0] = std::get<0>(magval->first); + xyz[i][j][k][1] = std::get<1>(magval->first); + xyz[i][j][k][2] = std::get<2>(magval->first); + bf[i][j][k][0] = std::get<0>(magval->second); + bf[i][j][k][1] = std::get<1>(magval->second); + bf[i][j][k][2] = std::get<2>(magval->second); if (Verbosity() > 0) { std::cout << "read x/y/z: " << xyz[i][j][k][0] / cm << "/" @@ -297,15 +292,15 @@ void PHField3DCartesian::GetFieldValue(const double point[4], double *Bfield) co // linear extrapolation in cube: - //Vxyz = - //V000 * x * y * z + - //V100 * (1 - x) * y * z + - //V010 * x * (1 - y) * z + - //V001 * x y * (1 - z) + - //V101 * (1 - x) * y * (1 - z) + - //V011 * x * (1 - y) * (1 - z) + - //V110 * (1 - x) * (1 - y) * z + - //V111 * (1 - x) * (1 - y) * (1 - z) + // Vxyz = + // V000 * x * y * z + + // V100 * (1 - x) * y * z + + // V010 * x * (1 - y) * z + + // V001 * x y * (1 - z) + + // V101 * (1 - x) * y * (1 - z) + + // V011 * x * (1 - y) * (1 - z) + + // V110 * (1 - x) * (1 - y) * z + + // V111 * (1 - x) * (1 - y) * (1 - z) for (int i = 0; i < 3; i++) { diff --git a/offline/packages/PHField/PHField3DCartesian.h b/offline/packages/PHField/PHField3DCartesian.h index 2521ae6e3f..23d61e3ee9 100644 --- a/offline/packages/PHField/PHField3DCartesian.h +++ b/offline/packages/PHField/PHField3DCartesian.h @@ -3,18 +3,16 @@ #include "PHField.h" -#include -#include - #include #include #include #include +#include class PHField3DCartesian : public PHField { public: -explicit PHField3DCartesian(const std::string &fname, const float magfield_rescale = 1.0, const float innerradius = 0, const float outerradius = 1.e10, const float size_z = 1.e10); + explicit PHField3DCartesian(const std::string &fname, const float magfield_rescale = 1.0, const float innerradius = 0, const float outerradius = 1.e10, const float size_z = 1.e10); ~PHField3DCartesian() override; //! access field value @@ -44,8 +42,8 @@ explicit PHField3DCartesian(const std::string &fname, const float magfield_resca mutable int cache_hits = 0; mutable int cache_misses = 0; - typedef boost::tuple trio; - std::map, boost::tuple > fieldmap; + typedef std::tuple trio; + std::map, std::tuple > fieldmap; std::set xvals; std::set yvals; std::set zvals; diff --git a/offline/packages/PHField/PHField3DCylindrical.cc b/offline/packages/PHField/PHField3DCylindrical.cc index 53e5fd3689..c91ab1c204 100644 --- a/offline/packages/PHField/PHField3DCylindrical.cc +++ b/offline/packages/PHField/PHField3DCylindrical.cc @@ -2,16 +2,10 @@ #include // for TDirectory, gDirectory #include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" #include -#pragma GCC diagnostic pop #include -#include - #include #include #include @@ -21,26 +15,24 @@ #include #include -using namespace std; - -PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int verb, const float magfield_rescale) +PHField3DCylindrical::PHField3DCylindrical(const std::string &filename, const int verb, const float magfield_rescale) : PHField(verb) { - cout << "\n================ Begin Construct Mag Field =====================" << endl; - cout << "\n-----------------------------------------------------------" - << "\n Magnetic field Module - Verbosity:" << Verbosity() - << "\n-----------------------------------------------------------"; + std::cout << "\n================ Begin Construct Mag Field =====================" << std::endl; + std::cout << "\n-----------------------------------------------------------" + << "\n Magnetic field Module - Verbosity:" << Verbosity() + << "\n-----------------------------------------------------------"; // open file TFile *rootinput = TFile::Open(filename.c_str()); if (!rootinput) { - cout << "\n could not open " << filename << " exiting now" << endl; + std::cout << "\n could not open " << filename << " exiting now" << std::endl; exit(1); } - cout << "\n ---> " - "Reading the field grid from " - << filename << " ... " << endl; + std::cout << "\n ---> " + "Reading the field grid from " + << filename << " ... " << std::endl; rootinput->cd(); // get root NTuple objects @@ -62,20 +54,20 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver static const int NENTRIES = field_map->GetEntries(); // run checks on entries - cout << " ---> The field grid contained " << NENTRIES << " entries" << endl; + std::cout << " ---> The field grid contained " << NENTRIES << " entries" << std::endl; if (Verbosity() > 0) { - cout << "\n NENTRIES should be the same as the following values:" - << "\n [ Number of values r,phi,z: " - << nr << " " << nphi << " " << nz << " ]! " << endl; + std::cout << "\n NENTRIES should be the same as the following values:" + << "\n [ Number of values r,phi,z: " + << nr << " " << nphi << " " << nz << " ]! " << std::endl; } if (nz != nr || nz != nphi || nr != nphi) { - cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - << "\n The file you entered is not a \"table\" of values" - << "\n Something very likely went oh so wrong" - << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + << "\n The file you entered is not a \"table\" of values" + << "\n Something very likely went oh so wrong" + << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; } // Keep track of the unique z, r, phi values in the grid using sets @@ -88,7 +80,7 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver // phi. if (Verbosity() > 0) { - cout << " --> Sorting Entries..." << endl; + std::cout << " --> Sorting Entries..." << std::endl; } std::map sorted_map; for (int i = 0; i < field_map->GetEntries(); i++) @@ -103,17 +95,17 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver phi_set.insert(ROOT_PHI * deg); } - // couts for assurance + // std::couts for assurance if (Verbosity() > 4) { - map::iterator it = sorted_map.begin(); + std::map::iterator it = sorted_map.begin(); print_map(it); - float last_z = it->first.get<0>(); + float last_z = std::get<0>(it->first); for (it = sorted_map.begin(); it != sorted_map.end(); ++it) { - if (it->first.get<0>() != last_z) + if (std::get<0>(it->first) != last_z) { - last_z = it->first.get<0>(); + last_z = std::get<0>(it->first); print_map(it); } } @@ -121,7 +113,7 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver if (Verbosity() > 0) { - cout << " --> Putting entries into containers... " << endl; + std::cout << " --> Putting entries into containers... " << std::endl; } // grab the minimum and maximum z values @@ -143,22 +135,22 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver std::copy(r_set.begin(), r_set.end(), r_map_.begin()); // initialize the field map vectors to the correct sizes - BFieldR_.resize(nz, vector >(nr, vector(nphi, 0))); - BFieldPHI_.resize(nz, vector >(nr, vector(nphi, 0))); - BFieldZ_.resize(nz, vector >(nr, vector(nphi, 0))); + BFieldR_.resize(nz, std::vector >(nr, std::vector(nphi, 0))); + BFieldPHI_.resize(nz, std::vector >(nr, std::vector(nphi, 0))); + BFieldZ_.resize(nz, std::vector >(nr, std::vector(nphi, 0))); // all of this assumes that z_prev < z , i.e. the table is ordered (as of right now) unsigned int ir = 0, iphi = 0, iz = 0; // useful indexes to keep track of - map::iterator iter = sorted_map.begin(); + std::map::iterator iter = sorted_map.begin(); for (; iter != sorted_map.end(); ++iter) { // equivalent to ->GetEntry(iter) - float z = iter->first.get<0>() * cm; - float r = iter->first.get<1>() * cm; - float phi = iter->first.get<2>() * deg; - float Bz = iter->second.get<0>() * gauss; - float Br = iter->second.get<1>() * gauss; - float Bphi = iter->second.get<2>() * gauss; + float z = std::get<0>(iter->first) * cm; + float r = std::get<1>(iter->first) * cm; + float phi = std::get<2>(iter->first) * deg; + float Bz = std::get<0>(iter->second) * gauss; + float Br = std::get<1>(iter->second) * gauss; + float Bphi = std::get<2>(iter->second) * gauss; if (z > maxz_) { @@ -189,7 +181,7 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver // shouldn't happen if (iz > 0 && z < z_map_[iz - 1]) { - cout << "!!!!!!!!! Your map isn't ordered.... z: " << z << " zprev: " << z_map_[iz - 1] << endl; + std::cout << "!!!!!!!!! Your map isn't ordered.... z: " << z << " zprev: " << z_map_[iz - 1] << std::endl; } BFieldR_[iz][ir][iphi] = Br * magfield_rescale; @@ -198,37 +190,37 @@ PHField3DCylindrical::PHField3DCylindrical(const string &filename, const int ver // you can change this to check table values for correctness // print_map prints the values in the root table, and the - // couts print the values entered into the vectors - if (fabs(z) < 10 && ir < 10 /*&& iphi==2*/ && Verbosity() > 3) + // std::couts print the values entered into the vectors + if (std::fabs(z) < 10 && ir < 10 /*&& iphi==2*/ && Verbosity() > 3) { print_map(iter); - cout << " B(" - << r_map_[ir] << ", " - << phi_map_[iphi] << ", " - << z_map_[iz] << "): (" - << BFieldR_[iz][ir][iphi] << ", " - << BFieldPHI_[iz][ir][iphi] << ", " - << BFieldZ_[iz][ir][iphi] << ")" << endl; + std::cout << " B(" + << r_map_[ir] << ", " + << phi_map_[iphi] << ", " + << z_map_[iz] << "): (" + << BFieldR_[iz][ir][iphi] << ", " + << BFieldPHI_[iz][ir][iphi] << ", " + << BFieldZ_[iz][ir][iphi] << ")" << std::endl; } } // end loop over root field map file rootinput->Close(); - cout << "\n ---> ... read file successfully " - << "\n ---> Z Boundaries ~ zlow, zhigh: " - << minz_ / cm << "," << maxz_ / cm << " cm " << endl; + std::cout << "\n ---> ... read file successfully " + << "\n ---> Z Boundaries ~ zlow, zhigh: " + << minz_ / cm << "," << maxz_ / cm << " cm " << std::endl; - cout << "\n================= End Construct Mag Field ======================\n" - << endl; + std::cout << "\n================= End Construct Mag Field ======================\n" + << std::endl; } void PHField3DCylindrical::GetFieldValue(const double point[4], double *Bfield) const { if (Verbosity() > 2) { - cout << "\nPHField3DCylindrical::GetFieldValue" << endl; + std::cout << "\nPHField3DCylindrical::GetFieldValue" << std::endl; } double x = point[0]; double y = point[1]; @@ -274,15 +266,15 @@ void PHField3DCylindrical::GetFieldValue(const double point[4], double *Bfield) Bfield[2] = 0.0; if (Verbosity() > 2) { - cout << "!!!!!!!!!! Field point not in defined region (outside of z bounds)" << endl; + std::cout << "!!!!!!!!!! Field point not in defined region (outside of z bounds)" << std::endl; } } if (Verbosity() > 2) { - cout << "END PHField3DCylindrical::GetFieldValue\n" - << " ---> {Bx, By, Bz} : " - << "< " << Bfield[0] << ", " << Bfield[1] << ", " << Bfield[2] << " >" << endl; + std::cout << "END PHField3DCylindrical::GetFieldValue\n" + << " ---> {Bx, By, Bz} : " + << "< " << Bfield[0] << ", " << Bfield[1] << ", " << Bfield[2] << " >" << std::endl; } return; @@ -300,14 +292,14 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC if (Verbosity() > 2) { - cout << "GetFieldCyl@ : {" << z << "," << r << "," << phi << "}" << endl; + std::cout << "GetFieldCyl@ : {" << z << "," << r << "," << phi << "}" << std::endl; } if (z <= z_map_[0] || z >= z_map_[z_map_.size() - 1]) { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (|z| too large)" << endl; + std::cout << "!!!! Point not in defined region (|z| too large)" << std::endl; } return; } @@ -316,7 +308,7 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC r = r_map_[0]; if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too small in specific z-plane). Use min radius" << endl; + std::cout << "!!!! Point not in defined region (radius too small in specific z-plane). Use min radius" << std::endl; } // return; } @@ -324,12 +316,12 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << endl; + std::cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << std::endl; } return; } - vector::const_iterator ziter = upper_bound(z_map_.begin(), z_map_.end(), z); + std::vector::const_iterator ziter = upper_bound(z_map_.begin(), z_map_.end(), z); int z_index0 = distance(z_map_.begin(), ziter) - 1; int z_index1 = z_index0 + 1; @@ -338,13 +330,13 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC assert(z_index0 < (int) z_map_.size()); assert(z_index1 < (int) z_map_.size()); - vector::const_iterator riter = upper_bound(r_map_.begin(), r_map_.end(), r); + std::vector::const_iterator riter = upper_bound(r_map_.begin(), r_map_.end(), r); int r_index0 = distance(r_map_.begin(), riter) - 1; if (r_index0 >= (int) r_map_.size()) { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << endl; + std::cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << std::endl; } return; } @@ -354,7 +346,7 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC { if (Verbosity() > 2) { - cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << endl; + std::cout << "!!!! Point not in defined region (radius too large in specific z-plane)" << std::endl; } return; } @@ -362,7 +354,7 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC assert(r_index0 >= 0); assert(r_index1 >= 0); - vector::const_iterator phiiter = upper_bound(phi_map_.begin(), phi_map_.end(), phi); + std::vector::const_iterator phiiter = upper_bound(phi_map_.begin(), phi_map_.end(), phi); int phi_index0 = distance(phi_map_.begin(), phiiter) - 1; int phi_index1 = phi_index0 + 1; if (phi_index1 >= (int) phi_map_.size()) @@ -438,22 +430,22 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC zweight * ((1 - rweight) * ((1 - phiweight) * Bphi100 + phiweight * Bphi101) + rweight * ((1 - phiweight) * Bphi110 + phiweight * Bphi111)); - // cout << "wr: " << rweight << " wz: " << zweight << " wphi: " << phiweight << endl; - // cout << "Bz000: " << Bz000 << endl - // << "Bz001: " << Bz001 << endl - // << "Bz010: " << Bz010 << endl - // << "Bz011: " << Bz011 << endl - // << "Bz100: " << Bz100 << endl - // << "Bz101: " << Bz101 << endl - // << "Bz110: " << Bz110 << endl - // << "Bz111: " << Bz111 << endl - // << "Bz: " << BfieldCyl[0] << endl << endl; + // std::cout << "wr: " << rweight << " wz: " << zweight << " wphi: " << phiweight << std::endl; + // std::cout << "Bz000: " << Bz000 << std::endl + // << "Bz001: " << Bz001 << std::endl + // << "Bz010: " << Bz010 << std::endl + // << "Bz011: " << Bz011 << std::endl + // << "Bz100: " << Bz100 << std::endl + // << "Bz101: " << Bz101 << std::endl + // << "Bz110: " << Bz110 << std::endl + // << "Bz111: " << Bz111 << std::endl + // << "Bz: " << BfieldCyl[0] << std::endl << std::endl; if (Verbosity() > 2) { - cout << "End GFCyl Call: : {" - << BfieldCyl[0] / gauss << "," << BfieldCyl[1] / gauss << "," << BfieldCyl[2] / gauss << "}" - << endl; + std::cout << "End GFCyl Call: : {" + << BfieldCyl[0] / gauss << "," << BfieldCyl[1] / gauss << "," << BfieldCyl[2] / gauss << "}" + << std::endl; } return; @@ -461,7 +453,7 @@ void PHField3DCylindrical::GetFieldCyl(const double CylPoint[4], double *BfieldC // a binary search algorithm that puts the location that "key" would be, into index... // it returns true if key was found, and false if not. -bool PHField3DCylindrical::bin_search(const vector &vec, unsigned start, unsigned end, const float &key, unsigned &index) const +bool PHField3DCylindrical::bin_search(const std::vector &vec, unsigned start, unsigned end, const float &key, unsigned &index) const { // Termination condition: start index greater than end index if (start > end) @@ -487,15 +479,15 @@ bool PHField3DCylindrical::bin_search(const vector &vec, unsigned start, } // debug function to print key/value pairs in map -void PHField3DCylindrical::print_map(map::iterator &it) const +void PHField3DCylindrical::print_map(std::map::iterator &it) const { - cout << " Key: <" - << it->first.get<0>() * cm << "," - << it->first.get<1>() * cm << "," - << it->first.get<2>() * deg << ">" - - << " Value: <" - << it->second.get<0>() * gauss << "," - << it->second.get<1>() * gauss << "," - << it->second.get<2>() * gauss << ">\n"; + std::cout << " Key: <" + << std::get<0>(it->first) * cm << "," + << std::get<1>(it->first) * cm << "," + << std::get<2>(it->first) * deg << ">" + + << " Value: <" + << std::get<0>(it->second) * gauss << "," + << std::get<1>(it->second) * gauss << "," + << std::get<2>(it->second) * gauss << ">" << std::endl; } diff --git a/offline/packages/PHField/PHField3DCylindrical.h b/offline/packages/PHField/PHField3DCylindrical.h index 015356d77d..31b824441f 100644 --- a/offline/packages/PHField/PHField3DCylindrical.h +++ b/offline/packages/PHField/PHField3DCylindrical.h @@ -22,15 +22,14 @@ #include "PHField.h" -#include - #include #include +#include #include class PHField3DCylindrical : public PHField { - typedef boost::tuple trio; + typedef std::tuple trio; public: PHField3DCylindrical(const std::string& filename, int verb = 0, const float magfield_rescale = 1.0); diff --git a/offline/packages/PHField/PHFieldConfig.cc b/offline/packages/PHField/PHFieldConfig.cc index f79411aed0..cea9da01b8 100644 --- a/offline/packages/PHField/PHFieldConfig.cc +++ b/offline/packages/PHField/PHFieldConfig.cc @@ -1,7 +1,7 @@ /*! * \file PHFieldConfig.cc - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ diff --git a/offline/packages/PHField/PHFieldConfig.h b/offline/packages/PHField/PHFieldConfig.h index d52363ff86..c17bd4592f 100644 --- a/offline/packages/PHField/PHFieldConfig.h +++ b/offline/packages/PHField/PHFieldConfig.h @@ -1,6 +1,6 @@ /*! * \file PHFieldConfig.h - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ diff --git a/offline/packages/PHField/PHFieldConfigv1.cc b/offline/packages/PHField/PHFieldConfigv1.cc index a4080bf789..4f0a622d66 100644 --- a/offline/packages/PHField/PHFieldConfigv1.cc +++ b/offline/packages/PHField/PHFieldConfigv1.cc @@ -2,7 +2,7 @@ /*! * \file PHFieldConfigv1.cc - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ diff --git a/offline/packages/PHField/PHFieldConfigv1.h b/offline/packages/PHField/PHFieldConfigv1.h index 6da742ae4b..3478e1dbc6 100644 --- a/offline/packages/PHField/PHFieldConfigv1.h +++ b/offline/packages/PHField/PHFieldConfigv1.h @@ -2,7 +2,7 @@ /*! * \file PHFieldConfig_v1.h - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ @@ -49,8 +49,7 @@ class PHFieldConfigv1 : public PHFieldConfig void Reset() override {} /// isValid returns non zero if object contains vailid data - int - isValid() const override; + int isValid() const override; FieldConfigTypes get_field_config() const override { diff --git a/offline/packages/PHField/PHFieldConfigv2.cc b/offline/packages/PHField/PHFieldConfigv2.cc index ccb06912e3..f28a22356c 100644 --- a/offline/packages/PHField/PHFieldConfigv2.cc +++ b/offline/packages/PHField/PHFieldConfigv2.cc @@ -2,7 +2,7 @@ /*! * \file PHFieldConfigv2.cc - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ diff --git a/offline/packages/PHField/PHFieldConfigv2.h b/offline/packages/PHField/PHFieldConfigv2.h index eb0d5affb0..677d3a0417 100644 --- a/offline/packages/PHField/PHFieldConfigv2.h +++ b/offline/packages/PHField/PHFieldConfigv2.h @@ -2,7 +2,7 @@ /*! * \file PHFieldConfigv2.h - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ @@ -49,8 +49,7 @@ class PHFieldConfigv2 : public PHFieldConfig void Reset() override {} /// isValid returns non zero if object contains vailid data - int - isValid() const override { return 3; } + int isValid() const override { return 3; } FieldConfigTypes get_field_config() const override { diff --git a/offline/packages/PHField/PHFieldUniform.cc b/offline/packages/PHField/PHFieldUniform.cc index 8c9c0b5ed4..2b04ffc18e 100644 --- a/offline/packages/PHField/PHFieldUniform.cc +++ b/offline/packages/PHField/PHFieldUniform.cc @@ -12,7 +12,7 @@ PHFieldUniform::PHFieldUniform( { } -void PHFieldUniform::GetFieldValue(const double /*point*/ [4], double *Bfield) const +void PHFieldUniform::GetFieldValue(const double /*point*/[4], double *Bfield) const { Bfield[0] = field_mag_x_; Bfield[1] = field_mag_y_; diff --git a/offline/packages/PHField/PHFieldUtility.cc b/offline/packages/PHField/PHFieldUtility.cc index 5d61b0ca26..7742532947 100644 --- a/offline/packages/PHField/PHFieldUtility.cc +++ b/offline/packages/PHField/PHFieldUtility.cc @@ -18,10 +18,7 @@ #include #include // for PHWHERE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" #include -#pragma GCC diagnostic pop #include #include // for getenv @@ -72,8 +69,8 @@ PHFieldUtility::BuildFieldMap(const PHFieldConfig *field_config, float inner_rad field = new PHField3DCartesian( field_config->get_filename(), field_config->get_magfield_rescale(), - inner_radius, - outer_radius, + inner_radius, + outer_radius, size_z); break; diff --git a/offline/packages/PHField/PHFieldUtility.h b/offline/packages/PHField/PHFieldUtility.h index bd6943cd83..fd80e9f19e 100644 --- a/offline/packages/PHField/PHFieldUtility.h +++ b/offline/packages/PHField/PHFieldUtility.h @@ -31,7 +31,7 @@ class PHFieldUtility //! Build or build field map with a configuration object static PHField * - BuildFieldMap(const PHFieldConfig *field_config, float inner_radius = 0., float outer_radius = 1.e10, float size_z = 1.e10, const int verbosity = 0); + BuildFieldMap(const PHFieldConfig *field_config, float inner_radius = 0., float outer_radius = 1.e10, float size_z = 1.e10, const int verbosity = 0); //! DST node name for RunTime field map object static std::string diff --git a/offline/packages/ResonanceJetTagging/ResonanceJetTagging.cc b/offline/packages/ResonanceJetTagging/ResonanceJetTagging.cc index d43c655b67..b094ab9bb5 100644 --- a/offline/packages/ResonanceJetTagging/ResonanceJetTagging.cc +++ b/offline/packages/ResonanceJetTagging/ResonanceJetTagging.cc @@ -11,8 +11,8 @@ #include /// Tracking includes -#include -#include +#include +#include #include #include @@ -732,12 +732,12 @@ void ResonanceJetTagging::findMCTaggedJets(PHCompositeNode *topNode) decayIDs.push_back((*it)->barcode()); } //if not, look into GEANT - } + } else { PHG4TruthInfoContainer::ConstRange range = m_truthinfo->GetParticleRange(); for(PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; ++iter) - { + { PHG4Particle* g4particle = iter->second; PHG4Particle* mother = nullptr; if (g4particle->get_parent_id() != 0) mother = m_truthinfo->GetParticle(g4particle->get_parent_id()); @@ -769,6 +769,10 @@ void ResonanceJetTagging::findMCTaggedJets(PHCompositeNode *topNode) { continue; } + if (std::abs((*p)->pdg_id()) == m_tag_pdg) + { + continue; + } partPDG = database->GetParticle((*p)->pdg_id()); double hepmcPartPt = std::sqrt(((*p)->momentum().px() * (*p)->momentum().px()) + ((*p)->momentum().py() * (*p)->momentum().py())); diff --git a/offline/packages/TPCHitTrackDisplay/Makefile.am b/offline/packages/TPCHitTrackDisplay/Makefile.am index c62c86622a..54ce516cf5 100644 --- a/offline/packages/TPCHitTrackDisplay/Makefile.am +++ b/offline/packages/TPCHitTrackDisplay/Makefile.am @@ -19,7 +19,6 @@ AM_LDFLAGS = \ libTPCHitTrackDisplay_la_LIBADD = \ -lphool \ -lg4detectors \ - -lepd \ -lcentrality_io \ -lphg4hit \ -lConstituentSubtractor \ diff --git a/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.cc b/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.cc index b8c90e6734..293075db88 100644 --- a/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.cc +++ b/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.cc @@ -60,10 +60,10 @@ using namespace std; TPCHitTrackDisplay::TPCHitTrackDisplay(const string &name) : SubsysReco(name) - , m_cut_ADC(200.0) + , m_cut_ADC(75.0) , m_trackless_clusters(true) , _pdgcode(0) - , outfile1((name + ".json").c_str(), std::ios::app) + , _fileName(name) { //initialize _event = 0; @@ -215,6 +215,10 @@ return; // write json file from simulation data for silicon and tpc clusters/tracks void TPCHitTrackDisplay::SimulationOut(PHCompositeNode *topNode) { + stringstream fname; + fname << _fileName << "event" << _event << ".json"; + fstream outfile1(fname.str(), ios_base::out); + cout << _event << endl; TrkrClusterContainer *clusterContainer = findNode::getClass(topNode, "TRKR_CLUSTER"); @@ -443,7 +447,9 @@ void TPCHitTrackDisplay::SimulationOut(PHCompositeNode *topNode) outfile1 << "}" << endl; outfile1 << "}" << endl; -return; + usedClusters.clear(); + + return; } diff --git a/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.h b/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.h index 02706b2bb7..3e9c31bcc6 100644 --- a/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.h +++ b/offline/packages/TPCHitTrackDisplay/TPCHitTrackDisplay.h @@ -63,7 +63,7 @@ class TPCHitTrackDisplay: public SubsysReco //Event counter int _event; int _pdgcode; - std::ofstream outfile1; + std::string _fileName; //bool isRawData; diff --git a/offline/packages/TrackerMillepedeAlignment/AlignmentDefs.cc b/offline/packages/TrackerMillepedeAlignment/AlignmentDefs.cc new file mode 100644 index 0000000000..a465b9180d --- /dev/null +++ b/offline/packages/TrackerMillepedeAlignment/AlignmentDefs.cc @@ -0,0 +1,190 @@ +#include "AlignmentDefs.h" + +void AlignmentDefs::getSiliconGlobalLabels(Surface surf, int glbl_label[], AlignmentDefs::siliconGrp grp) +{ + Acts::GeometryIdentifier id = surf->geometryId(); + int group = 0; + switch (grp) + { + case AlignmentDefs::siliconGrp::snsr: + group = 0; + break; + case AlignmentDefs::siliconGrp::stv: + group = 1; + break; + case AlignmentDefs::siliconGrp::brrl: + group = 2; + break; + } + + int label_base = getLabelBase(id, group); + for (int i = 0; i < NGL; ++i) + { + glbl_label[i] = label_base + i; + } +} + +void AlignmentDefs::getTpcGlobalLabels(Surface surf, int glbl_label[], AlignmentDefs::tpcGrp grp) +{ + Acts::GeometryIdentifier id = surf->geometryId(); + int group = 0; + switch (grp) + { + case AlignmentDefs::tpcGrp::htst: + group = 3; + break; + case AlignmentDefs::tpcGrp::sctr: + group = 4; + break; + case AlignmentDefs::tpcGrp::tp: + group = 5; + break; + } + + int label_base = getLabelBase(id, group); + for (int i = 0; i < NGL; ++i) + { + glbl_label[i] = label_base + i; + } +} +void AlignmentDefs::getMMGlobalLabels(Surface surf, int glbl_label[], AlignmentDefs::mmsGrp grp) +{ + Acts::GeometryIdentifier id = surf->geometryId(); + int group = 0; + switch (grp) + { + case AlignmentDefs::mmsGrp::tl: + group = 6; + break; + case AlignmentDefs::mmsGrp::mm: + group = 7; + break; + } + + int label_base = getLabelBase(id, group); + for (int i = 0; i < NGL; ++i) + { + glbl_label[i] = label_base + i; + } +} + +int AlignmentDefs::getTpcRegion(int layer) +{ + int region = 0; + if (layer > 23 && layer < 39) + region = 1; + if (layer > 38 && layer < 55) + region = 2; + + return region; +} +int AlignmentDefs::getLabelBase(Acts::GeometryIdentifier id, int group) +{ + unsigned int volume = id.volume(); + unsigned int acts_layer = id.layer(); + unsigned int layer = base_layer_map.find(volume)->second + acts_layer / 2 - 1; + unsigned int sensor = id.sensitive() - 1; // Acts starts at 1 + + int label_base = 1; // Mille wants to start at 1 + + // decide what level of grouping we want + if (layer < 7) + { + if (group == 0) + { + // every sensor has a different label + int stave = sensor / nsensors_stave[layer]; + label_base += layer * 1000000 + stave * 10000 + sensor * 10; + return label_base; + } + if (group == 1) + { + // layer and stave, assign all sensors to the stave number + int stave = sensor / nsensors_stave[layer]; + label_base += layer * 1000000 + stave * 10000; + return label_base; + } + if (group == 2) + // layer only, assign all sensors to sensor 0 + label_base += layer * 1000000 + 0; + return label_base; + } + else if (layer > 6 && layer < 55) + { + if (group == 3) + { + // want every hitset (layer, sector, side) to have a separate label + // each group of 12 subsurfaces (sensors) is in a single hitset + int hitset = sensor / 12; // 0-11 on side 0, 12-23 on side 1 + label_base += layer * 1000000 + hitset * 10000; + return label_base; + } + if (group == 4) + { + // group all tpc layers in each region and sector, assign layer 7 and side and sector number to all layers and hitsets + int side = sensor / 144; // 0-143 on side 0, 144-287 on side 1 + int sector = (sensor - side * 144) / 12; + // for a given layer there are only 12 sectors x 2 sides + // The following gives the sectors in the inner, mid, outer regions unique group labels + int region = getTpcRegion(layer); // inner, mid, outer + label_base += 7 * 1000000 + (region * 24 + side * 12 + sector) * 10000; + return label_base; + } + if (group == 5) + { + // all tpc layers and all sectors, assign layer 7 and sensor 0 to all layers and sensors + label_base += 7 * 1000000 + 0; + return label_base; + } + } + else + { + if (group == 6) + { + // every tile has different label + int tile = sensor; + label_base += layer * 1000000 + tile * 10000 + sensor * 10; + return label_base; + } + if (group == 7) + { + // assign layer 55 and tile 0 to all + label_base += 55 * 1000000 + 0; + return label_base; + } + } + + return -1; +} + +void AlignmentDefs::printBuffers(int index, Acts::Vector2 residual, Acts::Vector2 clus_sigma, float lcl_derivative[], float glbl_derivative[], int glbl_label[]) +{ + std::cout << " float buffer: " + << " residual " + << " " << residual(index); + for (int il = 0; il < NLC; ++il) + { + if (lcl_derivative[il] != 0) std::cout << " lcl_deriv[" << il << "] " << lcl_derivative[il] << " "; + } + std::cout << " sigma " + << " " << clus_sigma(index) << " "; + for (int ig = 0; ig < NGL; ++ig) + { + if (glbl_derivative[ig] != 0) std::cout << " glbl_deriv[" << ig << "] " << glbl_derivative[ig] << " "; + } + std::cout << " int buffer: " + << " 0 " + << " 0 " + << " "; // spacer, rmeas placeholder + for (int il = 0; il < NLC; ++il) + { + if (lcl_derivative[il] != 0) std::cout << " lcl_label[" << il << "] " << il + 1 << " "; + } + std::cout << " 0 " + << " "; + for (int ig = 0; ig < NGL; ++ig) + { + if (glbl_derivative[ig] != 0) std::cout << " glbl_label[" << ig << "] " << glbl_label[ig] << " "; + } + std::cout << " end of meas " << std::endl; +} diff --git a/offline/packages/TrackerMillepedeAlignment/AlignmentDefs.h b/offline/packages/TrackerMillepedeAlignment/AlignmentDefs.h new file mode 100644 index 0000000000..3c2c704b7b --- /dev/null +++ b/offline/packages/TrackerMillepedeAlignment/AlignmentDefs.h @@ -0,0 +1,45 @@ +#ifndef ALIGNMENTDEFS_H +#define ALIGNMENTDEFS_H + +#include + +namespace AlignmentDefs +{ + enum siliconGrp + { + snsr, + stv, + brrl + }; + enum tpcGrp + { + htst, + sctr, + tp + }; + enum mmsGrp + { + tl, + mm + }; + + static constexpr int NGL = 6; + static constexpr int NLC = 5; + + //! Map relating Acts::VolumeID to sPHENIX layer + static const std::map base_layer_map = {{10, 0}, {12, 3}, {14, 7}, {16, 55}}; + static constexpr int nsensors_stave[7] = {9, 9, 9, 4, 4, 4, 4}; + + int getTpcRegion(int layer); + void getSiliconGlobalLabels(Surface surf, int glbl_label[], siliconGrp grp); + void getTpcGlobalLabels(Surface surf, int glbl_label[], tpcGrp grp); + void getMMGlobalLabels(Surface surf, int glbl_label[], mmsGrp grp); + + int getLabelBase(Acts::GeometryIdentifier id, int group); + + void printBuffers(int index, Acts::Vector2 residual, + Acts::Vector2 clus_sigma, float lcl_derivative[], + float glbl_derivative[], int glbl_label[]); + +} // namespace AlignmentDefs +#endif diff --git a/offline/packages/TrackerMillepedeAlignment/HelicalFitter.cc b/offline/packages/TrackerMillepedeAlignment/HelicalFitter.cc index e3bb89aa27..a6bc1a30dd 100644 --- a/offline/packages/TrackerMillepedeAlignment/HelicalFitter.cc +++ b/offline/packages/TrackerMillepedeAlignment/HelicalFitter.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -99,8 +100,8 @@ int HelicalFitter::process_event(PHCompositeNode*) if(Verbosity() > 0) cout << PHWHERE - << " TPC track map size " << _track_map_tpc->size() - << " Silicon track map size " << _track_map_silicon->size() + << " TPC seed map size " << _track_map_tpc->size() + << " Silicon seed map size " << _track_map_silicon->size() << endl; if(_track_map_silicon->size() == 0 && _track_map_tpc->size() == 0) @@ -120,9 +121,6 @@ int HelicalFitter::process_event(PHCompositeNode*) std::vector global_vec; std::vector cluskey_vec; - - ////getTrackletClusters(tracklet, global_vec, cluskey_vec); // store cluster corrected global positions in a vector - // Get a vector of cluster keys from the tracklet getTrackletClusterList(tracklet, cluskey_vec); // store cluster global positions in a vector @@ -130,12 +128,11 @@ int HelicalFitter::process_event(PHCompositeNode*) correctTpcGlobalPositions( global_vec, cluskey_vec); - ////std::vector fitpars = fitClusters(global_vec, cluskey_vec); // do helical fit std::vector fitpars = TrackFitUtils::fitClusters(global_vec, cluskey_vec); // do helical fit` if(fitpars.size() == 0) continue; // discard this track, not enough clusters to fit - if(Verbosity() > 0) + if(Verbosity() > 1) { std::cout << " Track " << trackid << " radius " << fitpars[0] << " X0 " << fitpars[1]<< " Y0 " << fitpars[2] << " zslope " << fitpars[3] << " Z0 " << fitpars[4] << std::endl; } @@ -143,75 +140,195 @@ int HelicalFitter::process_event(PHCompositeNode*) if(fittpc && fitfulltrack) { // this associates silicon clusters and adds them to the vectors - //unsigned int nsilicon = addSiliconClusters(fitpars, global_vec, cluskey_vec); unsigned int nsilicon = TrackFitUtils::addSiliconClusters(fitpars, dca_cut, _tGeometry, _cluster_map, global_vec, cluskey_vec); if(nsilicon < 3) continue; // discard this TPC seed, did not get a good match to silicon // fit the full track now fitpars.clear(); - ////fitpars = fitClusters(global_vec, cluskey_vec); // do helical fit fitpars = TrackFitUtils::fitClusters(global_vec, cluskey_vec); // do helical fit if(fitpars.size() == 0) continue; // discard this track, fit failed - if(Verbosity() > 0) + if(Verbosity() > 1) { std::cout << " Full track " << trackid << " radius " << fitpars[0] << " X0 " << fitpars[1]<< " Y0 " << fitpars[2] << " zslope " << fitpars[3] << " Z0 " << fitpars[4] << std::endl; } } // get the residuals and derivatives for all clusters + for(unsigned int ivec=0;ivecfindCluster(cluskey); if(!cluster) { continue;} - - // PCA of helix to cluster global position - ////Acts::Vector3 pca = get_helix_pca(fitpars, global); - Acts::Vector3 pca = TrackFitUtils::get_helix_pca(fitpars, global); - if(Verbosity() > 0) {std::cout << " cluster position " << global(0) << " " << global(1) << " " << global(2) - << " pca " << pca(0) << " " << pca(1) << " " << pca(2) << std::endl;} + + unsigned int trkrid = TrkrDefs::getTrkrId(cluskey); + + // What we need now is to find the point on the surface at which the helix would intersect + // If we have that point, we can transform the fit back to local coords + // we have fitpars for the helix, and the cluster key - from which we get the surface + + Surface surf = _tGeometry->maps().getSurface(cluskey, cluster); + Acts::Vector3 fitpoint = get_helix_surface_intersection(surf, fitpars, global); + + // fitpoint is the point where the helical fit intersects the plane of the surface + // Now transform the helix fitpoint to local coordinates to compare with cluster local coordinates + Acts::Vector3 fitpoint_local = surf->transform(_tGeometry->geometry().getGeoContext()).inverse() * (fitpoint * Acts::UnitConstants::cm); + fitpoint_local /= Acts::UnitConstants::cm; + + auto xloc = cluster->getLocalX(); // in cm + auto zloc = cluster->getLocalY(); + if(trkrid == TrkrDefs::tpcId) { zloc = convertTimeToZ(cluskey, cluster); } + //float yloc = 0.0; // Because the fitpoint is on the surface, y will always be zero in local coordinates + + Acts::Vector2 residual(xloc - fitpoint_local(0), zloc - fitpoint_local(1)); + + unsigned int layer = TrkrDefs::getLayer(cluskey_vec[ivec]); + float phi = atan2(global(1), global(0)); + float beta = atan2(global(2), sqrt(pow(global(0),2) + pow(global(1),2))); - // capture residuals in the form of (data - fit) - auto residual = global - pca; + if(Verbosity() > 1) { + Acts::Vector3 loc_check = surf->transform(_tGeometry->geometry().getGeoContext()).inverse() * (global * Acts::UnitConstants::cm); + loc_check /= Acts::UnitConstants::cm; + std::cout << " layer " << layer << std::endl + << " cluster global " << global(0) << " " << global(1) << " " << global(2) << std::endl + << " fitpoint " << fitpoint(0) << " " << fitpoint(1) << " " << fitpoint(2) << std::endl + << " fitpoint_local " << fitpoint_local(0) << " " << fitpoint_local(1) << " " << fitpoint_local(2) << std::endl + << " cluster local x " << cluster->getLocalX() << " cluster local y " << cluster->getLocalY() << std::endl + << " cluster global to local x " << loc_check(0) << " local y " << loc_check(1) << " local z " << loc_check(2) << std::endl + << " cluster local residual x " << residual(0) << " cluster local residual y " <maps().getSurface(cluskey, cluster); - int glbl_label[NGL]; - getGlobalLabels(surf, glbl_label); // these depend on the sensor grouping + int glbl_label[AlignmentDefs::NGL]; + if(layer < 7) + { + AlignmentDefs::getSiliconGlobalLabels(surf, glbl_label, si_grp); + } + else if (layer < 55) + { + AlignmentDefs::getTpcGlobalLabels(surf, glbl_label, tpc_grp); + } + else if (layer < 57) + { + AlignmentDefs::getMMGlobalLabels(surf, glbl_label, mms_grp); + } - float lcl_derivative[NLC]; - float glbl_derivative[NGL]; - unsigned int crossing = 0; + // These derivatives are for the local parameters // The angleDerivs dimensions are [alpha/beta/gamma](x/y/z) - std::vector angleDerivs = getDerivativesAlignmentAngles(global, cluskey, cluster, surf, crossing); + //std::vector angleDerivs = getDerivativesAlignmentAngles(global, cluskey, cluster); + //std::vector translDerivs = getDerivativesAlignmentTranslations(global, cluskey, cluster); + + float lcl_derivativeX[AlignmentDefs::NLC]; + float lcl_derivativeY[AlignmentDefs::NLC]; + + getLocalDerivativesXY(surf, global, fitpars, lcl_derivativeX, lcl_derivativeY, layer); + + float glbl_derivativeX[AlignmentDefs::NGL]; + float glbl_derivativeY[AlignmentDefs::NGL]; + getGlobalDerivativesXY(surf, global, fitpoint, fitpars, glbl_derivativeX, glbl_derivativeY, layer); + + for(unsigned int i = 0; i < AlignmentDefs::NGL; ++i) + { + if( is_layer_param_fixed(layer, i) || is_layer_fixed(layer) ) + { + glbl_derivativeX[i] = 0; + glbl_derivativeY[i] = 0; + } + + if(trkrid == TrkrDefs::tpcId) + { + unsigned int sector = TpcDefs::getSectorId(cluskey_vec[ivec]); + unsigned int side = TpcDefs::getSide(cluskey_vec[ivec]); + if(is_tpc_sector_fixed(layer, sector, side)) + { + //if(i==0) std::cout << " param " << i << " layer " << layer << " sector " << sector << " side " << side << std::endl; + glbl_derivativeX[i] = 0; + glbl_derivativeY[i] = 0; + } + } + } // Add the measurement separately for each coordinate direction to Mille // set the derivatives non-zero only for parameters we want to be optimized - unsigned int layer = TrkrDefs::getLayer(cluskey_vec[ivec]); - getLocalDerivativesX(pca, fitpars, lcl_derivative); - getGlobalDerivativesX(angleDerivs, glbl_derivative, layer); - if(Verbosity() > 3) - { std::cout << "layer " << layer << " X buffers:" << std::endl; printBuffers(0, residual, clus_sigma, lcl_derivative, glbl_derivative, glbl_label); } - if( !isnan(residual(0)) && clus_sigma(0) < 1.0) // discards crazy clusters - { _mille->mille(NLC, lcl_derivative, NGL, glbl_derivative, glbl_label, residual(0), clus_sigma(0));} + // local parameter numbering is arbitrary: + float errinf = 1.0; - getLocalDerivativesY(pca, fitpars, lcl_derivative); - getGlobalDerivativesY(angleDerivs, glbl_derivative, layer); - if(Verbosity() > 3) - { std::cout << "layer " << layer << " Y buffers:" << std::endl; printBuffers(1, residual, clus_sigma, lcl_derivative, glbl_derivative, glbl_label); } - if( !isnan(residual(1)) && clus_sigma(1) < 1.0) // discards crazy clusters - {_mille->mille(NLC, lcl_derivative, NGL, glbl_derivative, glbl_label, residual(1), clus_sigma(1));} + if(_layerMisalignment.find(layer) != _layerMisalignment.end()) + { + errinf = _layerMisalignment.find(layer)->second; + } - unsigned int trkrid = TrkrDefs::getTrkrId(cluskey); - getLocalDerivativesZ(pca, lcl_derivative); - getGlobalDerivativesZ(angleDerivs, glbl_derivative, layer); - if(Verbosity() > 3) - { std::cout << "layer " << layer << " Z buffers:" << std::endl; printBuffers(2, residual, clus_sigma, lcl_derivative, glbl_derivative, glbl_label); } - if(!isnan(residual(2)) && clus_sigma(2) < 1.0 && trkrid != TrkrDefs::inttId) - {_mille->mille(NLC, lcl_derivative, NGL, glbl_derivative, glbl_label, residual(2), clus_sigma(2));} + // provides output that can be grep'ed to make plots of input to mille + if(Verbosity() > 1) + { + if(layer < 7) + { + // radius = fitpars[0], X0 = fitpars[1], Y0 = fitpars[2], zslope = fitpars[3], Z0 = fitpars[4] + std::cout << "Local residualsX: layer " << layer << " phi " << phi * 180 / M_PI << " beta " << beta * 180.90 / M_PI + << " dxloc " << residual(0) << " error " << clus_sigma(0) << " inflation_factor " << errinf + << " xloc " << xloc << " fitxloc " << fitpoint_local(0) + << " zglob " << global(2) << " fitzglob " << fitpoint(2) + << " xglob " << global(0) << " fitxglob " << fitpoint(0) + << " yglob " << global(1) << " fityglob " << fitpoint(1) + << " dzloc " << residual(1) + << " X0 " << fitpars[1] << " Y0 " << fitpars[2] + << " derivx R " << lcl_derivativeX[0] << " label " << 1 + << " derivx X0 " << lcl_derivativeX[1] << " label " << 2 + << " derivx Y0 " << lcl_derivativeX[2] << " label " << 3 + << " derivx Zslope " << lcl_derivativeX[3] << " label " << 4 + << " derivx Z0 " << lcl_derivativeX[4] << " label " << 5 + << " glblderivX alpha " << glbl_derivativeX[0] << " label " << glbl_label[0] + << " glblderivX beta " << glbl_derivativeX[1] << " label " << glbl_label[1] + << " glblderivX gamma " << glbl_derivativeX[2] << " label " << glbl_label[2] + << " glblderivX xtrans " << glbl_derivativeX[3] << " label " << glbl_label[3] + << " glblderivX ytrans " << glbl_derivativeX[4] << " label " << glbl_label[4] + << " glblderivX ztrans " << glbl_derivativeX[5] << " label " << glbl_label[5] + << std::endl; + } + } + + if( !isnan(residual(0)) && clus_sigma(0) < 1.0) // discards crazy clusters + { + _mille->mille(AlignmentDefs::NLC, lcl_derivativeX, AlignmentDefs::NGL, glbl_derivativeX, glbl_label, residual(0), errinf*clus_sigma(0)); + } + + // provides output that can be grep'ed to make plots of input to mille + if(Verbosity() > 1) + { + if(layer < 7) + { + std::cout << "Local residualsY: layer " << layer << " phi " << phi * 180 / M_PI << " beta " << beta * 180.90 / M_PI + << " dzloc " << residual(1) << " error " << clus_sigma(1) << " inflation_factor " << errinf + << " zloc " << zloc << " fitzloc " << fitpoint_local(1) + << " zglob " << global(2) << " fitzglob " << fitpoint(2) + << " xglob " << global(0) << " fitxglob " << fitpoint(0) + << " yglob " << global(1) << " fityglob " << fitpoint(1) + << " dxloc " << residual(0) + << " zslope " << fitpars[3] << " Z0 " << fitpars[4] + << " derivy R " << lcl_derivativeY[0] << " label " << 1 + << " derivy X0 " << lcl_derivativeY[1] << " label " << 2 + << " derivy Y0 " << lcl_derivativeY[2] << " label " << 3 + << " derivy Zslope " << lcl_derivativeY[3] << " label " << 4 + << " derivy Z0 " << lcl_derivativeY[4] << " label " << 5 + << " glblderivY alpha " << glbl_derivativeY[0] << " label " << glbl_label[0] + << " glblderivY beta " << glbl_derivativeY[1] << " label " << glbl_label[1] + << " glblderivY gamma " << glbl_derivativeY[2] << " label " << glbl_label[2] + << " glblderivY xtrans " << glbl_derivativeY[3] << " label " << glbl_label[3] + << " glblderivY ytrans " << glbl_derivativeY[4] << " label " << glbl_label[4] + << " glblderivY ztrans " << glbl_derivativeY[5] << " label " << glbl_label[5] + << std::endl; + } + } + + if(!isnan(residual(1)) && clus_sigma(1) < 1.0 && trkrid != TrkrDefs::inttId) + { + _mille->mille(AlignmentDefs::NLC, lcl_derivativeY, AlignmentDefs::NGL, glbl_derivativeY, glbl_label, residual(1), errinf*clus_sigma(1)); + } } // close out this track @@ -221,6 +338,112 @@ int HelicalFitter::process_event(PHCompositeNode*) return Fun4AllReturnCodes::EVENT_OK; } + +Acts::Vector3 HelicalFitter::get_helix_surface_intersection(Surface surf, std::vector& fitpars, Acts::Vector3 global) +{ + // we want the point where the helix intersects the plane of the surface + + // get the plane of the surface + Acts::Vector3 sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) * 0.1; // convert to cm + Acts::Vector3 sensorNormal = -surf->normal(_tGeometry->geometry().getGeoContext()); + sensorNormal /= sensorNormal.norm(); + + // there are analytic solutions for a line-plane intersection. + // to use this, need to get the vector tangent to the helix near the measurement and a point on it. + std::pair line = get_helix_tangent(fitpars, global); + Acts::Vector3 pca = line.first; + Acts::Vector3 tangent = line.second; + + // std::cout << " pca: " << pca(0) << " " << pca(1) << " " << pca(2) << " " << std::endl; + + Acts::Vector3 intersection = get_line_plane_intersection(pca, tangent, sensorCenter, sensorNormal); + + return intersection; +} + +Acts::Vector3 HelicalFitter::get_line_plane_intersection(Acts::Vector3 PCA, Acts::Vector3 tangent, Acts::Vector3 sensor_center, Acts::Vector3 sensor_normal) +{ + // get the intersection of the line made by PCA and tangent with the plane of the sensor + + // For a point on the line + // p = PCA + d * tangent; + // for a point on the plane + // (p - sensor_center).sensor_normal = 0 + + // The solution is: + float d = (sensor_center - PCA).dot(sensor_normal) / tangent.dot(sensor_normal); + Acts::Vector3 intersection = PCA + d * tangent; + /* + std::cout << " intersection: " << intersection(0) << " " << intersection(1) << " " << intersection(2) << " " << std::endl; + std::cout << " sensor_center: " << sensor_center(0) << " " << sensor_center(1) << " " << sensor_center(2) << " " << std::endl; + std::cout << " sensor_normal: " << sensor_normal(0) << " " << sensor_normal(1) << " " << sensor_normal(2) << " " << std::endl; + */ + return intersection; +} + + +std::pair HelicalFitter::get_helix_tangent(const std::vector& fitpars, Acts::Vector3 global) +{ + // no analytic solution for the coordinates of the closest approach of a helix to a point + // Instead, we get the PCA in x and y to the circle, and the PCA in z to the z vs R line at the R of the PCA + + float radius = fitpars[0]; + float x0 = fitpars[1]; + float y0 = fitpars[2]; + float zslope = fitpars[3]; + float z0 = fitpars[4]; + + Acts::Vector2 pca_circle = get_circle_point_pca(radius, x0, y0, global); + + // The radius of the PCA determines the z position: + float pca_circle_radius = pca_circle.norm(); // radius of the PCA of the circle to the point + float pca_z = pca_circle_radius * zslope + z0; + Acts::Vector3 pca(pca_circle(0), pca_circle(1), pca_z); + + // now we want a second point on the helix so we can get a local straight line approximation to the track + // Get the angle of the PCA relative to the fitted circle center + float angle_pca = atan2(pca_circle(1) - y0, pca_circle(0) - x0); + // calculate coords of a point at a slightly larger angle + float d_angle = 0.005; + float newx = radius * cos(angle_pca + d_angle) + x0; + float newy = radius * sin(angle_pca + d_angle) + y0; + float newz = sqrt(newx*newx+newy*newy) * zslope + z0; + Acts::Vector3 second_point_pca(newx, newy, newz); + + // pca and second_point_pca define a straight line approximation to the track + Acts::Vector3 tangent = (second_point_pca - pca) / (second_point_pca - pca).norm(); + + // get the PCA of the cluster to that line + Acts::Vector3 final_pca = getPCALinePoint(global, tangent, pca); + + if(Verbosity() > 2) + { + // different method for checking: + // project the circle PCA vector an additional small amount and find the helix PCA to that point + float projection = 0.25; // cm + Acts::Vector3 second_point = pca + projection * pca/pca.norm(); + Acts::Vector2 second_point_pca_circle = get_circle_point_pca(radius, x0, y0, second_point); + float second_point_pca_z = second_point_pca_circle.norm() * zslope + z0; + Acts::Vector3 second_point_pca2(second_point_pca_circle(0), second_point_pca_circle(1), second_point_pca_z); + Acts::Vector3 tangent2 = (second_point_pca2 - pca) / (second_point_pca2 - pca).norm(); + Acts::Vector3 final_pca2 = getPCALinePoint(global, tangent2, pca); + + std::cout << " getting tangent at angle_pca: " << angle_pca * 180.0 / M_PI << std::endl + << " pca " << pca(0) << " " << pca(1) << " " << pca(2) << std::endl + << " second_point " << second_point_pca(0) << " " << second_point_pca(1) << " " << second_point_pca(2) << std::endl + << " tangent " << tangent(0) << " " << tangent(1) << " " << tangent(2) << std::endl + << " final_pca " << final_pca(0) << " " << final_pca(1) << " " << final_pca(2) << std::endl + << " second_point2 " << second_point_pca2(0) << " " << second_point_pca2(1) << " " << second_point_pca2(2) << std::endl + << " tangent2 " << tangent2(0) << " " << tangent2(1) << " " << tangent2(2) << std::endl + << " final_pca2 " << final_pca2(0) << " " << final_pca2(1) << " " << final_pca2(2) + << std::endl; + } + + + std::pair line = std::make_pair(final_pca, tangent); + + return line; +} int HelicalFitter::End(PHCompositeNode* ) { @@ -298,113 +521,6 @@ Acts::Vector2 HelicalFitter::get_circle_point_pca(float radius, float x0, float return pca; } -std::vector HelicalFitter::getDerivativesAlignmentAngles(Acts::Vector3& global, TrkrDefs::cluskey cluster_key, TrkrCluster* cluster, Surface surface, int crossing) -{ - // The value of global is from the geocontext transformation - // we add to that transformation a small rotation around the relevant axis in the surface frame - - std::vector derivs_vector; - - // get the transformation from the geocontext - Acts::Transform3 transform = surface->transform(_tGeometry->geometry().getGeoContext()); - - // Make an additional transform that applies a small rotation angle in the surface frame - for(unsigned int iangle = 0; iangle < 3; ++iangle) - { - // creates transform that adds a perturbation rotation around one axis, uses it to estimate derivative wrt perturbation rotation - - unsigned int trkrId = TrkrDefs::getTrkrId(cluster_key); - unsigned int layer = TrkrDefs::getLayer(cluster_key); - - Acts::Vector3 derivs(0,0,0); - Eigen::Vector3d theseAngles(0,0,0); - theseAngles[iangle] = sensorAngles[iangle]; // set the one we want to be non-zero - - Acts::Vector3 keeper(0,0,0); - for(int ip = 0; ip < 2; ++ip) - { - if(ip == 1) { theseAngles[iangle] *= -1; } // test both sides of zero - - if(Verbosity() > 1) - { std::cout << " trkrId " << trkrId << " layer " << layer << " cluster_key " << cluster_key - << " sensorAngles " << theseAngles[0] << " " << theseAngles[1] << " " << theseAngles[2] << std::endl; } - - Acts::Transform3 perturbationTransformation = makePerturbationTransformation(theseAngles); - Acts::Transform3 overallTransformation = transform * perturbationTransformation; - - // transform the cluster local position to global coords with this additional rotation added - auto x = cluster->getLocalX() * 10; // mm - auto y = cluster->getLocalY() * 10; - if(trkrId == TrkrDefs::tpcId) { y = convertTimeToZ(cluster_key, cluster); } - - Eigen::Vector3d clusterLocalPosition (x,y,0); // follows the convention for the acts transform of local = (x,z,y) - Eigen::Vector3d finalCoords = overallTransformation*clusterLocalPosition; // result in mm - finalCoords /= 10.0; // convert mm back to cm - - // have to add corrections for TPC clusters after transformation to global - if(trkrId == TrkrDefs::tpcId) { makeTpcGlobalCorrections(cluster_key, crossing, global); } - - // note that global cancels out here - if(ip == 0) - { - keeper(0) = (finalCoords(0) - global(0)); - keeper(1) = (finalCoords(1) - global(1)); - keeper(2) = (finalCoords(2) - global(2)); - } - else - { - keeper(0) -= (finalCoords(0) - global(0)); - keeper(1) -= (finalCoords(1) - global(1)); - keeper(2) -= (finalCoords(2) - global(2)); - } - - if(Verbosity() > 1) - { - std::cout << " finalCoords(0) " << finalCoords(0) << " global(0) " << global(0) << " finalCoords(1) " << finalCoords(1) - << " global(1) " << global(1) << " finalCoords(2) " << finalCoords(2) << " global(2) " << global(2) << std::endl; - std::cout << " keeper now: keeper(0) " << keeper(0) << " keeper(1) " << keeper(1) << " keeper(2) " << keeper(2) << std::endl; - } - } - - // derivs vector contains: - // (dx/dalpha, dy/dalpha, dz/dalpha) (for iangle = 0) - // (dx/dbeta, dy/dbeta, dz/dbeta) (for iangle = 1) - // (dx/dgamma, dy/dgamma, dz/dgamma) (for iangle = 2) - - // Average the changes to get the estimate of the derivative - derivs(0) = keeper(0) / (2.0 * fabs(theseAngles[iangle])); - if( isnan(derivs(0)) ) { derivs(0) = 0; } - derivs(1) = keeper(1) / (2.0 * fabs(theseAngles[iangle])); - if( isnan(derivs(1)) ) { derivs(1) = 0; } - derivs(2) = keeper(2) / (2.0 * fabs(theseAngles[iangle])); - if( isnan(derivs(2)) ) { derivs(2) = 0; } - derivs_vector.push_back(derivs); - - if(Verbosity() > 1) { std::cout << " derivs(0) " << derivs(0) << " derivs(1) " << derivs(1) << " derivs(2) " << derivs(2) << std::endl; } - } - - return derivs_vector; -} - - Acts::Transform3 HelicalFitter::makePerturbationTransformation(Acts::Vector3 angles) - { - // Note: Here beta is apllied to the z axis and gamma is applied to the y axis because the geocontext transform - // will flip those axes when transforming to global coordinates - Eigen::AngleAxisd alpha(angles(0), Eigen::Vector3d::UnitX()); - Eigen::AngleAxisd beta(angles(2), Eigen::Vector3d::UnitY()); - Eigen::AngleAxisd gamma(angles(1), Eigen::Vector3d::UnitZ()); - Eigen::Quaternion q = gamma*beta*alpha; - Eigen::Matrix3d perturbationRotation = q.matrix(); - - // combine rotation and translation into an affine matrix - Eigen::Vector3d nullTranslation(0,0,0); - Acts::Transform3 perturbationTransformation; - perturbationTransformation.linear() = perturbationRotation; - perturbationTransformation.translation() = nullTranslation; - - return perturbationTransformation; - } - float HelicalFitter::convertTimeToZ(TrkrDefs::cluskey cluster_key, TrkrCluster *cluster) { // must convert local Y from cluster average time of arival to local cluster z position @@ -414,7 +530,7 @@ float HelicalFitter::convertTimeToZ(TrkrDefs::cluskey cluster_key, TrkrCluster * double zloc = surfCenterZ - zdriftlength; // converts z drift length to local z position in the TPC in north unsigned int side = TpcDefs::getSide(cluster_key); if(side == 0) zloc = -zloc; - float z = zloc * 10.0; + float z = zloc; // in cm return z; } @@ -432,109 +548,8 @@ void HelicalFitter::makeTpcGlobalCorrections(TrkrDefs::cluskey cluster_key, shor if(_dcc_fluctuation) { global = _distortionCorrection.get_corrected_position( global, _dcc_fluctuation ); } } -void HelicalFitter::getGlobalLabels(Surface surf, int glbl_label[]) -{ - // identify the global alignment parameters for this surface - Acts::GeometryIdentifier id = surf->geometryId(); - int label_base = getLabelBase(id); // This value depends on how the surfaces are grouped - for(int i=0;i 1) - { std::cout << " glbl " << i << " label " << glbl_label[i] << " "; } - } - if(Verbosity() > 1) { std::cout << std::endl; } -} -int HelicalFitter::getTpcRegion(int layer) -{ - int region = 0; - if(layer > 23 && layer < 39) - region = 1; - if(layer > 38 && layer < 55) - region = 2; - - return region; -} - -int HelicalFitter::getLabelBase(Acts::GeometryIdentifier id) -{ - unsigned int volume = id.volume(); - unsigned int acts_layer = id.layer(); - unsigned int layer = base_layer_map.find(volume)->second + acts_layer / 2 -1; - unsigned int sensor = id.sensitive() - 1; // Acts starts at 1 - - int label_base = 1; // Mille wants to start at 1 - - // decide what level of grouping we want - if(layer < 7) - { - if(si_grp == siliconGrp::snsr) - { - // every sensor has a different label - int stave = sensor / nsensors_stave[layer]; - label_base += layer*1000000 + stave*10000 + sensor*10; - return label_base; - } - if(si_grp == siliconGrp::stv) - { - // layer and stave, assign all sensors to the stave number - int stave = sensor / nsensors_stave[layer]; - label_base += layer*1000000 + stave*10000; - return label_base; - } - if(si_grp == siliconGrp::brrl) - // layer only, assign all sensors to sensor 0 - label_base += layer*1000000 + 0; - return label_base; - } - else if(layer > 6 && layer < 55) - { - if(tpc_grp == tpcGrp::htst) - { - // want every hitset (layer, sector, side) to have a separate label - // each group of 12 subsurfaces (sensors) is in a single hitset - int hitset = sensor/12; // 0-11 on side 0, 12-23 on side 1 - label_base += layer*1000000 + hitset*10000; - return label_base; - } - if(tpc_grp == tpcGrp::sctr) - { - // group all tpc layers in each region and sector, assign layer 7 and side and sector number to all layers and hitsets - int side = sensor / 144; // 0-143 on side 0, 144-287 on side 1 - int sector = (sensor - side *144) / 12; - // for a given layer there are only 12 sectors x 2 sides - // The following gives the sectors in the inner, mid, outer regions unique group labels - int region = getTpcRegion(layer); // inner, mid, outer - label_base += 7*1000000 + (region * 24 + side*12 + sector) *10000; - return label_base; - } - if(tpc_grp == tpcGrp::tp) - { - // all tpc layers and all sectors, assign layer 7 and sensor 0 to all layers and sensors - label_base += 7*1000000 + 0; - return label_base; - } - } - else - { - if(mms_grp == mmsGrp::tl) - { - // every tile has different label - int tile = sensor; - label_base += layer*1000000 + tile*10000+sensor*10; - return label_base; - } - if(mms_grp == mmsGrp::mm) - { - // assign layer 55 and tile 0 to all - label_base += 55*1000000 + 0; - return label_base; - } - } - return -1; -} // this method to be replaced by calls to TrackFitUtils void HelicalFitter::getTrackletClusters(TrackSeed *tracklet, std::vector& global_vec, std::vector& cluskey_vec) @@ -573,15 +588,14 @@ std::vector HelicalFitter::fitClusters(std::vector& global return TrackFitUtils::fitClusters(global_vec, cluskey_vec); // do helical fit } -Acts::Vector3 HelicalFitter::getClusterError(TrkrCluster *cluster, TrkrDefs::cluskey cluskey, Acts::Vector3& global) +Acts::Vector2 HelicalFitter::getClusterError(TrkrCluster *cluster, TrkrDefs::cluskey cluskey, Acts::Vector3& global) { - Acts::Vector3 clus_sigma(0,0,0); + Acts::Vector2 clus_sigma(0,0); if(_cluster_version==3) { - clus_sigma(2) = cluster->getZError(); - clus_sigma(0) = cluster->getRPhiError() / sqrt(2); - clus_sigma(1) = cluster->getRPhiError() / sqrt(2); + clus_sigma(1) = cluster->getZError(); + clus_sigma(0) = cluster->getRPhiError(); } else if(_cluster_version==4) { @@ -589,143 +603,162 @@ Acts::Vector3 HelicalFitter::getClusterError(TrkrCluster *cluster, TrkrDefs::clu auto para_errors = _ClusErrPara.get_simple_cluster_error(cluster,clusRadius,cluskey); float exy2 = para_errors.first * Acts::UnitConstants::cm2; float ez2 = para_errors.second * Acts::UnitConstants::cm2; - clus_sigma(2) = sqrt(ez2); - clus_sigma(0) = sqrt(exy2 / 2.0); - clus_sigma(1) = sqrt(exy2 / 2.0); + clus_sigma(1) = sqrt(ez2); + clus_sigma(0) = sqrt(exy2); } else if(_cluster_version == 5) { - clus_sigma(2) = cluster->getZError(); - clus_sigma(0) = cluster->getRPhiError() / sqrt(2); - clus_sigma(1) = cluster->getRPhiError() / sqrt(2); + double clusRadius = sqrt(global[0]*global[0] + global[1]*global[1]); + TrkrClusterv5* clusterv5 = dynamic_cast(cluster); + auto para_errors = _ClusErrPara.get_clusterv5_modified_error(clusterv5,clusRadius,cluskey); + double phierror = sqrt(para_errors.first); + double zerror = sqrt(para_errors.second); + clus_sigma(1) = zerror; + clus_sigma(0) = phierror; } return clus_sigma; } -void HelicalFitter::getLocalDerivativesX(Acts::Vector3& pca, std::vector& fitpars, float lcl_derivative[5]) +// new one +void HelicalFitter::getLocalDerivativesXY(Surface surf, Acts::Vector3 global, const std::vector& fitpars, float lcl_derivativeX[5], float lcl_derivativeY[5], unsigned int layer) { - float radius = fitpars[0]; - float x0 = fitpars[1]; - float y0 = fitpars[2]; - - float x_x0 = 1.0; - // dx/dradius = radius / (R^2 - (y-y0)^2)^1/2 , sign of (x-x0)/fabs(x-x0) - float x_radius = ( pca(0)-x0 ) / fabs( pca(0)-x0 ) * radius / sqrt(radius*radius - (pca(1) - y0 ) * (pca(1) - y0 ) ); - if(Verbosity() > 0) {std::cout << " x derivatives: x_x0 " << x_x0 << " x_radius " << x_radius << std::endl;} - if(isnan(x_radius)) {x_radius = 0.0; } - // dx/dy0 = (y-y0) / (R^2 - (y-y0)^2)^1/2 - float x_y0 = (pca(1) - y0) / sqrt(radius*radius - (pca(1) - y0) * (pca(1) - y0)); - if(isnan(x_y0)) {x_y0 = 0.0; } - - for(int i=0;i<5;++i) {lcl_derivative[i] = 0.0;} - lcl_derivative[0] = x_x0; - lcl_derivative[1] = x_y0; - lcl_derivative[3] = x_radius; -} + // Calculate the derivatives of the residual wrt the track parameters numerically + std::vector temp_fitpars; -void HelicalFitter::getLocalDerivativesY(Acts::Vector3& pca, std::vector& fitpars, float lcl_derivative[5]) -{ - float radius = fitpars[0]; - float x0 = fitpars[1]; - float y0 = fitpars[2]; - - float y_y0 = 1.0; - // dy/dradius = sign * radius / (R^2 - (x-x0)^2)^1/2 , sign of (y-y0)/fabs(y-y0) - float y_radius = ( pca(1)-y0 ) / fabs( pca(1)-y0 ) * radius / sqrt(radius*radius - (pca(0) - x0 ) * (pca(0) - x0 ) ); - if(Verbosity() > 0) { std::cout << " y derivatives: y_y0 " << y_y0 << " y_radius " << y_radius << std::endl; } - if(isnan(y_radius)) {y_radius = 0.0; } - // dy/dx0 = (x-x0) / (R^2 - (x-x0)^2)^1/2 - float y_x0 = (pca(0) - x0) / sqrt(radius*radius - (pca(0) - x0) * (pca(0) - x0)); - if(isnan(y_x0)) {y_x0 = 0.0; } - - for(int i=0;i fitpars_delta; + fitpars_delta.push_back(0.1); // radius, cm + fitpars_delta.push_back(0.1); // X0, cm + fitpars_delta.push_back(0.1); // Y0, cm + fitpars_delta.push_back(0.1); // zslope, cm + fitpars_delta.push_back(0.1); // Z0, cm -void HelicalFitter::getLocalDerivativesZ(Acts::Vector3& global, float lcl_derivative[5]) -{ - // z = z0 + zslope * cluster_radius - float cluster_radius = sqrt(global(0)*global(0)+global(1)*global(1)); - float z_zslope = cluster_radius; - float z_z0 = 1.0; - if(Verbosity() > 0) {std::cout << " z derivatives: z_zslope " << z_zslope << " z_z0 " << z_z0 << std::endl;} - - for(int i=0;i angleDerivs, float glbl_derivative[], unsigned int layer) -{ - // x - relevant global pars are alpha, beta, gamma, dx (ipar 0,1,2,3), relevant local pars are x_x0, x_radius - for(int i=0;i tangent = get_helix_tangent(fitpars, global) + std::pair tangent = get_helix_tangent(fitpars, global); // should this be global, not fitpoint? + + Acts::Vector3 projX(0,0,0), projY(0,0,0); + get_projectionXY(surf, tangent, projX, projY); + + + Acts::Vector3 intersection = get_helix_surface_intersection(surf, temp_fitpars, global); + + // loop over the track fit parameters + for(unsigned int ip = 0; ip < fitpars.size(); ++ip) { - glbl_derivative[3] = 1.0; // optimize dx - glbl_derivative[0] = angleDerivs[0](0); // dx/dalpha - glbl_derivative[1] = angleDerivs[1](0); // dx/dbeta - glbl_derivative[2] = angleDerivs[2](0); // dx/dgamma + temp_fitpars[ip] += fitpars_delta[ip]; - for(int i=0; i< NGL; ++i) + Acts::Vector3 temp_intersection = get_helix_surface_intersection(surf, temp_fitpars, global); + Acts::Vector3 intersection_delta = temp_intersection - intersection; + if(Verbosity() > 1) { - if(is_layer_param_fixed(layer,i)) - {glbl_derivative[i] = 0.0;} + std::cout << "Layer " << layer << " local parameter " << ip << ":" << std::endl; + std::cout << " intersection " << intersection(0) << " " << intersection(1) << " " << intersection(2) << std::endl; + std::cout << " temp_intersection " << temp_intersection(0) << " "<< temp_intersection(1) << " "<< temp_intersection(2)<< std::endl; + std::cout << " intersection_delta " << intersection_delta(0) << " " << intersection_delta(1) << " " << intersection_delta(2) << std::endl; } + + + // convert to delta-intersection / delta-parameter + intersection_delta /= fitpars_delta[ip]; + + if(Verbosity() > 1) + {std::cout << " intersection_delta / delta_p " << intersection_delta(0) << " " << intersection_delta(1) << " " << intersection_delta(2) << std::endl;} + + // calculate the change in residual for X and Y + lcl_derivativeX[ip] = intersection_delta.dot(projX); + lcl_derivativeY[ip] = intersection_delta.dot(projY); + if(Verbosity() > 1) + {std::cout << " ip " << ip << " derivativeX " << lcl_derivativeX[ip] << " " << " derivativeY " << lcl_derivativeY[ip] << std::endl;} + + temp_fitpars[ip] = fitpars[ip]; } } -void HelicalFitter::getGlobalDerivativesY( std::vector angleDerivs, float glbl_derivative[], unsigned int layer) +void HelicalFitter::getGlobalDerivativesXY(Surface surf, Acts::Vector3 global, Acts::Vector3 fitpoint, const std::vector& fitpars, float glbl_derivativeX[6], float glbl_derivativeY[6], unsigned int layer) { - // y - relevant global pars are alpha, beta, gamma, dy (ipar 0,1,2,4) - for(int i=0;i tangent = get_helix_tangent(fitpars, global); // should this be global, not fitpoint? + + Acts::Vector3 projX(0,0,0), projY(0,0,0); + get_projectionXY(surf, tangent, projX, projY); + + // translations + + glbl_derivativeX[3] = unitx.dot(projX); + glbl_derivativeX[4] = unity.dot(projX); + glbl_derivativeX[5] = unitz.dot(projX); + + glbl_derivativeY[3] = unitx.dot(projY); + glbl_derivativeY[4] = unity.dot(projY); + glbl_derivativeY[5] = unitz.dot(projY); + + // rotations + + // need center of sensor to intersection point + Acts::Vector3 sensorCenter = surf->center(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm; // convert to cm + Acts::Vector3 OM = fitpoint - sensorCenter; + + glbl_derivativeX[0] = (unitx.cross(OM)).dot(projX); + glbl_derivativeX[1] = (unity.cross(OM)).dot(projX); + glbl_derivativeX[2] = (unitz.cross(OM)).dot(projX); + + glbl_derivativeY[0] = (unitx.cross(OM)).dot(projY); + glbl_derivativeY[1] = (unity.cross(OM)).dot(projY); + glbl_derivativeY[2] = (unitz.cross(OM)).dot(projY); + + if(Verbosity() > 1) { - glbl_derivative[4] = 1.0; // optimize dy - glbl_derivative[0] = angleDerivs[0](1); // dy/dalpha - glbl_derivative[1] = angleDerivs[1](1); // dy/dbeta - glbl_derivative[2] = angleDerivs[2](1); // dy/dgamma + std::cout << " glbl_derivativesX for layer " << layer << std::endl; + for(unsigned int i = 0; i < 6; ++i) + { + std::cout << " i " << i << " glbl_derivative " << glbl_derivativeX[i] << std::endl; + } - for(int i=0; i< NGL; ++i) + std::cout << " glbl_derivativesY for layer " << layer << std::endl; + for(unsigned int i = 0; i < 6; ++i) { - if(is_layer_param_fixed(layer,i)) - {glbl_derivative[i] = 0.0;} + std::cout << " i " << i << " glbl_derivative " << glbl_derivativeY[i] << std::endl; } } -} -void HelicalFitter::getGlobalDerivativesZ( std::vector angleDerivs, float glbl_derivative[], unsigned int layer) -{ - // z - relevant global pars are alpha, beta, dz (ipar 0,1,5) - for(int i=0;i tangent, Acts::Vector3& projX, Acts::Vector3& projY) { - std::cout << " float buffer: " << " residual " << " " << residual(index); - for (int il=0;ilcenter(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm; // convert to cm + // sensorNormal is the Z vector + Acts::Vector3 Z = -surf->normal(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm; + + // get surface X and Y unit vectors in global frame + // transform Xlocal = 1.0 to global, subtract the surface center, normalize to 1 + Acts::Vector3 xloc(1.0,0.0,0.0); + Acts::Vector3 xglob = surf->transform(_tGeometry->geometry().getGeoContext()) * (xloc * Acts::UnitConstants::cm); + xglob /= Acts::UnitConstants::cm; + Acts::Vector3 yloc(0.0,1.0,0.0); + Acts::Vector3 yglob = surf->transform(_tGeometry->geometry().getGeoContext()) * (yloc * Acts::UnitConstants::cm); + yglob /= Acts::UnitConstants::cm; + + Acts::Vector3 X = (xglob-sensorCenter) / (xglob-sensorCenter).norm(); + Acts::Vector3 Y = (yglob-sensorCenter) / (yglob-sensorCenter).norm(); + + projX = X - (tanvec.dot(X) / tanvec.dot(Z)) * Z; + projY = Y - (tanvec.dot(Y) / tanvec.dot(Z)) * Z; + + return; } unsigned int HelicalFitter::addSiliconClusters(std::vector& fitpars, std::vector& global_vec, std::vector& cluskey_vec) @@ -748,6 +781,7 @@ unsigned int HelicalFitter::addSiliconClusters(std::vector& fitpars, std: { fixed_layers.insert(layer); } + bool HelicalFitter::is_layer_param_fixed(unsigned int layer, unsigned int param) { @@ -766,6 +800,25 @@ void HelicalFitter::set_layer_param_fixed(unsigned int layer, unsigned int param fixed_layer_params.insert(pair); } +void HelicalFitter::set_tpc_sector_fixed(unsigned int region, unsigned int sector, unsigned int side) + { + // make a combined subsector index + unsigned int subsector = region * 24 + side * 12 + sector; + fixed_sectors.insert(subsector); + } + +bool HelicalFitter::is_tpc_sector_fixed(unsigned int layer, unsigned int sector, unsigned int side) + { + bool ret = false; + unsigned int region = AlignmentDefs::getTpcRegion(layer); + unsigned int subsector = region * 24 + side * 12 + sector; + auto it = fixed_sectors.find(subsector); + if(it != fixed_sectors.end()) + ret = true; + + return ret; + } + void HelicalFitter::correctTpcGlobalPositions(std::vector global_vec, std::vector cluskey_vec) { for(unsigned int iclus=0;iclus #include #include @@ -24,10 +26,6 @@ class TpcDistortionCorrectionContainer; class Mille; class SvtxTrackSeed; -enum siliconGrp {snsr, stv, brrl}; -enum tpcGrp {htst, sctr, tp}; -enum mmsGrp {tl, mm}; - class HelicalFitter : public SubsysReco, public PHParameterInterface { public: @@ -57,14 +55,21 @@ class HelicalFitter : public SubsysReco, public PHParameterInterface void set_datafile_name(const std::string& file) { data_outfilename = file;} void set_steeringfile_name(const std::string& file) { steering_outfilename = file;} - void set_silicon_grouping(int group) {si_grp = (siliconGrp) group;} - void set_tpc_grouping(int group) {tpc_grp = (tpcGrp) group;} - void set_mms_grouping(int group) {mms_grp = (mmsGrp) group;} + void set_silicon_grouping(int group) {si_grp = (AlignmentDefs::siliconGrp) group;} + void set_tpc_grouping(int group) {tpc_grp = (AlignmentDefs::tpcGrp) group;} + void set_mms_grouping(int group) {mms_grp = (AlignmentDefs::mmsGrp) group;} void set_test_output(bool test) {test_output = test;} void set_layer_fixed(unsigned int layer); + void set_tpc_sector_fixed(unsigned int region, unsigned int sector, unsigned int side); void set_layer_param_fixed(unsigned int layer, unsigned int param); void set_cluster_version(unsigned int v) { _cluster_version = v; } + void set_fitted_subsystems(bool si, bool tpc, bool full) { fitsilicon = si; fittpc = tpc; fitfulltrack = full; } + void set_error_inflation_factor(unsigned int layer, float factor) + { + _layerMisalignment.insert(std::make_pair(layer,factor)); + } + // utility functions for analysis modules std::vector fitClusters(std::vector& global_vec, std::vector cluskey_vec); void getTrackletClusters(TrackSeed *_track, std::vector& global_vec, std::vector& cluskey_vec); @@ -82,26 +87,28 @@ class HelicalFitter : public SubsysReco, public PHParameterInterface Acts::Vector3 getPCALinePoint(Acts::Vector3 global, Acts::Vector3 tangent, Acts::Vector3 posref); Acts::Vector2 get_circle_point_pca(float radius, float x0, float y0, Acts::Vector3 global); + Acts::Vector3 get_line_plane_intersection(Acts::Vector3 PCA, Acts::Vector3 tangent, + Acts::Vector3 sensor_center, Acts::Vector3 sensor_normal); + std::pair get_helix_tangent(const std::vector& fitpars, Acts::Vector3 global); + Acts::Vector3 get_helix_surface_intersection(Surface surf, std::vector& fitpars, Acts::Vector3 global); + - int getLabelBase(Acts::GeometryIdentifier id); - Acts::Transform3 makePerturbationTransformation(Acts::Vector3 angles); - std::vector getDerivativesAlignmentAngles(Acts::Vector3& global, TrkrDefs::cluskey cluster_key, TrkrCluster* cluster, Surface surface, int crossing); float convertTimeToZ(TrkrDefs::cluskey cluster_key, TrkrCluster *cluster); void makeTpcGlobalCorrections(TrkrDefs::cluskey cluster_key, short int crossing, Acts::Vector3& global); - int getTpcRegion(int layer); - - Acts::Vector3 getClusterError(TrkrCluster *cluster, TrkrDefs::cluskey cluskey, Acts::Vector3& global); - void getGlobalLabels(Surface surf, int glbl_label[]); - void getLocalDerivativesX(Acts::Vector3& pca, std::vector& fitpars, float lcl_derivative[]); - void getLocalDerivativesY(Acts::Vector3& pca, std::vector& fitpars, float lcl_derivative[]); - void getLocalDerivativesZ(Acts::Vector3& global, float lcl_derivative[]); - void getGlobalDerivativesX( std::vector angleDerivs, float glbl_derivatives[], unsigned int layer); - void getGlobalDerivativesY( std::vector angleDerivs, float glbl_derivatives[], unsigned int layer); - void getGlobalDerivativesZ( std::vector angleDerivs, float glbl_derivatives[], unsigned int layer); - void printBuffers(int index, Acts::Vector3 residual, Acts::Vector3 clus_sigma, float lcl_derivative[], float glbl_derivative[], int glbl_label[]); + + Acts::Vector2 getClusterError(TrkrCluster *cluster, TrkrDefs::cluskey cluskey, Acts::Vector3& global); + + bool is_tpc_sector_fixed(unsigned int layer, unsigned int sector, unsigned int side); + bool is_layer_fixed(unsigned int layer); bool is_layer_param_fixed(unsigned int layer, unsigned int param); + void getLocalDerivativesXY(Surface surf, Acts::Vector3 global, const std::vector& fitpars, float lcl_derivativeX[5], float lcl_derivativeY[5], unsigned int layer); + + void getGlobalDerivativesXY(Surface surf, Acts::Vector3 global, Acts::Vector3 fitpoint, const std::vector& fitpars, float glb_derivativeX[6], float glbl_derivativeY[6], unsigned int layer); + + void get_projectionXY(Surface surf, std::pair tangent, Acts::Vector3& projX, Acts::Vector3& projY); + TpcClusterZCrossingCorrection m_clusterCrossingCorrection; TpcDistortionCorrectionContainer* _dcc_static{nullptr}; TpcDistortionCorrectionContainer* _dcc_average{nullptr}; @@ -112,19 +119,14 @@ class HelicalFitter : public SubsysReco, public PHParameterInterface ClusterErrorPara _ClusErrPara; - float sensorAngles[3] = {0.1, 0.1, 0.2}; // perturbation values for each alignment angle - std::set fixed_layers; + std::set fixed_sectors; std::set> fixed_layer_params; // set default groups to lowest level - siliconGrp si_grp = siliconGrp::snsr; - tpcGrp tpc_grp = tpcGrp::htst; - mmsGrp mms_grp = mmsGrp::tl; - - int nsensors_stave[7] = {9,9,9,4,4,4,4}; - - std::map base_layer_map = { {10, 0}, {12,3}, {14,7}, {16,55} }; + AlignmentDefs::siliconGrp si_grp = AlignmentDefs::siliconGrp::snsr; + AlignmentDefs::tpcGrp tpc_grp = AlignmentDefs::tpcGrp::htst; + AlignmentDefs::mmsGrp mms_grp = AlignmentDefs::mmsGrp::tl; /// tpc distortion correction utility class TpcDistortionCorrection _distortionCorrection; @@ -138,17 +140,15 @@ class HelicalFitter : public SubsysReco, public PHParameterInterface std::string data_outfilename = ("mille_helical_output_data_file.bin"); std::string steering_outfilename = ("steer_helical.txt"); - static const int NLC = 5; - static const int NGL = 6; - - bool fitsilicon = false; - bool fittpc = true; - bool fitfulltrack = true; + bool fitsilicon = true; + bool fittpc = false; + bool fitfulltrack = false; float dca_cut = 0.1; // 1 mm std::string _field; int _fieldDir = -1; + std::map _layerMisalignment; std::string _track_map_name = "TpcTrackSeedContainer"; std::string _silicon_track_map_name = "SiliconTrackSeedContainer"; diff --git a/offline/packages/TrackerMillepedeAlignment/MakeMilleFiles.cc b/offline/packages/TrackerMillepedeAlignment/MakeMilleFiles.cc index c448c2596d..27a9468574 100644 --- a/offline/packages/TrackerMillepedeAlignment/MakeMilleFiles.cc +++ b/offline/packages/TrackerMillepedeAlignment/MakeMilleFiles.cc @@ -79,13 +79,12 @@ int MakeMilleFiles::process_event(PHCompositeNode* /*topNode*/) { // Outline: // - // loop over tracks + // loop over track alignment states // Make any track cuts here to skip undesirable tracks (maybe low pT?) // loop over track states+measurements for each track - // for each measurement - // Get measurement value and error (global, what to use for error?) + // for each measurement, performed in trackreco/ActsAlignmentStates.cc + // Get measurement value and error // Calculate derivatives and residuals from Acts jacobians - // Rotate residual-derivative matrices to global coordinates // These are stored in a map and unpacked for mille // Call _mille->mille() with arguments obtained from previous iteration: // local pars @@ -100,20 +99,19 @@ int MakeMilleFiles::process_event(PHCompositeNode* /*topNode*/) // Note: all units are in the Acts units of mm and GeV to avoid converting matrices if (Verbosity() > 0) - { - std::cout << PHWHERE << " track map size " << _track_map->size() << std::endl; - std::cout << "state map size " << _state_map->size() << std::endl; - } + { + std::cout << PHWHERE << " track map size " << _track_map->size() << std::endl; + std::cout << "state map size " << _state_map->size() << std::endl; + } for (auto [key, statevec] : *_state_map) { - // Check if track was removed from cleaner auto iter = _track_map->find(key); - if(iter == _track_map->end()) - { - continue; - } + if (iter == _track_map->end()) + { + continue; + } SvtxTrack* track = iter->second; @@ -133,10 +131,10 @@ int MakeMilleFiles::process_event(PHCompositeNode* /*topNode*/) _mille->end(); } - if(Verbosity() > 0 ) - { - std::cout << "Finished processing mille file " << std::endl; - } + if (Verbosity() > 0) + { + std::cout << "Finished processing mille file " << std::endl; + } return Fun4AllReturnCodes::EVENT_OK; } @@ -196,100 +194,6 @@ Acts::Vector3 MakeMilleFiles::getPCALinePoint(Acts::Vector3 global, SvtxTrackSta return pca; } -int MakeMilleFiles::getTpcRegion(int layer) -{ - int region = 0; - if (layer > 23 && layer < 39) - region = 1; - if (layer > 38 && layer < 55) - region = 2; - - return region; -} - -int MakeMilleFiles::getLabelBase(Acts::GeometryIdentifier id) -{ - unsigned int volume = id.volume(); - unsigned int acts_layer = id.layer(); - unsigned int layer = base_layer_map.find(volume)->second + acts_layer / 2 - 1; - unsigned int sensor = id.sensitive() - 1; // Acts starts at 1 - - int label_base = 1; // Mille wants to start at 1 - - // decide what level of grouping we want - if (layer < 7) - { - if (si_group == siliconGroup::sensor) - { - // every sensor has a different label - int stave = sensor / nsensors_stave[layer]; - label_base += layer * 1000000 + stave * 10000 + sensor * 10; - return label_base; - } - if (si_group == siliconGroup::stave) - { - // layer and stave, assign all sensors to the stave number - int stave = sensor / nsensors_stave[layer]; - label_base += layer * 1000000 + stave * 10000; - return label_base; - } - if (si_group == siliconGroup::barrel) - { - // layer only, assign all sensors to sensor 0 - label_base += layer * 1000000 + 0; - - return label_base; - } - } - else if (layer > 6 && layer < 55) - { - if (tpc_group == tpcGroup::hitset) - { - // want every hitset (layer, sector, side) to have a separate label - // each group of 12 subsurfaces (sensors) is in a single hitset - int hitset = sensor / 12; // hitsets 0-11 on side 0, 12-23 on side 1 - label_base += layer * 1000000 + hitset * 10000; - return label_base; - } - if (tpc_group == tpcGroup::sector) - { - // group all tpc layers in each region and sector, assign layer 7 and side and sector number to all layers and hitsets - int side = sensor / 144; // 0-143 on side 0, 144-287 on side 1 - int sector = (sensor - side * 144) / 12; - // for a given layer there are only 12 sectors x 2 sides - // The following gives the sectors in the inner, mid, outer regions unique group labels - int region = getTpcRegion(layer); // inner, mid, outer - label_base += 7 * 1000000 + (region * 24 + side * 12 + sector) * 10000; - // std::cout << " layer " << layer << " sensor " << sensor << " region " << region << " side " << side << " sector " << sector << " label_base " << label_base << std::endl; - return label_base; - } - if (tpc_group == tpcGroup::tpc) - { - // all tpc layers and all sectors, assign layer 7 and sensor 0 to all layers and sensors - label_base += 7 * 1000000 + 0; - return label_base; - } - } - else - { - if (mms_group == mmsGroup::tile) - { - // every tile has different label - int tile = sensor; - label_base += layer * 1000000 + tile * 10000 + sensor * 10; - return label_base; - } - if (mms_group == mmsGroup::mms) - { - // assign layer 55 and tile 0 to all - label_base += 55 * 1000000 + 0; - return label_base; - } - } - - return -1; -} - void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec statevec) { for (auto state : statevec) @@ -303,19 +207,19 @@ void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec stateve // The global alignment parameters are given initial values of zero by default, we do not specify them // We identify the global alignment parameters for this surface - const auto cluster = _cluster_map->findCluster(ckey); - const auto layer = TrkrDefs::getLayer(ckey); + TrkrCluster* cluster = _cluster_map->findCluster(ckey); + const unsigned int layer = TrkrDefs::getLayer(ckey); - const auto residual = state->get_residual(); - const auto& global = _tGeometry->getGlobalPosition(ckey, cluster); + const SvtxAlignmentState::ResidualVector residual = state->get_residual(); + const Acts::Vector3 global = _tGeometry->getGlobalPosition(ckey, cluster); // need standard deviation of measurements SvtxAlignmentState::ResidualVector clus_sigma = SvtxAlignmentState::ResidualVector::Zero(); + if (_cluster_version == 3) { - clus_sigma(2) = cluster->getZError() * Acts::UnitConstants::cm; - clus_sigma(0) = cluster->getRPhiError() / sqrt(2) * Acts::UnitConstants::cm; - clus_sigma(1) = cluster->getRPhiError() / sqrt(2) * Acts::UnitConstants::cm; + clus_sigma(1) = cluster->getZError() * Acts::UnitConstants::cm; + clus_sigma(0) = cluster->getRPhiError() * Acts::UnitConstants::cm; } else if (_cluster_version == 4) { @@ -323,35 +227,40 @@ void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec stateve auto para_errors = _ClusErrPara.get_simple_cluster_error(cluster, clusRadius, ckey); float exy2 = para_errors.first * Acts::UnitConstants::cm2; float ez2 = para_errors.second * Acts::UnitConstants::cm2; - clus_sigma(2) = sqrt(ez2); - clus_sigma(0) = sqrt(exy2 / 2.0); - clus_sigma(1) = sqrt(exy2 / 2.0); + clus_sigma(1) = sqrt(ez2); + clus_sigma(0) = sqrt(exy2); } - else if(_cluster_version == 5) + else if (_cluster_version == 5) { - clus_sigma(2) = cluster->getZError(); - clus_sigma(0) = cluster->getRPhiError() / sqrt(2); - clus_sigma(1) = cluster->getRPhiError() / sqrt(2); + double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); + TrkrClusterv5* clusterv5 = dynamic_cast(cluster); + auto para_errors = _ClusErrPara.get_clusterv5_modified_error(clusterv5, clusRadius, ckey); + double phierror = sqrt(para_errors.first); + double zerror = sqrt(para_errors.second); + clus_sigma(1) = zerror * Acts::UnitConstants::cm; + clus_sigma(0) = phierror * Acts::UnitConstants::cm; } if (std::isnan(clus_sigma(0)) || - std::isnan(clus_sigma(1)) || - std::isnan(clus_sigma(2))) + std::isnan(clus_sigma(1))) { continue; } - Acts::GeometryIdentifier id = _tGeometry->maps().getSurface(ckey, cluster)->geometryId(); - int label_base = getLabelBase(id); // This value depends on how the surfaces are grouped + auto surf = _tGeometry->maps().getSurface(ckey, cluster); int glbl_label[SvtxAlignmentState::NGL]; - for (int i = 0; i < SvtxAlignmentState::NGL; ++i) + if (layer < 7) { - glbl_label[i] = label_base + i; - if (Verbosity() > 1) - { - std::cout << " glbl " << i << " label " << glbl_label[i] << " "; - } + AlignmentDefs::getSiliconGlobalLabels(surf, glbl_label, si_group); + } + else if (layer < 55) + { + AlignmentDefs::getTpcGlobalLabels(surf, glbl_label, tpc_group); + } + else if (layer < 57) + { + AlignmentDefs::getMMGlobalLabels(surf, glbl_label, mms_group); } if (Verbosity() > 1) @@ -359,15 +268,14 @@ void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec stateve std::cout << std::endl; } - /// For N residual coordinates x,y,z + /// For N residual local coordinates x, z for (int i = 0; i < SvtxAlignmentState::NRES; ++i) { // Add the measurement separately for each coordinate direction to Mille float glbl_derivative[SvtxAlignmentState::NGL]; for (int j = 0; j < SvtxAlignmentState::NGL; ++j) { - /// swap the order to match what is expected from the workflow - glbl_derivative[j] = state->get_global_derivative_matrix()(i, (j+3)%SvtxAlignmentState::NGL); + glbl_derivative[j] = state->get_global_derivative_matrix()(i, j); if (is_layer_fixed(layer) || is_layer_param_fixed(layer, j)) { @@ -387,6 +295,8 @@ void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec stateve for (int k = 0; k < SvtxAlignmentState::NGL; k++) { + if (glbl_derivative[k] > 0 || glbl_derivative[k] < 0) + std::cout << "NONZERO GLOBAL DERIVATIVE" << std::endl; std::cout << glbl_derivative[k] << ", "; } std::cout << std::endl @@ -400,13 +310,18 @@ void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec stateve if (clus_sigma(i) < 1.0) // discards crazy clusters { - if(Verbosity() > 3) - { - std::cout << "ckey " << ckey << " and layer " << layer << " buffers:" << std::endl; - printBuffers(i, residual, clus_sigma, lcl_derivative, glbl_derivative, glbl_label); - } + if (Verbosity() > 3) + { + std::cout << "ckey " << ckey << " and layer " << layer << " buffers:" << std::endl; + AlignmentDefs::printBuffers(i, residual, clus_sigma, lcl_derivative, glbl_derivative, glbl_label); + } + float errinf = 1.0; + if (m_layerMisalignment.find(layer) != m_layerMisalignment.end()) + { + errinf = m_layerMisalignment.find(layer)->second; + } - _mille->mille(SvtxAlignmentState::NLOC, lcl_derivative, SvtxAlignmentState::NGL, glbl_derivative, glbl_label, residual(i), clus_sigma(i)); + _mille->mille(SvtxAlignmentState::NLOC, lcl_derivative, SvtxAlignmentState::NGL, glbl_derivative, glbl_label, residual(i), errinf * clus_sigma(i)); } } } @@ -414,18 +329,6 @@ void MakeMilleFiles::addTrackToMilleFile(SvtxAlignmentStateMap::StateVec stateve return; } -void MakeMilleFiles::printBuffers(int index, Acts::Vector3 residual, Acts::Vector3 clus_sigma, float lcl_derivative[], float glbl_derivative[], int glbl_label[]) -{ - std::cout << " float buffer: " << " residual " << " " << residual(index); - for (int il=0;il #include @@ -32,24 +34,6 @@ class Mille; using Trajectory = ActsExamples::Trajectories; -enum siliconGroup -{ - sensor, - stave, - barrel -}; -enum tpcGroup -{ - hitset, - sector, - tpc -}; -enum mmsGroup -{ - tile, - mms -}; - class MakeMilleFiles : public SubsysReco { public: @@ -63,12 +47,17 @@ class MakeMilleFiles : public SubsysReco void set_datafile_name(const std::string& file) { data_outfilename = file; } void set_steeringfile_name(const std::string& file) { steering_outfilename = file; } - void set_silicon_grouping(int group) { si_group = (siliconGroup) group; } - void set_tpc_grouping(int group) { tpc_group = (tpcGroup) group; } - void set_mms_grouping(int group) { mms_group = (mmsGroup) group; } + void set_silicon_grouping(int group) { si_group = (AlignmentDefs::siliconGrp) group; } + void set_tpc_grouping(int group) { tpc_group = (AlignmentDefs::tpcGrp) group; } + void set_mms_grouping(int group) { mms_group = (AlignmentDefs::mmsGrp) group; } void set_layer_fixed(unsigned int layer); void set_layer_param_fixed(unsigned int layer, unsigned int param); void set_cluster_version(unsigned int v) { _cluster_version = v; } + void set_layers_fixed(unsigned int minlayer, unsigned int maxlayer); + void set_error_inflation_factor(unsigned int layer, float factor) + { + m_layerMisalignment.insert(std::make_pair(layer, factor)); + } private: Mille* _mille; @@ -80,12 +69,8 @@ class MakeMilleFiles : public SubsysReco TrkrCluster* cluster, Surface surface, int crossing); - int getLabelBase(Acts::GeometryIdentifier id); - int getTpcRegion(int layer); - bool is_layer_fixed(unsigned int layer); bool is_layer_param_fixed(unsigned int layer, unsigned int param); - void printBuffers(int index, Acts::Vector3 residual, Acts::Vector3 clus_sigma, float lcl_derivative[], float glbl_derivative[], int glbl_label[]); void addTrackToMilleFile(SvtxAlignmentStateMap::StateVec statevec); @@ -96,20 +81,16 @@ class MakeMilleFiles : public SubsysReco bool _binary = true; unsigned int _cluster_version = 5; - bool m_useAnalytic = true; + std::map m_layerMisalignment; // set default groups to lowest level - siliconGroup si_group = siliconGroup::sensor; - tpcGroup tpc_group = tpcGroup::hitset; - mmsGroup mms_group = mmsGroup::tile; - - int nsensors_stave[7] = {9, 9, 9, 4, 4, 4, 4}; + AlignmentDefs::siliconGrp si_group = AlignmentDefs::siliconGrp::snsr; + AlignmentDefs::tpcGrp tpc_group = AlignmentDefs::tpcGrp::htst; + AlignmentDefs::mmsGrp mms_group = AlignmentDefs::mmsGrp::tl; std::set fixed_layers; std::set> fixed_layer_params; - std::map base_layer_map = {{10, 0}, {12, 3}, {14, 7}, {16, 55}}; - SvtxTrackMap* _track_map{nullptr}; SvtxAlignmentStateMap* _state_map{nullptr}; ActsGeometry* _tGeometry{nullptr}; diff --git a/offline/packages/TrackerMillepedeAlignment/Makefile.am b/offline/packages/TrackerMillepedeAlignment/Makefile.am index d463b206e1..52da46c171 100644 --- a/offline/packages/TrackerMillepedeAlignment/Makefile.am +++ b/offline/packages/TrackerMillepedeAlignment/Makefile.am @@ -28,6 +28,7 @@ libtrackeralign_la_LIBADD = \ -ltpc_io pkginclude_HEADERS = \ + AlignmentDefs.h \ MakeMilleFiles.h \ Mille.h \ HelicalFitter.h @@ -35,6 +36,7 @@ pkginclude_HEADERS = \ pcmdir = $(libdir) libtrackeralign_la_SOURCES = \ + AlignmentDefs.cc \ MakeMilleFiles.cc \ Mille.cc \ HelicalFitter.cc diff --git a/offline/packages/TrackingDiagnostics/Makefile.am b/offline/packages/TrackingDiagnostics/Makefile.am index 080a988662..d20020a3d9 100644 --- a/offline/packages/TrackingDiagnostics/Makefile.am +++ b/offline/packages/TrackingDiagnostics/Makefile.am @@ -13,6 +13,7 @@ AM_LDFLAGS = \ pkginclude_HEADERS = \ KshortReconstruction.h \ helixResiduals.h \ + TrackResiduals.h \ TrkrNtuplizer.h lib_LTLIBRARIES = \ @@ -21,6 +22,7 @@ lib_LTLIBRARIES = \ libTrackingDiagnostics_la_SOURCES = \ KshortReconstruction.cc \ helixResiduals.cc \ + TrackResiduals.cc \ TrkrNtuplizer.cc libTrackingDiagnostics_la_LIBADD = \ diff --git a/offline/packages/TrackingDiagnostics/TrackResiduals.cc b/offline/packages/TrackingDiagnostics/TrackResiduals.cc new file mode 100644 index 0000000000..ef88825aae --- /dev/null +++ b/offline/packages/TrackingDiagnostics/TrackResiduals.cc @@ -0,0 +1,466 @@ + +#include "TrackResiduals.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +namespace +{ + template + inline T square(const T& t) + { + return t * t; + } + template + inline T r(const T& x, const T& y) + { + return std::sqrt(square(x) + square(y)); + } + + std::vector get_cluster_keys(SvtxTrack* track) + { + std::vector out; + for (const auto& seed : {track->get_silicon_seed(), track->get_tpc_seed()}) + { + if (seed) + { + std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out)); + } + } + + return out; + } +} // namespace + +//____________________________________________________________________________.. +TrackResiduals::TrackResiduals(const std::string& name) + : SubsysReco(name) +{ +} + +//____________________________________________________________________________.. +TrackResiduals::~TrackResiduals() +{ +} + +//____________________________________________________________________________.. +int TrackResiduals::Init(PHCompositeNode*) +{ + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TrackResiduals::InitRun(PHCompositeNode*) +{ + m_outfile = new TFile(m_outfileName.c_str(), "RECREATE"); + createBranches(); + + return Fun4AllReturnCodes::EVENT_OK; +} +void TrackResiduals::clearClusterStateVectors() +{ + m_statelxglobderivdx.clear(); + m_statelxglobderivdy.clear(); + m_statelxglobderivdz.clear(); + m_statelxglobderivdalpha.clear(); + m_statelxglobderivdbeta.clear(); + m_statelxglobderivdgamma.clear(); + + m_statelxlocderivd0.clear(); + m_statelxlocderivz0.clear(); + m_statelxlocderivphi.clear(); + m_statelxlocderivtheta.clear(); + m_statelxlocderivqop.clear(); + + m_statelzglobderivdx.clear(); + m_statelzglobderivdy.clear(); + m_statelzglobderivdz.clear(); + m_statelzglobderivdalpha.clear(); + m_statelzglobderivdbeta.clear(); + m_statelzglobderivdgamma.clear(); + + m_statelzlocderivd0.clear(); + m_statelzlocderivz0.clear(); + m_statelzlocderivphi.clear(); + m_statelzlocderivtheta.clear(); + m_statelzlocderivqop.clear(); + + m_cluslx.clear(); + m_cluslz.clear(); + m_cluselx.clear(); + m_cluselz.clear(); + m_clusgx.clear(); + m_clusgy.clear(); + m_clusgz.clear(); + m_cluslayer.clear(); + m_clussize.clear(); + + m_statelx.clear(); + m_statelz.clear(); + m_stateelx.clear(); + m_stateelz.clear(); + m_stategx.clear(); + m_stategy.clear(); + m_stategz.clear(); + m_statepx.clear(); + m_statepy.clear(); + m_statepz.clear(); +} +//____________________________________________________________________________.. +int TrackResiduals::process_event(PHCompositeNode* topNode) +{ + auto trackmap = findNode::getClass(topNode, "SvtxTrackMap"); + auto clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); + auto geometry = findNode::getClass(topNode, "ActsGeometry"); + auto vertexmap = findNode::getClass(topNode, "GlobalVertexMap"); + auto alignmentmap = findNode::getClass(topNode, "SvtxAlignmentStateMap"); + + if (!trackmap or !clustermap or !geometry or !vertexmap) + { + std::cout << "Missing node, can't continue" << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + if (Verbosity() > 1) + { + std::cout << "Track map size is " << trackmap->size() << std::endl; + } + + for (const auto& [key, track] : *trackmap) + { + if (!track) + { + continue; + } + m_trackid = key; + m_crossing = track->get_crossing(); + m_px = track->get_px(); + m_py = track->get_py(); + m_pz = track->get_pz(); + m_pt = std::sqrt(square(m_px) + square(m_py)); + m_eta = atanh(m_pz / std::sqrt(square(m_pt) + square(m_pz))); + m_phi = atan2(m_py, m_px); + float CVxx = track->get_error(3, 3); + float CVxy = track->get_error(3, 4); + float CVyy = track->get_error(4, 4); + m_deltapt = std::sqrt((CVxx * square(m_px) + 2 * CVxy * m_px * m_py + CVyy * square(m_py)) / (square(m_px) + square(m_py))); + + m_charge = track->get_charge(); + m_quality = track->get_quality(); + m_chisq = track->get_chisq(); + m_ndf = track->get_ndf(); + m_nmaps = 0; + m_nintt = 0; + m_ntpc = 0; + m_nmms = 0; + m_vertexid = track->get_vertex_id(); + auto vertex = vertexmap->find(m_vertexid)->second; + if (vertex) + { + m_vx = vertex->get_x(); + m_vy = vertex->get_y(); + m_vz = vertex->get_z(); + } + + m_pcax = track->get_x(); + m_pcay = track->get_y(); + m_pcaz = track->get_z(); + + clearClusterStateVectors(); + if (Verbosity() > 1) + { + std::cout << "Track " << key << " has cluster/states" + << std::endl; + } + + for (const auto& ckey : get_cluster_keys(track)) + { + fillClusterBranches(ckey, track, topNode); + } + + m_nhits = m_nmaps + m_nintt + m_ntpc + m_nmms; + + if (m_doAlignment) + { + /// repopulate with info that is going into alignment + clearClusterStateVectors(); + + if (alignmentmap and alignmentmap->find(key) != alignmentmap->end()) + { + auto& statevec = alignmentmap->find(key)->second; + + for (auto& state : statevec) + { + auto ckey = state->get_cluster_key(); + + fillClusterBranches(ckey, track, topNode); + + auto& globderivs = state->get_global_derivative_matrix(); + auto& locderivs = state->get_local_derivative_matrix(); + + m_statelxglobderivdalpha.push_back(globderivs(0, 0)); + m_statelxglobderivdbeta.push_back(globderivs(0, 1)); + m_statelxglobderivdgamma.push_back(globderivs(0, 2)); + m_statelxglobderivdx.push_back(globderivs(0, 3)); + m_statelxglobderivdy.push_back(globderivs(0, 4)); + m_statelxglobderivdz.push_back(globderivs(0, 5)); + + m_statelzglobderivdalpha.push_back(globderivs(1, 0)); + m_statelzglobderivdbeta.push_back(globderivs(1, 1)); + m_statelzglobderivdgamma.push_back(globderivs(1, 2)); + m_statelzglobderivdx.push_back(globderivs(1, 3)); + m_statelzglobderivdy.push_back(globderivs(1, 4)); + m_statelzglobderivdz.push_back(globderivs(1, 5)); + + m_statelxlocderivd0.push_back(locderivs(0, 0)); + m_statelxlocderivz0.push_back(locderivs(0, 1)); + m_statelxlocderivphi.push_back(locderivs(0, 2)); + m_statelxlocderivtheta.push_back(locderivs(0, 3)); + m_statelxlocderivqop.push_back(locderivs(0, 4)); + + m_statelzlocderivd0.push_back(locderivs(1, 0)); + m_statelzlocderivz0.push_back(locderivs(1, 1)); + m_statelzlocderivphi.push_back(locderivs(1, 2)); + m_statelzlocderivtheta.push_back(locderivs(1, 3)); + m_statelzlocderivqop.push_back(locderivs(1, 4)); + } + } + } + m_tree->Fill(); + } + + m_event++; + return Fun4AllReturnCodes::EVENT_OK; +} + +float TrackResiduals::convertTimeToZ(ActsGeometry* geometry, TrkrDefs::cluskey cluster_key, TrkrCluster* cluster) +{ + // must convert local Y from cluster average time of arival to local cluster z position + double drift_velocity = geometry->get_drift_velocity(); + double zdriftlength = cluster->getLocalY() * drift_velocity; + double surfCenterZ = 52.89; // 52.89 is where G4 thinks the surface center is + double zloc = surfCenterZ - zdriftlength; // converts z drift length to local z position in the TPC in north + unsigned int side = TpcDefs::getSide(cluster_key); + if (side == 0) zloc = -zloc; + float z = zloc; // in cm + + return z; +} + +//____________________________________________________________________________.. +int TrackResiduals::End(PHCompositeNode*) +{ + m_outfile->cd(); + m_tree->Write(); + m_outfile->Close(); + + return Fun4AllReturnCodes::EVENT_OK; +} + +void TrackResiduals::fillClusterBranches(TrkrDefs::cluskey ckey, SvtxTrack* track, + PHCompositeNode* topNode) +{ + auto clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); + auto geometry = findNode::getClass(topNode, "ActsGeometry"); + + ActsTransformations transformer; + TrkrCluster* cluster = clustermap->findCluster(ckey); + switch (TrkrDefs::getTrkrId(ckey)) + { + case TrkrDefs::mvtxId: + m_nmaps++; + break; + case TrkrDefs::inttId: + m_nintt++; + break; + case TrkrDefs::tpcId: + m_ntpc++; + break; + case TrkrDefs::micromegasId: + m_nmms++; + break; + } + + Acts::Vector3 clusglob = geometry->getGlobalPosition(ckey, cluster); + + auto matched_state = track->begin_states(); + float drmin = -1; + float clusr = r(clusglob.x(), clusglob.y()); + + for (auto state_iter = track->begin_states(); + state_iter != track->end_states(); + ++state_iter) + { + SvtxTrackState* state = state_iter->second; + float stater = r(state->get_x(), state->get_y()); + float thisdr = std::abs(clusr - stater); + if (drmin < 0 or thisdr < drmin) + { + matched_state = state_iter; + drmin = thisdr; + } + else + { + break; + } + } + + SvtxTrackState* state = matched_state->second; + + //! have cluster and state, fill vectors + m_cluslx.push_back(cluster->getLocalX()); + float clusz = cluster->getLocalY(); + + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::tpcId) + { + clusz = convertTimeToZ(geometry, ckey, cluster); + } + m_cluslz.push_back(clusz); + m_cluselx.push_back(cluster->getRPhiError()); + m_cluselz.push_back(cluster->getZError()); + m_clusgx.push_back(clusglob.x()); + m_clusgy.push_back(clusglob.y()); + m_clusgz.push_back(clusglob.z()); + m_cluslayer.push_back(TrkrDefs::getLayer(ckey)); + m_clussize.push_back(cluster->getPhiSize() + cluster->getZSize()); + m_clushitsetkey.push_back(TrkrDefs::getHitSetKeyFromClusKey(ckey)); + + if (Verbosity() > 1) + { + std::cout << "Track state/clus in layer " + << TrkrDefs::getLayer(ckey) << std::endl; + } + + auto surf = geometry->maps().getSurface(ckey, cluster); + Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); + Acts::Vector2 stateloc; + auto norm = surf->normal(geometry->geometry().getGeoContext()); + auto result = surf->globalToLocal(geometry->geometry().getGeoContext(), + stateglob * Acts::UnitConstants::cm, + norm); + if (result.ok()) + { + stateloc = result.value() / Acts::UnitConstants::cm; + } + else + { + //! manual transform for tpc + Acts::Vector3 loct = surf->transform(geometry->geometry().getGeoContext()).inverse() * (stateglob * Acts::UnitConstants::cm); + loct /= Acts::UnitConstants::cm; + stateloc(0) = loct(0); + stateloc(1) = loct(1); + } + + const Acts::BoundSymMatrix actscov = + transformer.rotateSvtxTrackCovToActs(state); + + m_statelx.push_back(stateloc(0)); + m_statelz.push_back(stateloc(1)); + m_stateelx.push_back(std::sqrt(actscov(Acts::eBoundLoc0, Acts::eBoundLoc0)) / Acts::UnitConstants::cm); + m_stateelz.push_back(std::sqrt(actscov(Acts::eBoundLoc1, Acts::eBoundLoc1)) / Acts::UnitConstants::cm); + m_stategx.push_back(state->get_x()); + m_stategy.push_back(state->get_y()); + m_stategz.push_back(state->get_z()); + m_statepx.push_back(state->get_px()); + m_statepy.push_back(state->get_py()); + m_statepz.push_back(state->get_pz()); + m_statepl.push_back(state->get_pathlength()); +} +void TrackResiduals::createBranches() +{ + m_tree = new TTree("residualtree", "A tree with track, cluster, and state info"); + m_tree->Branch("trackid", &m_trackid, "m_trackid/I"); + m_tree->Branch("crossing", &m_crossing, "m_crossing/I"); + m_tree->Branch("px", &m_px, "m_px/F"); + m_tree->Branch("py", &m_py, "m_py/F"); + m_tree->Branch("pz", &m_pz, "m_pz/F"); + m_tree->Branch("pt", &m_pt, "m_pt/F"); + m_tree->Branch("eta", &m_eta, "m_eta/F"); + m_tree->Branch("phi", &m_phi, "m_phi/F"); + m_tree->Branch("deltapt", &m_deltapt, "m_deltapt/F"); + m_tree->Branch("charge", &m_charge, "m_charge/I"); + m_tree->Branch("quality", &m_quality, "m_quality/F"); + m_tree->Branch("ndf", &m_ndf, "m_ndf/F"); + m_tree->Branch("nhits", &m_nhits, "m_nhits/I"); + m_tree->Branch("nmaps", &m_nmaps, "m_nmaps/I"); + m_tree->Branch("nintt", &m_nintt, "m_nintt/I"); + m_tree->Branch("ntpc", &m_ntpc, "m_ntpc/I"); + m_tree->Branch("nmms", &m_nmms, "m_nmms/I"); + m_tree->Branch("vertexid", &m_vertexid, "m_vertexid/I"); + m_tree->Branch("vx", &m_vx, "m_vx/F"); + m_tree->Branch("vy", &m_vy, "m_vy/F"); + m_tree->Branch("vz", &m_vz, "m_vz/F"); + m_tree->Branch("pcax", &m_pcax, "m_pcax/F"); + m_tree->Branch("pcay", &m_pcay, "m_pcay/F"); + m_tree->Branch("pcaz", &m_pcaz, "m_pcaz/F"); + + m_tree->Branch("cluslx", &m_cluslx); + m_tree->Branch("cluslz", &m_cluslz); + m_tree->Branch("cluselx", &m_cluselx); + m_tree->Branch("cluselz", &m_cluselz); + m_tree->Branch("clusgx", &m_clusgx); + m_tree->Branch("clusgy", &m_clusgy); + m_tree->Branch("clusgz", &m_clusgz); + m_tree->Branch("cluslayer", &m_cluslayer); + m_tree->Branch("clussize", &m_clussize); + m_tree->Branch("clushitsetkey", &m_clushitsetkey); + + m_tree->Branch("statelx", &m_statelx); + m_tree->Branch("statelz", &m_statelz); + m_tree->Branch("stateelx", &m_stateelx); + m_tree->Branch("stateelz", &m_stateelz); + m_tree->Branch("stategx", &m_stategx); + m_tree->Branch("stategy", &m_stategy); + m_tree->Branch("stategz", &m_stategz); + m_tree->Branch("statepx", &m_statepx); + m_tree->Branch("statepy", &m_statepy); + m_tree->Branch("statepz", &m_statepz); + m_tree->Branch("statepl", &m_statepl); + + m_tree->Branch("statelxglobderivdx", &m_statelxglobderivdx); + m_tree->Branch("statelxglobderivdy", &m_statelxglobderivdy); + m_tree->Branch("statelxglobderivdz", &m_statelxglobderivdz); + m_tree->Branch("statelxglobderivdalpha", &m_statelxglobderivdalpha); + m_tree->Branch("statelxglobderivdbeta", &m_statelxglobderivdbeta); + m_tree->Branch("statelxglobderivdgamma", &m_statelxglobderivdgamma); + + m_tree->Branch("statelxlocderivd0", &m_statelxlocderivd0); + m_tree->Branch("statelxlocderivz0", &m_statelxlocderivz0); + m_tree->Branch("statelxlocderivphi", &m_statelxlocderivphi); + m_tree->Branch("statelxlocderivtheta", &m_statelxlocderivtheta); + m_tree->Branch("statelxlocderivqop", &m_statelxlocderivqop); + + m_tree->Branch("statelzglobderivdx", &m_statelzglobderivdx); + m_tree->Branch("statelzglobderivdy", &m_statelzglobderivdy); + m_tree->Branch("statelzglobderivdz", &m_statelzglobderivdz); + m_tree->Branch("statelzglobderivdalpha", &m_statelzglobderivdalpha); + m_tree->Branch("statelzglobderivdbeta", &m_statelzglobderivdbeta); + m_tree->Branch("statelzglobderivdgamma", &m_statelzglobderivdgamma); + + m_tree->Branch("statelzlocderivd0", &m_statelzlocderivd0); + m_tree->Branch("statelzlocderivz0", &m_statelzlocderivz0); + m_tree->Branch("statelzlocderivphi", &m_statelzlocderivphi); + m_tree->Branch("statelzlocderivtheta", &m_statelzlocderivtheta); + m_tree->Branch("statelzlocderivqop", &m_statelzlocderivqop); +} diff --git a/offline/packages/TrackingDiagnostics/TrackResiduals.h b/offline/packages/TrackingDiagnostics/TrackResiduals.h new file mode 100644 index 0000000000..d3e50bae38 --- /dev/null +++ b/offline/packages/TrackingDiagnostics/TrackResiduals.h @@ -0,0 +1,132 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef TRACKRESIDUALS_H +#define TRACKRESIDUALS_H + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +class TrkrCluster; +class PHCompositeNode; +class ActsGeometry; +class SvtxTrack; + +class TrackResiduals : public SubsysReco +{ + public: + TrackResiduals(const std::string &name = "TrackResiduals"); + + ~TrackResiduals() override; + + int Init(PHCompositeNode *topNode) override; + int InitRun(PHCompositeNode *topNode) override; + int process_event(PHCompositeNode *topNode) override; + int End(PHCompositeNode *topNode) override; + void outfileName(std::string &name) { m_outfileName = name; } + void alignment(bool align) { m_doAlignment = align; } + + private: + void clearClusterStateVectors(); + void createBranches(); + float convertTimeToZ(ActsGeometry *geometry, TrkrDefs::cluskey cluster_key, TrkrCluster *cluster); + + void fillClusterBranches(TrkrDefs::cluskey ckey, SvtxTrack *track, + PHCompositeNode *topNode); + + std::string m_outfileName = ""; + TFile *m_outfile = nullptr; + TTree *m_tree = nullptr; + + bool m_doAlignment = false; + + int m_event = 0; + //! Track level quantities + unsigned int m_trackid = std::numeric_limits::quiet_NaN(); + unsigned int m_crossing = std::numeric_limits::quiet_NaN(); + float m_px = std::numeric_limits::quiet_NaN(); + float m_py = std::numeric_limits::quiet_NaN(); + float m_pz = std::numeric_limits::quiet_NaN(); + float m_pt = std::numeric_limits::quiet_NaN(); + float m_eta = std::numeric_limits::quiet_NaN(); + float m_phi = std::numeric_limits::quiet_NaN(); + float m_deltapt = std::numeric_limits::quiet_NaN(); + int m_charge = std::numeric_limits::quiet_NaN(); + float m_quality = std::numeric_limits::quiet_NaN(); + float m_chisq = std::numeric_limits::quiet_NaN(); + float m_ndf = std::numeric_limits::quiet_NaN(); + int m_nhits = std::numeric_limits::quiet_NaN(); + int m_nmaps = std::numeric_limits::quiet_NaN(); + int m_nintt = std::numeric_limits::quiet_NaN(); + int m_ntpc = std::numeric_limits::quiet_NaN(); + int m_nmms = std::numeric_limits::quiet_NaN(); + unsigned int m_vertexid = std::numeric_limits::quiet_NaN(); + float m_vx = std::numeric_limits::quiet_NaN(); + float m_vy = std::numeric_limits::quiet_NaN(); + float m_vz = std::numeric_limits::quiet_NaN(); + float m_pcax = std::numeric_limits::quiet_NaN(); + float m_pcay = std::numeric_limits::quiet_NaN(); + float m_pcaz = std::numeric_limits::quiet_NaN(); + + //! clusters on track information + std::vector m_cluslx; + std::vector m_cluslz; + std::vector m_cluselx; + std::vector m_cluselz; + std::vector m_clusgx; + std::vector m_clusgy; + std::vector m_clusgz; + std::vector m_cluslayer; + std::vector m_clussize; + std::vector m_clushitsetkey; + + //! states on track information + std::vector m_statelx; + std::vector m_statelz; + std::vector m_stateelx; + std::vector m_stateelz; + std::vector m_stategx; + std::vector m_stategy; + std::vector m_stategz; + std::vector m_statepx; + std::vector m_statepy; + std::vector m_statepz; + std::vector m_statepl; + + std::vector m_statelxglobderivdx; + std::vector m_statelxglobderivdy; + std::vector m_statelxglobderivdz; + std::vector m_statelxglobderivdalpha; + std::vector m_statelxglobderivdbeta; + std::vector m_statelxglobderivdgamma; + + std::vector m_statelxlocderivd0; + std::vector m_statelxlocderivz0; + std::vector m_statelxlocderivphi; + std::vector m_statelxlocderivtheta; + std::vector m_statelxlocderivqop; + + std::vector m_statelzglobderivdx; + std::vector m_statelzglobderivdy; + std::vector m_statelzglobderivdz; + std::vector m_statelzglobderivdalpha; + std::vector m_statelzglobderivdbeta; + std::vector m_statelzglobderivdgamma; + + std::vector m_statelzlocderivd0; + std::vector m_statelzlocderivz0; + std::vector m_statelzlocderivphi; + std::vector m_statelzlocderivtheta; + std::vector m_statelzlocderivqop; +}; + +#endif // TRACKRESIDUALS_H diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc index f36d48ac51..0496735a11 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc @@ -398,50 +398,54 @@ void TrkrNtuplizer::printOutputInfo(PHCompositeNode* topNode) cout << "===Tracking Summary============================" << endl; - TrkrHitSetContainer* hitsetmap = findNode::getClass(topNode, "TRKR_HITSET"); + unsigned int nclusters[100] = {0}; + unsigned int nhits[100] = {0}; - TrkrClusterContainer* clustermap = findNode::getClass(topNode, "CORRECTED_TRKR_CLUSTER"); - if (!clustermap) + for (const auto& [trkrID, trkrName] : TrkrDefs::TrkrNames) { - clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); - } + TrkrHitSetContainer* hitsetmap = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); - unsigned int nclusters[100] = {0}; - unsigned int nhits[100] = {0}; + TrkrClusterContainer* clustermap = findNode::getClass(topNode, "CORRECTED_TRKR_CLUSTER"); + if (!clustermap) + { + clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); + } - ActsGeometry* tgeometry = findNode::getClass(topNode, "ActsGeometry"); - if (!tgeometry) - { - std::cout << PHWHERE << "No Acts geometry on node tree. Can't continue." - << std::endl; - } + ActsGeometry* tgeometry = findNode::getClass(topNode, "ActsGeometry"); - if (hitsetmap) - { - TrkrHitSetContainer::ConstRange all_hitsets = hitsetmap->getHitSets(); - for (TrkrHitSetContainer::ConstIterator hitsetiter = all_hitsets.first; - hitsetiter != all_hitsets.second; - ++hitsetiter) + if (!tgeometry) { - // we have a single hitset, get the layer - unsigned int layer = TrkrDefs::getLayer(hitsetiter->first); + std::cout << PHWHERE << "No Acts geometry on node tree. Can't continue." + << std::endl; + } - // count all hits in this hitset - TrkrHitSet::ConstRange hitrangei = hitsetiter->second->getHits(); - for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr) - { - ++nhits[layer]; - } - auto range = clustermap->getClusters(hitsetiter->first); - for (auto clusIter = range.first; clusIter != range.second; ++clusIter) + if (hitsetmap) + { + TrkrHitSetContainer::ConstRange all_hitsets = hitsetmap->getHitSets(); + for (TrkrHitSetContainer::ConstIterator hitsetiter = all_hitsets.first; + hitsetiter != all_hitsets.second; + ++hitsetiter) { - const auto cluskey = clusIter->first; - // const auto cluster = clusIter->second; - // unsigned int layer = TrkrDefs::getLayer(cluskey); - nclusters[TrkrDefs::getLayer(cluskey)]++; + // we have a single hitset, get the layer + unsigned int layer = TrkrDefs::getLayer(hitsetiter->first); + + // count all hits in this hitset + TrkrHitSet::ConstRange hitrangei = hitsetiter->second->getHits(); + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) + { + ++nhits[layer]; + } + auto range = clustermap->getClusters(hitsetiter->first); + for (auto clusIter = range.first; clusIter != range.second; ++clusIter) + { + const auto cluskey = clusIter->first; + // const auto cluster = clusIter->second; + // unsigned int layer = TrkrDefs::getLayer(cluskey); + nclusters[TrkrDefs::getLayer(cluskey)]++; + } } } } @@ -525,37 +529,41 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) float occ31 = 0; float occ316 = 0; - TrkrHitSetContainer* hitmap_in = findNode::getClass(topNode, "TRKR_HITSET"); - if (hitmap_in) + for (const auto& [trkrID, trkrName] : TrkrDefs::TrkrNames) { - TrkrHitSetContainer::ConstRange all_hitsets = hitmap_in->getHitSets(); - for (TrkrHitSetContainer::ConstIterator hitsetiter = all_hitsets.first; - hitsetiter != all_hitsets.second; - ++hitsetiter) + TrkrHitSetContainer* hitmap_in = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + + if (hitmap_in) { - // we have a single hitset, get the layer - unsigned int layer = TrkrDefs::getLayer(hitsetiter->first); - if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) + TrkrHitSetContainer::ConstRange all_hitsets = hitmap_in->getHitSets(); + for (TrkrHitSetContainer::ConstIterator hitsetiter = all_hitsets.first; + hitsetiter != all_hitsets.second; + ++hitsetiter) { - // count all hits in this hitset - TrkrHitSet::ConstRange hitrangei = hitsetiter->second->getHits(); - for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr) + // we have a single hitset, get the layer + unsigned int layer = TrkrDefs::getLayer(hitsetiter->first); + if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) { - nhit[layer]++; - nhit_tpc_all++; - if ((float) layer == _nlayers_maps + _nlayers_intt) - { - nhit_tpc_in++; - } - if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc - 1) - { - nhit_tpc_out++; - } - if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc / 2 - 1) + // count all hits in this hitset + TrkrHitSet::ConstRange hitrangei = hitsetiter->second->getHits(); + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) { - nhit_tpc_mid++; + nhit[layer]++; + nhit_tpc_all++; + if ((float) layer == _nlayers_maps + _nlayers_intt) + { + nhit_tpc_in++; + } + if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc - 1) + { + nhit_tpc_out++; + } + if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc / 2 - 1) + { + nhit_tpc_mid++; + } } } } @@ -756,89 +764,92 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) _timer->restart(); } // need things off of the DST... - TrkrHitSetContainer* hitmap = findNode::getClass(topNode, "TRKR_HITSET"); - PHG4TpcCylinderGeomContainer* geom_container_local = - findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); - if (!geom_container_local) + for (const auto& [trkrID, trkrName] : TrkrDefs::TrkrNames) { - std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; - return; - } + TrkrHitSetContainer* hitmap = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + PHG4TpcCylinderGeomContainer* geom_container_local = + findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); + if (!geom_container_local) + { + std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; + return; + } - if (hitmap) - { - TrkrHitSetContainer::ConstRange all_hitsets = hitmap->getHitSets(); - for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; - iter != all_hitsets.second; - ++iter) + if (hitmap) { - TrkrDefs::hitsetkey hitset_key = iter->first; - TrkrHitSet* hitset = iter->second; - - // get all hits for this hitset - TrkrHitSet::ConstRange hitrangei = hitset->getHits(); - for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr) + TrkrHitSetContainer::ConstRange all_hitsets = hitmap->getHitSets(); + for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; + iter != all_hitsets.second; + ++iter) { - TrkrDefs::hitkey hit_key = hitr->first; - TrkrHit* hit = hitr->second; - float event = _ievent; - float hitID = hit_key; - float e = hit->getEnergy(); - float adc = hit->getAdc(); - float layer_local = TrkrDefs::getLayer(hitset_key); - float sector = TpcDefs::getSectorId(hitset_key); - float side = TpcDefs::getSide(hitset_key); - float cellID = 0; - float ecell = hit->getAdc(); - - float phibin = NAN; - float tbin = NAN; - float phi = NAN; - float z = NAN; - - if (layer_local >= _nlayers_maps + _nlayers_intt && layer_local < _nlayers_maps + _nlayers_intt + _nlayers_tpc) + TrkrDefs::hitsetkey hitset_key = iter->first; + TrkrHitSet* hitset = iter->second; + + // get all hits for this hitset + TrkrHitSet::ConstRange hitrangei = hitset->getHits(); + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) { - PHG4TpcCylinderGeom* GeoLayer_local = geom_container_local->GetLayerCellGeom(layer_local); - phibin = (float) TpcDefs::getPad(hit_key); - tbin = (float) TpcDefs::getTBin(hit_key); - phi = GeoLayer_local->get_phicenter(phibin); - - double zdriftlength = tbin * m_tGeometry->get_drift_velocity() * AdcClockPeriod; - // convert z drift length to z position in the TPC - // cout << " tbin: " << tbin << " vdrift " <get_drift_velocity() << " l drift: " << zdriftlength <get_zbins(); - double m_tdriftmax = AdcClockPeriod * NTBins / 2.0; - double clusz = (m_tdriftmax * m_tGeometry->get_drift_velocity()) - zdriftlength; - if (side == 0) + TrkrDefs::hitkey hit_key = hitr->first; + TrkrHit* hit = hitr->second; + float event = _ievent; + float hitID = hit_key; + float e = hit->getEnergy(); + float adc = hit->getAdc(); + float layer_local = TrkrDefs::getLayer(hitset_key); + float sector = TpcDefs::getSectorId(hitset_key); + float side = TpcDefs::getSide(hitset_key); + float cellID = 0; + float ecell = hit->getAdc(); + + float phibin = NAN; + float tbin = NAN; + float phi = NAN; + float z = NAN; + + if (layer_local >= _nlayers_maps + _nlayers_intt && layer_local < _nlayers_maps + _nlayers_intt + _nlayers_tpc) { - clusz = -clusz; + PHG4TpcCylinderGeom* GeoLayer_local = geom_container_local->GetLayerCellGeom(layer_local); + phibin = (float) TpcDefs::getPad(hit_key); + tbin = (float) TpcDefs::getTBin(hit_key); + phi = GeoLayer_local->get_phicenter(phibin); + + double zdriftlength = tbin * m_tGeometry->get_drift_velocity() * AdcClockPeriod; + // convert z drift length to z position in the TPC + // cout << " tbin: " << tbin << " vdrift " <get_drift_velocity() << " l drift: " << zdriftlength <get_zbins(); + double m_tdriftmax = AdcClockPeriod * NTBins / 2.0; + double clusz = (m_tdriftmax * m_tGeometry->get_drift_velocity()) - zdriftlength; + if (side == 0) + { + clusz = -clusz; + } + z = clusz; } - z = clusz; - } - float hit_data[] = { - event, - (float) _iseed, - hitID, - e, - adc, - layer_local, - sector, - side, - cellID, - ecell, - (float) phibin, - (float) tbin, - phi, - z, - nhit_tpc_all, - nhit_tpc_in, - nhit_tpc_mid, - nhit_tpc_out, nclus_all, nclus_tpc, nclus_intt, nclus_maps, nclus_mms}; - - _ntp_hit->Fill(hit_data); + float hit_data[] = { + event, + (float) _iseed, + hitID, + e, + adc, + layer_local, + sector, + side, + cellID, + ecell, + (float) phibin, + (float) tbin, + phi, + z, + nhit_tpc_all, + nhit_tpc_in, + nhit_tpc_mid, + nhit_tpc_out, nclus_all, nclus_tpc, nclus_intt, nclus_maps, nclus_mms}; + + _ntp_hit->Fill(hit_data); + } } } } @@ -873,8 +884,17 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } TrkrClusterHitAssoc* clusterhitmap = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); - TrkrHitSetContainer* hitsets = findNode::getClass(topNode, "TRKR_HITSET"); + + std::map hitsetsmap; + for (const auto & [trkrID, trkrName] : TrkrDefs::TrkrNames) + { + TrkrHitSetContainer * hitsets = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + if (hitsets) + hitsetsmap[trkrID] = hitsets; + } + TrkrClusterIterationMapv1* _iteration_map = findNode::getClass(topNode, "CLUSTER_ITERATION_MAP"); + ClusterErrorPara ClusErrPara; if (Verbosity() > 1) { @@ -894,7 +914,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) { cout << "no clusterhitmap" << endl; } - if (hitsets != nullptr) + if (hitsetsmap.size() != 0) { cout << "got hitsets" << endl; } @@ -904,7 +924,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } } - if (clustermap && clusterhitmap && hitsets) + if (clustermap && clusterhitmap && hitsetsmap.size() != 0) { for (const auto& hitsetkey : clustermap->getHitSetKeys()) { @@ -955,8 +975,6 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) { phisize = cluster->getPhiSize(); zsize = cluster->getZSize(); - double clusRadius = r; - ClusterErrorPara ClusErrPara; TrackSeed* seed = nullptr; if (track != nullptr) { @@ -970,7 +988,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } if (seed != nullptr) { - auto para_errors = ClusErrPara.get_cluster_error(seed, cluster, clusRadius, cluster_key); + auto para_errors = ClusErrPara.get_cluster_error(cluster, r, cluster_key, seed->get_qOverR(), seed->get_slope()); pephi = sqrt(para_errors.first * Acts::UnitConstants::cm2); pez = sqrt(para_errors.second * Acts::UnitConstants::cm2); } @@ -979,11 +997,13 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) else if (m_cluster_version == 5) { TrkrClusterv5* clusterv5 = dynamic_cast(cluster); + auto para_errors = ClusErrPara.get_clusterv5_modified_error(clusterv5,r ,cluster_key); + phisize = clusterv5->getPhiSize(); zsize = clusterv5->getZSize(); // double clusRadius = r; - ez = clusterv5->getZError(); - ephi = clusterv5->getRPhiError(); + ez = sqrt(para_errors.second); + ephi = sqrt(para_errors.first); maxadc = clusterv5->getMaxAdc(); } float e = cluster->getAdc(); @@ -1004,26 +1024,35 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } */ float sumadc = 0; - TrkrHitSetContainer::Iterator hitset = hitsets->findOrAddHitSet(hitsetkey_local); - std::pair::const_iterator, std::multimap::const_iterator> - hitrange = clusterhitmap->getHits(cluster_key); - for (std::multimap::const_iterator - clushititer = hitrange.first; - clushititer != hitrange.second; ++clushititer) + + auto hitsetsmap_iter = hitsetsmap.find(TrkrDefs::getTrkrId(hitsetkey)); + if (hitsetsmap_iter != hitsetsmap.end()) { - TrkrHit* hit = hitset->second->getHit(clushititer->second); - if (!hit) + TrkrHitSetContainer* hitsets = hitsetsmap_iter->second; + assert(hitsets); + + TrkrHitSetContainer::Iterator hitset = hitsets->findOrAddHitSet(hitsetkey_local); + std::pair::const_iterator, std::multimap::const_iterator> + hitrange = clusterhitmap->getHits(cluster_key); + for (std::multimap::const_iterator + clushititer = hitrange.first; + clushititer != hitrange.second; ++clushititer) { - continue; - } + TrkrHit* hit = hitset->second->getHit(clushititer->second); + if (!hit) + { + continue; + } - ++size; - sumadc += (hit->getAdc() - 70); - if ((hit->getAdc() - 70) > maxadc) - { - maxadc = (hit->getAdc() - 70); + ++size; + sumadc += (hit->getAdc() - 70); + if ((hit->getAdc() - 70) > maxadc) + { + maxadc = (hit->getAdc() - 70); + } } - } + } // if (hitsetsmap_iter != hitsetsmap.end()) + e = sumadc; float trackID = NAN; diff --git a/offline/packages/bbc/BbcDefs.h b/offline/packages/bbc/BbcDefs.h new file mode 100644 index 0000000000..d8ae92001d --- /dev/null +++ b/offline/packages/bbc/BbcDefs.h @@ -0,0 +1,88 @@ +#ifndef BBC_BBCDEFS_H +#define BBC_BBCDEFS_H + +#include +#include + +namespace BbcDefs +{ + const Double_t index_refract = 1.4585; + const Double_t v_ckov = 1.0 / index_refract; // velocity threshold for CKOV + const Double_t C = 29.9792458; // cm/ns + + // kludge where we have the hardcoded positions of the tubes + // These are the x,y for the south BBC (in cm). + // The north inverts the x coordinate (x -> -x) + + /* unused causes compiler warning + const float TubeLoc[64][2] = { + { -12.2976, 4.26 }, + { -12.2976, 1.42 }, + { -9.83805, 8.52 }, + { -9.83805, 5.68 }, + { -9.83805, 2.84 }, + { -7.37854, 9.94 }, + { -7.37854, 7.1 }, + { -7.37854, 4.26 }, + { -7.37854, 1.42 }, + { -4.91902, 11.36 }, + { -4.91902, 8.52 }, + { -4.91902, 5.68 }, + { -2.45951, 12.78 }, + { -2.45951, 9.94 }, + { -2.45951, 7.1 }, + { 0, 11.36 }, + { 0, 8.52 }, + { 2.45951, 12.78 }, + { 2.45951, 9.94 }, + { 2.45951, 7.1 }, + { 4.91902, 11.36 }, + { 4.91902, 8.52 }, + { 4.91902, 5.68 }, + { 7.37854, 9.94 }, + { 7.37854, 7.1 }, + { 7.37854, 4.26 }, + { 7.37854, 1.42 }, + { 9.83805, 8.52 }, + { 9.83805, 5.68 }, + { 9.83805, 2.84 }, + { 12.2976, 4.26 }, + { 12.2976, 1.42 }, + { 12.2976, -4.26 }, + { 12.2976, -1.42 }, + { 9.83805, -8.52 }, + { 9.83805, -5.68 }, + { 9.83805, -2.84 }, + { 7.37854, -9.94 }, + { 7.37854, -7.1 }, + { 7.37854, -4.26 }, + { 7.37854, -1.42 }, + { 4.91902, -11.36 }, + { 4.91902, -8.52 }, + { 4.91902, -5.68 }, + { 2.45951, -12.78 }, + { 2.45951, -9.94 }, + { 2.45951, -7.1 }, + { 0, -11.36 }, + { 0, -8.52 }, + { -2.45951, -12.78 }, + { -2.45951, -9.94 }, + { -2.45951, -7.1 }, + { -4.91902, -11.36 }, + { -4.91902, -8.52 }, + { -4.91902, -5.68 }, + { -7.37854, -9.94 }, + { -7.37854, -7.1 }, + { -7.37854, -4.26 }, + { -7.37854, -1.42 }, + { -9.83805, -8.52 }, + { -9.83805, -5.68 }, + { -9.83805, -2.84 }, + { -12.2976, -4.26 }, + { -12.2976, -1.42 } + }; + */ + +} // namespace BbcDefs + +#endif diff --git a/offline/packages/bbc/BbcLinkDef.h b/offline/packages/bbc/BbcLinkDef.h deleted file mode 100644 index 725e3d9b89..0000000000 --- a/offline/packages/bbc/BbcLinkDef.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef __CINT__ - -#pragma link off all classes; -#pragma link off all functions; -#pragma link off all globals; - -#pragma link C++ class BbcOut+; -#pragma link C++ class BbcOutV1+; -#pragma link C++ class BbcNorthSouth+; -#pragma link C++ class BbcNorthSouthV1+; -#pragma link C++ class BbcPmtContainer+; -#pragma link C++ class BbcPmtContainerV1+; -#pragma link C++ class BbcPmtHit+; -#pragma link C++ class BbcPmtHitV1+; - -#endif diff --git a/offline/packages/bbc/BbcNorthSouth.cc b/offline/packages/bbc/BbcNorthSouth.cc index 496cbb3f1e..102ca87a3c 100644 --- a/offline/packages/bbc/BbcNorthSouth.cc +++ b/offline/packages/bbc/BbcNorthSouth.cc @@ -1,11 +1,6 @@ #include "BbcNorthSouth.h" -using namespace std; - -ClassImp(BbcNorthSouth) - -void BbcNorthSouth::identify(ostream& out) const +void BbcNorthSouth::identify(std::ostream& out) const { - out << "identify yourself: I am a BbcNorthSouth object" << endl; + out << "identify yourself: I am a BbcNorthSouth object" << std::endl; } - diff --git a/offline/packages/bbc/BbcNorthSouth.h b/offline/packages/bbc/BbcNorthSouth.h index 75fad2c887..76427c4233 100644 --- a/offline/packages/bbc/BbcNorthSouth.h +++ b/offline/packages/bbc/BbcNorthSouth.h @@ -1,30 +1,41 @@ -#ifndef __BBCNORTHSOUTH_H__ -#define __BBCNORTHSOUTH_H__ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCNORTHSOUTH_H +#define BBC_BBCNORTHSOUTH_H -#include "phool/phool.h" -#include +#include "BbcReturnCodes.h" +#include +#include -class BbcNorthSouth : public TObject -{ -public: - BbcNorthSouth() { } - BbcNorthSouth(const Short_t /*npmts*/, const Float_t /*ncharge*/, const Float_t /*meantime*/) {} - virtual ~BbcNorthSouth() { } - virtual void identify(std::ostream& os = std::cout) const; - - virtual Short_t get_nPMT() const { PHOOL_VIRTUAL_WARNING; return -9999; } - virtual Float_t get_nCharge() const { PHOOL_VIRTUAL_WARNING; return -9999; } - virtual Float_t get_MeanTime() const { PHOOL_VIRTUAL_WARNING; return -9999; } - -protected: - - virtual void Clear(Option_t * /*option*/ = "") override { PHOOL_VIRTUAL_WARNING; } - -private: - - ClassDefOverride(BbcNorthSouth,1) +#include +class BbcNorthSouth : public PHObject +{ + public: + BbcNorthSouth() = default; + + ~BbcNorthSouth() override = default; + virtual void identify(std::ostream& os = std::cout) const override; + + virtual short get_nPMT() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_SHORT; + } + virtual float get_nCharge() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_FLOAT; + } + virtual float get_MeanTime() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_FLOAT; + } + + private: + ClassDefOverride(BbcNorthSouth, 1) }; #endif diff --git a/offline/packages/bbc/BbcNorthSouthLinkDef.h b/offline/packages/bbc/BbcNorthSouthLinkDef.h new file mode 100644 index 0000000000..4201bdb864 --- /dev/null +++ b/offline/packages/bbc/BbcNorthSouthLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcNorthSouth + ; + +#endif diff --git a/offline/packages/bbc/BbcNorthSouthV1.cc b/offline/packages/bbc/BbcNorthSouthV1.cc index 572b40efd4..0b1b933d9f 100644 --- a/offline/packages/bbc/BbcNorthSouthV1.cc +++ b/offline/packages/bbc/BbcNorthSouthV1.cc @@ -1,18 +1,13 @@ #include "BbcNorthSouthV1.h" -using namespace std; - -ClassImp(BbcNorthSouthV1) - -BbcNorthSouthV1::BbcNorthSouthV1(const Short_t npmt, const Float_t ncharge, const Float_t meantime) +BbcNorthSouthV1::BbcNorthSouthV1(const short npmt, const float ncharge, const float meantime) + : nPmt(npmt) + , nCharge(ncharge) + , MeanTime(meantime) { - nPmt = npmt; - nCharge = ncharge; - MeanTime = meantime; } - -void BbcNorthSouthV1::identify(ostream& out) const +void BbcNorthSouthV1::identify(std::ostream& out) const { - out << "identify yourself: I am a BbcNorthSouthV1 object" << endl; + out << "identify yourself: I am a BbcNorthSouthV1 object" << std::endl; } diff --git a/offline/packages/bbc/BbcNorthSouthV1.h b/offline/packages/bbc/BbcNorthSouthV1.h index 5ae8c60a20..c812e80225 100644 --- a/offline/packages/bbc/BbcNorthSouthV1.h +++ b/offline/packages/bbc/BbcNorthSouthV1.h @@ -1,30 +1,34 @@ -#ifndef __BBCNORTHSOUTHV1_H__ -#define __BBCNORTHSOUTHV1_H__ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCNORTHSOUTHV1_H +#define BBC_BBCNORTHSOUTHV1_H #include "BbcNorthSouth.h" +#include +#include class BbcNorthSouthV1 : public BbcNorthSouth { -public: - BbcNorthSouthV1() { } - BbcNorthSouthV1(const Short_t npmt, const Float_t chargesum, const Float_t timing); - virtual ~BbcNorthSouthV1() { } + public: + BbcNorthSouthV1() = default; + BbcNorthSouthV1(const short npmt, const float chargesum, const float timing); + virtual ~BbcNorthSouthV1() {} void identify(std::ostream& os = std::cout) const override; - Short_t get_nPMT() const override { return nPmt; } - Float_t get_nCharge() const override { return nCharge; } - Float_t get_MeanTime() const override { return MeanTime; } + short get_nPMT() const override { return nPmt; } + float get_nCharge() const override { return nCharge; } + float get_MeanTime() const override { return MeanTime; } -protected: - virtual void Clear(Option_t * /*option*/ = "") override { } + protected: + virtual void Clear(Option_t* /*option*/ = "") override {} - Short_t nPmt; - Float_t nCharge; - Float_t MeanTime; + short nPmt = 0; + float nCharge = std::numeric_limits::quiet_NaN(); + float MeanTime = std::numeric_limits::quiet_NaN(); -private: - ClassDefOverride(BbcNorthSouth,1) + private: + ClassDefOverride(BbcNorthSouth, 1) }; #endif diff --git a/offline/packages/bbc/BbcNorthSouthV1LinkDef.h b/offline/packages/bbc/BbcNorthSouthV1LinkDef.h new file mode 100644 index 0000000000..2f53ca3dbd --- /dev/null +++ b/offline/packages/bbc/BbcNorthSouthV1LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcNorthSouthV1 + ; + +#endif diff --git a/offline/packages/bbc/BbcOut.cc b/offline/packages/bbc/BbcOut.cc index ebca871408..0d69e446da 100644 --- a/offline/packages/bbc/BbcOut.cc +++ b/offline/packages/bbc/BbcOut.cc @@ -1,21 +1,19 @@ -#include "BbcReturnCodes.h" #include "BbcOut.h" +#include "BbcReturnCodes.h" #include #include -//ClassImp(BbcOut) - void BbcOut::identify(std::ostream& os) const { - os << "virtual BbcOut object"; - return ; + os << "virtual BbcOut object" << std::endl; + return; } void BbcOut::Reset() { std::cout << "ERROR BbcOut: Reset() not implemented by daughter class" << std::endl; - return ; + return; } int BbcOut::isValid() const @@ -24,90 +22,89 @@ int BbcOut::isValid() const return 0; } -Float_t BbcOut::get_VertexPoint() const +float BbcOut::get_VertexPoint() const { virtual_warning("get_VertexPoint()"); return NAN; } -Float_t BbcOut::get_dVertexPoint() const +float BbcOut::get_dVertexPoint() const { virtual_warning("get_dVertexPoint()"); return NAN; } -Float_t BbcOut::get_TimeZero() const +float BbcOut::get_TimeZero() const { virtual_warning("get_TimeZero()"); return NAN; } //__________________________________________ -Float_t BbcOut::get_dTimeZero() const +float BbcOut::get_dTimeZero() const { virtual_warning("get_dTimeZero()"); return NAN; } //__________________________________________ -void BbcOut::set_TimeZero(const Float_t, const Float_t) +void BbcOut::set_TimeZero(const float /*unused*/, const float /*unused*/) { - virtual_warning("set_TimeZero(const Float_t t0, const Float_t t0err)"); - return ; + virtual_warning("set_TimeZero(const float t0, const float t0err)"); + return; } //__________________________________________ -void BbcOut::set_Vertex( const Float_t, const Float_t ) +void BbcOut::set_Vertex(const float /*unused*/, const float /*unused*/) { - virtual_warning("set_Vertex(const Float_t vtx, const Float_t vtxerr)"); - return ; + virtual_warning("set_Vertex(const float vtx, const float vtxerr)"); + return; } //__________________________________________ -void BbcOut::set_dZVertex(const Float_t ) +void BbcOut::set_dZVertex(const float /*unused*/) { - virtual_warning("set_dZVertex(const Float_t vtxerr)"); - return ; + virtual_warning("set_dZVertex(const float vtxerr)"); + return; } //________________________________________________________________ -void BbcOut::AddBbcNS(const int /*nBbc*/, const Short_t /*npmt*/, const Float_t /*energy*/, const Float_t /*timing*/) +void BbcOut::AddBbcNS(const int /*nBbc*/, const short /*npmt*/, const float /*energy*/, const float /*timing*/) { - virtual_warning("AddBbcNS(const int iBBC, const Short_t npmt, const Float_t energy, const Float_t timing)"); - return ; + virtual_warning("AddBbcNS(const int iBBC, const short npmt, const float energy, const float timing)"); + return; } -Short_t BbcOut::get_nPMT(const int /*nBbc*/) const +short BbcOut::get_nPMT(const int /*nBbc*/) const { virtual_warning("get_nPMT(const int nBbc)"); - return BBC_INVALID_SHORT; + return BbcReturnCodes::BBC_INVALID_SHORT; } -Float_t BbcOut::get_nCharge(const int /*nBbc*/) const +float BbcOut::get_nCharge(const int /*nBbc*/) const { virtual_warning("get_nCharge(const int nBbc)"); return NAN; } -Float_t BbcOut::get_Timing(const int /*nBbc*/) const +float BbcOut::get_Timing(const int /*nBbc*/) const { virtual_warning("get_Timing(const int nBbc)"); return NAN; } -void BbcOut::virtual_warning(const char *funcsname) const +void BbcOut::virtual_warning(const std::string& funcsname) const { std::cout << "BbcOut::" << funcsname << " is virtual, doing nothing" << std::endl; - return ; + return; } void BbcOut::FillFromClass(const BbcOut& old) { - for(int iarm = 0; iarm < 2; iarm++) + for (int iarm = 0; iarm < 2; iarm++) { - AddBbcNS( iarm, old.get_nPMT(iarm), old.get_nCharge(iarm), old.get_Timing(iarm) ); + AddBbcNS(iarm, old.get_nPMT(iarm), old.get_nCharge(iarm), old.get_Timing(iarm)); } - set_TimeVertex( old.get_TimeZero(), old.get_dTimeZero(), old.get_VertexPoint(), old.get_dVertexPoint() ); - + set_TimeVertex(old.get_TimeZero(), old.get_dTimeZero(), old.get_VertexPoint(), old.get_dVertexPoint()); } diff --git a/offline/packages/bbc/BbcOut.h b/offline/packages/bbc/BbcOut.h index b6a1f38d7e..9a68c0d709 100644 --- a/offline/packages/bbc/BbcOut.h +++ b/offline/packages/bbc/BbcOut.h @@ -1,97 +1,97 @@ -#ifndef __BBCOUT_H__ -#define __BBCOUT_H__ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCOUT_H +#define BBC_BBCOUT_H -#include "phool/PHObject.h" +#include + +#include /// -class BbcOut: public PHObject +class BbcOut : public PHObject { -public: + public: /// - virtual ~BbcOut() {} - + ~BbcOut() override {} + /** identify Function from PHObject - @param os Output Stream + @param os Output Stream */ - virtual void identify(std::ostream& os = std::cout) const override; + void identify(std::ostream& os = std::cout) const override; /// Clear Event - virtual void Reset() override; + void Reset() override; /// isValid returns non zero if object contains vailid data - virtual int isValid() const override; + int isValid() const override; /// get ZVertex determined by Bbc - virtual Float_t get_VertexPoint() const; + virtual float get_VertexPoint() const; /// get Error on ZVertex determined by Bbc - virtual Float_t get_dVertexPoint() const; + virtual float get_dVertexPoint() const; /// get T0 determined by Bbc - virtual Float_t get_TimeZero() const; + virtual float get_TimeZero() const; /// get Error on T0 determined by Bbc - virtual Float_t get_dTimeZero() const; + virtual float get_dTimeZero() const; /** set T0, Error on T0, ZVertex and Error on ZVertex @param t0 Bbc T0 @param t0err Bbc Error on T0 - @param vtx Bbc ZVertex + @param vtx Bbc ZVertex @param vtxerr Bbc Error on ZVertex */ - virtual void set_TimeVertex(const Float_t t0, const Float_t t0err, const Float_t vtx, const Float_t vtxerr) - { - set_TimeZero( t0, t0err ); - set_Vertex( vtx, vtxerr ); + virtual void set_TimeVertex(const float t0, const float t0err, const float vtx, const float vtxerr) + { + set_TimeZero(t0, t0err); + set_Vertex(vtx, vtxerr); } /** set T0 for Bbc @param t0 Bbc T0 @param t0err Bbc T0 error */ - virtual void set_TimeZero(const Float_t t0, const Float_t t0err = 0); + virtual void set_TimeZero(const float t0, const float t0err = 0); //! set vertex - virtual void set_Vertex( const Float_t vtx, const Float_t vtxerr); - + virtual void set_Vertex(const float vtx, const float vtxerr); + /** set Vtx Error for Bbc @param vtxerr Bbc Vtx Error */ - virtual void set_dZVertex(const Float_t vtxerr); - + virtual void set_dZVertex(const float vtxerr); + /** Add Bbc North/South object containing Number of pmt's, Energy and Timing @param npmt Number of PMT's fired @param ncharge Number of Charged Particles into North/South @param timing Timing of North/South @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual void AddBbcNS(const int iBBC, const Short_t npmt, const Float_t ncharge, const Float_t timing); + virtual void AddBbcNS(const int iBBC, const short npmt, const float ncharge, const float timing); /** get Number of PMT's fired in North/South Bbc @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual Short_t get_nPMT(const int iBBC) const; + virtual short get_nPMT(const int iBBC) const; /** get Number of Charged Particles into North/South Bbc @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual Float_t get_nCharge(const int iBBC) const; + virtual float get_nCharge(const int iBBC) const; /** get Timing of North/South Bbc @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual Float_t get_Timing(const int iBBC) const; + virtual float get_Timing(const int iBBC) const; virtual void FillFromClass(const BbcOut& old); - -private: - void virtual_warning(const char *funcname) const; - - /// Root Internal Version - ClassDefOverride(BbcOut,1) + private: + void virtual_warning(const std::string& funcname) const; + ClassDefOverride(BbcOut, 1) }; #endif - diff --git a/offline/packages/bbc/BbcOutLinkDef.h b/offline/packages/bbc/BbcOutLinkDef.h new file mode 100644 index 0000000000..2fa23e8cab --- /dev/null +++ b/offline/packages/bbc/BbcOutLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcOut + ; + +#endif diff --git a/offline/packages/bbc/BbcOutV1.cc b/offline/packages/bbc/BbcOutV1.cc index 782fd21270..eb400b25ba 100644 --- a/offline/packages/bbc/BbcOutV1.cc +++ b/offline/packages/bbc/BbcOutV1.cc @@ -1,46 +1,40 @@ -#include "BbcReturnCodes.h" #include "BbcOutV1.h" #include "BbcNorthSouthV1.h" +#include "BbcReturnCodes.h" #include + #include -//static const int NPMTBBCV1 = 128; static const int NBBC = 2; -using namespace std; - -ClassImp(BbcOutV1) - //______________________________________ BbcOutV1::BbcOutV1() { Init(); - BbcNS = new TClonesArray("BbcNorthSouthV1",NBBC); + BbcNS = new TClonesArray("BbcNorthSouthV1", NBBC); } //______________________________________ void BbcOutV1::Init() { - Bbc_ZVertex = -99999.9; - Bbc_dZVertex = -99999.9; - Bbc_TimeZero = -99999.9; - Bbc_dTimeZero = -99999.9; + Bbc_ZVertex = std::numeric_limits::quiet_NaN(); + Bbc_dZVertex = std::numeric_limits::quiet_NaN(); + Bbc_TimeZero = std::numeric_limits::quiet_NaN(); + Bbc_dTimeZero = std::numeric_limits::quiet_NaN(); } //______________________________________ BbcOutV1::~BbcOutV1() -{ - if (BbcNS) - { - delete BbcNS; - } +{ + delete BbcNS; } //______________________________________ int BbcOutV1::isValid() const { - return((Bbc_TimeZero >-9999.) ? 1 : 0); +// compatible with old invalid setting of -9999.9 + return ((std::isfinite(Bbc_TimeZero) && (Bbc_TimeZero > -9999.)) ? 1 : 0); } //______________________________________ @@ -54,60 +48,59 @@ void BbcOutV1::Reset() } //______________________________________ -void BbcOutV1::identify(ostream& out) const +void BbcOutV1::identify(std::ostream &out) const { - out << "identify yourself: I am a BbcOutV1 object" << endl; - out << "Vertex: " << Bbc_ZVertex << " Error: " << Bbc_dZVertex << endl; - out << "T0: " << Bbc_TimeZero << " Error: " << Bbc_dTimeZero << endl; + out << "identify yourself: I am a BbcOutV1 object" << std::endl; + out << "Vertex: " << Bbc_ZVertex << " Error: " << Bbc_dZVertex << std::endl; + out << "T0: " << Bbc_TimeZero << " Error: " << Bbc_dTimeZero << std::endl; } //______________________________________ -void BbcOutV1::set_TimeZero(const Float_t t0, const Float_t t0err ) +void BbcOutV1::set_TimeZero(const float t0, const float t0err) { - Bbc_TimeZero = t0; + Bbc_TimeZero = t0; Bbc_dTimeZero = t0err; } //______________________________________ -void BbcOutV1::set_Vertex( const Float_t vtx, const Float_t vtxerr) +void BbcOutV1::set_Vertex(const float vtx, const float vtxerr) { - Bbc_ZVertex = vtx; - Bbc_dZVertex = vtxerr; + Bbc_ZVertex = vtx; + Bbc_dZVertex = vtxerr; } //______________________________________ -void BbcOutV1::set_dZVertex( const Float_t vtxerr) +void BbcOutV1::set_dZVertex(const float vtxerr) { Bbc_dZVertex = vtxerr; } //______________________________________ -void BbcOutV1::AddBbcNS(const int iBBC, const Short_t npmt, const Float_t energy, const Float_t timing) +void BbcOutV1::AddBbcNS(const int iBBC, const short npmt, const float energy, const float timing) { TClonesArray &bbcns = *BbcNS; - new(bbcns[iBBC]) BbcNorthSouthV1(npmt, energy,timing); + new (bbcns[iBBC]) BbcNorthSouthV1(npmt, energy, timing); } //______________________________________ -Short_t BbcOutV1::get_nPMT(const int nBbc) const +short BbcOutV1::get_nPMT(const int nBbc) const { - BbcNorthSouthV1 *bbcns = (BbcNorthSouthV1*) GetBbcNS()->UncheckedAt(nBbc); - // if bbcns=nil (does not exist) return BBC_INVALID_SHORT, else nPMT - return((bbcns) ? bbcns->get_nPMT() : BBC_INVALID_SHORT); + BbcNorthSouthV1 *bbcns = static_cast (GetBbcNS()->UncheckedAt(nBbc)); + // if bbcns=null (does not exist) return BbcReturnCodes::BBC_INVALID_SHORT, else nPMT + return ((bbcns) ? bbcns->get_nPMT() : BbcReturnCodes::BBC_INVALID_SHORT); } //______________________________________ -Float_t BbcOutV1::get_nCharge(const int nBbc) const +float BbcOutV1::get_nCharge(const int nBbc) const { - BbcNorthSouth *bbcns = (BbcNorthSouthV1*) GetBbcNS()->UncheckedAt(nBbc); - // if bbcns=nil (does not exist) return BBC_INVALID_FLOAT, else Energy - return((bbcns) ? bbcns->get_nCharge() : BBC_INVALID_FLOAT); + BbcNorthSouth *bbcns = static_cast (GetBbcNS()->UncheckedAt(nBbc)); + // if bbcns=null (does not exist) return BbcReturnCodes::BBC_INVALID_FLOAT, else Energy + return ((bbcns) ? bbcns->get_nCharge() : BbcReturnCodes::BBC_INVALID_FLOAT); } -Float_t BbcOutV1::get_Timing(const int nBbc) const +float BbcOutV1::get_Timing(const int nBbc) const { - BbcNorthSouth *bbcns = (BbcNorthSouthV1*) GetBbcNS()->UncheckedAt(nBbc); - // if bbcns=nil (does not exist) return BBC_INVALID_FLOAT, else Timing - return((bbcns) ? bbcns->get_MeanTime() : BBC_INVALID_FLOAT); + BbcNorthSouth *bbcns = static_cast (GetBbcNS()->UncheckedAt(nBbc)); + // if bbcns=null (does not exist) return BbcReturnCodes::BBC_INVALID_FLOAT, else Timing + return ((bbcns) ? bbcns->get_MeanTime() : BbcReturnCodes::BBC_INVALID_FLOAT); } - diff --git a/offline/packages/bbc/BbcOutV1.h b/offline/packages/bbc/BbcOutV1.h index b884b0de47..53e07fbeda 100644 --- a/offline/packages/bbc/BbcOutV1.h +++ b/offline/packages/bbc/BbcOutV1.h @@ -1,55 +1,59 @@ -#ifndef __BBCOUTV1_H -#define __BBCOUTV1_H +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCOUTV1_H +#define BBC_BBCOUTV1_H #include "BbcOut.h" + +#include + class TClonesArray; /// -class BbcOutV1: public BbcOut +class BbcOutV1 : public BbcOut { -public: - + public: /// BbcOutV1(); /// - virtual ~BbcOutV1(); + ~BbcOutV1() override; /// Clear Event from memory - virtual void Reset() override; + void Reset() override; /** identify Function from PHObject - @param os Output Stream + @param os Output Stream */ - virtual void identify(std::ostream& os = std::cout) const override; + void identify(std::ostream &os = std::cout) const override; /// isValid returns non zero if object contains vailid data - virtual int isValid() const override; + int isValid() const override; /// get ZVertex determined by Bbc - virtual Float_t get_VertexPoint() const override {return Bbc_ZVertex;} + float get_VertexPoint() const override { return Bbc_ZVertex; } /// get Error on ZVertex determined by Bbc - virtual Float_t get_dVertexPoint() const override {return Bbc_dZVertex;} + float get_dVertexPoint() const override { return Bbc_dZVertex; } /// get T0 determined by Bbc - virtual Float_t get_TimeZero() const override {return Bbc_TimeZero;} + float get_TimeZero() const override { return Bbc_TimeZero; } /// get Error on T0 determined by Bbc - virtual Float_t get_dTimeZero() const override {return Bbc_dTimeZero;} + float get_dTimeZero() const override { return Bbc_dTimeZero; } /** set T0 for Bbc @param t0 Bbc T0 @param t0err Bbc T0 error */ - virtual void set_TimeZero(const Float_t t0, const Float_t t0err = 0) override; + void set_TimeZero(const float t0, const float t0err = 0) override; //! set vertex - virtual void set_Vertex( const Float_t vtx, const Float_t vtxerr = 0) override; - + void set_Vertex(const float vtx, const float vtxerr = 0) override; + /** set Vtx Error for Bbc @param vtxerr Bbc Vtx Error */ - virtual void set_dZVertex(const Float_t vtxerr) override; + void set_dZVertex(const float vtxerr) override; /** Add Bbc North/South object containing Number of pmt's, Energy and Timing @param npmt Number of PMT's fired @@ -57,41 +61,36 @@ class BbcOutV1: public BbcOut @param timing Timing of North/South @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual void AddBbcNS(const int nBbc, const Short_t npmt, const Float_t chargesum, const Float_t timing) override; + void AddBbcNS(const int nBbc, const short npmt, const float chargesum, const float timing) override; /** get Number of PMT's fired in North/South Bbc @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual Short_t get_nPMT(const int nBbc) const override; - + short get_nPMT(const int nBbc) const override; /** get Number of Charged Particles into North/South Bbc @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual Float_t get_nCharge(const int nBbc) const override; + float get_nCharge(const int nBbc) const override; /** get Timing of North/South Bbc @param nBbc Arm, use Bbc::North and Bbc::South */ - virtual Float_t get_Timing(const int nBbc) const override; + float get_Timing(const int nBbc) const override; + + + private: -protected: - - virtual void Init(); - TClonesArray *GetBbcNS() const { return BbcNS; } + void Init(); -private: - - Float_t Bbc_ZVertex; - Float_t Bbc_dZVertex; - Float_t Bbc_TimeZero; - Float_t Bbc_dTimeZero; + float Bbc_ZVertex{}; + float Bbc_dZVertex{}; + float Bbc_TimeZero{}; + float Bbc_dTimeZero{}; TClonesArray *BbcNS; -private: // so the ClassDef does not show up with doc++ - ClassDefOverride(BbcOutV1,1) - + ClassDefOverride(BbcOutV1, 1) }; #endif diff --git a/offline/packages/bbc/BbcOutV1LinkDef.h b/offline/packages/bbc/BbcOutV1LinkDef.h new file mode 100644 index 0000000000..d06f7dabab --- /dev/null +++ b/offline/packages/bbc/BbcOutV1LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcOutV1 + ; + +#endif diff --git a/offline/packages/bbc/BbcPmtContainer.cc b/offline/packages/bbc/BbcPmtContainer.cc index c9c3b79734..163200103b 100644 --- a/offline/packages/bbc/BbcPmtContainer.cc +++ b/offline/packages/bbc/BbcPmtContainer.cc @@ -1,22 +1,20 @@ -#include -#include "phool/phool.h" #include "BbcPmtContainer.h" #include "BbcReturnCodes.h" -using namespace std; +#include -//ClassImp(BbcPmtContainer) +#include -void BbcPmtContainer::identify(ostream& os) const +void BbcPmtContainer::identify(std::ostream& os) const { - os << "virtual BbcPmtContainer object"; - return ; + os << "virtual BbcPmtContainer object" << std::endl; + return; } void BbcPmtContainer::Reset() { - cout << PHWHERE << "ERROR Reset() not implemented by daughter class" << endl; - return ; + std::cout << PHWHERE << "ERROR Reset() not implemented by daughter class" << std::endl; + return; } int BbcPmtContainer::isValid() const @@ -25,45 +23,50 @@ int BbcPmtContainer::isValid() const return 0; } -void BbcPmtContainer::set_npmt(const Short_t /*ival*/) +void BbcPmtContainer::set_npmt(const short /*ival*/) { virtual_warning("set_npmt(const short ival)"); - return ; + return; } short BbcPmtContainer::get_npmt() const { virtual_warning("get_npmt()"); - return BBC_INVALID_SHORT; + return BbcReturnCodes::BBC_INVALID_SHORT; +} + +short BbcPmtContainer::get_pmt(const int /*iPmt*/) const +{ + virtual_warning("get_pmt(const short iPmt)"); + return BbcReturnCodes::BBC_INVALID_SHORT; } -Float_t BbcPmtContainer::get_adc(const int /*iPmt*/) const +float BbcPmtContainer::get_adc(const int /*iPmt*/) const { virtual_warning("get_Adc(const short iPmt)"); - return BBC_INVALID_SHORT; + return BbcReturnCodes::BBC_INVALID_FLOAT; } -Float_t BbcPmtContainer::get_tdc0(const int /*iPmt*/) const +float BbcPmtContainer::get_tdc0(const int /*iPmt*/) const { virtual_warning("get_Tdc0(const short iPmt)"); - return BBC_INVALID_SHORT; + return BbcReturnCodes::BBC_INVALID_FLOAT; } -Float_t BbcPmtContainer::get_tdc1(const int /*iPmt*/) const +float BbcPmtContainer::get_tdc1(const int /*iPmt*/) const { virtual_warning("get_Tdc1(const short iPmt)"); - return BBC_INVALID_SHORT; + return BbcReturnCodes::BBC_INVALID_FLOAT; } -void BbcPmtContainer::AddBbcPmt(const Short_t /*ipmt*/, const Float_t /*adc*/, const Float_t /*tdc0*/, const Float_t /*tdc1*/) +void BbcPmtContainer::AddBbcPmt(const short /*ipmt*/, const float /*adc*/, const float /*tdc0*/, const float /*tdc1*/) { - virtual_warning("AddBbcPmtHit(const Short_t ipmt, const Short_t adc, const Float_t tdc0, const Float_t tdc1)"); - return ; + virtual_warning("AddBbcPmtHit(const short ipmt, const short adc, const float tdc0, const float tdc1)"); + return; } -void BbcPmtContainer::virtual_warning(const char *funcsname) const +void BbcPmtContainer::virtual_warning(const std::string& funcsname) const { - cout << "BbcPmtContainer::" << funcsname << " is virtual, doing nothing" << endl; - return ; + std::cout << "BbcPmtContainer::" << funcsname << " is virtual, doing nothing" << std::endl; + return; } - diff --git a/offline/packages/bbc/BbcPmtContainer.h b/offline/packages/bbc/BbcPmtContainer.h index ebca5ea07c..b4e40b0434 100644 --- a/offline/packages/bbc/BbcPmtContainer.h +++ b/offline/packages/bbc/BbcPmtContainer.h @@ -1,10 +1,14 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. // virtual Bbc PMT Container class -#ifndef __BBCPMTCONTAINER_H__ -#define __BBCPMTCONTAINER_H__ +#ifndef BBC_BBCPMTCONTAINER_H +#define BBC_BBCPMTCONTAINER_H + +#include -#include "phool/PHObject.h" #include +#include /// class BbcPmtContainer : public PHObject @@ -14,7 +18,7 @@ class BbcPmtContainer : public PHObject virtual ~BbcPmtContainer() {} /** identify Function from PHObject - @param os Output Stream + @param os Output Stream */ virtual void identify(std::ostream& os = std::cout) const override; @@ -27,25 +31,30 @@ class BbcPmtContainer : public PHObject /** set number of PMTs for Bbc @param ival Number of Bbc Pmt's */ - virtual void set_npmt(const Short_t ival); + virtual void set_npmt(const short ival); /// get Number of Bbc Pmt's - virtual Short_t get_npmt() const; + virtual short get_npmt() const; + + /** get id of Pmt iPmt in TClonesArray + @param iPmt no of Pmt in TClonesArray + */ + virtual short get_pmt(const int iPmt) const; /** get Adc of Pmt iPmt in TClonesArray @param iPmt no of Pmt in TClonesArray */ - virtual Float_t get_adc(const int iPmt) const; + virtual float get_adc(const int iPmt) const; /** get Tdc0 of Pmt iPmt in TClonesArray @param iPmt no of Pmt in TClonesArray */ - virtual Float_t get_tdc0(const int iPmt) const; + virtual float get_tdc0(const int iPmt) const; /** get Tdc1 of Pmt iPmt in TClonesArray @param iPmt no of Pmt in TClonesArray */ - virtual Float_t get_tdc1(const int iPmt) const; + virtual float get_tdc1(const int iPmt) const; /** Add Bbc Raw hit object to TCLonesArray @param ipmt Pmt id @@ -53,12 +62,12 @@ class BbcPmtContainer : public PHObject @param tdc0 Tdc0 value @param tdc1 Tdc1 value */ - virtual void AddBbcPmt(const Short_t ipmt, const Float_t adc, const Float_t tdc0, const Float_t tdc1); + virtual void AddBbcPmt(const short ipmt, const float adc, const float tdc0, const float tdc1); private: - void virtual_warning(const char *funcname) const; + void virtual_warning(const std::string& funcname) const; - ClassDefOverride(BbcPmtContainer,1) + ClassDefOverride(BbcPmtContainer, 1) }; #endif diff --git a/offline/packages/bbc/BbcPmtContainerLinkDef.h b/offline/packages/bbc/BbcPmtContainerLinkDef.h new file mode 100644 index 0000000000..25ae7d422d --- /dev/null +++ b/offline/packages/bbc/BbcPmtContainerLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcPmtContainer + ; + +#endif diff --git a/offline/packages/bbc/BbcPmtContainerV1.cc b/offline/packages/bbc/BbcPmtContainerV1.cc index b12e342bc3..a8e6baa9fe 100644 --- a/offline/packages/bbc/BbcPmtContainerV1.cc +++ b/offline/packages/bbc/BbcPmtContainerV1.cc @@ -1,37 +1,31 @@ #include "BbcPmtContainerV1.h" #include "BbcPmtHitV1.h" #include "BbcReturnCodes.h" + #include -#include -using namespace std; +#include static const int NPMTBBCV1 = 128; -ClassImp(BbcPmtContainerV1) - BbcPmtContainerV1::BbcPmtContainerV1() { // BbcPmtHit is class for single hit (members: pmt,adc,tdc0,tdc1), do not mix // with TClonesArray *BbcPmtHits BbcPmtHits = new TClonesArray("BbcPmtHitV1", NPMTBBCV1); - npmt = 0; } BbcPmtContainerV1::~BbcPmtContainerV1() { - if (BbcPmtHits) - { - delete BbcPmtHits; - } + delete BbcPmtHits; } int BbcPmtContainerV1::isValid() const { if (npmt <= 0) - { - return 0; - } + { + return 0; + } return 1; } @@ -41,31 +35,37 @@ void BbcPmtContainerV1::Reset() npmt = 0; } -void BbcPmtContainerV1::AddBbcPmt(const Short_t pmt, const Float_t adc, const Float_t tdc0, const Float_t tdc1) +void BbcPmtContainerV1::AddBbcPmt(const short pmt, const float adc, const float tdc0, const float tdc1) { TClonesArray &Bbchits = *BbcPmtHits; - new(Bbchits[npmt++]) BbcPmtHitV1(pmt, adc, tdc0, tdc1); + new (Bbchits[npmt++]) BbcPmtHitV1(pmt, adc, tdc0, tdc1); +} + +short BbcPmtContainerV1::get_pmt(const int iPmt) const +{ + BbcPmtHit *Bbchit = static_cast (GetBbcPmtHits()->UncheckedAt(iPmt)); + return ((Bbchit) ? Bbchit->get_pmt() : BbcReturnCodes::BBC_INVALID_SHORT); } -Float_t BbcPmtContainerV1::get_adc(const int iPmt) const +float BbcPmtContainerV1::get_adc(const int iPmt) const { - BbcPmtHit *Bbchit = (BbcPmtHit*) GetBbcPmtHits()->UncheckedAt(iPmt); - return ((Bbchit) ? Bbchit->get_adc() : BBC_INVALID_SHORT); + BbcPmtHit *Bbchit = static_cast (GetBbcPmtHits()->UncheckedAt(iPmt)); + return ((Bbchit) ? Bbchit->get_adc() : BbcReturnCodes::BBC_INVALID_FLOAT); } -Float_t BbcPmtContainerV1::get_tdc0(const int iPmt) const +float BbcPmtContainerV1::get_tdc0(const int iPmt) const { - BbcPmtHit *Bbchit = (BbcPmtHit*) GetBbcPmtHits()->UncheckedAt(iPmt); - return ((Bbchit) ? Bbchit->get_tdc0() : BBC_INVALID_SHORT); + BbcPmtHit *Bbchit = static_cast (GetBbcPmtHits()->UncheckedAt(iPmt)); + return ((Bbchit) ? Bbchit->get_tdc0() : BbcReturnCodes::BBC_INVALID_FLOAT); } -Float_t BbcPmtContainerV1::get_tdc1(const int iPmt) const +float BbcPmtContainerV1::get_tdc1(const int iPmt) const { - BbcPmtHit *Bbchit = (BbcPmtHit*) GetBbcPmtHits()->UncheckedAt(iPmt); - return ((Bbchit) ? Bbchit->get_tdc1() : BBC_INVALID_SHORT); + BbcPmtHit *Bbchit = static_cast (GetBbcPmtHits()->UncheckedAt(iPmt)); + return ((Bbchit) ? Bbchit->get_tdc1() : BbcReturnCodes::BBC_INVALID_FLOAT); } -void BbcPmtContainerV1::identify(ostream& out) const +void BbcPmtContainerV1::identify(std::ostream &out) const { - out << "identify yourself: I am a BbcPmtContainerV1 object" << endl; + out << "identify yourself: I am a BbcPmtContainerV1 object" << std::endl; } diff --git a/offline/packages/bbc/BbcPmtContainerV1.h b/offline/packages/bbc/BbcPmtContainerV1.h index 91e269ad27..f7d5e3364a 100644 --- a/offline/packages/bbc/BbcPmtContainerV1.h +++ b/offline/packages/bbc/BbcPmtContainerV1.h @@ -1,14 +1,18 @@ -#ifndef __BBCPMTCONTAINERV1_H__ -#define __BBCPMTCONTAINERV1_H__ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCPMTCONTAINERV1_H +#define BBC_BBCPMTCONTAINERV1_H #include "BbcPmtContainer.h" +#include + class TClonesArray; /// class BbcPmtContainerV1 : public BbcPmtContainer { -public: + public: /// ctor BbcPmtContainerV1(); @@ -19,36 +23,44 @@ class BbcPmtContainerV1 : public BbcPmtContainer void Reset() override; /** identify Function from PHObject - @param os Output Stream + @param os Output Stream */ - void identify(std::ostream& os = std::cout) const override; + void identify(std::ostream &os = std::cout) const override; /// isValid returns non zero if object contains vailid data int isValid() const override; - /** set T0 for Bbc @param ival Number of Bbc Pmt's */ - void set_npmt(const Short_t ival) override {npmt=ival;return;} + void set_npmt(const short ival) override + { + npmt = ival; + return; + } /// get Number of Bbc Pmt's - Short_t get_npmt() const override {return npmt;} + short get_npmt() const override { return npmt; } + + /** get id of Pmt iPmt in TClonesArray + @param iPmt no of Pmt in TClonesArray + */ + short get_pmt(const int iPmt) const override; /** get Adc of Pmt iPmt in TClonesArray @param iPmt no of Pmt in TClonesArray */ - Float_t get_adc(const int iPmt) const override; + float get_adc(const int iPmt) const override; /** get Tdc0 of Pmt iPmt in TClonesArray @param iPmt no of Pmt in TClonesArray */ - Float_t get_tdc0(const int iPmt) const override; + float get_tdc0(const int iPmt) const override; /** get Tdc1 of Pmt iPmt in TClonesArray @param iPmt no of Pmt in TClonesArray */ - Float_t get_tdc1(const int iPmt) const override; + float get_tdc1(const int iPmt) const override; /** Add Bbc Raw hit object to TCLonesArray @param pmt Pmt id @@ -57,19 +69,15 @@ class BbcPmtContainerV1 : public BbcPmtContainer @param tdc1 Tdc1 value @param ipmt no of pmt */ - void AddBbcPmt(const Short_t ipmt, const Float_t adc, const Float_t tdc0, const Float_t tdc1) override; + void AddBbcPmt(const short ipmt, const float adc, const float tdc0, const float tdc1) override; -protected: - TClonesArray *GetBbcPmtHits() const {return BbcPmtHits;} + private: + TClonesArray *GetBbcPmtHits() const { return BbcPmtHits; } - Short_t npmt; - TClonesArray *BbcPmtHits; + short npmt = 0; + TClonesArray *BbcPmtHits = nullptr; - -private: // so the ClassDef does not show up with doc++ - ClassDefOverride(BbcPmtContainerV1,1) + ClassDefOverride(BbcPmtContainerV1, 1) }; #endif - - diff --git a/offline/packages/bbc/BbcPmtContainerV1LinkDef.h b/offline/packages/bbc/BbcPmtContainerV1LinkDef.h new file mode 100644 index 0000000000..37bc20a340 --- /dev/null +++ b/offline/packages/bbc/BbcPmtContainerV1LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcPmtContainerV1 + ; + +#endif diff --git a/offline/packages/bbc/BbcPmtHit.cc b/offline/packages/bbc/BbcPmtHit.cc index c4f0d83782..6807d3bd7e 100644 --- a/offline/packages/bbc/BbcPmtHit.cc +++ b/offline/packages/bbc/BbcPmtHit.cc @@ -1,11 +1,8 @@ #include "BbcPmtHit.h" -#include - -ClassImp(BbcPmtHit) -using namespace std; +#include -void BbcPmtHit::identify(ostream& out) const +void BbcPmtHit::identify(std::ostream& out) const { - out << "identify yourself: I am a BbcPmtHit object" << endl; + out << "identify yourself: I am a BbcPmtHit object" << std::endl; } diff --git a/offline/packages/bbc/BbcPmtHit.h b/offline/packages/bbc/BbcPmtHit.h index 4187da217a..6d79c9328c 100644 --- a/offline/packages/bbc/BbcPmtHit.h +++ b/offline/packages/bbc/BbcPmtHit.h @@ -1,27 +1,47 @@ -#ifndef __BBCPMTHIT_H__ -#define __BBCPMTHIT_H__ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCPMTHIT_H +#define BBC_BBCPMTHIT_H -#include +#include "BbcReturnCodes.h" + +#include #include -#include -class BbcPmtHit : public TObject -{ -public: +#include +class BbcPmtHit : public PHObject +{ + public: BbcPmtHit() {} - BbcPmtHit(const Short_t /*pmt*/, const Float_t /*adc*/, const Float_t /*tdc0*/, const Float_t /*tdc1*/) {} - virtual ~BbcPmtHit() { } + BbcPmtHit(const short /*pmt*/, const float /*adc*/, const float /*tdc0*/, const float /*tdc1*/) {} + virtual ~BbcPmtHit() {} - virtual Short_t get_pmt() const { PHOOL_VIRTUAL_WARNING; return -9999; } - virtual Float_t get_adc() const { PHOOL_VIRTUAL_WARNING; return -9999; } - virtual Float_t get_tdc0() const { PHOOL_VIRTUAL_WARNING; return -9999; } - virtual Float_t get_tdc1() const { PHOOL_VIRTUAL_WARNING; return -9999; } + virtual short get_pmt() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_SHORT; + } + virtual float get_adc() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_FLOAT; + } + virtual float get_tdc0() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_FLOAT; + } + virtual float get_tdc1() const + { + PHOOL_VIRTUAL_WARNING; + return BbcReturnCodes::BBC_INVALID_FLOAT; + } - void identify(std::ostream& os = std::cout) const; + void identify(std::ostream& os = std::cout) const override; -private: - ClassDefOverride(BbcPmtHit,1) + private: + ClassDefOverride(BbcPmtHit, 1) }; #endif diff --git a/offline/packages/bbc/BbcPmtHitLinkDef.h b/offline/packages/bbc/BbcPmtHitLinkDef.h new file mode 100644 index 0000000000..19dc7717c7 --- /dev/null +++ b/offline/packages/bbc/BbcPmtHitLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcPmtHit + ; + +#endif diff --git a/offline/packages/bbc/BbcPmtHitV1.cc b/offline/packages/bbc/BbcPmtHitV1.cc index d3c7c0401c..52e10189af 100644 --- a/offline/packages/bbc/BbcPmtHitV1.cc +++ b/offline/packages/bbc/BbcPmtHitV1.cc @@ -1,20 +1,18 @@ #include "BbcPmtHitV1.h" -#include - -ClassImp(BbcPmtHitV1) -using namespace std; +#include -BbcPmtHitV1::BbcPmtHitV1(const Short_t ipmt, const Float_t iadc, const Float_t itdc0, const Float_t itdc1) : - pmt(ipmt), - adc(iadc), - tdc0(itdc0), - tdc1(itdc1) +BbcPmtHitV1::BbcPmtHitV1(const short ipmt, const float iadc, const float itdc0, const float itdc1) + : pmt(ipmt) + , adc(iadc) + , tdc0(itdc0) + , tdc1(itdc1) { } - -void BbcPmtHitV1::identify(ostream& out) const +void BbcPmtHitV1::identify(std::ostream& out) const { - out << "identify yourself: I am a BbcPmtHitV1 object" << endl; + out << "identify yourself: I am a BbcPmtHitV1 object" << std::endl; + out << "Pmt: " << pmt << ", adc: " << adc << ", tdc0: " + << tdc0 << ", tdc1: " << tdc1 << std::endl; } diff --git a/offline/packages/bbc/BbcPmtHitV1.h b/offline/packages/bbc/BbcPmtHitV1.h index 4221232105..4fa30c44ae 100644 --- a/offline/packages/bbc/BbcPmtHitV1.h +++ b/offline/packages/bbc/BbcPmtHitV1.h @@ -1,32 +1,34 @@ -#ifndef __BBCPMTHITV1_H__ -#define __BBCPMTHITV1_H__ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBC_BBCPMTHITV1_H +#define BBC_BBCPMTHITV1_H #include "BbcPmtHit.h" + #include +#include class BbcPmtHitV1 : public BbcPmtHit { + public: + BbcPmtHitV1() = default; + BbcPmtHitV1(const short pmt, const float adc, const float tdc0, const float tdc1); + ~BbcPmtHitV1() override = default; -public: - BbcPmtHitV1() { } - BbcPmtHitV1(const Short_t pmt, const Float_t adc, const Float_t tdc0, const Float_t tdc1); - virtual ~BbcPmtHitV1() { } - - Short_t get_pmt() const override {return pmt;} - Float_t get_adc() const override {return adc;} - Float_t get_tdc0() const override {return tdc0;} - Float_t get_tdc1() const override {return tdc1;} + short get_pmt() const override { return pmt; } + float get_adc() const override { return adc; } + float get_tdc0() const override { return tdc0; } + float get_tdc1() const override { return tdc1; } - void identify(std::ostream& os = std::cout) const; + void identify(std::ostream& os = std::cout) const override; -protected: - Short_t pmt; - Float_t adc; - Float_t tdc0; - Float_t tdc1; + private: + short pmt = 0; + float adc = std::numeric_limits::quiet_NaN(); + float tdc0 = std::numeric_limits::quiet_NaN(); + float tdc1 = std::numeric_limits::quiet_NaN(); -private: - ClassDefOverride(BbcPmtHitV1,1) + ClassDefOverride(BbcPmtHitV1, 1) }; #endif diff --git a/offline/packages/bbc/BbcPmtHitV1LinkDef.h b/offline/packages/bbc/BbcPmtHitV1LinkDef.h new file mode 100644 index 0000000000..b696f7427a --- /dev/null +++ b/offline/packages/bbc/BbcPmtHitV1LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcPmtHitV1 + ; + +#endif diff --git a/offline/packages/bbc/BbcReconstruction.cc b/offline/packages/bbc/BbcReconstruction.cc new file mode 100644 index 0000000000..ee29f6d3b7 --- /dev/null +++ b/offline/packages/bbc/BbcReconstruction.cc @@ -0,0 +1,206 @@ +#include "BbcReconstruction.h" +#include "BbcDefs.h" +#include "BbcPmtContainer.h" +#include "BbcReturnCodes.h" +#include "BbcVertexMapv1.h" +#include "BbcVertexv2.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//____________________________________________________________________________.. +BbcReconstruction::BbcReconstruction(const std::string &name) + : SubsysReco(name) +{ + h_evt_bbct[0] = nullptr; + h_evt_bbct[1] = nullptr; +} + +//____________________________________________________________________________.. +BbcReconstruction::~BbcReconstruction() +{ +} + +//____________________________________________________________________________.. +int BbcReconstruction::Init(PHCompositeNode *) +{ + m_gaussian = std::make_unique("gaussian", "gaus", 0, 20); + m_gaussian->FixParameter(2, m_tres); + + TString name, title; + for (int iarm = 0; iarm < 2; iarm++) + { + // + name = "hevt_bbct"; + name += iarm; + title = "bbc times, arm "; + title += iarm; + h_evt_bbct[iarm] = new TH1F(name, title, 200, 7.5, 11.5); + h_evt_bbct[iarm]->SetLineColor(4); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int BbcReconstruction::InitRun(PHCompositeNode *topNode) +{ + if (createNodes(topNode) == Fun4AllReturnCodes::ABORTEVENT) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + + int ret = getNodes(topNode); + return ret; +} + +//____________________________________________________________________________.. +int BbcReconstruction::process_event(PHCompositeNode *) +{ + + std::vector hit_times[2]; + float bbcq[2] = {0}; + float bbcn[2] = {0}; + float bbct[2] = {0}; + + for (int ich = 0; ich < 128; ich++) + { + const auto pmt = m_bbcpmts->get_pmt(ich); + const int arm = pmt / 64; + auto bbchit = m_bbcpmts->get_tdc0(ich); + + if (std::isnan(m_bbcpmts->get_adc(ich))) + { + //! PMT with no ADC, skip it + continue; + } + + if (bbchit < 9999.) + { + //! total charge + bbcq[arm] += m_bbcpmts->get_adc(ich); + + //! number of hit pmts + bbcn[arm]++; + + h_evt_bbct[arm]->Fill(bbchit); + hit_times[arm].push_back(bbchit); + } + if (Verbosity() > 0) + { + std::cout << "Channel " << ich << " with pmt " << pmt << " in arm " << arm << " has " << m_bbcpmts->get_adc(ich) << std::endl; + } + } + + if (Verbosity() > 0) + { + std::cout << "nbbc arm 1,2: " << bbcn[0] << ", " << bbcn[1] << std::endl; + } + + if (bbcn[0] > 0 && bbcn[1] > 0) + { + for (int iarm = 0; iarm < 2; iarm++) + { + if (hit_times[iarm].empty()) + { + continue; + } + + std::sort(hit_times[iarm].begin(), hit_times[iarm].end()); + float earliest = hit_times[iarm][0]; + m_gaussian->SetParameter(0, 5); + m_gaussian->SetParameter(1, earliest); + m_gaussian->SetRange(6, earliest + 5 * m_tres); + h_evt_bbct[iarm]->Fit(m_gaussian.get(), "BLRNQ"); + bbct[iarm] = m_gaussian->GetParameter(1); + } + + float bbcz = (bbct[0] - bbct[1]) * BbcDefs::C / 2.; + float bbct0 = (bbct[0] + bbct[1]) / 2.; + + auto vertex = std::make_unique(); + vertex->set_t(bbct0); + vertex->set_z(bbcz); + vertex->set_z_err(0.6); + vertex->set_t_err(m_tres); + + for (int iarm = 0; iarm < 2; iarm++) + { + vertex->set_bbc_ns(iarm, bbcn[iarm], bbcq[iarm], bbct[iarm]); + } + + if (Verbosity() > 0) + { + std::cout << "bbc vertex z and t0 " << bbcz << ", " + << bbct0 << std::endl; + } + + m_bbcvertexmap->insert(vertex.release()); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int BbcReconstruction::End(PHCompositeNode *) +{ + return Fun4AllReturnCodes::EVENT_OK; +} + +int BbcReconstruction::createNodes(PHCompositeNode *topNode) +{ + PHNodeIterator iter(topNode); + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + PHCompositeNode *bbcNode = dynamic_cast(iter.findFirst("PHCompositeNode", "BBC")); + if (!bbcNode) + { + bbcNode = new PHCompositeNode("BBC"); + dstNode->addNode(bbcNode); + } + + m_bbcvertexmap = findNode::getClass(bbcNode, "BbcVertexMap"); + if (!m_bbcvertexmap) + { + m_bbcvertexmap = new BbcVertexMapv1(); + PHIODataNode *VertexMapNode = new PHIODataNode(m_bbcvertexmap, "BbcVertexMap", "PHObject"); + bbcNode->addNode(VertexMapNode); + } + + return Fun4AllReturnCodes::EVENT_OK; +} +int BbcReconstruction::getNodes(PHCompositeNode *topNode) +{ + // BbcPmtContainer + m_bbcpmts = findNode::getClass(topNode, "BbcPmtContainer"); + if (!m_bbcpmts) + { + std::cout << PHWHERE << " BbcPmtContainer node not found on node tree" << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + m_bbcvertexmap = findNode::getClass(topNode, "BbcVertexMap"); + if (!m_bbcvertexmap) + { + std::cout << PHWHERE << "BbcVertexMap node not found on node tree" << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/bbc/BbcReconstruction.h b/offline/packages/bbc/BbcReconstruction.h new file mode 100644 index 0000000000..7229100225 --- /dev/null +++ b/offline/packages/bbc/BbcReconstruction.h @@ -0,0 +1,40 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BBCRECONSTRUCTION_H +#define BBCRECONSTRUCTION_H + +#include + +#include +#include + +class PHCompositeNode; +class BbcPmtContainer; +class BbcVertexMap; +class TF1; +class TH1; + +class BbcReconstruction : public SubsysReco +{ + public: + BbcReconstruction(const std::string &name = "BbcReconstruction"); + + ~BbcReconstruction() override; + + int Init(PHCompositeNode *topNode) override; + int InitRun(PHCompositeNode *topNode) override; + int process_event(PHCompositeNode *topNode) override; + int End(PHCompositeNode *topNode) override; + + private: + int createNodes(PHCompositeNode *topNode); + int getNodes(PHCompositeNode *topNode); + std::unique_ptr m_gaussian = nullptr; + + float m_tres = 0.05; + TH1 *h_evt_bbct[2]; + BbcVertexMap *m_bbcvertexmap = nullptr; + BbcPmtContainer *m_bbcpmts = nullptr; +}; + +#endif // BBCRECONSTRUCTION_H diff --git a/offline/packages/bbc/BbcReturnCodes.h b/offline/packages/bbc/BbcReturnCodes.h index 3d39b8500a..44787bd4c1 100644 --- a/offline/packages/bbc/BbcReturnCodes.h +++ b/offline/packages/bbc/BbcReturnCodes.h @@ -1,13 +1,16 @@ -/* -Return codes -*/ +// Tell emacs that this is a C++ source +// -*- C++ -*-. -#ifndef BBCRETURNCODE -#define BBCRETURNCODE +#ifndef BBC_BBCRETURNCODES_H +#define BBC_BBCRETURNCODES_H -const short BBC_INVALID_SHORT = -9999; -const int BBC_INVALID_INT = -9999; -const long BBC_INVALID_LONG = -9999; -const float BBC_INVALID_FLOAT = -9999.9; +#include + +namespace BbcReturnCodes +{ + const short BBC_INVALID_SHORT = std::numeric_limits::min(); //-9999; + const int BBC_INVALID_INT = std::numeric_limits::min(); //-9999; + const float BBC_INVALID_FLOAT = std::numeric_limits::quiet_NaN(); +} // namespace BbcReturnCodes #endif diff --git a/simulation/g4simulation/g4bbc/BbcVertex.h b/offline/packages/bbc/BbcVertex.h similarity index 80% rename from simulation/g4simulation/g4bbc/BbcVertex.h rename to offline/packages/bbc/BbcVertex.h index 65747330d5..f7a60791fb 100644 --- a/simulation/g4simulation/g4bbc/BbcVertex.h +++ b/offline/packages/bbc/BbcVertex.h @@ -34,6 +34,11 @@ class BbcVertex : public PHObject virtual float get_z_err() const { return NAN; } virtual void set_z_err(float) {} + virtual void set_bbc_ns(int, int, float, float) {} + virtual int get_bbc_npmt(int) const { return std::numeric_limits::max(); } + virtual float get_bbc_q(int) const { return NAN; } + virtual float get_bbc_t(int) const { return NAN; } + protected: BbcVertex() {} diff --git a/simulation/g4simulation/g4bbc/BbcVertexLinkDef.h b/offline/packages/bbc/BbcVertexLinkDef.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexLinkDef.h rename to offline/packages/bbc/BbcVertexLinkDef.h diff --git a/simulation/g4simulation/g4bbc/BbcVertexMap.cc b/offline/packages/bbc/BbcVertexMap.cc similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexMap.cc rename to offline/packages/bbc/BbcVertexMap.cc diff --git a/simulation/g4simulation/g4bbc/BbcVertexMap.h b/offline/packages/bbc/BbcVertexMap.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexMap.h rename to offline/packages/bbc/BbcVertexMap.h diff --git a/simulation/g4simulation/g4bbc/BbcVertexMapLinkDef.h b/offline/packages/bbc/BbcVertexMapLinkDef.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexMapLinkDef.h rename to offline/packages/bbc/BbcVertexMapLinkDef.h diff --git a/simulation/g4simulation/g4bbc/BbcVertexMapv1.cc b/offline/packages/bbc/BbcVertexMapv1.cc similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexMapv1.cc rename to offline/packages/bbc/BbcVertexMapv1.cc diff --git a/simulation/g4simulation/g4bbc/BbcVertexMapv1.h b/offline/packages/bbc/BbcVertexMapv1.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexMapv1.h rename to offline/packages/bbc/BbcVertexMapv1.h diff --git a/simulation/g4simulation/g4bbc/BbcVertexMapv1LinkDef.h b/offline/packages/bbc/BbcVertexMapv1LinkDef.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexMapv1LinkDef.h rename to offline/packages/bbc/BbcVertexMapv1LinkDef.h diff --git a/simulation/g4simulation/g4bbc/BbcVertexv1.cc b/offline/packages/bbc/BbcVertexv1.cc similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexv1.cc rename to offline/packages/bbc/BbcVertexv1.cc diff --git a/simulation/g4simulation/g4bbc/BbcVertexv1.h b/offline/packages/bbc/BbcVertexv1.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexv1.h rename to offline/packages/bbc/BbcVertexv1.h diff --git a/simulation/g4simulation/g4bbc/BbcVertexv1LinkDef.h b/offline/packages/bbc/BbcVertexv1LinkDef.h similarity index 100% rename from simulation/g4simulation/g4bbc/BbcVertexv1LinkDef.h rename to offline/packages/bbc/BbcVertexv1LinkDef.h diff --git a/offline/packages/bbc/BbcVertexv2.cc b/offline/packages/bbc/BbcVertexv2.cc new file mode 100644 index 0000000000..98f9d03d08 --- /dev/null +++ b/offline/packages/bbc/BbcVertexv2.cc @@ -0,0 +1,59 @@ +#include "BbcVertexv2.h" + +#include + +using namespace std; + +BbcVertexv2::BbcVertexv2() + : _id(0xFFFFFFFF) + , _t(NAN) + , _t_err(NAN) + , _z(NAN) + , _z_err(NAN) +{ + for (int i = 0; i < 2; i++) + { + _bbc_ns_npmt[i] = 0; + _bbc_ns_q[i] = NAN; + _bbc_ns_t[i] = NAN; + } +} + +BbcVertexv2::~BbcVertexv2() = default; + +void BbcVertexv2::identify(ostream& os) const +{ + os << "---BbcVertexv2--------------------------------" << endl; + os << "vertexid: " << get_id() << endl; + os << " t = " << get_t() << " +/- " << get_t_err() << endl; + os << " z = " << get_z() << " +/- " << get_z_err() << endl; + os << "-----------------------------------------------" << endl; + + return; +} + +int BbcVertexv2::isValid() const +{ + if (_id == 0xFFFFFFFF) + { + return 0; + } + if (isnan(_t)) + { + return 0; + } + if (isnan(_t_err)) + { + return 0; + } + if (isnan(_z)) + { + return 0; + } + if (isnan(_z_err)) + { + return 0; + } + + return 1; +} diff --git a/offline/packages/bbc/BbcVertexv2.h b/offline/packages/bbc/BbcVertexv2.h new file mode 100644 index 0000000000..09591e3dca --- /dev/null +++ b/offline/packages/bbc/BbcVertexv2.h @@ -0,0 +1,62 @@ +#ifndef G4BBC_BBCVERTEXV2_H +#define G4BBC_BBCVERTEXV2_H + +#include "BbcVertex.h" + +#include + +class BbcVertexv2 : public BbcVertex +{ + public: + BbcVertexv2(); + ~BbcVertexv2() override; + + // PHObject virtual overloads + + void identify(std::ostream& os = std::cout) const override; + void Reset() override { *this = BbcVertexv2(); } + int isValid() const override; + PHObject* CloneMe() const override { return new BbcVertexv2(*this); } + + // vertex info + + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + float get_t() const override { return _t; } + void set_t(float t) override { _t = t; } + + float get_t_err() const override { return _t_err; } + void set_t_err(float t_err) override { _t_err = t_err; } + + float get_z() const override { return _z; } + void set_z(float z) override { _z = z; } + + float get_z_err() const override { return _z_err; } + void set_z_err(float z_err) override { _z_err = z_err; } + + void set_bbc_ns(int iarm, int bbc_npmt, float bbc_q, float bbc_t) override + { + _bbc_ns_npmt[iarm] = bbc_npmt; + _bbc_ns_q[iarm] = bbc_q; + _bbc_ns_t[iarm] = bbc_t; + } + + int get_bbc_npmt(int iarm) const override { return _bbc_ns_npmt[iarm]; } + float get_bbc_q(int iarm) const override { return _bbc_ns_q[iarm]; } + float get_bbc_t(int iarm) const override { return _bbc_ns_t[iarm]; } + + private: + unsigned int _id; //< unique identifier within container + float _t; //< collision time + float _t_err; //< collision time uncertainty + float _z; //< collision position z + float _z_err; //< collision position z uncertainty + int _bbc_ns_npmt[2]; + float _bbc_ns_q[2]; + float _bbc_ns_t[2]; + + ClassDefOverride(BbcVertexv2, 1); +}; + +#endif diff --git a/offline/packages/bbc/BbcVertexv2LinkDef.h b/offline/packages/bbc/BbcVertexv2LinkDef.h new file mode 100644 index 0000000000..64673af5b8 --- /dev/null +++ b/offline/packages/bbc/BbcVertexv2LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BbcVertexv2 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/bbc/Makefile.am b/offline/packages/bbc/Makefile.am index 0ac4ddb820..1160ced917 100644 --- a/offline/packages/bbc/Makefile.am +++ b/offline/packages/bbc/Makefile.am @@ -5,7 +5,7 @@ AUTOMAKE_OPTIONS = foreign # List of shared libraries to produce lib_LTLIBRARIES = \ - libbbc.la + libbbc_io.la AM_CPPFLAGS = \ -I$(includedir) \ @@ -19,6 +19,7 @@ AM_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib64 pkginclude_HEADERS = \ + BbcDefs.h \ BbcOut.h \ BbcOutV1.h \ BbcNorthSouth.h \ @@ -27,14 +28,49 @@ pkginclude_HEADERS = \ BbcPmtContainerV1.h \ BbcPmtHit.h \ BbcPmtHitV1.h \ - BbcReturnCodes.h + BbcReconstruction.h \ + BbcReturnCodes.h \ + BbcVertex.h \ + BbcVertexv1.h \ + BbcVertexv2.h \ + BbcVertexMap.h \ + BbcVertexMapv1.h + +ROOTDICTS = \ + BbcOut_Dict.cc \ + BbcOutV1_Dict.cc \ + BbcNorthSouth_Dict.cc \ + BbcNorthSouthV1_Dict.cc \ + BbcPmtHit_Dict.cc \ + BbcPmtHitV1_Dict.cc \ + BbcPmtContainer_Dict.cc \ + BbcPmtContainerV1_Dict.cc \ + BbcVertex_Dict.cc \ + BbcVertexv1_Dict.cc \ + BbcVertexv2_Dict.cc \ + BbcVertexMap_Dict.cc \ + BbcVertexMapv1_Dict.cc pcmdir = $(libdir) -nobase_dist_pcm_DATA = \ - Bbc_Dict_rdict.pcm -libbbc_la_SOURCES = \ - Bbc_Dict.cc \ +nobase_dist_pcm_DATA = \ + BbcOut_Dict_rdict.pcm \ + BbcOutV1_Dict_rdict.pcm \ + BbcNorthSouth_Dict_rdict.pcm \ + BbcNorthSouthV1_Dict_rdict.pcm \ + BbcPmtHit_Dict_rdict.pcm \ + BbcPmtHitV1_Dict_rdict.pcm \ + BbcPmtContainer_Dict_rdict.pcm \ + BbcPmtContainerV1_Dict_rdict.pcm \ + BbcVertex_Dict_rdict.pcm \ + BbcVertexv1_Dict_rdict.pcm \ + BbcVertexv2_Dict_rdict.pcm \ + BbcVertexMap_Dict_rdict.pcm \ + BbcVertexMapv1_Dict_rdict.pcm + + +libbbc_io_la_SOURCES = \ + $(ROOTDICTS) \ BbcOut.cc \ BbcOutV1.cc \ BbcNorthSouth.cc \ @@ -42,17 +78,23 @@ libbbc_la_SOURCES = \ BbcPmtHit.cc \ BbcPmtHitV1.cc \ BbcPmtContainer.cc \ - BbcPmtContainerV1.cc + BbcPmtContainerV1.cc \ + BbcReconstruction.cc \ + BbcVertexv1.cc \ + BbcVertexv2.cc \ + BbcVertexMap.cc \ + BbcVertexMapv1.cc -libbbc_la_LIBADD = \ - -lphool +libbbc_io_la_LIBADD = \ + -lphool \ + -lSubsysReco # Rule for generating table CINT dictionaries. -Bbc_Dict.cc: BbcOut.h BbcOutV1.h BbcNorthSouth.h BbcNorthSouthV1.h BbcPmtContainer.h BbcPmtContainerV1.h BbcPmtHit.h BbcPmtHitV1.h BbcLinkDef.h +%_Dict.cc: %.h %LinkDef.h rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ #just to get the dependency -Bbc_Dict_rdict.pcm: Bbc_Dict.cc ; +%_Dict_rdict.pcm: %_Dict.cc ; ################################################ @@ -62,10 +104,10 @@ BUILT_SOURCES = \ testexternals.cc noinst_PROGRAMS = \ - testexternals_bbc + testexternals -testexternals_bbc_SOURCES = testexternals.cc -testexternals_bbc_LDADD = libbbc.la +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libbbc_io.la testexternals.cc: echo "//*** this is a generated file. Do not commit, do not edit" > $@ diff --git a/offline/packages/decayfinder/DecayFinder.cc b/offline/packages/decayfinder/DecayFinder.cc index c1fb96587f..188254165e 100644 --- a/offline/packages/decayfinder/DecayFinder.cc +++ b/offline/packages/decayfinder/DecayFinder.cc @@ -581,7 +581,14 @@ void DecayFinder::searchGeant4Record(int barcode, int pid, std::vector deca { if (Verbosity() >= VERBOSITY_MAX) std::cout << "This is a child you were looking for" << std::endl; actualDecayProducts.push_back(particleID); - decayChain.push_back(std::make_pair(std::make_pair(m_genevt->get_embedding_id(),g4particle->get_barcode()), particleID)); + if (m_geneventmap) + { + decayChain.push_back(std::make_pair(std::make_pair(m_genevt->get_embedding_id(),g4particle->get_barcode()), particleID)); + } + else + { + decayChain.push_back(std::make_pair(std::make_pair(g4particle->get_primary_id(),g4particle->get_barcode()), particleID)); + } } } //Now check if it's part of the other resonance list else if (m_allowPhotons && particleID == 22) continue; diff --git a/offline/packages/epd/EpdGeom.h b/offline/packages/epd/EpdGeom.h index 4b829ec48d..5564fc3c6e 100644 --- a/offline/packages/epd/EpdGeom.h +++ b/offline/packages/epd/EpdGeom.h @@ -1,12 +1,18 @@ +/* + Originated by Tristan Protzman 12/15/22 + Re-written by Ejiro Umaka 03/28/23 +*/ + #ifndef EPD_GEOM_H #define EPD_GEOM_H +#include + #include #include #include #include - -#include +#include class EpdGeom : public PHObject { @@ -14,29 +20,17 @@ class EpdGeom : public PHObject EpdGeom() = default; ~EpdGeom() override {}; - virtual unsigned int side_r_phi_to_id(unsigned int /*side*/, unsigned int /*r_index*/, unsigned int /*phi_index*/) {return 999;}; - virtual unsigned int side_sector_tile_to_id(unsigned int /*side*/, unsigned int /*sector*/, unsigned int /*tile*/) {return 999;}; - virtual std::tuple id_to_side_r_phi(unsigned int /*id*/) {return {0, 0, 0};}; - virtual std::tuple id_to_side_sector_tile(unsigned int /*id*/) {return {0, 0, 0};}; - virtual float r(unsigned int /*id*/) {return -999;}; - virtual float r_from_key(unsigned int /*key*/) {return -999;}; - virtual float r_from_side_r_phi(unsigned int /*side*/, unsigned int /*r_index*/, unsigned int /*phi_index*/) {return -999;}; - virtual float r_from_side_sector_tile(unsigned int /*side*/, unsigned int /*sector*/, unsigned int /*tile*/) {return -999;}; - virtual float phi(unsigned int /*id*/) {return -999;}; - virtual float phi_from_key(unsigned int /*key*/) {return -999;}; - virtual float phi_from_side_r_phi(unsigned int /*side*/, unsigned int /*r_index*/, unsigned int /*phi_index*/) {return -999;}; - virtual float phi_from_side_sector_tile(unsigned int /*side*/, unsigned int /*sector*/, unsigned int /*tile*/) {return -999;}; - virtual float z(unsigned int /*id*/) {return -999;}; - virtual float z_from_key(unsigned int /*key*/) {return -999;}; - virtual float z_from_side_r_phi(unsigned int /*side*/, unsigned int /*r_inxed*/, unsigned int /*phi_index*/) {return -999;}; - virtual float z_from_side_sector_tile(unsigned int /*side*/, unsigned int /*sector*/, unsigned int /*tile*/) {return -999;}; - virtual unsigned int decode_epd(unsigned int /*tower_key*/) {return 999;}; - - virtual void Reset() override {return;}; // Reset doesn't need to do anything + virtual void set_z(unsigned int /*key*/, float /*z*/) {return;} + virtual void set_r(unsigned int /*key*/, float /*r*/) {return;} + virtual void set_phi(unsigned int /*key*/, float /*f*/) {return;} + virtual void set_phi0(unsigned int /*key*/, float /*f0*/) {return;} + virtual float get_r(unsigned int /*key*/) const {return NAN;}; + virtual float get_z(unsigned int /*key*/) const {return NAN;}; + virtual float get_phi(unsigned int /*key*/) const {return NAN;}; private: ClassDefOverride(EpdGeom, 1); }; -#endif // EPD_GEOM_H \ No newline at end of file +#endif // EPD_GEOM_H diff --git a/offline/packages/epd/EpdGeomMaker.cc b/offline/packages/epd/EpdGeomMaker.cc deleted file mode 100644 index 9e12bfec86..0000000000 --- a/offline/packages/epd/EpdGeomMaker.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "EpdGeomMaker.h" - -#include "EpdGeom.h" -#include "EpdGeomV1.h" - -#include - -#include -#include - -#include -#include -#include - -EpdGeomMaker::EpdGeomMaker(const std::string &name) : SubsysReco(name) { - this->epd_geom = new EpdGeomV1(); -} - -EpdGeomMaker::~EpdGeomMaker() { - delete this->epd_geom; -} - -void EpdGeomMaker::CreateNodeTree(PHCompositeNode *topNode) { - // Find the DST node - PHNodeIterator node_itr(topNode); - PHCompositeNode *dst_node = dynamic_cast(node_itr.findFirst("PHCompositeNode", "DST")); - if (!dst_node) { - std::cout << "PHComposite node created: DST" << std::endl; - dst_node = new PHCompositeNode("DST"); - topNode->addNode(dst_node); - } - PHIODataNode *epd_geom_node = new PHIODataNode(this->epd_geom, "EPD_Geometry", "PHObject"); - dst_node->addNode(epd_geom_node); -} \ No newline at end of file diff --git a/offline/packages/epd/EpdGeomMaker.h b/offline/packages/epd/EpdGeomMaker.h deleted file mode 100644 index a58218a8e9..0000000000 --- a/offline/packages/epd/EpdGeomMaker.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -Creates the EPD Geometry object and adds it to the node tree -*/ - -#include "EpdGeom.h" - -#include - -#include - -#include - - -class EpdGeomMaker : public SubsysReco { -public: - EpdGeomMaker(const std::string &name = "EpdGeomMaker"); - ~EpdGeomMaker() override; - - void CreateNodeTree(PHCompositeNode *topNode); - -private: - EpdGeom *epd_geom; -}; \ No newline at end of file diff --git a/offline/packages/epd/EpdGeomV1.cc b/offline/packages/epd/EpdGeomV1.cc index 8502d24f49..db59c5aa64 100644 --- a/offline/packages/epd/EpdGeomV1.cc +++ b/offline/packages/epd/EpdGeomV1.cc @@ -1,5 +1,9 @@ #include "EpdGeomV1.h" +#include + +#include + #include #include #include @@ -7,217 +11,48 @@ #include #include -// Initializes the EPD Geometry -EpdGeomV1::EpdGeomV1() { - build_lookup(); -} - -// Cleanup -EpdGeomV1::~EpdGeomV1() {}; - - -// Calculates the appropriate tower id from a given side/r/phi index -unsigned int EpdGeomV1::side_r_phi_to_id(unsigned int side, unsigned int r_index, unsigned int phi_index) { - unsigned int id = 0x0; - id = id | (side << 20); - id = id | (r_index << 10); - id = id | phi_index; - return id; -}; - -// Calculates the appropriate tower id from a given side/sector/tile index -unsigned int EpdGeomV1::side_sector_tile_to_id(unsigned int side, unsigned int sector, unsigned int tile) { - int rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; - int phimap[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; - unsigned int phi = phimap[tile] + (sector * 2); - return side_r_phi_to_id(side, rmap[tile], phi); -} - -// Calculates the appropriate side/r/phi index from a tower ID -std::tuple EpdGeomV1::id_to_side_r_phi(unsigned int id) { - unsigned int side, r_index, phi_index; - side = (id >> 20) & 0x1; - r_index = (id >> 10) & 0x3ff; - phi_index = id & 0x3ff; - return std::tuple(side, r_index, phi_index); -}; - -// Calculates the appropriate side/sector/tile from a tower ID -std::tuple EpdGeomV1::id_to_side_sector_tile(unsigned int id) { - unsigned int side, r_index, phi_index; - std::tie(side, r_index, phi_index) = id_to_side_r_phi(id); - unsigned int sector = phi_index / 2; - unsigned int tile = r_index * 2; - if (r_index && (phi_index % 2 == 0)) { - tile --; - } - return std::tuple(side, sector, tile); -} - -float EpdGeomV1::r(unsigned int id) { - return r_lookup[id]; -} - -// Returns the r location of the specified tile. -// Arguments: -// int id: The tile's ID -// Returns: -// float: the tile's location in r/phi space -float EpdGeomV1::r_from_key(unsigned int key) { - return r(decode_epd(key)); -}; - -// Returns the r location of the specified tile. -// Arguments: -// int r_index: The r index of the desired tile -// int phi_index: The phi index of the desired tile -// Returns: -// float: the tile's location in r/phi space -float EpdGeomV1::r_from_side_r_phi(unsigned int side, unsigned int r_index, unsigned int phi_index) { - unsigned int key; - key = side_r_phi_to_id(side, r_index, phi_index); - return r_from_key(key); -}; - -float EpdGeomV1::r_from_side_sector_tile(unsigned int side, unsigned int sector, unsigned int tile) { - unsigned int key = side_sector_tile_to_id(side, sector, tile); - return r_from_key(key); +float EpdGeomV1::get_r(unsigned int key) const +{ + return tile_r[TowerInfoDefs::get_epd_rbin(key)]; } -float EpdGeomV1::phi(unsigned int id) { - return phi_lookup[id]; +float EpdGeomV1::get_z(unsigned int key) const +{ + return tile_z[TowerInfoDefs::get_epd_arm(key)]; } -// Returns the phi location of the specified tile. -// Arguments: -// int id: The tile's ID -// Returns: -// float: the tile's location in r/phi space -float EpdGeomV1::phi_from_key(unsigned int key) { - return phi(decode_epd(key)); -}; - -// Returns the phi location of the specified tile. -// Arguments: -// int r_index: The r index of the desired tile -// int phi_index: The phi index of the desired tile -// Returns: -// float: the tile's location in r/phi space -float EpdGeomV1::phi_from_side_r_phi(unsigned int side, unsigned int r_index, unsigned int phi_index) { - unsigned int key; - key = side_r_phi_to_id(side, r_index, phi_index); - return phi_from_key(key); -}; - -float EpdGeomV1::phi_from_side_sector_tile(unsigned int side, unsigned int sector, unsigned int tile) { - unsigned int key = side_sector_tile_to_id(side, sector, tile); - return phi_from_key(key); -} +float EpdGeomV1::get_phi(unsigned int key) const +{ -float EpdGeomV1::z(unsigned int id) { - return z_lookup[id]; -} + if(TowerInfoDefs::get_epd_rbin(key) == 0) + { + return tile_phi0[TowerInfoDefs::get_epd_phibin(key)]; + } + else + { + return tile_phi[TowerInfoDefs::get_epd_phibin(key)]; + } -float EpdGeomV1::z_from_key(unsigned int key) { - return z(decode_epd(key)); } - -float EpdGeomV1::z_from_side_r_phi(unsigned int side, unsigned int r_index, unsigned int phi_index) { - unsigned int key = side_r_phi_to_id(side, r_index, phi_index); - return z_from_key(key); + +void EpdGeomV1::set_z(unsigned int key, float z) +{ + tile_z[TowerInfoDefs::get_epd_arm(key)] = z; } -float EpdGeomV1::z_from_side_sector_tile(unsigned int side, unsigned int sector, unsigned int tile) { - unsigned int key = side_sector_tile_to_id(side, sector, tile); - return z_from_key(key); +void EpdGeomV1::set_r(unsigned int key, float r) +{ + tile_r[TowerInfoDefs::get_epd_rbin(key)] = r; } -unsigned int EpdGeomV1::decode_epd(unsigned int tower_key) { - int channels_per_sector = 31; - int supersector = channels_per_sector * 12; - unsigned int ns_sector = tower_key >> 20U; - unsigned int rbin = (tower_key - (ns_sector << 20U)) >> 10U; - unsigned int phibin = tower_key - (ns_sector << 20U) - (rbin << 10U); - int epdchnlmap[16][2] = {{0, 0}, {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, {19, 20}, {21, 22}, {23, 24}, {25, 26}, {27, 28}, {29, 30}}; - int sector = phibin / 2; - int channel = 0; - if (rbin > 0) - { - channel = epdchnlmap[rbin][phibin - 2 * sector]; - } - else - { - channel = 0; - } - unsigned int index = 0; - index = ns_sector * supersector + sector * channels_per_sector + channel; - return index; +void EpdGeomV1::set_phi(unsigned int key, float f) +{ + tile_phi[TowerInfoDefs::get_epd_phibin(key)] = f; } - -// Generates the maps returning the r and phi for a particular tile -void EpdGeomV1::build_lookup() { - r_lookup = std::vector(NUM_TOWERS, -999); - phi_lookup = std::vector(NUM_TOWERS, -999); - z_lookup = std::vector(NUM_TOWERS, -999); - std::string epd_geom_file_path("epd_geometry.tsv"); - std::ifstream epd_geom_file(epd_geom_file_path); - if (!epd_geom_file.is_open()) { - std::cerr << "Could not read EPD Geometry file: " << epd_geom_file_path << std::endl; - return; // Should this throw an error? Not sure what the sPHENIX way to do things like that is - } - std::string line; - uint filled = 0; - while(std::getline(epd_geom_file, line)) { - std::stringstream tokens(line); - int tower; - tokens >> tower; // Read the first column into the tower name; - float r, phi, z; - tokens >> r; - tokens >> phi; - tokens >> z; // This could all use error checking - r_lookup[tower] = r; - phi_lookup[tower] = phi; - z_lookup[tower] = z; - filled++; - } - if (filled != NUM_TOWERS) { - std::cerr << "Did not find geometry values for all EPD towers!" << std::endl; - } - // for (uint i = 0; i < NUM_TOWERS; i++) { - // printf("%d\t%f\t%f\t%f\n", i, r_lookup[i], phi_lookup[i], z_lookup[i]); - // } +void EpdGeomV1::set_phi0(unsigned int key, float f0) +{ + tile_phi0[TowerInfoDefs::get_epd_phibin(key)] = f0; } -bool EpdGeomV1::test_id_mapping() { - bool pass = true; - for (unsigned int side = 0; side < 2; side++) { - for (unsigned int r_index = 0; r_index < 16; r_index++) { - for (unsigned int phi_index = 0; phi_index < 24; phi_index++) { - if (r_index == 0 && (phi_index & 0x1)) { - continue; - } - std::cout << "side: " << side << "\tr: " << r_index << "\tphi: " << phi_index << std::endl; - unsigned int id_from_r_phi = side_r_phi_to_id(side, r_index, phi_index); // side r phi to id - std::cout << "id 1: " << id_from_r_phi << std::endl; - unsigned int temp_side, sector, tile; - std::tie(temp_side, sector, tile) = id_to_side_sector_tile(id_from_r_phi); // id to side sector tile - std::cout << "side: " << side << "\tsector: " << sector << "\ttile: " << tile << std::endl; - unsigned int id_from_sector_tile = side_sector_tile_to_id(temp_side, sector, tile); // side sector tile to id - std::cout << "id 2: " << id_from_sector_tile << std::endl; - unsigned int final_side, final_r_index, final_phi_index; - std::tie(final_side, final_r_index, final_phi_index) = id_to_side_r_phi(id_from_sector_tile); /// id to side r phi - std::cout << "side: " << final_side << "\tr: " << final_r_index << "\tphi: " << final_phi_index << std::endl; - if (side != final_side || r_index != final_r_index || phi_index != final_phi_index) { - pass = false; - std::cout << "COORDINATE FAILED" << std::endl; - } else{ - std::cout << "coordinate passed" << std::endl; - } - std::cout << "\n\n" << std::endl; - } - } - } - return pass; -} diff --git a/offline/packages/epd/EpdGeomV1.h b/offline/packages/epd/EpdGeomV1.h index 4f7403fb32..62c1f733bc 100644 --- a/offline/packages/epd/EpdGeomV1.h +++ b/offline/packages/epd/EpdGeomV1.h @@ -1,92 +1,37 @@ -/* -sEPD Geometry class - -Tristan Protzman -tlprotzman@gmail.com -December 15, 2022 - -Converts from r/phi index to location in r/phi space - -Key format: -100000000000000000000_2 -211111111110000000000 -098765432109876543210 -*/ - #ifndef EPD_GEOM_V1_H #define EPD_GEOM_V1_H #include "EpdGeom.h" -#include "EpdGeomV1.h" -#include #include #include #include -#include - -// sEPD geometry class class EpdGeomV1 : public EpdGeom { public: - EpdGeomV1(); - ~EpdGeomV1() override; - - unsigned int side_r_phi_to_id(unsigned int side, unsigned int r_index, unsigned int phi_index) override; - unsigned int side_sector_tile_to_id(unsigned int side, unsigned int sector, unsigned int tile) override; - std::tuple id_to_side_r_phi(unsigned int id) override; - std::tuple id_to_side_sector_tile(unsigned int id) override; - float r(unsigned int id) override; - float r_from_key(unsigned int key) override; - float r_from_side_r_phi(unsigned int side, unsigned int r_index, unsigned int phi_index) override; - float r_from_side_sector_tile(unsigned int side, unsigned int sector, unsigned int tile) override; - float phi(unsigned int id) override; - float phi_from_key(unsigned int key) override; - float phi_from_side_r_phi(unsigned int side, unsigned int r_index, unsigned int phi_index) override; - float phi_from_side_sector_tile(unsigned int side, unsigned int sector, unsigned int tile) override; - float z(unsigned int id) override; - float z_from_key(unsigned int key) override; - float z_from_side_r_phi(unsigned int side, unsigned int r_inxed, unsigned int phi_index) override; - float z_from_side_sector_tile(unsigned int side, unsigned int sector, unsigned int tile) override; - unsigned int decode_epd(unsigned int tower_key) override; - + EpdGeomV1() = default; + ~EpdGeomV1() override = default; + float get_r(unsigned int key) const override; + float get_z(unsigned int key) const override; + float get_phi(unsigned int key) const override; + void set_z(unsigned int key, float z) override; + void set_r(unsigned int key, float r) override; + void set_phi(unsigned int key, float f) override; + void set_phi0(unsigned int key, float f0) override; - void Reset() override {return;}; // Reset doesn't need to do anything private: - const unsigned int NUM_TOWERS = 744; - const unsigned int MAX_R = 16; - const unsigned int MAX_PHI = 24; - const unsigned int NUM_SECTORS = 12; - const unsigned int NUM_TILES = 31; - - std::vector r_lookup; - std::vector phi_lookup; - std::vector z_lookup; - bool test_id_mapping(); - - // const float NAIVE_R_INDEX[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - const float NAIVE_R_LOC[16] = {6.8, 11.2, 15.6, 20.565, 26.095, 31.625, 37.155, 42.685, 48.215, 53.745, 59.275, 64.805, 70.335, 75.865, 81.395, 86.925}; - const float NAIVE_PHI_LOC_RING_0[12] = {0.26179939, 0.78539816, 1.30899694, 1.83259571, 2.35619449, - 2.87979327, 3.40339204, 3.92699082, 4.45058959, 4.97418837, - 5.49778714, 6.02138592}; + float tile_r[16] = {}; + float tile_z[2] = {}; + float tile_phi[24] = {}; + float tile_phi0[12] = {}; - const float NAIVE_PHI_LOC[24] = {0.13089969, 0.39269908, 0.65449847, 0.91629786, 1.17809725, - 1.43989663, 1.70169602, 1.96349541, 2.2252948 , 2.48709418, - 2.74889357, 3.01069296, 3.27249235, 3.53429174, 3.79609112, - 4.05789051, 4.3196899 , 4.58148929, 4.84328867, 5.10508806, - 5.36688745, 5.62868684, 5.89048623, 6.15228561}; - - const float NAIVE_Z_MAP[2] = {-316, 316}; - - void build_lookup(); - ClassDefOverride(EpdGeomV1, 1) }; -#endif // EPD_GEOM_V1_H \ No newline at end of file +#endif // EPD_GEOM_V1_H diff --git a/offline/packages/epd/Makefile.am b/offline/packages/epd/Makefile.am index 9dce4ebb5f..9b84eafa6a 100644 --- a/offline/packages/epd/Makefile.am +++ b/offline/packages/epd/Makefile.am @@ -5,8 +5,7 @@ AUTOMAKE_OPTIONS = foreign # list of shared libraries to produce lib_LTLIBRARIES = \ - libepd_io.la \ - libepd.la + libepd_io.la AM_CPPFLAGS = \ -I$(includedir) \ @@ -20,19 +19,13 @@ AM_LDFLAGS = \ -L$(ROOTSYS)/lib libepd_io_la_LIBADD = \ - -lphool - -libepd_la_LIBADD = \ - libepd_io.la \ - -lgsl \ - -lgslcblas \ - -lSubsysReco + -lphool \ + -lcalo_io pkginclude_HEADERS = \ EPDDefs.h \ EpdGeom.h \ - EpdGeomV1.h \ - EpdGeomMaker.h + EpdGeomV1.h ROOTDICTS = \ EpdGeom_Dict.cc \ @@ -48,10 +41,6 @@ libepd_io_la_SOURCES = \ $(ROOTDICTS) \ EpdGeomV1.cc -libepd_la_SOURCES = \ - EpdGeomMaker.cc - - # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ @@ -65,12 +54,8 @@ libepd_la_SOURCES = \ BUILT_SOURCES = testexternals.cc noinst_PROGRAMS = \ - testexternals \ testexternals_io -testexternals_SOURCES = testexternals.cc -testexternals_LDADD = libepd.la - testexternals_io_SOURCES = testexternals.cc testexternals_io_LDADD = libepd_io.la diff --git a/simulation/g4simulation/g4vertex/GlobalVertex.cc b/offline/packages/globalvertex/GlobalVertex.cc similarity index 100% rename from simulation/g4simulation/g4vertex/GlobalVertex.cc rename to offline/packages/globalvertex/GlobalVertex.cc diff --git a/simulation/g4simulation/g4vertex/GlobalVertex.h b/offline/packages/globalvertex/GlobalVertex.h similarity index 91% rename from simulation/g4simulation/g4vertex/GlobalVertex.h rename to offline/packages/globalvertex/GlobalVertex.h index 5d56823233..b5c0928462 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertex.h +++ b/offline/packages/globalvertex/GlobalVertex.h @@ -12,11 +12,15 @@ class GlobalVertex : public PHObject { public: + // the order matters (best vertex -> highest number), so leave some space in case we want to wedge other vertices in here enum VTXTYPE { - NONE = 0, - BBC = 1, - SVTX = 2 + UNDEFINED = 0, + TRUTH = 100, + SMEARED = 200, + BBC = 300, + SVTX = 400, + SVTX_BBC = 500 }; typedef std::map::const_iterator ConstVtxIter; diff --git a/simulation/g4simulation/g4vertex/GlobalVertexLinkDef.h b/offline/packages/globalvertex/GlobalVertexLinkDef.h similarity index 100% rename from simulation/g4simulation/g4vertex/GlobalVertexLinkDef.h rename to offline/packages/globalvertex/GlobalVertexLinkDef.h diff --git a/simulation/g4simulation/g4vertex/GlobalVertexMap.cc b/offline/packages/globalvertex/GlobalVertexMap.cc similarity index 99% rename from simulation/g4simulation/g4vertex/GlobalVertexMap.cc rename to offline/packages/globalvertex/GlobalVertexMap.cc index fe6dd72064..55da18b389 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexMap.cc +++ b/offline/packages/globalvertex/GlobalVertexMap.cc @@ -31,4 +31,3 @@ GlobalVertexMap::Iter GlobalVertexMap::end() { return DummyGlobalVertexMap.end(); } - diff --git a/simulation/g4simulation/g4vertex/GlobalVertexMap.h b/offline/packages/globalvertex/GlobalVertexMap.h similarity index 100% rename from simulation/g4simulation/g4vertex/GlobalVertexMap.h rename to offline/packages/globalvertex/GlobalVertexMap.h diff --git a/simulation/g4simulation/g4vertex/GlobalVertexMapLinkDef.h b/offline/packages/globalvertex/GlobalVertexMapLinkDef.h similarity index 100% rename from simulation/g4simulation/g4vertex/GlobalVertexMapLinkDef.h rename to offline/packages/globalvertex/GlobalVertexMapLinkDef.h diff --git a/offline/packages/globalvertex/GlobalVertexMapv1.cc b/offline/packages/globalvertex/GlobalVertexMapv1.cc new file mode 100644 index 0000000000..9abcae3a0b --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexMapv1.cc @@ -0,0 +1,59 @@ +#include "GlobalVertexMapv1.h" + +#include "GlobalVertex.h" +#include "GlobalVertexMap.h" + +#include // for reverse_iterator +#include // for pair, make_pair + +GlobalVertexMapv1::~GlobalVertexMapv1() +{ + clear(); +} + +void GlobalVertexMapv1::identify(std::ostream& os) const +{ + os << "GlobalVertexMapv1: size = " << _map.size() << std::endl; + for (auto& m : _map) + { + m.second->identify(os); + } + return; +} + +void GlobalVertexMapv1::clear() +{ + for (const auto& iter : _map) + { + delete iter.second; + } + _map.clear(); + return; +} + +const GlobalVertex* GlobalVertexMapv1::get(unsigned int id) const +{ + ConstIter iter = _map.find(id); + if (iter == _map.end()) + { + return nullptr; + } + return iter->second; +} + +GlobalVertex* GlobalVertexMapv1::get(unsigned int id) +{ + Iter iter = _map.find(id); + if (iter == _map.end()) + { + return nullptr; + } + return iter->second; +} + +GlobalVertex* GlobalVertexMapv1::insert(GlobalVertex* clus) +{ + unsigned int index = clus->get_id(); + auto ret = _map.insert(std::make_pair(index, clus)); + return ret.first->second; +} diff --git a/simulation/g4simulation/g4vertex/GlobalVertexMapv1.h b/offline/packages/globalvertex/GlobalVertexMapv1.h similarity index 95% rename from simulation/g4simulation/g4vertex/GlobalVertexMapv1.h rename to offline/packages/globalvertex/GlobalVertexMapv1.h index 00712dfa16..33fb957cc6 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexMapv1.h +++ b/offline/packages/globalvertex/GlobalVertexMapv1.h @@ -7,14 +7,14 @@ #include "GlobalVertex.h" -#include // for size_t +#include // for size_t #include #include class GlobalVertexMapv1 : public GlobalVertexMap { public: - GlobalVertexMapv1(); + GlobalVertexMapv1() = default; ~GlobalVertexMapv1() override; void identify(std::ostream& os = std::cout) const override; diff --git a/simulation/g4simulation/g4vertex/GlobalVertexMapv1LinkDef.h b/offline/packages/globalvertex/GlobalVertexMapv1LinkDef.h similarity index 100% rename from simulation/g4simulation/g4vertex/GlobalVertexMapv1LinkDef.h rename to offline/packages/globalvertex/GlobalVertexMapv1LinkDef.h diff --git a/simulation/g4simulation/g4vertex/GlobalVertexReco.cc b/offline/packages/globalvertex/GlobalVertexReco.cc similarity index 64% rename from simulation/g4simulation/g4vertex/GlobalVertexReco.cc rename to offline/packages/globalvertex/GlobalVertexReco.cc index 6748c9024d..0cfb383619 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexReco.cc +++ b/offline/packages/globalvertex/GlobalVertexReco.cc @@ -1,54 +1,43 @@ #include "GlobalVertexReco.h" +#include "GlobalVertex.h" // for GlobalVertex, GlobalVe... +#include "GlobalVertexMap.h" // for GlobalVertexMap #include "GlobalVertexMapv1.h" -#include "GlobalVertexMap.h" // for GlobalVertexMap -#include "GlobalVertex.h" // for GlobalVertex, GlobalVe... #include "GlobalVertexv1.h" -#include -#include +#include +#include +#include +#include #include #include #include -#include // for SubsysReco +#include // for SubsysReco #include #include -#include // for PHNode +#include // for PHNode #include -#include // for PHObject +#include // for PHObject #include -#include // for PHWHERE +#include // for PHWHERE #include #include -#include // for exit -#include // for _Rb_tree_const_iterator +#include // for exit #include -#include // for pair +#include // for _Rb_tree_const_iterator +#include // for pair using namespace std; GlobalVertexReco::GlobalVertexReco(const string &name) : SubsysReco(name) - , _xdefault(0.0) - , _xerr(0.3) - , _ydefault(0.0) - , _yerr(0.3) - , _tdefault(0.0) - , _terr(0.2) { } -GlobalVertexReco::~GlobalVertexReco() {} - -int GlobalVertexReco::Init(PHCompositeNode */*topNode*/) -{ - return Fun4AllReturnCodes::EVENT_OK; -} - int GlobalVertexReco::InitRun(PHCompositeNode *topNode) { if (Verbosity() > 0) @@ -62,7 +51,10 @@ int GlobalVertexReco::InitRun(PHCompositeNode *topNode) int GlobalVertexReco::process_event(PHCompositeNode *topNode) { - if (Verbosity() > 1) cout << "GlobalVertexReco::process_event -- entered" << endl; + if (Verbosity() > 1) + { + cout << "GlobalVertexReco::process_event -- entered" << endl; + } //--------------------------------- // Get Objects off of the Node Tree @@ -76,6 +68,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) SvtxVertexMap *svtxmap = findNode::getClass(topNode, "SvtxVertexMap"); BbcVertexMap *bbcmap = findNode::getClass(topNode, "BbcVertexMap"); + SvtxTrackMap *trackmap = findNode::getClass(topNode, "SvtxTrackMap"); // we will make 3 different kinds of global vertexes // (1) SVTX+BBC vertexes - we match SVTX vertex to the nearest BBC vertex within 3 sigma in zvertex @@ -95,10 +88,13 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) std::set used_svtx_vtxids; std::set used_bbc_vtxids; - + if (svtxmap && bbcmap) { - if (Verbosity()) cout << "GlobalVertexReco::process_event - svtxmap && bbcmap" << endl; + if (Verbosity()) + { + cout << "GlobalVertexReco::process_event - svtxmap && bbcmap" << endl; + } for (SvtxVertexMap::ConstIter svtxiter = svtxmap->begin(); svtxiter != svtxmap->end(); @@ -123,10 +119,13 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } } - if (min_sigma > 3.0 || !bbc_best) continue; + if (min_sigma > 3.0 || !bbc_best) + { + continue; + } // we have a matching pair - GlobalVertex *vertex = new GlobalVertexv1(); + GlobalVertex *vertex = new GlobalVertexv1(GlobalVertex::VTXTYPE::SVTX_BBC); for (unsigned int i = 0; i < 3; ++i) { @@ -147,17 +146,35 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) used_svtx_vtxids.insert(svtx->get_id()); vertex->insert_vtxids(GlobalVertex::BBC, bbc_best->get_id()); used_bbc_vtxids.insert(bbc_best->get_id()); + vertex->set_id(globalmap->size()); globalmap->insert(vertex); - if (Verbosity()) vertex->identify(); + //! Reset track ids to the new vertex object + if (trackmap) + { + for (auto iter = svtx->begin_tracks(); iter != svtx->end_tracks(); + ++iter) + { + auto track = trackmap->find(*iter)->second; + track->set_vertex_id(vertex->get_id()); + } + } + + if (Verbosity() > 1) + { + vertex->identify(); + } } } // okay now loop over all unused SVTX vertexes (2nd class)... if (svtxmap) { - if (Verbosity()) cout << "GlobalVertexReco::process_event - svtxmap " << endl; + if (Verbosity()) + { + cout << "GlobalVertexReco::process_event - svtxmap " << endl; + } for (SvtxVertexMap::ConstIter svtxiter = svtxmap->begin(); svtxiter != svtxmap->end(); @@ -165,11 +182,19 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) { const SvtxVertex *svtx = svtxiter->second; - if (used_svtx_vtxids.find(svtx->get_id()) != used_svtx_vtxids.end()) continue; - if (isnan(svtx->get_z())) continue; + if (used_svtx_vtxids.find(svtx->get_id()) != used_svtx_vtxids.end()) + { + continue; + } + if (isnan(svtx->get_z())) + { + continue; + } // we have a standalone SVTX vertex - GlobalVertex *vertex = new GlobalVertexv1(); + GlobalVertex *vertex = new GlobalVertexv1(GlobalVertex::VTXTYPE::SVTX); + + vertex->set_id(globalmap->size()); for (unsigned int i = 0; i < 3; ++i) { @@ -180,26 +205,38 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } } - // default time could also come from somewhere else at some point - vertex->set_t(_tdefault); - vertex->set_t_err(_terr); - vertex->set_chisq(svtx->get_chisq()); vertex->set_ndof(svtx->get_ndof()); vertex->insert_vtxids(GlobalVertex::SVTX, svtx->get_id()); used_svtx_vtxids.insert(svtx->get_id()); + //! Reset track ids to the new vertex object + if (trackmap) + { + for (auto iter = svtx->begin_tracks(); iter != svtx->end_tracks(); + ++iter) + { + auto track = trackmap->find(*iter)->second; + track->set_vertex_id(vertex->get_id()); + } + } globalmap->insert(vertex); - if (Verbosity()) vertex->identify(); + if (Verbosity() > 1) + { + vertex->identify(); + } } } - + // okay now loop over all unused BBC vertexes (3rd class)... if (bbcmap) { - if (Verbosity()) cout << "GlobalVertexReco::process_event - bbcmap" << endl; + if (Verbosity()) + { + cout << "GlobalVertexReco::process_event - bbcmap" << endl; + } for (BbcVertexMap::ConstIter bbciter = bbcmap->begin(); bbciter != bbcmap->end(); @@ -207,10 +244,17 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) { const BbcVertex *bbc = bbciter->second; - if (used_bbc_vtxids.find(bbc->get_id()) != used_bbc_vtxids.end()) continue; - if (isnan(bbc->get_z())) continue; + if (used_bbc_vtxids.find(bbc->get_id()) != used_bbc_vtxids.end()) + { + continue; + } + if (isnan(bbc->get_z())) + { + continue; + } - GlobalVertex *vertex = new GlobalVertexv1(); + GlobalVertex *vertex = new GlobalVertexv1(GlobalVertex::VTXTYPE::BBC); + vertex->set_id(globalmap->size()); // nominal beam location // could be replaced with a beam spot some day @@ -225,9 +269,9 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) vertex->set_error(0, 1, 0.0); vertex->set_error(0, 2, 0.0); - vertex->set_error(1, 1, 0.0); + vertex->set_error(1, 0, 0.0); vertex->set_error(1, 1, pow(_yerr, 2)); - vertex->set_error(1, 1, 0.0); + vertex->set_error(1, 2, 0.0); vertex->set_error(0, 2, 0.0); vertex->set_error(1, 2, 0.0); @@ -238,15 +282,50 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) globalmap->insert(vertex); - if (Verbosity()) vertex->identify(); + if (Verbosity() > 1) + { + vertex->identify(); + } } } + + /// Associate any tracks that were not assigned a track-vertex + if (trackmap) + { + for (const auto &[tkey, track] : *trackmap) + { + //! Check that the vertex hasn't already been assigned + auto trackvtxid = track->get_vertex_id(); + if (globalmap->find(trackvtxid) != globalmap->end()) + { + continue; + } - return Fun4AllReturnCodes::EVENT_OK; -} + float maxdz = std::numeric_limits::max(); + unsigned int vtxid = std::numeric_limits::max(); -int GlobalVertexReco::End(PHCompositeNode */*topNode*/) -{ + for (const auto &[vkey, vertex] : *globalmap) + { + float dz = track->get_z() - vertex->get_z(); + if (fabs(dz) < maxdz) + { + maxdz = dz; + vtxid = vkey; + } + } + + track->set_vertex_id(vtxid); + if (Verbosity()) + { + std::cout << "Associated track with z " << track->get_z() << " to GlobalVertex id " << track->get_vertex_id() << std::endl; + } + } + } + + if (Verbosity()) + { + globalmap->identify(); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -255,7 +334,7 @@ int GlobalVertexReco::CreateNodes(PHCompositeNode *topNode) PHNodeIterator iter(topNode); // Looking for the DST node - PHCompositeNode *dstNode = static_cast(iter.findFirst("PHCompositeNode", "DST")); + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); if (!dstNode) { cout << PHWHERE << "DST Node missing, doing nothing." << endl; @@ -278,11 +357,5 @@ int GlobalVertexReco::CreateNodes(PHCompositeNode *topNode) PHIODataNode *VertexMapNode = new PHIODataNode(vertexes, "GlobalVertexMap", "PHObject"); globalNode->addNode(VertexMapNode); } - else - { - cout << PHWHERE << "::ERROR - GlobalVertexMap pre-exists, but should not, perhaps you are also running the FastSim" << endl; - exit(-1); - } - return Fun4AllReturnCodes::EVENT_OK; } diff --git a/simulation/g4simulation/g4vertex/GlobalVertexReco.h b/offline/packages/globalvertex/GlobalVertexReco.h similarity index 82% rename from simulation/g4simulation/g4vertex/GlobalVertexReco.h rename to offline/packages/globalvertex/GlobalVertexReco.h index f01568a93f..6c0ae222fb 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexReco.h +++ b/offline/packages/globalvertex/GlobalVertexReco.h @@ -12,7 +12,7 @@ #include -#include // for string +#include // for string class PHCompositeNode; @@ -24,12 +24,10 @@ class GlobalVertexReco : public SubsysReco { public: GlobalVertexReco(const std::string &name = "GlobalVertexReco"); - ~GlobalVertexReco() override; + ~GlobalVertexReco() override = default; - int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; - int End(PHCompositeNode *topNode) override; void set_x_defaults(float xdefault, float xerr) { @@ -50,9 +48,12 @@ class GlobalVertexReco : public SubsysReco private: int CreateNodes(PHCompositeNode *topNode); - float _xdefault, _xerr; - float _ydefault, _yerr; - float _tdefault, _terr; + float _xdefault = 0.; + float _xerr = 0.3; + float _ydefault = 0.; + float _yerr = 0.3; + float _tdefault = 0.; + float _terr = 0.2; }; #endif // G4VERTEX_GLOBALVERTEXRECO_H diff --git a/offline/packages/globalvertex/GlobalVertexv1.cc b/offline/packages/globalvertex/GlobalVertexv1.cc new file mode 100644 index 0000000000..b79f8acf75 --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv1.cc @@ -0,0 +1,110 @@ +#include "GlobalVertexv1.h" + +#include + +GlobalVertexv1::GlobalVertexv1(const GlobalVertex::VTXTYPE id) + : _id(id) +{ + std::fill(std::begin(_pos), std::end(_pos), std::numeric_limits::quiet_NaN()); + std::fill(std::begin(_err), std::end(_err), std::numeric_limits::quiet_NaN()); +} + +void GlobalVertexv1::identify(std::ostream& os) const +{ + os << "---GlobalVertexv1-----------------------" << std::endl; + os << "vertexid: " << get_id(); + + os << " t = " << get_t() << std::endl; + + os << " (x,y,z) = (" << get_position(0); + os << ", " << get_position(1) << ", "; + os << get_position(2) << ") cm" << std::endl; + + os << " chisq = " << get_chisq() << ", "; + os << " ndof = " << get_ndof() << std::endl; + + os << " ( "; + os << get_error(0, 0) << " , "; + os << get_error(0, 1) << " , "; + os << get_error(0, 2) << " )" << std::endl; + os << " err = ( "; + os << get_error(1, 0) << " , "; + os << get_error(1, 1) << " , "; + os << get_error(1, 2) << " )" << std::endl; + os << " ( "; + os << get_error(2, 0) << " , "; + os << get_error(2, 1) << " , "; + os << get_error(2, 2) << " )" << std::endl; + + os << " list of vtx ids: " << std::endl; + for (ConstVtxIter iter = begin_vtxids(); iter != end_vtxids(); ++iter) + { + os << " " << iter->first << " => " << iter->second << std::endl; + } + os << "-----------------------------------------------" << std::endl; + + return; +} + +int GlobalVertexv1::isValid() const +{ + if (!std::isfinite(_t)) + { + return 0; + } + if (!std::isfinite(_t_err)) + { + return 0; + } + if (!std::isfinite(_chisq)) + { + return 0; + } + if (_ndof == std::numeric_limits::max()) + { + return 0; + } + + for (float _po : _pos) + { + if (!std::isfinite(_po)) + { + return 0; + } + } + for (int j = 0; j < 3; ++j) + { + for (int i = j; i < 3; ++i) + { + if (!std::isfinite(get_error(i, j))) + { + return 0; + } + } + } + if (_vtx_ids.empty()) + { + return 0; + } + return 1; +} + +void GlobalVertexv1::set_error(unsigned int i, unsigned int j, float value) +{ + _err[covar_index(i, j)] = value; + return; +} + +float GlobalVertexv1::get_error(unsigned int i, unsigned int j) const +{ + return _err[covar_index(i, j)]; +} + +unsigned int GlobalVertexv1::covar_index(unsigned int i, unsigned int j) const +{ + if (i > j) + { + std::swap(i, j); + } + return i + 1 + (j + 1) * (j) / 2 - 1; +} diff --git a/simulation/g4simulation/g4vertex/GlobalVertexv1.h b/offline/packages/globalvertex/GlobalVertexv1.h similarity index 80% rename from simulation/g4simulation/g4vertex/GlobalVertexv1.h rename to offline/packages/globalvertex/GlobalVertexv1.h index c43a06085b..cd7119b817 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexv1.h +++ b/offline/packages/globalvertex/GlobalVertexv1.h @@ -5,18 +5,19 @@ #include "GlobalVertex.h" -#include // for size_t +#include // for size_t #include +#include #include -#include // for pair, make_pair +#include // for pair, make_pair class PHObject; class GlobalVertexv1 : public GlobalVertex { public: - GlobalVertexv1(); - ~GlobalVertexv1() override; + GlobalVertexv1(const GlobalVertex::VTXTYPE id = GlobalVertex::UNDEFINED); + ~GlobalVertexv1() override = default; // PHObject virtual overloads @@ -82,13 +83,13 @@ class GlobalVertexv1 : public GlobalVertex private: unsigned int covar_index(unsigned int i, unsigned int j) const; - unsigned int _id; //< unique identifier within container - float _t; //< collision time - float _t_err; //< collision time uncertainty - float _pos[3]; //< collision position x,y,z - float _chisq; //< vertex fit chisq - unsigned int _ndof; //< degrees of freedom - float _err[6]; //< error covariance matrix (+/- cm^2) + unsigned int _id = std::numeric_limits::max(); //< unique identifier within container + float _t = std::numeric_limits::quiet_NaN(); //< collision time + float _t_err = std::numeric_limits::quiet_NaN(); //< collision time uncertainty + float _pos[3] = {}; //< collision position x,y,z + float _chisq = std::numeric_limits::quiet_NaN(); //< vertex fit chisq + unsigned int _ndof = std::numeric_limits::max(); + float _err[6] = {}; //< error covariance matrix (+/- cm^2) std::map _vtx_ids; //< list of vtx ids ClassDefOverride(GlobalVertexv1, 1); diff --git a/simulation/g4simulation/g4vertex/GlobalVertexv1LinkDef.h b/offline/packages/globalvertex/GlobalVertexv1LinkDef.h similarity index 100% rename from simulation/g4simulation/g4vertex/GlobalVertexv1LinkDef.h rename to offline/packages/globalvertex/GlobalVertexv1LinkDef.h diff --git a/offline/packages/globalvertex/Makefile.am b/offline/packages/globalvertex/Makefile.am new file mode 100644 index 0000000000..1416a12718 --- /dev/null +++ b/offline/packages/globalvertex/Makefile.am @@ -0,0 +1,89 @@ +AUTOMAKE_OPTIONS = foreign + +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include \ + -I`root-config --incdir` + +lib_LTLIBRARIES = \ + libglobalvertex_io.la \ + libglobalvertex.la + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib + +libglobalvertex_io_la_LIBADD = \ + -lphool \ + -ltrackbase_historic_io + +libglobalvertex_la_LIBADD = \ + libglobalvertex_io.la \ + -lbbc_io \ + -lg4detectors \ + -lfun4all \ + -lg4bbc_io \ + -ltrackbase_historic_io + +pkginclude_HEADERS = \ + GlobalVertex.h \ + GlobalVertexv1.h \ + GlobalVertexMap.h \ + GlobalVertexMapv1.h \ + GlobalVertexReco.h + +ROOTDICTS = \ + GlobalVertex_Dict.cc \ + GlobalVertexv1_Dict.cc \ + GlobalVertexMap_Dict.cc \ + GlobalVertexMapv1_Dict.cc + +pcmdir = $(libdir) +nobase_dist_pcm_DATA = \ + GlobalVertex_Dict_rdict.pcm \ + GlobalVertexv1_Dict_rdict.pcm \ + GlobalVertexMap_Dict_rdict.pcm \ + GlobalVertexMapv1_Dict_rdict.pcm + +libglobalvertex_io_la_SOURCES = \ + $(ROOTDICTS) \ + GlobalVertex.cc \ + GlobalVertexv1.cc \ + GlobalVertexMap.cc \ + GlobalVertexMapv1.cc + +libglobalvertex_la_SOURCES = \ + GlobalVertexReco.cc + +# Rule for generating table CINT dictionaries. +%_Dict.cc: %.h %LinkDef.h + rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ + +#just to get the dependency +%_Dict_rdict.pcm: %_Dict.cc ; + +################################################ +# linking tests + +noinst_PROGRAMS = \ + testexternals_globalvertex_io \ + testexternals_globalvertex + +BUILT_SOURCES = \ + testexternals.cc + +testexternals_globalvertex_io_SOURCES = testexternals.cc +testexternals_globalvertex_io_LDADD = libglobalvertex_io.la + +testexternals_globalvertex_SOURCES = testexternals.cc +testexternals_globalvertex_LDADD = libglobalvertex.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +clean-local: + rm -f *Dict* $(BUILT_SOURCES) *.pcm diff --git a/simulation/g4simulation/eASTPhysicsList/autogen.sh b/offline/packages/globalvertex/autogen.sh similarity index 100% rename from simulation/g4simulation/eASTPhysicsList/autogen.sh rename to offline/packages/globalvertex/autogen.sh diff --git a/offline/packages/globalvertex/configure.ac b/offline/packages/globalvertex/configure.ac new file mode 100644 index 0000000000..8d3b54a55b --- /dev/null +++ b/offline/packages/globalvertex/configure.ac @@ -0,0 +1,25 @@ +AC_INIT(globalvertex, [1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE + +AC_PROG_CXX(CC g++) +LT_INIT([disable-static]) + +dnl leaving this here in case we want to play with different compiler +dnl specific flags +case $CXX in + clang++) + CXXFLAGS="$CXXFLAGS -Wall -Werror -Wextra" + ;; + *g++) + CXXFLAGS="$CXXFLAGS -Wall -Werror -Wextra" + ;; +esac + + +CINTDEFS=" -noIncludePaths -inlineInputHeader " +AC_SUBST(CINTDEFS) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/offline/packages/intt/InttClusterizer.cc b/offline/packages/intt/InttClusterizer.cc index 7d08cc5fe7..491bdcaaf2 100644 --- a/offline/packages/intt/InttClusterizer.cc +++ b/offline/packages/intt/InttClusterizer.cc @@ -245,10 +245,10 @@ int InttClusterizer::process_event(PHCompositeNode* topNode) // get node containing the digitized hits if(!do_read_raw){ - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_INTT"); if (!m_hits) { - cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << endl; + cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_INTT" << endl; return Fun4AllReturnCodes::ABORTRUN; } }else{ @@ -256,7 +256,7 @@ int InttClusterizer::process_event(PHCompositeNode* topNode) m_rawhits = findNode::getClass(topNode, "TRKR_RAWHITSET"); if (!m_rawhits) { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + std::cout << PHWHERE << "ERROR: Can't find node TRKR_RAWHITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } } diff --git a/offline/packages/intt/InttDeadMapHelper.cc b/offline/packages/intt/InttDeadMapHelper.cc new file mode 100644 index 0000000000..d267adf8f9 --- /dev/null +++ b/offline/packages/intt/InttDeadMapHelper.cc @@ -0,0 +1,379 @@ +#include "InttDeadMapHelper.h" + +InttDeadMapHelper::InttDeadMapHelper() +{ + N = 0; + points = nullptr; + + n_z = 0.0; + n_t = 0.0; + p = 0.0; + q = 0.0; + + mu = 0; + sg = 0; + + n_g = 0; + n_l = 0; + n_u = 0; + + i_lower = 0; + i_upper = 0; + D = 0; +} + +InttDeadMapHelper::InttDeadMapHelper(InttDeadMapHelper const& _o) +{ + N = _o.N; + points = new struct InttDeadMap_Point_s[N]; + for(InttDeadMap_Long_t i = 0; i < N; ++i) + { + points[i] = _o.points[i]; + } + + n_z = _o.n_z; + n_t = _o.n_t; + + p = _o.p; + q = _o.q; + + mu = _o.mu; + sg = _o.sg; + + n_g = _o.n_g; + n_l = _o.n_l; + n_u = _o.n_u; + + i_lower = _o.i_lower; + i_upper = _o.i_upper; + D = _o.D; +} + +InttDeadMapHelper& InttDeadMapHelper::operator=(InttDeadMapHelper const& _o) +{ + if(this == &_o)return *this; + + N = _o.N; + points = new struct InttDeadMap_Point_s[N]; + for(InttDeadMap_Long_t i = 0; i < N; ++i) + { + points[i] = _o.points[i]; + } + + n_z = _o.n_z; + n_t = _o.n_t; + + p = _o.p; + q = _o.q; + + mu = _o.mu; + sg = _o.sg; + + n_g = _o.n_g; + n_l = _o.n_l; + n_u = _o.n_u; + + i_lower = _o.i_lower; + i_upper = _o.i_upper; + D = _o.D; + + return *this; +} + +InttDeadMapHelper::InttDeadMapHelper(InttDeadMap_Long_t const& _N, InttDeadMap_Double_t const& _n_z, InttDeadMap_Double_t const& _n_t) +{ + N = _N; + points = new struct InttDeadMap_Point_s[N]; + + n_z = _n_z; + n_t = _n_t; + p = 1.0 - erfl(n_z / sqrtl(2.0)); + q = sqrtl(p * (1.0 - p)); + + mu = 0; + sg = 0; + + n_g = 0; + n_l = 0; + n_u = 0; + + i_lower = 0; + i_upper = N; + D = 0; +} + +InttDeadMapHelper::~InttDeadMapHelper() +{ + if(points)delete[] points; +} + +void InttDeadMapHelper::quicksort_hitkey(InttDeadMap_Long_t const& _l, InttDeadMap_Long_t const& _u) +{ + if(_l < 0)return; + if(_u < 1)return; + if(_u <= _l)return; + if(!points)return; + + InttDeadMap_Long_t i_pivot = _l - 1; + + { + InttDeadMap_Long_t i; + + struct InttDeadMap_Point_s pivot = points[_u - 1]; + struct InttDeadMap_Point_s temp; + + for(i = _l; i < _u - 1; ++i) + { + if(points[i].hitkey <= pivot.hitkey) + { + ++i_pivot; + temp = points[i]; + points[i] = points[i_pivot]; + points[i_pivot] = temp; + } + } + + ++i_pivot; + temp = points[i_pivot]; + points[i_pivot] = points[_u - 1]; + points[_u - 1] = temp; + } + + quicksort_hitkey(_l, i_pivot); + quicksort_hitkey(i_pivot + 1, _u); +} + +void InttDeadMapHelper::quicksort_counts(InttDeadMap_Long_t const& _l, InttDeadMap_Long_t const& _u) +{ + if(_l < 0)return; + if(_u < 1)return; + if(_u <= _l)return; + if(!points)return; + + InttDeadMap_Long_t i_pivot = _l - 1; + + { + InttDeadMap_Long_t i; + + struct InttDeadMap_Point_s pivot = points[_u- 1]; + struct InttDeadMap_Point_s temp; + + for(i = _l; i < _u - 1; ++i) + { + if(points[i].counts <= pivot.counts) + { + ++i_pivot; + temp = points[i]; + points[i] = points[i_pivot]; + points[i_pivot] = temp; + } + } + + ++i_pivot; + temp = points[i_pivot]; + points[i_pivot] = points[_u - 1]; + points[_u - 1] = temp; + } + + quicksort_counts(_l, i_pivot); + quicksort_counts(i_pivot + 1, _u); +} + + +struct InttDeadMapHelper::InttDeadMap_Point_s* InttDeadMapHelper::get_point(InttDeadMap_HitKey_t const& hitkey, InttDeadMap_Long_t const& _l, InttDeadMap_Long_t const& _u) +{ + if(!points) return nullptr; + if(points[(_u + _l) / 2].hitkey == hitkey) return &(points[(i_upper + i_lower) / 2]); + + if(_u - _l <= 1) return nullptr; + + if(hitkey < points[(_u + _l) / 2].hitkey) return get_point(hitkey, _l, (_u + _l) / 2); + if(hitkey > points[(_u + _l) / 2].hitkey) return get_point(hitkey, (_u + _l) / 2, _u); + + return nullptr; +} + +int InttDeadMapHelper::count_type_i() +{ + if(!points)return EXIT_FAILURE; + + //Alternatively, instead of a two-pass and then classify, + //I can fit to a Gaussian and use a goodness-of-fit parameter + InttDeadMap_Long_t i = 0; + + InttDeadMap_Double_t lower; + InttDeadMap_Double_t upper; + + mu = 0; + sg = 0; + + n_g = 0; + n_l = 0; + n_u = 0; + + for(i = i_lower; i < i_upper; ++i) + { + mu += points[i].counts; + } + mu /= (i_upper - i_lower); + + for(i = i_lower; i < i_upper; ++i) + { + sg += (points[i].counts - mu) * (points[i].counts - mu); + } + sg /= (i_upper - i_lower); + sg = sqrtl(sg); + + lower = mu - n_z * sg; + upper = mu + n_z * sg; + + for(i = i_lower; i < i_upper; ++i) + { + if(points[i].counts < lower) + { + ++n_l; + points[i].status = InttDeadMap_Status_LOWER; + continue; + } + + if(upper < points[i].counts) + { + ++n_u; + points[i].status = InttDeadMap_Status_UPPER; + continue; + } + + ++n_g; + points[i].status = InttDeadMap_Status_GOOD; + } + + return EXIT_SUCCESS; +} + +int InttDeadMapHelper::check_type_i() +{ + if(!points)return EXIT_FAILURE; + + printf("check_type_i\n"); + + if(i_upper - i_lower <= 1)return EXIT_FAILURE; + + count_type_i(); + + { + int flag = 0; + + InttDeadMap_Long_t d; + + InttDeadMap_Double_t lower = p * (i_upper - i_lower) - n_t * q * sqrtl(i_upper - i_lower); + InttDeadMap_Double_t upper = p * (i_upper - i_lower) + n_t * q * sqrtl(i_upper - i_lower); + + d = 0; + if(n_l + n_u < floor(lower)) + { + d = floor(lower) - n_l - n_u; + } + if(ceil(upper) < n_l + n_u) + { + d = n_l + n_u - ceil(upper); + } + if(n_l - n_u > ceil((upper - lower) / 2.0)) + { + d = n_l - n_u - ceil((upper - lower) / 2.0); + } + if(n_u - n_l > ceil((upper - lower) / 2.0)) + { + d = n_u - n_l - ceil((upper - lower) / 2.0); + } + + std::cout << "\t" << floor(lower) << " < " << n_l << " + " << n_u << " < " << ceil(upper) << std::endl; + std::cout << "\t" << "mu: " << mu << "\tsg: " << sg << std::endl; + std::cout << "\t" << "lower: " << i_lower << "\tupper: " << i_upper << std::endl; + std::cout << "\td_l: " << (mu - points[i_lower].counts) / sg; + std::cout << "\td_u: " << (points[i_upper - 1].counts - mu) / sg << std::endl; + if(d == 0)return EXIT_SUCCESS; + + lower = mu - n_z * sg; + upper = mu + n_z * sg; + + flag = 0; + flag = flag || points[i_lower].status != InttDeadMap_Status_GOOD; + flag = flag || points[i_upper - 1].status != InttDeadMap_Status_GOOD; + + D = 0; + while(d) + { + if(i_upper - i_lower <= 1)break; + + if(points[i_upper - 1].counts - mu < mu - points[i_lower].counts) + { + if(flag && points[i_lower].status == InttDeadMap_Status_GOOD)break; + points[i_lower].status = InttDeadMap_Status_LOWER; + ++i_lower; + } + else + { + if(flag && points[i_upper - 1].status == InttDeadMap_Status_GOOD)break; + points[i_upper - 1].status = InttDeadMap_Status_UPPER; + --i_upper; + } + + --d; + ++D; + } + } + + return check_type_i(); +} + +void InttDeadMapHelper::gen_points(InttDeadMap_Double_t const& frac) +{ + if(!points)return; + + InttDeadMap_Long_t n_bad = ceil(frac * N / 2.0); + + mu = 4121.1324151; + sg = 124.14124; + + InttDeadMap_Double_t z[2]; + InttDeadMap_Double_t u[2]; + + InttDeadMap_Long_t i; + InttDeadMap_HitKey_t h; + InttDeadMap_Double_t c; + + for(i = 0; i < N; ++i) + { + if(i % 2 == 0) + { + u[0] = (InttDeadMap_Double_t)rand() / (InttDeadMap_Double_t)RAND_MAX; + u[1] = (InttDeadMap_Double_t)rand() / (InttDeadMap_Double_t)RAND_MAX; + + z[0] = sqrt(-2.0 * log(u[0])) * cos(2.0 * 3.14159265358979 * u[1]); + z[1] = sqrt(-2.0 * log(u[0])) * sin(2.0 * 3.14159265358979 * u[1]); + } + + c = mu + sg * z[i % 2]; + + points[i].hitkey = i; + points[i].counts = c; + points[i].status = InttDeadMap_Status_GOOD; + } + + c = 999999.999; + for(i = 0; i < n_bad; ++i) + { + h = rand() % N; + points[h].counts = c; + } + + c = 0.0; + for(i = 0; i < n_bad; ++i) + { + h = rand() % N; + points[h].counts = c; + } +} + + + diff --git a/offline/packages/intt/InttDeadMapHelper.h b/offline/packages/intt/InttDeadMapHelper.h new file mode 100644 index 0000000000..1ca9f3c519 --- /dev/null +++ b/offline/packages/intt/InttDeadMapHelper.h @@ -0,0 +1,79 @@ +#ifndef INTT_DEAD_MAP_HELPER_H +#define INTT_DEAD_MAP_HELPER_H + +//C style includes +#include +#include + +//CPP style includes +#include + +//ROOT and sPHENIX includes +#include //for getHitSetKey + +//class TrkrHitSetKey; or whatever it is + +class InttDeadMapHelper +{ +public: + typedef int InttDeadMap_HitKey_t; + typedef long double InttDeadMap_Double_t; + typedef long long InttDeadMap_Long_t; + + enum InttDeadMap_Status_e + { + InttDeadMap_Status_GOOD, + InttDeadMap_Status_LOWER, + InttDeadMap_Status_UPPER + }; + + struct InttDeadMap_Point_s + { + InttDeadMap_HitKey_t hitkey; + InttDeadMap_Long_t counts; + InttDeadMap_Status_e status; + }; + + InttDeadMapHelper(); + + InttDeadMapHelper(InttDeadMapHelper const&); + InttDeadMapHelper& operator=(InttDeadMapHelper const&); + + InttDeadMapHelper(InttDeadMap_Long_t const&, InttDeadMap_Double_t const&, InttDeadMap_Double_t const&); + + ~InttDeadMapHelper(); + + void gen_points(InttDeadMap_Double_t const&); + +//commented while debugging +//protected: + struct InttDeadMap_Point_s* get_point(InttDeadMap_HitKey_t const&, InttDeadMap_Long_t const&, InttDeadMap_Long_t const&); + + int count_type_i(); + int check_type_i(); + + void quicksort_hitkey(InttDeadMap_Long_t const&, InttDeadMap_Long_t const&); + void quicksort_counts(InttDeadMap_Long_t const&, InttDeadMap_Long_t const&); + + + InttDeadMap_Long_t N; + InttDeadMap_Point_s* points; + + InttDeadMap_Double_t n_z; + InttDeadMap_Double_t n_t; + InttDeadMap_Double_t p; + InttDeadMap_Double_t q; + + InttDeadMap_Double_t mu; + InttDeadMap_Double_t sg; + + InttDeadMap_Long_t n_g; + InttDeadMap_Long_t n_l; + InttDeadMap_Long_t n_u; + + InttDeadMap_Long_t i_lower; + InttDeadMap_Long_t i_upper; + InttDeadMap_Long_t D; +}; + +#endif diff --git a/offline/packages/intt/InttFelixMap.cc b/offline/packages/intt/InttFelixMap.cc new file mode 100755 index 0000000000..c455f97c79 --- /dev/null +++ b/offline/packages/intt/InttFelixMap.cc @@ -0,0 +1,646 @@ +#include "InttFelixMap.h" + +int INTT_Felix::FelixMap(int const& felix, int const& felix_channel, struct Ladder_s& ladder_struct) +{ + switch(felix) + { + case 0: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 1: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 2: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 3: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 12; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 12; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 13; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 13; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 14; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 14; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 15; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 15; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 4: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 0; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 1; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 2; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 5: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 3; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 5; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 4; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 6: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 6; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 7; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 8; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + case 7: + switch(felix_channel) + { + case 0: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 1: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 9; + return EXIT_SUCCESS; + case 2: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 3: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 12; + return EXIT_SUCCESS; + case 4: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 12; + return EXIT_SUCCESS; + case 5: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 13; + return EXIT_SUCCESS; + case 6: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 13; + return EXIT_SUCCESS; + case 7: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 10; + return EXIT_SUCCESS; + case 8: + ladder_struct.barrel = 0; + ladder_struct.layer = 1; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + case 9: + ladder_struct.barrel = 0; + ladder_struct.layer = 0; + ladder_struct.ladder = 11; + return EXIT_SUCCESS; + case 10: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 14; + return EXIT_SUCCESS; + case 11: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 14; + return EXIT_SUCCESS; + case 12: + ladder_struct.barrel = 1; + ladder_struct.layer = 1; + ladder_struct.ladder = 15; + return EXIT_SUCCESS; + case 13: + ladder_struct.barrel = 1; + ladder_struct.layer = 0; + ladder_struct.ladder = 15; + return EXIT_SUCCESS; + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + default: + ladder_struct.barrel = -1; + ladder_struct.layer = -1; + ladder_struct.ladder = -1; + return EXIT_FAILURE; + } + return EXIT_FAILURE; +} diff --git a/offline/packages/intt/InttFelixMap.h b/offline/packages/intt/InttFelixMap.h new file mode 100755 index 0000000000..c78a654595 --- /dev/null +++ b/offline/packages/intt/InttFelixMap.h @@ -0,0 +1,18 @@ +#ifndef FELIX_MAP_H +#define FELIX_MAP_H + +#include + +namespace INTT_Felix +{ + struct Ladder_s + { + int barrel; + int layer; + int ladder; + }; + + int FelixMap(int const&, int const&, struct Ladder_s&); +}; + +#endif//FELIX_MAP_H diff --git a/offline/packages/intt/InttRawDataDecoder.cc b/offline/packages/intt/InttRawDataDecoder.cc new file mode 100644 index 0000000000..ca2bba139a --- /dev/null +++ b/offline/packages/intt/InttRawDataDecoder.cc @@ -0,0 +1,117 @@ +#include "InttRawDataDecoder.h" + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +InttRawDataDecoder::InttRawDataDecoder(std::string const& name): + SubsysReco(name) +{ + //Do nothing +} + +//Init +int InttRawDataDecoder::Init(PHCompositeNode* /*topNode*/) +{ + //Do nothing (yet) + return Fun4AllReturnCodes::EVENT_OK; +} + +//InitRun +int InttRawDataDecoder::InitRun(PHCompositeNode* /*topNode*/) +{ + //Do nothing (yet) + return Fun4AllReturnCodes::EVENT_OK; +} + +//process_event +int InttRawDataDecoder::process_event(PHCompositeNode* topNode) +{ + TrkrHitSetContainer* trkr_hit_set_container = findNode::getClass(topNode, "TRKR_HITSET"); + if(!trkr_hit_set_container)return Fun4AllReturnCodes::DISCARDEVENT; + + Event* evt = findNode::getClass(topNode, "PRDF"); + if(!evt)return Fun4AllReturnCodes::DISCARDEVENT; + + int adc = 0; + //int amp = 0; + int bco = 0; + int chp = 0; + int chn = 0; + int fee = 0; + + struct INTT_Felix::Ladder_s ldr_struct; + int layer = 0; + int ladder_z = 0; + int ladder_phi = 0; + int arm = 0; + int strip_x = 0; + int strip_y = 0; + + TrkrDefs::hitsetkey hit_set_key = 0; + TrkrDefs::hitkey hit_key = 0; + TrkrHitSetContainer::Iterator hit_set_container_itr; + TrkrHit* hit = nullptr; + + for(int pid = 3001; pid < 3009; ++pid) + { + Packet* p = evt->getPacket(pid); + if(!p)continue; + + int N = p->iValue(0, "NR_HITS"); + if(!N)continue; + + full_bco = p->lValue(0, "BCO"); + + for(int n = 0; n < N; ++n) + { + adc = p->iValue(n, "ADC"); + //amp = p->iValue(n, "AMPLITUE"); + bco = p->iValue(n, "FPHX_BCO"); + chp = p->iValue(n, "CHIP_ID"); + chn = p->iValue(n, "CHANNEL_ID"); + fee = p->iValue(n, "FEE"); + + INTT_Felix::FelixMap(pid - 3001, fee, ldr_struct); + layer = 2 * ldr_struct.barrel + ldr_struct.ladder; + ladder_phi = ldr_struct.ladder; // B A A B + ladder_z = arm * 2 + (chp % 13 < 5); //South<- 1, 0, 2, 3 ->North + arm = (pid - 3001) / 4; + strip_x = 25 * arm - (2 * arm - 1) * chp % 13; + strip_y = 128 * ((arm + chp / 13) % 2) + chn; //need to check this is the convention + + hit_key = InttDefs::genHitKey(strip_x, strip_y); + hit_set_key = InttDefs::genHitSetKey(layer, ladder_z, ladder_phi, bco); + + hit_set_container_itr = trkr_hit_set_container->findOrAddHitSet(hit_set_key); + hit = hit_set_container_itr->second->getHit(hit_key); + if(hit)continue; + + hit = new TrkrHitv2; + hit->setAdc(adc); + hit_set_container_itr->second->addHitSpecificKey(hit_key, hit); + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//End +int InttRawDataDecoder::End(PHCompositeNode* /*topNode*/) +{ + //Do nothing (yet) + return Fun4AllReturnCodes::EVENT_OK; +} + diff --git a/offline/packages/intt/InttRawDataDecoder.h b/offline/packages/intt/InttRawDataDecoder.h new file mode 100644 index 0000000000..f1c5bccf9c --- /dev/null +++ b/offline/packages/intt/InttRawDataDecoder.h @@ -0,0 +1,35 @@ +#ifndef INTT_RAW_DATA_DECODER_H +#define INTT_RAW_DATA_DECODER_H + +////////////////////////////////////////////////////////////////////////////// +// Shamelessly imitaged from the micromegas version: +// +// coresoftware/offline/packages/micromegas/MicromegasRawDataDecoder.h +// +// Thank you Hugo + +#include "InttFelixMap.h" + +#include + +#include +#include +#include + +class PHCompositeNode; + +class InttRawDataDecoder : public SubsysReco +{ +public: + InttRawDataDecoder(std::string const& name = "InttRawDataDecoder"); + + int Init(PHCompositeNode*) override; + int InitRun(PHCompositeNode*) override; + int process_event(PHCompositeNode*) override; + int End(PHCompositeNode*) override; + +private: + int64_t full_bco = 0; +}; + +#endif//INTT_RAW_DATA_DECODER_H diff --git a/offline/packages/intt/Makefile.am b/offline/packages/intt/Makefile.am index 1c5bef835e..e555e46bca 100644 --- a/offline/packages/intt/Makefile.am +++ b/offline/packages/intt/Makefile.am @@ -19,6 +19,9 @@ AM_LDFLAGS = \ pkginclude_HEADERS = \ InttClusterizer.h \ + InttDeadMapHelper.h \ + InttFelixMap.h \ + InttRawDataDecoder.h \ CylinderGeomIntt.h ROOTDICTS = \ @@ -30,7 +33,10 @@ nobase_dist_pcm_DATA = \ # sources for intt library libintt_la_SOURCES = \ - InttClusterizer.cc + InttClusterizer.cc \ + InttDeadMapHelper.cc \ + InttFelixMap.cc \ + InttRawDataDecoder.cc libintt_la_LIBADD = \ libintt_io.la \ diff --git a/offline/packages/micromegas/Makefile.am b/offline/packages/micromegas/Makefile.am index b049816da3..def022a6eb 100644 --- a/offline/packages/micromegas/Makefile.am +++ b/offline/packages/micromegas/Makefile.am @@ -3,6 +3,47 @@ AUTOMAKE_OPTIONS = foreign +if USE_ONLINE + +### trimmed version of libmicromegas_io library, for online monitoring +### it only contains MicromegasDefs.h and MicromegasMapping + +lib_LTLIBRARIES = \ + libmicromegas_io.la + +## TODO: check with Chris where headers are installed (TrkrDefs.h) in "online" build +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include + +## TODO: check with Chris where libraries are installed (TrkrDefs.h) in "online" build +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib + +pkginclude_HEADERS = \ + MicromegasDefs.h \ + MicromegasMapping.h + +# sources for io library +libmicromegas_io_la_SOURCES = \ + MicromegasDefs.cc \ + MicromegasMapping.cc + +libmicromegas_io_la_LIBADD = \ + -ltrack_io + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals_micromegas_io + +testexternals_micromegas_io_SOURCES = testexternals.cc +testexternals_micromegas_io_LDADD = libmicromegas_io.la + +else + +### full offline version lib_LTLIBRARIES = \ libmicromegas_io.la \ libmicromegas.la @@ -25,6 +66,7 @@ pkginclude_HEADERS = \ MicromegasMapping.h \ MicromegasRawDataCalibration.h \ MicromegasRawDataDecoder.h \ + MicromegasRawDataEvaluation.h \ MicromegasTile.h ROOTDICTS = \ @@ -34,9 +76,9 @@ ROOTDICTS = \ pcmdir = $(libdir) nobase_dist_pcm_DATA = \ CylinderGeomMicromegas_Dict_rdict.pcm \ + MicromegasRawDataEvaluation_Dict_rdict.pcm \ MicromegasTile_Dict_rdict.pcm -# sources for io library libmicromegas_io_la_SOURCES = \ $(ROOTDICTS) \ CylinderGeomMicromegas.cc \ @@ -52,27 +94,23 @@ libmicromegas_io_la_LIBADD = \ -ltrack_io \ -ltrackbase_historic_io -# sources for micromegas library libmicromegas_la_SOURCES = \ MicromegasClusterizer.cc \ MicromegasRawDataCalibration.cc \ - MicromegasRawDataDecoder.cc + MicromegasRawDataDecoder.cc \ + MicromegasRawDataEvaluation.cc \ + MicromegasRawDataEvaluation_Dict.cc libmicromegas_la_LIBADD = \ libmicromegas_io.la \ -lphg4hit \ -lSubsysReco -# Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ -#just to get the dependency %_Dict_rdict.pcm: %_Dict.cc ; -################################################ -# linking tests - BUILT_SOURCES = testexternals.cc noinst_PROGRAMS = \ @@ -85,6 +123,8 @@ testexternals_micromegas_io_LDADD = libmicromegas_io.la testexternals_micromegas_SOURCES = testexternals.cc testexternals_micromegas_LDADD = libmicromegas.la +endif + testexternals.cc: echo "//*** this is a generated file. Do not commit, do not edit" > $@ echo "int main()" >> $@ @@ -92,7 +132,5 @@ testexternals.cc: echo " return 0;" >> $@ echo "}" >> $@ -################################################ - clean-local: rm -f *Dict* $(BUILT_SOURCES) *.pcm diff --git a/offline/packages/micromegas/MicromegasClusterizer.cc b/offline/packages/micromegas/MicromegasClusterizer.cc index b8e9c3b822..c2c08b4d5c 100644 --- a/offline/packages/micromegas/MicromegasClusterizer.cc +++ b/offline/packages/micromegas/MicromegasClusterizer.cc @@ -144,7 +144,7 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) assert(geonode); // hitset container - auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); assert( trkrhitsetcontainer ); // cluster container diff --git a/offline/packages/micromegas/MicromegasDefs.h b/offline/packages/micromegas/MicromegasDefs.h index 6a903080d1..45611aa7f5 100644 --- a/offline/packages/micromegas/MicromegasDefs.h +++ b/offline/packages/micromegas/MicromegasDefs.h @@ -11,6 +11,8 @@ #include +#include + namespace MicromegasDefs { @@ -91,6 +93,22 @@ namespace MicromegasDefs s*/ uint8_t getTileId(TrkrDefs::cluskey); + //! TPOT packet ids + static constexpr int m_npackets = 2; + static constexpr std::array m_packet_ids = {5000, 5001}; + + //! number of channels per fee board + static constexpr int m_nchannels_fee = 256; + + //! number of fee boards + static constexpr int m_nfee = 16; + + //! total number of channels + static constexpr int m_nchannels_total = m_nfee*m_nchannels_fee; + + //! max adc value per readout sample + static constexpr int m_max_adc = 1024; + } #endif diff --git a/offline/packages/micromegas/MicromegasMapping.cc b/offline/packages/micromegas/MicromegasMapping.cc index cd46c23727..e79c2a509b 100644 --- a/offline/packages/micromegas/MicromegasMapping.cc +++ b/offline/packages/micromegas/MicromegasMapping.cc @@ -7,6 +7,75 @@ #include "MicromegasDefs.h" #include +#include + +namespace +{ + + class mec8_channel_id + { + public: + + /* + * 0 or 1, corresponding to cable1 and cable 2 as defined by Takao in + * https://indico.bnl.gov/event/18458/contributions/73400/attachments/46043/77969/FEE_to_MEC_map_Feb17_2023.xlsx + */ + int m_cable_id = 0; + + /* + * 0 or 1, corresponding to j2 or j3 in transition board drawing in + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png + * and as defined by Takao in + * https://indico.bnl.gov/event/18458/contributions/73400/attachments/46043/77969/FEE_to_MEC_map_Feb17_2023.xlsx + */ + int m_connector_id = 0; + + /* + * 1 to 70 as defined in + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png + */ + int m_channel_id = 0; + + // constructor + mec8_channel_id( int cable_id, int connector_id, int channel_id ): + m_cable_id( cable_id ), + m_connector_id( connector_id ), + m_channel_id( channel_id ) + {} + + }; + + // less than operator + inline bool operator < (const mec8_channel_id& lhs, const mec8_channel_id& rhs ) + { + if( lhs.m_cable_id != rhs.m_cable_id ) return lhs.m_cable_id < rhs.m_cable_id; + if( lhs.m_connector_id != rhs.m_connector_id ) return lhs.m_connector_id < rhs.m_connector_id; + return lhs.m_channel_id < rhs.m_channel_id; + } + + // print mapping + [[maybe_unused]] void print_mapping( const std::string& name, const std::array& array ) + { + int count = 0; + std::cout << "int " << name << "[" << array.size() << "] = {" << std::endl << " "; + for( size_t i =0; i < array.size(); ++i ) + { + if( i > 0 ) std::cout << ", "; + if( count == 32 ) + { + std::cout << std::endl << " "; + count = 0; + } + std::cout << array[i]; + ++count; + } + + std::cout << std::endl << "};" << std::endl; + } + +} //____________________________________________________________________________________________________ MicromegasMapping::MicromegasMapping(): @@ -20,7 +89,9 @@ m_detectors( { {6, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 0 ), "sec21.0", "R3.3", "M5P", "SCOP" }, {8, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z, 0 ), "sec21.1", "R3.4", "M5Z", "SCOZ" }, {9, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 1 ), "sec21.2", "R3.5", "M8P", "SCIP" }, - {10, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z, 1 ), "sec21.3", "R3.6", "M8Z", "SCIZ" }, + /* {10, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z, 1 ), "sec21.3", "R3.6", "M8Z", "SCIZ" }, */ + // updated after fiber swapping on May 23, to fix flaky initialization of the FEE + {23, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z, 1 ), "sec21.3", "R3.9", "M8Z", "SCIZ" }, {24, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 6 ), "sec22.0", "R3.8", "M6P", "SWIP" }, {25, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z, 6 ), "sec22.1", "R3.8", "M6Z", "SWIZ" }, @@ -36,9 +107,13 @@ m_detectors( { { std::cout << "MicromegasMapping::MicromegasMapping." << std::endl; - /// fill detector map from vector + // fill detector map from vector for( const auto& detector_id:m_detectors ) { m_detector_map.emplace( detector_id.m_fee_id, detector_id ); } + + // construct channel mapping + construct_channel_mapping(); + } //____________________________________________________________________________________________________ @@ -83,12 +158,326 @@ std::string MicromegasMapping::get_detname_sphenix( int fee_id ) const } //____________________________________________________________________________________________________ -int MicromegasMapping::get_physical_strip( int /*fee_id*/, int channel_id) const +int MicromegasMapping::get_physical_strip( int fee_id, int channel_id) const +{ + // bound check + if( channel_id < 0 || channel_id >= MicromegasDefs::m_nchannels_fee ) + { + std::cout << "MicromegasMapping::get_physical_strip - invalid channel: " << channel_id << std::endl; + return -1; + } + + // get hitsetkey and orientation + const auto hitsetkey = get_hitsetkey(fee_id); + const auto segmentation_type = MicromegasDefs::getSegmentationType(hitsetkey); + switch (segmentation_type) + { + case MicromegasDefs::SegmentationType::SEGMENTATION_Z: + return m_fee_to_strip_mapping_z[channel_id]; + + case MicromegasDefs::SegmentationType::SEGMENTATION_PHI: + return m_fee_to_strip_mapping_phi[channel_id]; + } + + // never reached + return -1; +} + +//____________________________________________________________________________________________________ +std::string MicromegasMapping::get_detname_saclay_from_hitsetkey( TrkrDefs::hitsetkey key ) const +{ + const auto iter = std::find_if( m_detectors.begin(), m_detectors.end(), [key](const DetectorId& detector ) { return detector.m_hitsetkey == key; } ); + if( iter == m_detectors.end() ) + { + std::cout << "MicromegasMapping::get_detname_saclay_from_hitsetkey - invalid key: " << key << std::endl; + return std::string(); + } else return iter->m_detname_saclay; +} + +//____________________________________________________________________________________________________ +std::string MicromegasMapping::get_detname_sphenix_from_hitsetkey( TrkrDefs::hitsetkey key ) const +{ + const auto iter = std::find_if( m_detectors.begin(), m_detectors.end(), [key](const DetectorId& detector ) { return detector.m_hitsetkey == key; } ); + if( iter == m_detectors.end() ) + { + std::cout << "MicromegasMapping::get_detname_sphenix_from_hitsetkey - invalid key: " << key << std::endl; + return std::string(); + } else return iter->m_detname_sphenix; +} + +//____________________________________________________________________________________________________ +void MicromegasMapping::construct_channel_mapping() { + // procedure details: https://indico.bnl.gov/event/19349/contributions/75908/attachments/47219/80098/talk.pdf + /* - * this maps channel id (0-255) on a given FEE board, to physical strip number in the detector - * Just a placeholder for now. We just return the same index. + * map channel id on FEE board (0-255) to mec8 connector and channel + * there are 2 cables (left and right) per FEE board + * each cable has two MEC8 connector + * on each MEC8 connector, channel 1,2, 35, 36, 69 and 70 are connected to the ground + * the other 64 channels are signals */ - return channel_id; -} + // source: https://indico.bnl.gov/event/18458/contributions/73400/attachments/46043/77969/FEE_to_MEC_map_Feb17_2023.xlsx + std::array fee_to_mec8_mapping = + {{ + {0,0,34}, {0,0,33}, {0,0,32}, {0,0,31}, {0,0,30}, {0,0,29}, {0,0,28}, {0,0,27}, + {0,0,26}, {0,0,25}, {0,0,24}, {0,0,23}, {0,0,22}, {0,0,21}, {0,0,20}, {0,0,19}, + {0,0,18}, {0,0,17}, {0,0,16}, {0,0,15}, {0,0,14}, {0,0,13}, {0,0,12}, {0,0,11}, + {0,0,10}, {0,0,9}, {0,0,8}, {0,0,7}, {0,0,6}, {0,0,5}, {0,0,4}, {0,0,3}, + + {0,0,68}, {0,0,67}, {0,0,66}, {0,0,65}, {0,0,64}, {0,0,63}, {0,0,62}, {0,0,61}, + {0,0,60}, {0,0,59}, {0,0,58}, {0,0,57}, {0,0,56}, {0,0,55}, {0,0,54}, {0,0,53}, + {0,0,52}, {0,0,51}, {0,0,50}, {0,0,49}, {0,0,48}, {0,0,47}, {0,0,46}, {0,0,45}, + {0,0,44}, {0,0,43}, {0,0,42}, {0,0,41}, {0,0,40}, {0,0,39}, {0,0,38}, {0,0,37}, + + {0,1,34}, {0,1,33}, {0,1,32}, {0,1,31}, {0,1,30}, {0,1,29}, {0,1,28}, {0,1,27}, + {0,1,26}, {0,1,25}, {0,1,24}, {0,1,23}, {0,1,22}, {0,1,21}, {0,1,20}, {0,1,19}, + {0,1,18}, {0,1,17}, {0,1,16}, {0,1,15}, {0,1,14}, {0,1,13}, {0,1,12}, {0,1,11}, + {0,1,10}, {0,1,9}, {0,1,8}, {0,1,7}, {0,1,6}, {0,1,5}, {0,1,4}, {0,1,3}, + + {0,1,68}, {0,1,67}, {0,1,66}, {0,1,65}, {0,1,64}, {0,1,63}, {0,1,62}, {0,1,61}, + {0,1,60}, {0,1,59}, {0,1,58}, {0,1,57}, {0,1,56}, {0,1,55}, {0,1,54}, {0,1,53}, + {0,1,52}, {0,1,51}, {0,1,50}, {0,1,49}, {0,1,48}, {0,1,47}, {0,1,46}, {0,1,45}, + {0,1,44}, {0,1,43}, {0,1,42}, {0,1,41}, {0,1,40}, {0,1,39}, {0,1,38}, {0,1,37}, + + {1,0,34}, {1,0,33}, {1,0,32}, {1,0,31}, {1,0,30}, {1,0,29}, {1,0,28}, {1,0,27}, + {1,0,26}, {1,0,25}, {1,0,24}, {1,0,23}, {1,0,22}, {1,0,21}, {1,0,20}, {1,0,19}, + {1,0,18}, {1,0,17}, {1,0,16}, {1,0,15}, {1,0,14}, {1,0,13}, {1,0,12}, {1,0,11}, + {1,0,10}, {1,0,9}, {1,0,8}, {1,0,7}, {1,0,6}, {1,0,5}, {1,0,4}, {1,0,3}, + + {1,0,68}, {1,0,67}, {1,0,66}, {1,0,65}, {1,0,64}, {1,0,63}, {1,0,62}, {1,0,61}, + {1,0,60}, {1,0,59}, {1,0,58}, {1,0,57}, {1,0,56}, {1,0,55}, {1,0,54}, {1,0,53}, + {1,0,52}, {1,0,51}, {1,0,50}, {1,0,49}, {1,0,48}, {1,0,47}, {1,0,46}, {1,0,45}, + {1,0,44}, {1,0,43}, {1,0,42}, {1,0,41}, {1,0,40}, {1,0,39}, {1,0,38}, {1,0,37}, + + {1,1,34}, {1,1,33}, {1,1,32}, {1,1,31}, {1,1,30}, {1,1,29}, {1,1,28}, {1,1,27}, + {1,1,26}, {1,1,25}, {1,1,24}, {1,1,23}, {1,1,22}, {1,1,21}, {1,1,20}, {1,1,19}, + {1,1,18}, {1,1,17}, {1,1,16}, {1,1,15}, {1,1,14}, {1,1,13}, {1,1,12}, {1,1,11}, + {1,1,10}, {1,1,9}, {1,1,8}, {1,1,7}, {1,1,6}, {1,1,5}, {1,1,4}, {1,1,3}, + + {1,1,68}, {1,1,67}, {1,1,66}, {1,1,65}, {1,1,64}, {1,1,63}, {1,1,62}, {1,1,61}, + {1,1,60}, {1,1,59}, {1,1,58}, {1,1,57}, {1,1,56}, {1,1,55}, {1,1,54}, {1,1,53}, + {1,1,52}, {1,1,51}, {1,1,50}, {1,1,49}, {1,1,48}, {1,1,47}, {1,1,46}, {1,1,45}, + {1,1,44}, {1,1,43}, {1,1,42}, {1,1,41}, {1,1,40}, {1,1,39}, {1,1,38}, {1,1,37} + }}; + + // map mec8 channel id (1-70) to mec8 signal id on detector as defined by audrey in z views (1-64) + /* sources: + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png + * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79750/MappingGerber.pdf + * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2 + */ + std::map mec8_to_signal_mapping_z = { + /* bottom row on mec8 (female) connector corresponds to bottom row on detector as defined by Audrey */ + {1,-1}, + {3,1}, {5,2}, {7,3}, {9,4}, {11,5}, {13,6}, {15,7}, {17,8}, + {19,9}, {21,10}, {23,11}, {25,12}, {27,13}, {29,14}, {31,15}, {33,16}, + {35,-1}, + {37,17}, {39,18}, {41,19}, {43,20}, {45,21}, {47,22}, {49,23}, {51,24}, + {53,25}, {55,26}, {57,27}, {59,28}, {61,29}, {63,30}, {65,31}, {67,32}, + {69,-1}, + /* top row on mec8 (female) connector corresponds to top row on detector as defined by Audrey */ + {2,-1}, + {4,33}, {6,34}, {8,35}, {10,36}, {12,37}, {14,38}, {16,39}, {18,40}, + {20,41}, {22,42}, {24,43}, {26,44}, {28,45}, {30,46}, {32,47}, {34,48}, + {36,-1}, + {38,49}, {40,50}, {42,51}, {44,52}, {46,53}, {48,54}, {50,55}, {52,56}, + {54,57}, {56,58}, {58,59}, {60,60}, {62,61}, {64,62}, {66,63}, {68,64}, + {70,-1} + }; + + // map all mec8 channel id to signal id on detector as defined by audrey in z views (1-256) + /* sources: + * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79750/MappingGerber.pdf + * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2 + */ + std::map mec8_to_signal_mapping_z_all; + for( const auto& [mec8_channel,signal_id]:mec8_to_signal_mapping_z ) + { + + // ignore ground channels + if( signal_id == -1 ) continue; + // cable 0, connector 0 corresponds to signal ids 1 to 64 + mec8_to_signal_mapping_z_all.insert(std::pair({0,0,mec8_channel}, signal_id)); + + // cable 0, connector 1 corresponds to signal ids 65 to 128 + mec8_to_signal_mapping_z_all.insert(std::pair({0,1,mec8_channel}, signal_id+64)); + + // cable 1, connector 0 corresponds to signal ids 129 to 192 + mec8_to_signal_mapping_z_all.insert(std::pair({1,0,mec8_channel}, signal_id+128)); + + // cable 1, connector 1 corresponds to signal ids 193 to 256 + mec8_to_signal_mapping_z_all.insert(std::pair({1,1,mec8_channel}, signal_id+192)); + } + + // map phisical strips in the detector to MEC8 signal id on detector as defined by Audrey + // source: https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79824/MappingTPOT.xlsx + std::map strip_to_signal_id_mapping_all = + { + {1,1}, {2,33}, {3,2}, {4,34}, {5,3}, {6,35}, {7,4}, {8,36}, + {9,5}, {10,37}, {11,6}, {12,38}, {13,7}, {14,39}, {15,8}, {16,40}, + {17,9}, {18,41}, {19,10}, {20,42}, {21,11}, {22,43}, {23,12}, {24,44}, + {25,13}, {26,45}, {27,14}, {28,46}, {29,15}, {30,47}, {31,16}, {32,48}, + {33,17}, {34,49}, {35,18}, {36,50}, {37,19}, {38,51}, {39,20}, {40,52}, + {41,21}, {42,53}, {43,22}, {44,54}, {45,23}, {46,55}, {47,24}, {48,56}, + {49,25}, {50,57}, {51,26}, {52,58}, {53,27}, {54,59}, {55,28}, {56,60}, + {57,29}, {58,61}, {59,30}, {60,62}, {61,31}, {62,63}, {63,32}, {64,64}, + + {65,65}, {66,97}, {67,66}, {68,98}, {69,67}, {70,99}, {71,68}, {72,100}, + {73,69}, {74,101}, {75,70}, {76,102}, {77,71}, {78,103}, {79,72}, {80,104}, + {81,73}, {82,105}, {83,74}, {84,106}, {85,75}, {86,107}, {87,76}, {88,108}, + {89,77}, {90,109}, {91,78}, {92,110}, {93,79}, {94,111}, {95,80}, {96,112}, + {97,81}, {98,113}, {99,82}, {100,114}, {101,83}, {102,115}, {103,84}, {104,116}, + {105,85}, {106,117}, {107,86}, {108,118}, {109,87}, {110,119}, {111,88}, {112,120}, + {113,89}, {114,121}, {115,90}, {116,122}, {117,91}, {118,123}, {119,92}, {120,124}, + {121,93}, {122,125}, {123,94}, {124,126}, {125,95}, {126,127}, {127,96}, {128,128}, + + {129,129}, {130,161}, {131,130}, {132,162}, {133,131}, {134,163}, {135,132}, {136,164}, + {137,133}, {138,165}, {139,134}, {140,166}, {141,135}, {142,167}, {143,136}, {144,168}, + {145,137}, {146,169}, {147,138}, {148,170}, {149,139}, {150,171}, {151,140}, {152,172}, + {153,141}, {154,173}, {155,142}, {156,174}, {157,143}, {158,175}, {159,144}, {160,176}, + {161,145}, {162,177}, {163,146}, {164,178}, {165,147}, {166,179}, {167,148}, {168,180}, + {169,149}, {170,181}, {171,150}, {172,182}, {173,151}, {174,183}, {175,152}, {176,184}, + {177,153}, {178,185}, {179,154}, {180,186}, {181,155}, {182,187}, {183,156}, {184,188}, + {185,157}, {186,189}, {187,158}, {188,190}, {189,159}, {190,191}, {191,160}, {192,192}, + + {193,193}, {194,225}, {195,194}, {196,226}, {197,195}, {198,227}, {199,196}, {200,228}, + {201,197}, {202,229}, {203,198}, {204,230}, {205,199}, {206,231}, {207,200}, {208,232}, + {209,201}, {210,233}, {211,202}, {212,234}, {213,203}, {214,235}, {215,204}, {216,236}, + {217,205}, {218,237}, {219,206}, {220,238}, {221,207}, {222,239}, {223,208}, {224,240}, + {225,209}, {226,241}, {227,210}, {228,242}, {229,211}, {230,243}, {231,212}, {232,244}, + {233,213}, {234,245}, {235,214}, {236,246}, {237,215}, {238,247}, {239,216}, {240,248}, + {241,217}, {242,249}, {243,218}, {244,250}, {245,219}, {246,251}, {247,220}, {248,252}, + {249,221}, {250,253}, {251,222}, {252,254}, {253,223}, {254,255}, {255,224}, {256,256} + }; + + // add mapping from strip number as defined by Audrey and geant convention + auto get_strip_geant_z = []( int strip_audrey ) + { + /* + * for z views, audrey and geant strips are numbered in oposite directions + * geant strips start from zero + */ + return MicromegasDefs::m_nchannels_fee-strip_audrey; + }; + + // construct fee channel id to strip + /* + * fee channel id is from 0 to 255 + * strip id from 0 to 255 (-1 with respect to Audrey's convention + */ + for( int channel_id = 0; channel_id < MicromegasDefs::m_nchannels_fee; ++channel_id ) + { + + // mec8 channel id + auto mec8_channel_id = fee_to_mec8_mapping[channel_id]; + + // mec8 signal id as defined by Audrey + int mec8_signal_id = mec8_to_signal_mapping_z_all.at(mec8_channel_id); + + // find mec8_signal_id in detector mapping + const auto iter = std::find_if( strip_to_signal_id_mapping_all.begin(), strip_to_signal_id_mapping_all.end(), [mec8_signal_id]( const std::pair& pair ) { return pair.second == mec8_signal_id; } ); + assert( iter != strip_to_signal_id_mapping_all.end() ); + const int strip_audrey = iter->first; + + // convert to geant convention + const int strip_geant = get_strip_geant_z( strip_audrey ); + + // store in array + m_fee_to_strip_mapping_z[channel_id] = strip_geant; + } + + // print_mapping( "m_fee_to_strip_mapping_z", m_fee_to_strip_mapping_z ); + + // map mec8 channel id (1-70) to mec8 signal id on detector as defined by audrey in phi views + /* sources: + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png + * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png + * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79823/MappingGerber.pdf + * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2 + */ + std::map mec8_to_signal_mapping_phi = { + /* bottom row on mec8 (female) connector corresponds to top row on detector as defined by Audrey */ + {1,-1}, + {3,64}, {5,63}, {7,62}, {9,61}, {11,60}, {13,59}, {15,58}, {17,57}, + {19,56}, {21,55}, {23,54}, {25,53}, {27,52}, {29,51}, {31,50}, {33,49}, + {35,-1}, + {37,48}, {39,47}, {41,46}, {43,45}, {45,44}, {47,43}, {49,42}, {51,41}, + {53,40}, {55,39}, {57,38}, {59,37}, {61,36}, {63,35}, {65,34}, {67,33}, + {69,-1}, + /* top row on mec8 (female) connector corresponds to bottom row on detector as defined by Audrey */ + {2,-1}, + {4,32}, {6,31}, {8,30}, {10,29}, {12,28}, {14,27}, {16,26}, {18,25}, + {20,24}, {22,23}, {24,22}, {26,21}, {28,20}, {30,19}, {32,18}, {34,17}, + {36,-1}, + {38,16}, {40,15}, {42,14}, {44,13}, {46,12}, {48,11}, {50,10}, {52,9}, + {54,8}, {56,7}, {58,6}, {60,5}, {62,4}, {64,3}, {66,2}, {68,1}, + {70,-1} + }; + + // map all mec8 channel id to signal id on detector as defined by audrey in phi views + /* sources: + * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79823/MappingGerber.pdf + * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2 + */ + std::map mec8_to_signal_mapping_phi_all; + for( const auto& [mec8_channel,signal_id]:mec8_to_signal_mapping_phi ) + { + + // ignore ground channels + if( signal_id == -1 ) continue; + + // cable 0, connector 0 corresponds to signal ids 193 to 256 + mec8_to_signal_mapping_phi_all.insert(std::pair({0,0,mec8_channel}, signal_id+192)); + + // cable 0, connector 1 corresponds to signal ids 129 to 160 + mec8_to_signal_mapping_phi_all.insert(std::pair({0,1,mec8_channel}, signal_id+128)); + + // cable 1, connector 0 corresponds to signal ids 65 to 128 + mec8_to_signal_mapping_phi_all.insert(std::pair({1,0,mec8_channel}, signal_id+64)); + + // cable 1, connector 1 corresponds to signal ids 1 to 64 + mec8_to_signal_mapping_phi_all.insert(std::pair({1,1,mec8_channel}, signal_id)); + } + + // add mapping from strip number as defined by Audrey and geant convention + auto get_strip_geant_phi = []( int strip_audrey ) + { + /* + * for phi views, audrey and geant strips are numbered in oposite directions + * geant strips start from zero + */ + return MicromegasDefs::m_nchannels_fee-strip_audrey; + }; + + // construct fee channel id to strip + /* + * fee channel id is from 0 to 255 + * strip id from 0 to 255 (-1 with respect to Audrey's convention + */ + for( int channel_id = 0; channel_id < MicromegasDefs::m_nchannels_fee; ++channel_id ) + { + + // mec8 channel id + auto mec8_channel_id = fee_to_mec8_mapping[channel_id]; + + // mec8 signal id as defined by Audrey + int mec8_signal_id = mec8_to_signal_mapping_phi_all.at(mec8_channel_id); + + // find mec8_signal_id in detector mapping + const auto iter = std::find_if( strip_to_signal_id_mapping_all.begin(), strip_to_signal_id_mapping_all.end(), [mec8_signal_id]( const std::pair& pair ) { return pair.second == mec8_signal_id; } ); + assert( iter != strip_to_signal_id_mapping_all.end() ); + const int strip_audrey = iter->first; + + // convert to geant convention + const int strip_geant = get_strip_geant_phi( strip_audrey ); + + // store in array + m_fee_to_strip_mapping_phi[channel_id] = strip_geant; + } + + // print_mapping( "m_fee_to_strip_mapping_phi", m_fee_to_strip_mapping_phi ); + +} diff --git a/offline/packages/micromegas/MicromegasMapping.h b/offline/packages/micromegas/MicromegasMapping.h index 53c007ddbf..88e30ff692 100644 --- a/offline/packages/micromegas/MicromegasMapping.h +++ b/offline/packages/micromegas/MicromegasMapping.h @@ -6,8 +6,11 @@ * \author Hugo Pereira Da Costa */ +#include "MicromegasDefs.h" + #include +#include #include #include #include @@ -30,7 +33,7 @@ class MicromegasMapping /** saclay detector name are of type MxxP and MxxZ, with xx the module number */ std::string get_detname_saclay( int /*fee_id*/) const; - /// get detector name (saclay) from fiber_id (fee_id) + /// get detector name (sphenix) from fiber_id (fee_id) /** sphenix detector name are of type SWP, SWZ, etc. */ std::string get_detname_sphenix( int /*fee_id*/) const; @@ -42,8 +45,17 @@ class MicromegasMapping */ int get_physical_strip( int /*fee_id*/, int /*channel_id*/) const; + /// get detector name (sphenix) from hitset key + std::string get_detname_saclay_from_hitsetkey( TrkrDefs::hitsetkey ) const; + + /// get detector name (saclay) from hitset key + std::string get_detname_sphenix_from_hitsetkey( TrkrDefs::hitsetkey ) const; + private: + /// construct fee channel id to physical strip mapping + void construct_channel_mapping(); + /// contains all relevant detector information /** this effectively implements mapping between fee_id as defined in EDBC,
 * detector names (in both Saclay and sPHENIX convention), * and hitsetkey which is the detector unique identifier @@ -89,6 +101,12 @@ class MicromegasMapping /// map detector_id to fee_id std::map m_detector_map; + + /// map FEE channel id to physical strip id (z view) + std::array m_fee_to_strip_mapping_z = {{0}}; + + /// map FEE channel id to physical strip id (phi view) + std::array m_fee_to_strip_mapping_phi = {{0}}; }; diff --git a/offline/packages/micromegas/MicromegasRawDataCalibration.cc b/offline/packages/micromegas/MicromegasRawDataCalibration.cc index acb73f95cb..abe3854bb2 100644 --- a/offline/packages/micromegas/MicromegasRawDataCalibration.cc +++ b/offline/packages/micromegas/MicromegasRawDataCalibration.cc @@ -5,6 +5,7 @@ #include "MicromegasRawDataCalibration.h" #include "MicromegasCalibrationData.h" +#include "MicromegasDefs.h" #include #include @@ -16,12 +17,11 @@ #include #include -#include -#include #include #include #include +#include //_________________________________________________________ MicromegasRawDataCalibration::MicromegasRawDataCalibration( const std::string& name ): @@ -31,9 +31,7 @@ MicromegasRawDataCalibration::MicromegasRawDataCalibration( const std::string& n //_____________________________________________________________________ int MicromegasRawDataCalibration::Init(PHCompositeNode* /*topNode*/ ) { - // histogram evaluation - if( m_savehistograms ) create_histograms(); return Fun4AllReturnCodes::EVENT_OK; } @@ -44,20 +42,7 @@ int MicromegasRawDataCalibration::InitRun(PHCompositeNode* /*topNode*/) //___________________________________________________________________________ int MicromegasRawDataCalibration::process_event(PHCompositeNode *topNode) { - - // map fee id to detector index in histogram - using fee_map_t = std::map; - fee_map_t fee_map = { - {2, 0}, - {1, 1}, - {3, 2}, - {4, 3}, - {8, 4}, - {9, 5}, - {7, 6}, - {5, 7} - }; - + // load relevant nodes // PRDF node auto event = findNode::getClass(topNode, "PRDF"); @@ -68,81 +53,55 @@ int MicromegasRawDataCalibration::process_event(PHCompositeNode *topNode) { return Fun4AllReturnCodes::DISCARDEVENT; } - // get TPOT packet number - /* - * for now it is the same packet number as the TPC: 4001. - * To be fixed at a later stage. - * check with Martin Purschke - */ - auto packet = event->getPacket(4001); - if( !packet ) - { - // no data - std::cout << "MicromegasRawDataCalibration::process_event - event contains no TPOT data" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; - } - - // get number of datasets (also call waveforms) - const auto n_waveforms = packet->iValue(0, "NR_WF" ); - if( Verbosity() ) - { std::cout << "MicromegasRawDataCalibration::process_event - n_waveforms: " << n_waveforms << std::endl; } - - for( int i=0; iiValue( i, "CHANNEL" ); - int fee = packet->iValue(i, "FEE" ); - int samples = packet->iValue( i, "SAMPLES" ); - if( Verbosity() ) + std::unique_ptr packet( event->getPacket(packet_id) ); + if( !packet ) { - std::cout - << "MicromegasRawDataCalibration::process_event -" - << " waveform: " << i - << " fee: " << fee - << " channel: " << channel - << " samples: " << samples - << std::endl; + // no data + std::cout << "MicromegasRawDataCalibration::process_event - event contains no TPOT data" << std::endl; + return Fun4AllReturnCodes::EVENT_OK; } - - // find relevant profile histogram - TProfile* profile = nullptr; - auto piter = m_profile_map.lower_bound( fee ); - if( piter == m_profile_map.end() || fee < piter->first ) - { - // create and insert - profile = new TProfile( Form( "h_adc_channel_%i", fee ), "ADC vs channel;channel;adc", m_nchannels_fee, 0, m_nchannels_fee ); - profile->SetErrorOption( "s" ); - m_profile_map.insert( piter, std::make_pair( fee, profile ) ); - } else profile = piter->second; - - // fill - for( int is = std::max( m_sample_min,0 ); is < std::min( m_sample_max,samples ); ++ is ) - { profile->Fill( channel, packet->iValue(i,is) ); } - // fill evaluation histograms - if( m_savehistograms ) + // get number of datasets (also call waveforms) + const auto n_waveforms = packet->iValue(0, "NR_WF" ); + if( Verbosity() ) + { std::cout << "MicromegasRawDataCalibration::process_event - n_waveforms: " << n_waveforms << std::endl; } + + for( int i=0; iFill(fee); - - // find fee index from map - const auto iter = fee_map.find( fee ); - if( iter == fee_map.end() ) + auto channel = packet->iValue( i, "CHANNEL" ); + int fee = packet->iValue(i, "FEE" ); + int samples = packet->iValue( i, "SAMPLES" ); + if( Verbosity() ) { - std::cout << "MicromegasRawDataCalibration::process_event - unable to find fee " << fee << " in map" << std::endl; - } else { + std::cout + << "MicromegasRawDataCalibration::process_event -" + << " waveform: " << i + << " fee: " << fee + << " channel: " << channel + << " samples: " << samples + << std::endl; + } + + // find relevant profile histogram + TProfile* profile = nullptr; + auto piter = m_profile_map.lower_bound( fee ); + if( piter == m_profile_map.end() || fee < piter->first ) + { + // create and insert + profile = new TProfile( Form( "h_adc_channel_%i", fee ), "ADC vs channel;channel;adc", MicromegasDefs::m_nchannels_fee, 0, MicromegasDefs::m_nchannels_fee ); + profile->SetErrorOption( "s" ); + m_profile_map.insert( piter, std::make_pair( fee, profile ) ); + } else profile = piter->second; + + // fill + for( int is = std::max( m_sample_min,0 ); is < std::min( m_sample_max,samples ); ++ is ) + { profile->Fill( channel, packet->iValue(i,is) ); } - const auto fee_index = iter->second; - const auto channel_index = fee_index*m_nchannels_fee + channel; - - // loop over samples - if( m_h_adc_channel ) - { - for( int is = std::max( m_sample_min,0 ); is < std::min( m_sample_max,samples ); ++ is ) - { m_h_adc_channel->Fill( channel_index, packet->iValue(i,is) ); } - } - } } } - return Fun4AllReturnCodes::EVENT_OK; } @@ -171,36 +130,5 @@ int MicromegasRawDataCalibration::End(PHCompositeNode* /*topNode*/ ) calibration_data.write( m_calibration_filename ); } - // save evaluation histograms - if( m_savehistograms && m_histogramfile ) - { - // create mean and rms histograms - auto profile = m_h_adc_channel->ProfileX("h_adc_channel_profx", 1, -1, "s" ); - auto h_pedestal = new TH1F( "h_pedestal", "pedestal vs channel;channel;pedestal (adc)", m_nchannels_total, 0, m_nchannels_total ); - auto h_rms = new TH1F( "h_rms", "rms vs channel;channel;RMS (adc)", m_nchannels_total, 0, m_nchannels_total ); - for( int i =0; iSetBinContent( i+1, profile->GetBinContent(i+1) ); - h_rms->SetBinContent(i+1, profile->GetBinError(i+1) ); - } - - m_histogramfile->cd(); - m_h_fee_id->Write(); - m_h_adc_channel->Write(); - h_pedestal->Write(); - h_rms->Write(); - m_histogramfile->Close(); - } return Fun4AllReturnCodes::EVENT_OK; } - -//_____________________________________________________________________ -void MicromegasRawDataCalibration::create_histograms() -{ - std::cout << "MicromegasRawDataCalibration::create_histograms - writing evaluation histograms to: " << m_histogramfilename << std::endl; - m_histogramfile.reset( new TFile(m_histogramfilename.c_str(), "RECREATE") ); - m_histogramfile->cd(); - - m_h_fee_id = new TH1I( "h_fee_id", "FEE id;Fee id;entries", 10, 0, 10 ); - m_h_adc_channel = new TH2I( "h_adc_channel", "ADC vs channel;channel;adc", m_nchannels_total, 0, m_nchannels_total, m_max_adc, 0, m_max_adc ); -} diff --git a/offline/packages/micromegas/MicromegasRawDataCalibration.h b/offline/packages/micromegas/MicromegasRawDataCalibration.h index 1120747ce1..1604900584 100644 --- a/offline/packages/micromegas/MicromegasRawDataCalibration.h +++ b/offline/packages/micromegas/MicromegasRawDataCalibration.h @@ -5,7 +5,6 @@ * \file MicromegasRawDataCalibration.h * \author Hugo Pereira Da Costa */ - #include #include @@ -47,22 +46,8 @@ class MicromegasRawDataCalibration : public SubsysReco /// set to true to store evaluation histograms and ntuples void set_calibration_file( const std::string& value ) { m_calibration_filename = value; } - /// set to true to store evaluation histograms and ntuples - void set_save_histograms( bool value ) { m_savehistograms = value; } - - /// output file name for evaluation histograms - void set_histogram_outputfile(const std::string &outputfile) {m_histogramfilename = outputfile;} - private: - /// create evaluation histograms - void create_histograms(); - - static constexpr int m_nchannels_fee = 256; - static constexpr int m_nfee = 16; - static constexpr int m_nchannels_total = m_nfee*m_nchannels_fee; - static constexpr int m_max_adc = 1024; - /// min sample for noise estimation int m_sample_min = 0; @@ -76,24 +61,6 @@ class MicromegasRawDataCalibration : public SubsysReco using profile_map_t = std::map; profile_map_t m_profile_map; - ///@name evaluation histograms - //@{ - - /// Output root histograms - bool m_savehistograms = true; - - /// histogram output file name - std::string m_histogramfilename = "MicromegasRawDataCalibration.root"; - std::unique_ptr m_histogramfile; - - /// Fired FEE - TH1* m_h_fee_id = nullptr; - - /// ADC distribution vs channel number - TH2* m_h_adc_channel = nullptr; - - //@} - }; #endif diff --git a/offline/packages/micromegas/MicromegasRawDataDecoder.cc b/offline/packages/micromegas/MicromegasRawDataDecoder.cc index 8d6e2d821d..793795a11c 100644 --- a/offline/packages/micromegas/MicromegasRawDataDecoder.cc +++ b/offline/packages/micromegas/MicromegasRawDataDecoder.cc @@ -22,6 +22,7 @@ #include #include +#include //_________________________________________________________ MicromegasRawDataDecoder::MicromegasRawDataDecoder( const std::string& name ): @@ -50,23 +51,24 @@ int MicromegasRawDataDecoder::InitRun(PHCompositeNode *topNode) } // create hitset container if needed - auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); if (!hitsetcontainer) { - std::cout << "MicromegasRawDataDecoder::InitRun - creating TRKR_HITSET." << std::endl; + if (Verbosity()) + std::cout << "MicromegasRawDataDecoder::InitRun - creating TRKR_HITSET_MICROMEGAS." << std::endl; // find or create TRKR node PHNodeIterator dstiter(dstNode); - auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "MICROMEGAS")); if (!trkrnode) { - trkrnode = new PHCompositeNode("TRKR"); + trkrnode = new PHCompositeNode("MICROMEGAS"); dstNode->addNode(trkrnode); } // create container and add to the tree hitsetcontainer = new TrkrHitSetContainerv1; - auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET_MICROMEGAS", "PHObject"); trkrnode->addNode(newNode); } @@ -80,7 +82,7 @@ int MicromegasRawDataDecoder::process_event(PHCompositeNode *topNode) // load relevant nodes // Get the TrkrHitSetContainer node - auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); assert(trkrhitsetcontainer); // PRDF node @@ -91,101 +93,98 @@ int MicromegasRawDataDecoder::process_event(PHCompositeNode *topNode) if(event->getEvtType() >= 8) { return Fun4AllReturnCodes::DISCARDEVENT; } - // get TPOT packet number - /* - * for now it is the same packet number as the TPC: 4001. - * To be fixed at a later stage. - * check with Martin Purschke - */ - auto packet = event->getPacket(4001); - if( !packet ) + // loop over TPOT packets + for( const auto& packet_id:MicromegasDefs::m_packet_ids ) { - // no data - std::cout << "MicromegasRawDataDecoder::process_event - event contains no TPOT data" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; - } - - // get number of datasets (also call waveforms) - const auto n_waveforms = packet->iValue(0, "NR_WF" ); - if( Verbosity() ) - { std::cout << "MicromegasRawDataDecoder::process_event - n_waveforms: " << n_waveforms << std::endl; } - for( int i=0; iiValue( i, "CHANNEL" ); - int fee = packet->iValue(i, "FEE" ); - int samples = packet->iValue( i, "SAMPLES" ); - if( Verbosity() ) + std::unique_ptr packet( event->getPacket(packet_id) ); + if( !packet ) { - std::cout - << "MicromegasRawDataDecoder::process_event -" - << " waveform: " << i - << " fee: " << fee - << " channel: " << channel - << " samples: " << samples - << std::endl; + // no data + std::cout << "MicromegasRawDataDecoder::process_event - event contains no TPOT data" << std::endl; + return Fun4AllReturnCodes::EVENT_OK; } - - // get channel rms and pedestal from calibration data - const double pedestal = m_calibration_data.get_pedestal( fee, channel ); - const double rms = m_calibration_data.get_rms( fee, channel ); - - // a rms of zero means the calibration has failed. the data is unusable - if( rms <= 0 ) continue; - - // loop over samples find maximum - std::vector adc; - for( int is = std::max( m_sample_min,0 ); is < std::min( m_sample_max,samples ); ++ is ) - { adc.push_back( packet->iValue( i, is ) ); } - - if( adc.empty() ) continue; - - // get max adc value in range - /* TODO: use more advanced signal processing */ - auto max_adc = *std::max_element( adc.begin(), adc.end() ); - - // subtract pedestal - max_adc -= pedestal; - // compare to threshold - if( max_adc > m_n_sigma * rms ) + // get number of datasets (also call waveforms) + const auto n_waveforms = packet->iValue(0, "NR_WF" ); + if( Verbosity() ) + { std::cout << "MicromegasRawDataDecoder::process_event - n_waveforms: " << n_waveforms << std::endl; } + for( int i=0; ifindOrAddHitSet(hitsetkey); - - // generate hit key - const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip); - - // find existing hit, or create - auto hit = hitset_it->second->getHit(hitkey); - if( hit ) + auto channel = packet->iValue( i, "CHANNEL" ); + int fee = packet->iValue(i, "FEE" ); + int samples = packet->iValue( i, "SAMPLES" ); + if( Verbosity() ) { - std::cout << "MicromegasRawDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; - continue; + std::cout + << "MicromegasRawDataDecoder::process_event -" + << " waveform: " << i + << " fee: " << fee + << " channel: " << channel + << " samples: " << samples + << std::endl; } - - // create hit, assign adc and insert in hitset - hit = new TrkrHitv2; - hit->setAdc( max_adc ); - hitset_it->second->addHitSpecificKey(hitkey, hit); - // increment counter - ++m_hitcounts[hitsetkey]; + // get channel rms and pedestal from calibration data + const double pedestal = m_calibration_data.get_pedestal( fee, channel ); + const double rms = m_calibration_data.get_rms( fee, channel ); + + // a rms of zero means the calibration has failed. the data is unusable + if( rms <= 0 ) continue; + + // loop over samples find maximum + std::vector adc; + for( int is = std::max( m_sample_min,0 ); is < std::min( m_sample_max,samples ); ++ is ) + { adc.push_back( packet->iValue( i, is ) ); } + + if( adc.empty() ) continue; + + // get max adc value in range + /* TODO: use more advanced signal processing */ + auto max_adc = *std::max_element( adc.begin(), adc.end() ); + + // subtract pedestal + max_adc -= pedestal; + + // compare to threshold + if( max_adc > m_n_sigma * rms ) + { + + // map fee and channel to physical hitsetid and physical strip + // get hitset key matching this fee + const TrkrDefs::hitsetkey hitsetkey = m_mapping.get_hitsetkey( fee ); + if( !hitsetkey ) continue; + + // get matching physical strip + int strip = m_mapping.get_physical_strip( fee, channel ); + if( strip < 0 ) continue; + + // get matching hitset + const auto hitset_it = trkrhitsetcontainer->findOrAddHitSet(hitsetkey); + + // generate hit key + const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip); + + // find existing hit, or create + auto hit = hitset_it->second->getHit(hitkey); + if( hit ) + { + std::cout << "MicromegasRawDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; + continue; + } + + // create hit, assign adc and insert in hitset + hit = new TrkrHitv2; + hit->setAdc( max_adc ); + hitset_it->second->addHitSpecificKey(hitkey, hit); + + // increment counter + ++m_hitcounts[hitsetkey]; + + } } - } - return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/micromegas/MicromegasRawDataEvaluation.cc b/offline/packages/micromegas/MicromegasRawDataEvaluation.cc new file mode 100644 index 0000000000..89fdd647dd --- /dev/null +++ b/offline/packages/micromegas/MicromegasRawDataEvaluation.cc @@ -0,0 +1,163 @@ +/*! + * \file MicromegasRawDataEvaluation.cc + * \author Hugo Pereira Da Costa + */ + +#include "MicromegasRawDataEvaluation.h" +#include "MicromegasDefs.h" + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +//_________________________________________________________ +void MicromegasRawDataEvaluation::Container::Reset() +{ + n_waveforms = 0; + samples.clear(); +} + +//_________________________________________________________ +MicromegasRawDataEvaluation::MicromegasRawDataEvaluation( const std::string& name ): + SubsysReco( name ) +{} + +//_____________________________________________________________________ +int MicromegasRawDataEvaluation::Init(PHCompositeNode* /*topNode*/ ) +{ + m_evaluation_file.reset( new TFile( m_evaluation_filename.c_str(), "RECREATE" ) ); + m_evaluation_tree = new TTree( "T", "T" ); + m_container = new Container; + m_evaluation_tree->Branch( "Event", &m_container ); + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int MicromegasRawDataEvaluation::InitRun(PHCompositeNode* /*topNode*/) +{ return Fun4AllReturnCodes::EVENT_OK; } + +//___________________________________________________________________________ +int MicromegasRawDataEvaluation::process_event(PHCompositeNode *topNode) +{ + + // map fee id to detector index in histogram + using fee_map_t = std::map; + fee_map_t fee_map = { + {5, 0}, // SEIP + {7, 1}, // SEIZ + {6, 2}, // SCOP + {8, 3}, // SCOZ + {9, 4}, // SCIP + + // old mapping until May 23 + /* it is ok to keep it here, to be able to process older files */ + {10, 5}, // SCIZ + // updated after May 23 + {23, 5}, // SCIZ + {24, 6}, // SWIP + {25, 7}, // SWIZ + + {11, 8}, // NEIP + {12, 9}, // NEIZ + {19, 10}, // NCOP + {18, 11}, // NCOZ + {0, 12}, // NCIP + {1, 13}, // NCIZ + {15, 14}, // NWIP + {14, 15}, // NWIZ + }; + + // load relevant nodes + // PRDF node + auto event = findNode::getClass(topNode, "PRDF"); + assert( event ); + + // check event type + if(event->getEvtType() >= 8) + { return Fun4AllReturnCodes::DISCARDEVENT; } + + m_container->Reset(); + + // loop over TPOT packets + for( const auto& packet_id:MicromegasDefs::m_packet_ids ) + { + std::unique_ptr packet( event->getPacket(packet_id) ); + if( !packet ) + { + // no data + std::cout << "MicromegasRawDataEvaluation::process_event - packet " << packet_id << " not found." << std::endl; + return Fun4AllReturnCodes::EVENT_OK; + } + + // get number of datasets (also call waveforms) + const auto n_waveforms = packet->iValue(0, "NR_WF" ); + m_container->n_waveforms = n_waveforms; + if( Verbosity() ) + { std::cout << "MicromegasRawDataEvaluation::process_event - packet: " << packet_id << " n_waveforms: " << n_waveforms << std::endl; } + + for( int i=0; iiValue(i, "FEE" ); + const unsigned short channel = packet->iValue( i, "CHANNEL" ); + + // get hitsetkey, layer and tile + const auto hitsetkey = m_mapping.get_hitsetkey(fee); + const unsigned short layer = TrkrDefs::getLayer( hitsetkey ); + const unsigned short tile = MicromegasDefs::getTileId( hitsetkey ); + + // get detector index and absolute channel number + const unsigned short det_index = fee_map[fee]; + const unsigned short absolute_channel = channel + det_index*MicromegasDefs::m_nchannels_fee; + + // get number of samples and loop + const unsigned short samples = packet->iValue( i, "SAMPLES" ); + for( unsigned short is = 0; is < samples; ++is ) + { + unsigned short adc = packet->iValue(i,is); + m_container->samples.push_back( + Sample + { + .packet_id = packet_id, + .fee_id = fee, + .layer = layer, + .tile = tile, + .channel = channel, + .absolute_channel = absolute_channel, + .sample = is, + .adc = adc + }); + } + + } + } + + m_evaluation_tree->Fill(); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//_____________________________________________________________________ +int MicromegasRawDataEvaluation::End(PHCompositeNode* /*topNode*/ ) +{ + if( m_evaluation_file && m_evaluation_tree ) + { + m_evaluation_file->cd(); + m_evaluation_tree->Write(); + m_evaluation_file->Close(); + } + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/micromegas/MicromegasRawDataEvaluation.h b/offline/packages/micromegas/MicromegasRawDataEvaluation.h new file mode 100644 index 0000000000..bcc5cab00f --- /dev/null +++ b/offline/packages/micromegas/MicromegasRawDataEvaluation.h @@ -0,0 +1,89 @@ +#ifndef MICROMEGAS_MicromegasRawDataEvaluation_H +#define MICROMEGAS_MicromegasRawDataEvaluation_H + +/*! + * \file MicromegasRawDataEvaluation.h + * \author Hugo Pereira Da Costa + */ + +#include "MicromegasMapping.h" + +#include +#include + +#include + +#include +#include +#include + +class PHCompositeNode; +class TFile; +class TH1; +class TH2; +class TProfile; + +/// micromegas raw data decoder +class MicromegasRawDataEvaluation : public SubsysReco +{ + public: + + /// constructor + MicromegasRawDataEvaluation( const std::string &name = "MicromegasRawDataEvaluation" ); + + /// global initialization + int Init(PHCompositeNode*) override; + + /// run initialization + int InitRun(PHCompositeNode*) override; + + /// event processing + int process_event(PHCompositeNode*) override; + + /// end of processing + int End(PHCompositeNode*) override; + + /// output file name for evaluation histograms + void set_evaluation_outputfile(const std::string &outputfile) {m_evaluation_filename = outputfile;} + + class Sample + { + public: + unsigned int packet_id = 0; + unsigned short fee_id = 0; + unsigned short layer = 0; + unsigned short tile = 0; + unsigned short channel = 0; + unsigned short absolute_channel = 0; + unsigned short sample = 0; + unsigned short adc = 0; + using List = std::vector; + }; + + class Container: public PHObject + { + public: + void Reset(); + int n_waveforms = 0; + Sample::List samples; + ClassDef(Container,1) + }; + + private: + + // evaluation output filename + std::string m_evaluation_filename = "MicromegasRawDataEvaluation.root"; + std::unique_ptr m_evaluation_file; + + // mapping + MicromegasMapping m_mapping; + + // tree + TTree* m_evaluation_tree = nullptr; + + // main branch + Container* m_container = nullptr; + +}; + +#endif diff --git a/offline/packages/micromegas/MicromegasRawDataEvaluationLinkDef.h b/offline/packages/micromegas/MicromegasRawDataEvaluationLinkDef.h new file mode 100644 index 0000000000..cb6f58bc9d --- /dev/null +++ b/offline/packages/micromegas/MicromegasRawDataEvaluationLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class MicromegasRawDataEvaluation::Container+; + +#endif /* __CINT__ */ diff --git a/offline/packages/micromegas/configure.ac b/offline/packages/micromegas/configure.ac index d31000325a..39a779fa35 100644 --- a/offline/packages/micromegas/configure.ac +++ b/offline/packages/micromegas/configure.ac @@ -21,5 +21,16 @@ esac CINTDEFS=" -noIncludePaths -inlineInputHeader " AC_SUBST(CINTDEFS) +### add "online" build option +AC_ARG_ENABLE(online, + [ --enable-online build using for online [default=no]], + [case "${enableval}" in + yes) online=true ;; + no) online=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-online) ;; + esac], + online=false) +AM_CONDITIONAL(USE_ONLINE, test "x$online" = xtrue) + AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/offline/packages/mvtx/Makefile.am b/offline/packages/mvtx/Makefile.am index f06786c9d3..692a171039 100644 --- a/offline/packages/mvtx/Makefile.am +++ b/offline/packages/mvtx/Makefile.am @@ -20,6 +20,7 @@ AM_LDFLAGS = \ pkginclude_HEADERS = \ MvtxClusterizer.h \ MvtxHitPruner.h \ + MvtxRawDataDecoder.h \ CylinderGeom_Mvtx.h \ SegmentationAlpide.h @@ -34,7 +35,8 @@ nobase_dist_pcm_DATA = \ # sources for mvtx library libmvtx_la_SOURCES = \ MvtxClusterizer.cc \ - MvtxHitPruner.cc + MvtxHitPruner.cc \ + MvtxRawDataDecoder.cc libmvtx_la_LIBADD = \ libmvtx_io.la \ diff --git a/offline/packages/mvtx/MvtxClusterizer.cc b/offline/packages/mvtx/MvtxClusterizer.cc index 2539aa8e11..e5b33a0abc 100644 --- a/offline/packages/mvtx/MvtxClusterizer.cc +++ b/offline/packages/mvtx/MvtxClusterizer.cc @@ -212,10 +212,10 @@ int MvtxClusterizer::process_event(PHCompositeNode *topNode) { // get node containing the digitized hits if(!do_read_raw){ - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_MVTX"); if (!m_hits) { - cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << endl; + cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_MVTX" << endl; return Fun4AllReturnCodes::ABORTRUN; } }else{ @@ -223,7 +223,7 @@ int MvtxClusterizer::process_event(PHCompositeNode *topNode) m_rawhits = findNode::getClass(topNode, "TRKR_RAWHITSET"); if (!m_rawhits) { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + std::cout << PHWHERE << "ERROR: Can't find node TRKR_RAWHITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } } @@ -344,8 +344,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) cluster_ids.insert(component[i]); clusters.insert(make_pair(component[i], hitvec[i])); } - // cout << "found cluster #: "<< clusters.size()<< endl; - // loop over the componenets and make clusters + int total_clusters = 0; for (set::iterator clusiter = cluster_ids.begin(); clusiter != cluster_ids.end(); ++clusiter) { int clusid = *clusiter; @@ -353,7 +352,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) if (Verbosity() > 2) cout << "Filling cluster id " << clusid << " of " << std::distance(cluster_ids.begin(),clusiter )<< endl; - // make the cluster directly in the node tree + ++total_clusters; auto ckey = TrkrDefs::genClusKey(hitset->getHitSetKey(), clusid); // determine the size of the cluster in phi and z @@ -405,9 +404,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) locclusz = loczsum / nhits; const double pitch = layergeom->get_pixel_x(); - // std::cout << " pitch: " << pitch << std::endl; const double length = layergeom->get_pixel_z(); - // std::cout << " length: " << length << std::endl; const double phisize = phibins.size() * pitch; const double zsize = zbins.size() * length; diff --git a/offline/packages/mvtx/MvtxHitPruner.cc b/offline/packages/mvtx/MvtxHitPruner.cc index 8183ac24c4..2a6258fe39 100644 --- a/offline/packages/mvtx/MvtxHitPruner.cc +++ b/offline/packages/mvtx/MvtxHitPruner.cc @@ -82,10 +82,10 @@ int MvtxHitPruner::InitRun(PHCompositeNode * /*topNode*/) int MvtxHitPruner::process_event(PHCompositeNode *topNode) { // get node containing the digitized hits - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_MVTX"); if (!m_hits) { - cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << endl; + cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_MVTX" << endl; return Fun4AllReturnCodes::ABORTRUN; } diff --git a/offline/packages/mvtx/MvtxRawDataDecoder.cc b/offline/packages/mvtx/MvtxRawDataDecoder.cc new file mode 100644 index 0000000000..349cf02471 --- /dev/null +++ b/offline/packages/mvtx/MvtxRawDataDecoder.cc @@ -0,0 +1,168 @@ +/*! + * \file MvtxRawDataDecoder.cc + * \author Jakub Kvapil + */ + +#include "MvtxRawDataDecoder.h" + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +//_________________________________________________________ +MvtxRawDataDecoder::MvtxRawDataDecoder( const std::string& name ): + SubsysReco( name ) +{} + +//_____________________________________________________________________ +int MvtxRawDataDecoder::Init(PHCompositeNode* /*topNode*/ ) +{ + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int MvtxRawDataDecoder::InitRun(PHCompositeNode *topNode) +{ + + // get dst node + PHNodeIterator iter(topNode); + auto dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << "MvtxRawDataDecoder::InitRun - DST Node missing, doing nothing." << std::endl; + exit(1); + } + + // create hitset container if needed + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + if (!hitsetcontainer) + { + // find or create TRKR node + PHNodeIterator dstiter(dstNode); + auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + if (!trkrnode) + { + trkrnode = new PHCompositeNode("TRKR"); + dstNode->addNode(trkrnode); + } + + // create container and add to the tree + hitsetcontainer = new TrkrHitSetContainerv1; + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + trkrnode->addNode(newNode); + } + + return Fun4AllReturnCodes::EVENT_OK; + +} + +//___________________________________________________________________________ +int MvtxRawDataDecoder::process_event(PHCompositeNode *topNode) +{ + + // load relevant nodes + // Get the TrkrHitSetContainer node + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + assert(trkrhitsetcontainer); + + // PRDF node + auto event = findNode::getClass(topNode, "PRDF"); + assert(event); + // check event type + + +//UNCOMMENT THIS ONCE HAVING DECODER!!!! +/* if(event->getEvtType() >= 8) + { return Fun4AllReturnCodes::DISCARDEVENT; } + + // get MVTX packet number + auto packet = event->getPacket(2001); + if( !packet ) + { + // no data + std::cout << "MvtxRawDataDecoder::process_event - event contains no MVTX data" << std::endl; + // return Fun4AllReturnCodes::EVENT_OK; + } + +*/ + + //loop over triggers ADD + //loop over chips + for( int i=0; i<1; i++ ) + { + int strobe = 11+i; //get from decoder; + int layer = 0;//get from decoder; + int stave = 1;//get from decoder; + int chip = 2;//get from decoder; + + if( Verbosity() ){ + std::cout + << "MvtxRawDataDecoder::process_event -" + << " strobe: " << strobe + << " layer: " << layer + << " stave: " << stave + << " chip: " << chip + << std::endl; + } + + // map fee and channel to physical hitsetid and physical strip + // get hitset key matching this fee + const TrkrDefs::hitsetkey hitsetkey = MvtxDefs::genHitSetKey(layer, stave, chip, strobe); + if( !hitsetkey ) continue; + + // get matching hitset + const auto hitset_it = trkrhitsetcontainer->findOrAddHitSet(hitsetkey); + + for( int ihit=0; ihit<10/*nhit in chip from decoder*/; ++ihit ){ + uint16_t col = 150;//get from decoder; + uint16_t row = ihit*10;//get from decoder; + + // generate hit key + const TrkrDefs::hitkey hitkey = MvtxDefs::genHitKey(col,row); + + // find existing hit, or create + auto hit = hitset_it->second->getHit(hitkey); + if( hit ){ + std::cout << "MvtxRawDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " hitkey: " << hitkey << std::endl; + continue; + } + + // create hit and insert in hitset + hit = new TrkrHitv2; + hitset_it->second->addHitSpecificKey(hitkey, hit); + + // increment counter + ++m_hitcounts[hitsetkey]; + + } + } + + return Fun4AllReturnCodes::EVENT_OK; + +} + +//_____________________________________________________________________ +int MvtxRawDataDecoder::End(PHCompositeNode* /*topNode*/ ) +{ + if( Verbosity() ) + { + for( const auto& [hitsetkey, count]:m_hitcounts ) + { std::cout << "MvtxRawDataDecoder - hitsetkey: " << hitsetkey << ", count: " << count << std::endl; } + } + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/mvtx/MvtxRawDataDecoder.h b/offline/packages/mvtx/MvtxRawDataDecoder.h new file mode 100644 index 0000000000..e33eccc51f --- /dev/null +++ b/offline/packages/mvtx/MvtxRawDataDecoder.h @@ -0,0 +1,45 @@ +#ifndef MVTX_MVTXRAWDATADECODER_H +#define MVTX_MVTXRAWDATADECODER_H + +/*! + * \file MvtxRawDataDecoder.h + * \author Jakub Kvapil + */ + +#include +#include + +#include +#include +#include + +class PHCompositeNode; + +/// mvtx raw data decoder +class MvtxRawDataDecoder : public SubsysReco +{ + public: + + /// constructor + MvtxRawDataDecoder( const std::string &name = "MvtxRawDataDecoder" ); + + /// global initialization + int Init(PHCompositeNode*) override; + + /// run initialization + int InitRun(PHCompositeNode*) override; + + /// event processing + int process_event(PHCompositeNode*) override; + + /// end of processing + int End(PHCompositeNode*) override; + + private: + /// keep track of number of hits per hitsetid + using hitcountmap_t = std::map; + hitcountmap_t m_hitcounts; + +}; + +#endif diff --git a/offline/packages/particleflow/Makefile.am b/offline/packages/particleflow/Makefile.am index de276784b0..5858fe3d03 100644 --- a/offline/packages/particleflow/Makefile.am +++ b/offline/packages/particleflow/Makefile.am @@ -53,7 +53,7 @@ libparticleflow_la_LIBADD = \ -lg4jets_io \ -ltrackbase_historic_io \ -lCLHEP \ - -lg4vertex_io \ + -lglobalvertex_io \ -lSubsysReco %_Dict.cc: %.h %LinkDef.h diff --git a/offline/packages/particleflow/ParticleFlowReco.cc b/offline/packages/particleflow/ParticleFlowReco.cc index 7aeec627a3..4cf38fd7ba 100644 --- a/offline/packages/particleflow/ParticleFlowReco.cc +++ b/offline/packages/particleflow/ParticleFlowReco.cc @@ -3,13 +3,11 @@ #include "ParticleFlowElementContainer.h" #include "ParticleFlowElementv1.h" -#include -#include +#include +#include #include #include -#include -#include #include #include #include @@ -34,10 +32,10 @@ #include // examine second value of std::pair, sort by smallest -bool sort_by_pair_second_lowest( const std::pair &a, const std::pair &b) -{ - return (a.second < b.second); -} +bool sort_by_pair_second_lowest( const std::pair &a, const std::pair &b) +{ + return (a.second < b.second); +} float ParticleFlowReco::calculate_dR( float eta1, float eta2, float phi1, float phi2 ) { @@ -50,7 +48,7 @@ float ParticleFlowReco::calculate_dR( float eta1, float eta2, float phi1, float } std::pair ParticleFlowReco::get_expected_signature( int trk ) { - + float response = ( 0.553437 + 0.0572246 * log( _pflow_TRK_p[ trk ] ) ) * _pflow_TRK_p[ trk ]; float resolution = sqrt( pow( 0.119123 , 2 ) + pow( 0.312361 , 2 ) / _pflow_TRK_p[ trk ] ) * _pflow_TRK_p[ trk ] ; @@ -101,16 +99,6 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) // used for indexing PFlow elements in container int global_pflow_index = 0; - - // read in towers - RawTowerContainer *towersEM = findNode::getClass(topNode, "TOWER_CALIB_CEMC"); - RawTowerContainer *towersIH = findNode::getClass(topNode, "TOWER_CALIB_HCALIN"); - RawTowerContainer *towersOH = findNode::getClass(topNode, "TOWER_CALIB_HCALOUT"); - - if ( !towersEM || !towersIH || !towersOH ) { - std::cout << "ParticleFlowReco::process_event : FATAL ERROR, cannot find tower containers" << std::endl; - return Fun4AllReturnCodes::ABORTEVENT; - } // read in tower geometries RawTowerGeomContainer *geomEM = findNode::getClass(topNode, "TOWERGEOM_CEMC"); @@ -122,7 +110,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } - // read in clusters + // read in clusters RawClusterContainer *clustersEM = findNode::getClass(topNode, "TOPOCLUSTER_EMCAL"); RawClusterContainer *clustersHAD = findNode::getClass(topNode, "TOPOCLUSTER_HCAL"); @@ -177,13 +165,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } } - if ( Verbosity() > 2 ) + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : initial population of TRK, EM, HAD objects " << std::endl; // read in tracks with > 0.5 GeV { SvtxTrackMap* trackmap = findNode::getClass(topNode, _track_map_name); - + float cemcradius = geomEM->get_radius(); float ohcalradius = geomOH->get_radius(); @@ -200,7 +188,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if(Verbosity() > 2) { std::cout << "Track with p= " << track->get_p() <<", eta / phi = " - << track->get_eta() << " / " << track->get_phi() + << track->get_eta() << " / " << track->get_phi() << std::endl; } @@ -211,7 +199,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) _pflow_TRK_match_EM.push_back( std::vector() ); _pflow_TRK_match_HAD.push_back( std::vector() ); _pflow_TRK_addtl_match_EM.push_back( std::vector< std::pair >() ); - + SvtxTrackState* cemcstate = track->get_state(cemcradius); SvtxTrackState* ohstate = track->get_state(ohcalradius); /// Get the track projections. If they failed for some reason, just use the track @@ -220,8 +208,8 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) { _pflow_TRK_EMproj_phi.push_back(atan2(cemcstate->get_y(), cemcstate->get_x())); _pflow_TRK_EMproj_eta.push_back(asinh(cemcstate->get_z()/sqrt(cemcstate->get_x()*cemcstate->get_x() + cemcstate->get_y()*cemcstate->get_y()))); - } - else { + } + else { _pflow_TRK_EMproj_phi.push_back(track->get_phi()); _pflow_TRK_EMproj_eta.push_back(track->get_eta()); } @@ -230,15 +218,15 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) _pflow_TRK_HADproj_phi.push_back(atan2(ohstate->get_py(), ohstate->get_px())); _pflow_TRK_HADproj_eta.push_back(asinh(ohstate->get_pz()/ohstate->get_pt())); } - else { + else { _pflow_TRK_HADproj_phi.push_back(track->get_phi()); _pflow_TRK_HADproj_eta.push_back(track->get_eta()); } } - } // + } // + - // read in EMCal topoClusters with E > 0.2 GeV { @@ -247,12 +235,12 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) { float cluster_E = hiter->second->get_energy(); if ( cluster_E < 0.2 ) continue; - + float cluster_phi = hiter->second->get_phi(); /// default assume at vx_z = 0 float cluster_theta = M_PI / 2.0 - atan2( hiter->second->get_z() , hiter->second->get_r() ); float cluster_eta = -1 * log( tan( cluster_theta / 2.0 ) ); - + if(vertex) { cluster_eta = RawClusterUtility::GetPseudorapidity(*(hiter->second),CLHEP::Hep3Vector(vertex->get_x(), vertex->get_y(), vertex->get_z())); @@ -264,36 +252,35 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) _pflow_EM_cluster.push_back(hiter->second); _pflow_EM_match_HAD.push_back( std::vector() ); _pflow_EM_match_TRK.push_back( std::vector() ); - - if ( Verbosity() > 5 && cluster_E > 0.2 ) + + if ( Verbosity() > 5 && cluster_E > 0.2 ) std::cout << " EM topoCluster with E = " << cluster_E << ", eta / phi = " << cluster_eta << " / " << cluster_phi << " , nTow = " << hiter->second->getNTowers() << std::endl; - + std::vector this_cluster_tower_eta; std::vector this_cluster_tower_phi; - + // read in towers RawCluster::TowerConstRange begin_end_towers = hiter->second->get_towers(); for (RawCluster::TowerConstIterator iter = begin_end_towers.first; iter != begin_end_towers.second; ++iter) { - + if ( RawTowerDefs::decode_caloid( iter->first ) == RawTowerDefs::CalorimeterId::CEMC ) { - RawTower* tower = towersEM->getTower(iter->first); - RawTowerGeom *tower_geom = geomEM->get_tower_geometry(tower->get_key()); - + RawTowerGeom *tower_geom = geomEM->get_tower_geometry(iter->first); + this_cluster_tower_phi.push_back( tower_geom->get_phi() ); this_cluster_tower_eta.push_back( tower_geom->get_eta() ); } else { std::cout << "ParticleFlowReco::process_event : FATAL ERROR , EM topoClusters seem to contain HCal towers" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; - } + } } // close tower loop - + _pflow_EM_tower_eta.push_back( this_cluster_tower_eta ); _pflow_EM_tower_phi.push_back( this_cluster_tower_phi ); - + } // close cluster loop - - } // close + + } // close // read in HCal topoClusters with E > 0.2 GeV { @@ -302,7 +289,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) { float cluster_E = hiter->second->get_energy(); if ( cluster_E < 0.2 ) continue; - + float cluster_phi = hiter->second->get_phi(); // for now, assume event at vx_z = 0 float cluster_theta = M_PI / 2.0 - atan2( hiter->second->get_z() , hiter->second->get_r() ); @@ -319,69 +306,67 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) _pflow_HAD_match_EM.push_back( std::vector() ); _pflow_HAD_match_TRK.push_back( std::vector() ); - - if ( Verbosity() > 5 && cluster_E > 0.2 ) + + if ( Verbosity() > 5 && cluster_E > 0.2 ) std::cout << " HAD topoCluster with E = " << cluster_E << ", eta / phi = " << cluster_eta << " / " << cluster_phi << " , nTow = " << hiter->second->getNTowers() << std::endl; - + std::vector this_cluster_tower_eta; std::vector this_cluster_tower_phi; - + // read in towers RawCluster::TowerConstRange begin_end_towers = hiter->second->get_towers(); for (RawCluster::TowerConstIterator iter = begin_end_towers.first; iter != begin_end_towers.second; ++iter) { - + if ( RawTowerDefs::decode_caloid( iter->first ) == RawTowerDefs::CalorimeterId::HCALIN ) { - RawTower* tower = towersIH->getTower(iter->first); - RawTowerGeom *tower_geom = geomIH->get_tower_geometry(tower->get_key()); - + RawTowerGeom *tower_geom = geomIH->get_tower_geometry(iter->first); + this_cluster_tower_phi.push_back( tower_geom->get_phi() ); this_cluster_tower_eta.push_back( tower_geom->get_eta() ); } else if ( RawTowerDefs::decode_caloid( iter->first ) == RawTowerDefs::CalorimeterId::HCALOUT ) { - RawTower* tower = towersOH->getTower(iter->first); - RawTowerGeom *tower_geom = geomOH->get_tower_geometry(tower->get_key()); - + RawTowerGeom *tower_geom = geomOH->get_tower_geometry(iter->first); + this_cluster_tower_phi.push_back( tower_geom->get_phi() ); this_cluster_tower_eta.push_back( tower_geom->get_eta() ); } else { std::cout << "ParticleFlowReco::process_event : FATAL ERROR , HCal topoClusters seem to contain EM towers" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - - + + } // close tower loop - + _pflow_HAD_tower_eta.push_back( this_cluster_tower_eta ); _pflow_HAD_tower_phi.push_back( this_cluster_tower_phi ); - + } // close cluster loop - - } // close + + } // close // BEGIN LINKING STEP // Link TRK -> EM (best match, but keep reserve of others), and TRK -> HAD (best match) - if ( Verbosity() > 2 ) + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : TRK -> EM and TRK -> HAD linking " << std::endl; for (unsigned int trk = 0; trk < _pflow_TRK_p.size() ; trk++ ) { - + if ( Verbosity() > 10 ) std::cout << " TRK " << trk << " with p / eta / phi = " << _pflow_TRK_p[ trk ] << " / " << _pflow_TRK_eta[ trk ] << " / " << _pflow_TRK_phi[ trk ] << std::endl; // TRK -> EM link float min_em_dR = 0.2; int min_em_index = -1; - + for (unsigned int em = 0 ; em < _pflow_EM_E.size() ; em++) { float dR = calculate_dR( _pflow_TRK_EMproj_eta[ trk ] , _pflow_EM_eta[ em ] , _pflow_TRK_EMproj_phi[ trk ] , _pflow_EM_phi[ em ] ); - + if ( dR > 0.2 ) continue; - + bool has_overlap = false; for (unsigned int tow = 0; tow < _pflow_EM_tower_eta.at( em ).size() ; tow++) { @@ -403,21 +388,21 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( has_overlap ) { - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> possible match to EM " << em << " with dR = " << dR << std::endl; _pflow_TRK_addtl_match_EM.at( trk ).push_back( std::pair( em, dR ) ); } else { - - if ( Verbosity() > 5 ) + + if ( Verbosity() > 5 ) std::cout << " -> no match to EM " << em << " (even though dR = " << dR << " )" << std::endl; - + } } - // sort possible matches + // sort possible matches std::sort( _pflow_TRK_addtl_match_EM.at( trk ).begin(), _pflow_TRK_addtl_match_EM.at( trk ).end(), sort_by_pair_second_lowest ); if ( Verbosity() > 10 ) { @@ -425,7 +410,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) std::cout << " -> sorted list of matches, EM / dR = " << _pflow_TRK_addtl_match_EM.at( trk ).at( n ).first << " / " << _pflow_TRK_addtl_match_EM.at( trk ).at( n ).second << std::endl; } } - + if ( _pflow_TRK_addtl_match_EM.at( trk ).size() > 0 ) { min_em_index = _pflow_TRK_addtl_match_EM.at( trk ).at( 0 ).first; min_em_dR = _pflow_TRK_addtl_match_EM.at( trk ).at( 0 ).second; @@ -442,13 +427,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) std::cout << " -> matched EM " << min_em_index << " with pt / eta / phi = " << _pflow_EM_E.at( min_em_index ) << " / " << _pflow_EM_eta.at( min_em_index ) << " / " << _pflow_EM_phi.at( min_em_index ) << ", dR = " << min_em_dR; std::cout << " ( " << _pflow_TRK_addtl_match_EM.at( trk ).size() << " other possible matches ) " << std::endl; } - + } else { - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> no EM match! ( best dR = " << min_em_dR << " ) " << std::endl; } - + // TRK -> HAD link float min_had_dR = 0.2; int min_had_index = -1; @@ -458,9 +443,9 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) for (unsigned int had = 0 ; had < _pflow_HAD_E.size() ; had++) { float dR = calculate_dR( _pflow_TRK_HADproj_eta[ trk ] , _pflow_HAD_eta[ had ] , _pflow_TRK_HADproj_phi[ trk ] , _pflow_HAD_phi[ had ] ); - + if ( dR > 0.5 ) continue; - + bool has_overlap = false; for (unsigned int tow = 0; tow < _pflow_HAD_tower_eta.at( had ).size() ; tow++) { @@ -482,7 +467,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( has_overlap ) { - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> possible match to HAD " << had << " with dR = " << dR << std::endl; if ( _pflow_HAD_E.at( had ) > max_had_pt ) { @@ -492,10 +477,10 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } } else { - - if ( Verbosity() > 5 ) + + if ( Verbosity() > 5 ) std::cout << " -> no match to HAD " << had << " (even though dR = " << dR << " )" << std::endl; - + } } @@ -504,11 +489,11 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) _pflow_HAD_match_TRK.at( min_had_index ).push_back( trk ); _pflow_TRK_match_HAD.at( trk ).push_back( min_had_index ); - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> matched HAD " << min_had_index << " with pt / eta / phi = " << _pflow_HAD_E.at( min_had_index ) << " / " << _pflow_HAD_eta.at( min_had_index ) << " / " << _pflow_HAD_phi.at( min_had_index ) << ", dR = " << min_had_dR << std::endl; - + } else { - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> no HAD match! ( best dR = " << min_had_dR << " ) " << std::endl; } @@ -516,20 +501,20 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } - // EM->HAD linking - if ( Verbosity() > 2 ) + // EM->HAD linking + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : EM -> HAD linking " << std::endl; for (unsigned int em = 0; em < _pflow_EM_E.size() ; em++ ) { - + if ( Verbosity() > 10 ) std::cout << " EM with E / eta / phi = " << _pflow_EM_E[ em ] << " / " << _pflow_EM_eta[ em ] << " / " << _pflow_EM_phi[ em ] << std::endl; - + // TRK -> HAD link float min_had_dR = 0.2; int min_had_index = -1; float max_had_pt = 0; - + for (unsigned int had = 0 ; had < _pflow_HAD_E.size() ; had++) { float dR = calculate_dR( _pflow_EM_eta[ em ] , _pflow_HAD_eta[ had ] , _pflow_EM_phi[ em ] , _pflow_HAD_phi[ had ] ); @@ -556,7 +541,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( has_overlap ) { - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> possible match to HAD " << had << " with dR = " << dR << std::endl; if ( _pflow_HAD_E.at( had ) > max_had_pt ) { @@ -566,10 +551,10 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } } else { - - if ( Verbosity() > 5 ) + + if ( Verbosity() > 5 ) std::cout << " -> no match to HAD " << had << " (even though dR = " << dR << " )" << std::endl; - + } } @@ -578,19 +563,19 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) _pflow_HAD_match_EM.at( min_had_index ).push_back( em ); _pflow_EM_match_HAD.at( em ).push_back( min_had_index ); - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> matched HAD with E / eta / phi = " << _pflow_HAD_E.at( min_had_index ) << " / " << _pflow_HAD_eta.at( min_had_index ) << " / " << _pflow_HAD_phi.at( min_had_index ) << ", dR = " << min_had_dR << std::endl; - + } else { - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> no HAD match! ( best dR = " << min_had_dR << " ) " << std::endl; } } - // SEQUENTIAL MATCHING: if TRK -> EM and EM -> HAD, ensure that TRK -> HAD - if ( Verbosity() > 2 ) + // SEQUENTIAL MATCHING: if TRK -> EM and EM -> HAD, ensure that TRK -> HAD + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : sequential TRK -> EM && EM -> HAD ==> TRK -> HAD matching " << std::endl; for (unsigned int trk = 0; trk < _pflow_TRK_p.size() ; trk++ ) { @@ -610,8 +595,8 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) for (unsigned int k = 0; k < _pflow_TRK_match_HAD.at( trk ).size(); k++) { int existing_had = _pflow_TRK_match_HAD.at( trk ).at( k ); if ( had == existing_had ) is_trk_matched_to_HAD = true; - } - + } + // if this is the case, create TRK->HAD link if ( ! is_trk_matched_to_HAD ) { _pflow_TRK_match_HAD.at( trk ).push_back( had ); @@ -631,18 +616,18 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } // close the TRK loop // TRK->EM->HAD removal - if ( Verbosity() > 2 ) + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : resolve TRK(s) + EM(s) -> HAD systems " << std::endl; - + for (unsigned int had = 0; had < _pflow_HAD_E.size() ; had++ ) { - // only consider HAD with matched tracks ... others we will deal with later + // only consider HAD with matched tracks ... others we will deal with later if ( _pflow_HAD_match_TRK.at( had ).size() == 0 ) continue; if ( Verbosity() > 5 ) { std::cout << " HAD " << had << " with E / eta / phi = " << _pflow_HAD_E.at( had ) << " / " << _pflow_HAD_eta.at( had ) << " / " << _pflow_HAD_phi.at( had ) << std::endl; } - + // setup for Sum-pT^trk -> calo prediction float total_TRK_p = 0; float total_expected_E = 0; @@ -653,7 +638,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) std::vector matchedEClusters; - // iterate over the EMs matched to this HAD + // iterate over the EMs matched to this HAD for (unsigned int j = 0; j < _pflow_HAD_match_EM.at( had ).size() ; j++ ) { int em = _pflow_HAD_match_EM.at( had ).at( j ); @@ -661,7 +646,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) // ensure there is at least one track matched to this EM if ( _pflow_EM_match_TRK.at( em ).size() == 0 ) continue; - // add it to the total calo E + // add it to the total calo E total_EMHAD_E += _pflow_EM_E.at( em ); matchedEClusters.push_back(_pflow_EM_cluster.at(em)); if ( Verbosity() > 5 ) { @@ -669,7 +654,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } } - + // iterate over the TRKs matched to this HAD for (unsigned int j = 0 ; j < _pflow_HAD_match_TRK.at( had ).size() ; j++) { @@ -678,7 +663,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " -> -> LINKED TRK " << trk << " with p / eta / phi = " << _pflow_TRK_p.at( trk ) << " / " << _pflow_TRK_eta.at( trk ) << " / " << _pflow_TRK_phi.at( trk ) << std::endl; } - + total_TRK_p += _pflow_TRK_p.at( trk ); std::pair expected_signature = get_expected_signature( trk ); @@ -689,16 +674,16 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " -> -> -> expected calo signature is " << expected_E_mean << " +/- " << expected_E_sigma << std::endl; } - + total_expected_E += expected_E_mean; total_expected_E_var += pow( expected_E_sigma , 2 ); // add PFlow element for each track ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume pion mass - TLorentzVector tlv; - tlv.SetPtEtaPhiM( _pflow_TRK_p[ trk ] / cosh( _pflow_TRK_eta[ trk ] ) , _pflow_TRK_eta[ trk ] , _pflow_TRK_phi[ trk ] , 0.135 ); + TLorentzVector tlv; + tlv.SetPtEtaPhiM( _pflow_TRK_p[ trk ] / cosh( _pflow_TRK_eta[ trk ] ) , _pflow_TRK_eta[ trk ] , _pflow_TRK_phi[ trk ] , 0.135 ); pflow->set_px( tlv.Px() ); pflow->set_py( tlv.Py() ); @@ -709,14 +694,14 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) pflow->set_hcluster(_pflow_HAD_cluster.at(had)); pflow->set_id( global_pflow_index ); pflow->set_type( ParticleFlowElement::PFLOWTYPE::MATCHED_CHARGED_HADRON ); - + pflowContainer->AddParticleFlowElement( global_pflow_index, pflow ); global_pflow_index++; } // Track + E+HCal PF elements are created - - // process compatibility of fit + + // process compatibility of fit float total_expected_E_err = sqrt( total_expected_E_var ); if ( Verbosity() > 5 ) { @@ -726,25 +711,25 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) // if Sum pT > calo, add in additional possible matched EMs associated with tracks until that is no longer the case if ( total_expected_E > total_EMHAD_E ) { - - if ( Verbosity() > 5 ) + + if ( Verbosity() > 5 ) std::cout << " -> Expected E > Observed E, looking for additional potential TRK->EM matches" << std::endl; - + std::map additional_EMs; - + for (unsigned int j = 0 ; j < _pflow_HAD_match_TRK.at( had ).size() ; j++) { - + int trk = _pflow_HAD_match_TRK.at( had ).at( j ); int addtl_matches = _pflow_TRK_addtl_match_EM.at( trk ).size(); if ( Verbosity() > 10 ) std::cout << " -> -> TRK " << trk << " has " << addtl_matches << " additional matches! " << std::endl; - + for (unsigned int n = 0 ; n < _pflow_TRK_addtl_match_EM.at( trk ).size() ; n++ ) { if ( Verbosity() > 10 ) std::cout << " -> -> -> additional match to EM = " << _pflow_TRK_addtl_match_EM.at( trk ).at( n ).first << " with dR = " << _pflow_TRK_addtl_match_EM.at( trk ).at( n ).second << std::endl; - + float existing_dR = 0.21; int counts = additional_EMs.count( _pflow_TRK_addtl_match_EM.at( trk ).at( n ).first ); if ( counts > 0 ) { @@ -753,7 +738,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( _pflow_TRK_addtl_match_EM.at( trk ).at( n ).second < existing_dR ) additional_EMs[ _pflow_TRK_addtl_match_EM.at( trk ).at( n ).first ] = _pflow_TRK_addtl_match_EM.at( trk ).at( n ).second; } - + } // map now assured to have only minimal dR values for each possible additional EM @@ -767,7 +752,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) std::sort( additional_EMs_vec.begin(), additional_EMs_vec.end(), sort_by_pair_second_lowest ); - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> Sorting the set of potential additional EMs " << std::endl; // now add in additional EMs until there are none left or it is no longer the case that Sum pT > calo @@ -777,13 +762,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) int new_EM = additional_EMs_vec.at( 0 ).first; - if ( Verbosity() > 5 ) + if ( Verbosity() > 5 ) std::cout << " -> adding EM " << new_EM << " ( dR = " << additional_EMs_vec.at( 0 ).second << " to the system (should not see it as orphan below)" << std::endl; // for now, just make the first HAD-linked track point to this new EM, and vice versa _pflow_EM_match_TRK.at( new_EM ).push_back( _pflow_HAD_match_TRK.at( had ).at( 0 ) ); _pflow_TRK_match_EM.at( _pflow_HAD_match_TRK.at( had ).at( 0 ) ).push_back( new_EM ); - + // add to expected calo total_EMHAD_E += _pflow_EM_E.at( new_EM ); @@ -792,28 +777,28 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) n_EM_added++; } - + if ( Verbosity() > 5) { if ( n_EM_added > 0 ) { std::cout << "After adding N = " << n_EM_added << " any additional EMs : " << std::endl; std::cout << "-> Total track Sum p = " << total_TRK_p << " , expected calo Sum E = " << total_expected_E << " +/- " << total_expected_E_err << " , observed EM+HAD Sum E = " << total_EMHAD_E << std::endl; } - else { + else { std::cout << "No additional EMs found, continuing hypothesis check" << std::endl; } } } - - - + + + if ( total_expected_E + _energy_match_Nsigma * total_expected_E_err > total_EMHAD_E ) { - + if ( Verbosity() > 5 ) { std::cout << " -> -> calo compatible within Nsigma = " << _energy_match_Nsigma << " , remove and keep tracks " << std::endl; } // PFlow elements already created from tracks above, no more needs to be done - + } else { float residual_energy = total_EMHAD_E - total_expected_E; @@ -824,9 +809,9 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) // create additional PFlow element (tracks already created above) ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume no mass, but could update to use K0L mass(?) - TLorentzVector tlv; tlv.SetPtEtaPhiM( residual_energy / cosh( _pflow_HAD_eta[ had ] ) , _pflow_HAD_eta[ had ] , _pflow_HAD_phi[ had ] , 0 ); + TLorentzVector tlv; tlv.SetPtEtaPhiM( residual_energy / cosh( _pflow_HAD_eta[ had ] ) , _pflow_HAD_eta[ had ] , _pflow_HAD_phi[ had ] , 0 ); pflow->set_px( tlv.Px() ); pflow->set_py( tlv.Py() ); @@ -843,13 +828,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } - } // close HAD loop + } // close HAD loop // TRK->EM removal - if ( Verbosity() > 2 ) + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : resolve TRK(s) -> EM(s) ( + no HAD) systems " << std::endl; - + for (unsigned int em = 0; em < _pflow_EM_E.size() ; em++ ) { // only consider EM with matched tracks, but no matched HADs @@ -859,7 +844,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " EM " << em << " with E / eta / phi = " << _pflow_EM_E.at( em ) << " / " << _pflow_EM_eta.at( em ) << " / " << _pflow_EM_phi.at( em ) << std::endl; } - + // setup for Sum-pT^trk -> calo prediction float total_TRK_p = 0; float total_expected_E = 0; @@ -867,7 +852,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) // begin with this EM calo energy float total_EM_E = _pflow_EM_E.at( em ); - + // iterate over the TRKs matched to this EM for (unsigned int j = 0 ; j < _pflow_EM_match_TRK.at( em ).size() ; j++) { @@ -876,7 +861,7 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " -> -> LINKED TRK with p / eta / phi = " << _pflow_TRK_p.at( trk ) << " / " << _pflow_TRK_eta.at( trk ) << " / " << _pflow_TRK_phi.at( trk ) << std::endl; } - + total_TRK_p += _pflow_TRK_p.at( trk ); std::pair expected_signature = get_expected_signature( trk ); @@ -887,15 +872,15 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " -> -> -> expected calo signature is " << expected_E_mean << " +/- " << expected_E_sigma << std::endl; } - + total_expected_E += expected_E_mean; total_expected_E_var += pow( expected_E_sigma , 2 ); // add PFlow element for each track ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume pion mass - TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_TRK_p[ trk ] / cosh( _pflow_TRK_eta[ trk ] ) , _pflow_TRK_eta[ trk ] , _pflow_TRK_phi[ trk ] , 0.135 ); + TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_TRK_p[ trk ] / cosh( _pflow_TRK_eta[ trk ] ) , _pflow_TRK_eta[ trk ] , _pflow_TRK_phi[ trk ] , 0.135 ); std::vector eclus; eclus.push_back(_pflow_EM_cluster.at(em)); @@ -915,21 +900,21 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } - // process compatibility of fit + // process compatibility of fit float total_expected_E_err = sqrt( total_expected_E_var ); if ( Verbosity() > 5 ) { std::cout << " -> Total track Sum p = " << total_TRK_p << " , expected calo Sum E = " << total_expected_E << " +/- " << total_expected_E_err << " , observed EM Sum E = " << total_EM_E << std::endl; } - + if ( total_expected_E + _energy_match_Nsigma * total_expected_E_err > total_EM_E ) { - + if ( Verbosity() > 5 ) { std::cout << " -> -> calo compatible within Nsigma = " << _energy_match_Nsigma << " , remove and keep tracks " << std::endl; } // PFlow elements already created from tracks above, no more needs to be done - + } else { float residual_energy = total_EM_E - total_expected_E; @@ -940,9 +925,9 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) // create additional PFlow element (tracks already created above) ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume no mass, but could update to use K0L mass(?) - TLorentzVector tlv; tlv.SetPtEtaPhiM( residual_energy / cosh( _pflow_EM_eta[ em ] ) , _pflow_EM_eta[ em ] , _pflow_EM_phi[ em ] , 0 ); + TLorentzVector tlv; tlv.SetPtEtaPhiM( residual_energy / cosh( _pflow_EM_eta[ em ] ) , _pflow_EM_eta[ em ] , _pflow_EM_phi[ em ] , 0 ); std::vector eclus; eclus.push_back(_pflow_EM_cluster.at(em)); @@ -962,13 +947,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) } - } // close EM loop + } // close EM loop // now remove unmatched elements - if ( Verbosity() > 2 ) + if ( Verbosity() > 2 ) std::cout << "ParticleFlowReco::process_event : remove TRK-unlinked EMs and HADs " << std::endl; - + for (unsigned int em = 0; em < _pflow_EM_E.size() ; em++ ) { // only consider EMs withOUT matched tracks ... we have dealt with the matched cases above @@ -977,13 +962,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " unmatched EM " << em << " with E / eta / phi = " << _pflow_EM_E.at( em ) << " / " << _pflow_EM_eta.at( em ) << " / " << _pflow_EM_phi.at( em ) << std::endl; } - - // add PFlow element for this EM + + // add PFlow element for this EM ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume massless, could be updated to use K0L - TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_EM_E[ em ] / cosh( _pflow_EM_eta[ em ] ) , _pflow_EM_eta[ em ] , _pflow_EM_phi[ em ] , 0 ); - + TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_EM_E[ em ] / cosh( _pflow_EM_eta[ em ] ) , _pflow_EM_eta[ em ] , _pflow_EM_phi[ em ] , 0 ); + std::vector eclus; eclus.push_back(_pflow_EM_cluster.at(em)); @@ -999,9 +984,9 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) pflowContainer->AddParticleFlowElement( global_pflow_index, pflow ); global_pflow_index++; - - - } // close EM loop + + + } // close EM loop for (unsigned int had = 0; had < _pflow_HAD_E.size() ; had++ ) { @@ -1011,13 +996,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) if ( Verbosity() > 5 ) { std::cout << " unmatched HAD " << had << " with E / eta / phi = " << _pflow_HAD_E.at( had ) << " / " << _pflow_HAD_eta.at( had ) << " / " << _pflow_HAD_phi.at( had ) << std::endl; } - - // add PFlow element for this HAD + + // add PFlow element for this HAD ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume massless, could be updated to use K0L - TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_HAD_E[ had ] / cosh( _pflow_HAD_eta[ had ] ) , _pflow_HAD_eta[ had ] , _pflow_HAD_phi[ had ] , 0 ); - + TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_HAD_E[ had ] / cosh( _pflow_HAD_eta[ had ] ) , _pflow_HAD_eta[ had ] , _pflow_HAD_phi[ had ] , 0 ); + pflow->set_px( tlv.Px() ); pflow->set_py( tlv.Py() ); pflow->set_pz( tlv.Pz() ); @@ -1030,25 +1015,25 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) pflowContainer->AddParticleFlowElement( global_pflow_index, pflow ); global_pflow_index++; - - - } // close HAD loop + + + } // close HAD loop for (unsigned int trk = 0; trk < _pflow_TRK_p.size() ; trk++ ) { - // only consider TRKs withOUT matched EM or HAD + // only consider TRKs withOUT matched EM or HAD if ( _pflow_TRK_match_EM.at( trk ).size() != 0 || _pflow_TRK_match_HAD.at( trk ).size() != 0 ) continue; if ( Verbosity() > 5 ) { std::cout << " unmatched TRK " << trk << " with p / eta / phi = " << _pflow_TRK_p.at( trk ) << " / " << _pflow_TRK_eta.at( trk ) << " / " << _pflow_TRK_phi.at( trk ) << std::endl; } - - // add PFlow element for this TRK + + // add PFlow element for this TRK ParticleFlowElement *pflow = new ParticleFlowElementv1(); - + // assume massless, could be updated to use K0L - TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_TRK_p[ trk ] / cosh( _pflow_TRK_eta[ trk ] ) , _pflow_TRK_eta[ trk ] , _pflow_TRK_phi[ trk ] , 0.135 ); - + TLorentzVector tlv; tlv.SetPtEtaPhiM( _pflow_TRK_p[ trk ] / cosh( _pflow_TRK_eta[ trk ] ) , _pflow_TRK_eta[ trk ] , _pflow_TRK_phi[ trk ] , 0.135 ); + pflow->set_px( tlv.Px() ); pflow->set_py( tlv.Py() ); pflow->set_pz( tlv.Pz() ); @@ -1061,13 +1046,13 @@ int ParticleFlowReco::process_event(PHCompositeNode *topNode) pflowContainer->AddParticleFlowElement( global_pflow_index, pflow ); global_pflow_index++; - - } // close TRK loop + + } // close TRK loop // DEBUG: print out all PFLow elements if ( Verbosity() > 5 ) { std::cout << "ParticleFlowReco::process_event: summary of PFlow objects " << std::endl; - + ParticleFlowElementContainer::ConstRange begin_end = pflowContainer->getParticleFlowElements(); for ( ParticleFlowElementContainer::ConstIterator hiter = begin_end.first; hiter != begin_end.second; ++hiter) { hiter->second->identify(); diff --git a/offline/packages/rawtodst/Makefile.am b/offline/packages/rawtodst/Makefile.am index 2a4e930d0d..2ad4ede40a 100644 --- a/offline/packages/rawtodst/Makefile.am +++ b/offline/packages/rawtodst/Makefile.am @@ -11,7 +11,9 @@ AM_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib64 pkginclude_HEADERS = \ - tpc_hits.h + tpc_hits.h \ + TPCMap.h \ + TPC_RawHit.h lib_LTLIBRARIES = \ librawtodst.la diff --git a/offline/packages/rawtodst/TPCMap.cc b/offline/packages/rawtodst/TPCMap.cc index 5139b5fc0f..20985104bf 100644 --- a/offline/packages/rawtodst/TPCMap.cc +++ b/offline/packages/rawtodst/TPCMap.cc @@ -40,13 +40,13 @@ void TPCMap::setMapNames(const std::string &r1, const std::string &r2, const std } } -int TPCMap::digest_map(const std::string &s, const unsigned int section_offset) +int TPCMap::digest_map(const std::string &fileName, const unsigned int section_offset) { - std::ifstream infile(s, std::ios::in); + std::ifstream infile(fileName, std::ios::in); if (!infile.is_open()) { - std::cout << "Could not open file " << std::endl; + std::cout << "Could not open file: "<< fileName << std::endl; _broken = 1; return -1; } @@ -174,6 +174,22 @@ unsigned int TPCMap::getLayer(const unsigned int FEE, const unsigned int FEEChan return itr->second.layer; } +unsigned int TPCMap::getPad(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int /* packetid */) const +{ + if (FEE >= 26 || FEEChannel > 255) + { + return 0.; + } + unsigned int key = 256 * FEE + FEEChannel; + + std::map::const_iterator itr = tmap.find(key); + if (itr == tmap.end()) + { + return -100; + } + return itr->second.padnr; +} + double TPCMap::getR(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int /* packetid */) const { if (FEE >= 26 || FEEChannel > 255) diff --git a/offline/packages/rawtodst/TPCMap.h b/offline/packages/rawtodst/TPCMap.h index 63e8c230b6..9dc230aec1 100644 --- a/offline/packages/rawtodst/TPCMap.h +++ b/offline/packages/rawtodst/TPCMap.h @@ -12,12 +12,13 @@ class TPCMap virtual ~TPCMap() = default; virtual unsigned int getLayer(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; + virtual unsigned int getPad(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; virtual double getR(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; virtual double getPhi(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; virtual void setMapNames(const std::string &r1, const std::string &r2, const std::string &r3); private: - int digest_map(const std::string &s, const unsigned int section_offset); + int digest_map(const std::string &fileName, const unsigned int section_offset); int _broken = 0; struct tpc_map diff --git a/offline/packages/rawtodst/tpc_hits.cc b/offline/packages/rawtodst/tpc_hits.cc index ec7be43442..f69d040bb1 100644 --- a/offline/packages/rawtodst/tpc_hits.cc +++ b/offline/packages/rawtodst/tpc_hits.cc @@ -2,6 +2,12 @@ #include "tpc_hits.h" #include +#include +#include +#include +#include + +#include #include #include #include @@ -19,22 +25,26 @@ #include -#include +#include +#include //____________________________________________________________________________.. tpc_hits::tpc_hits(const std::string &name) : SubsysReco(name) -{ + , hm(nullptr) + , _filename("./outputfile.root") + { std::cout << "tpc_hits::tpc_hits(const std::string &name)" << std::endl; starting_BCO = -1; rollover_value = 0; current_BCOBIN = 0; - M.setMapNames("AutoPad-R1-RevA.sch.ChannelMapping.csv", "AutoPad-R3-RevA.sch.ChannelMapping.csv", "AutoPad-R2-RevA-Pads.sch.ChannelMapping.csv"); + M.setMapNames("AutoPad-R1-RevA.sch.ChannelMapping.csv", "AutoPad-R2-RevA-Pads.sch.ChannelMapping.csv", "AutoPad-R3-RevA.sch.ChannelMapping.csv"); } //____________________________________________________________________________.. tpc_hits::~tpc_hits() { + delete hm; std::cout << "tpc_hits::~tpc_hits() Calling dtor" << std::endl; } @@ -42,14 +52,48 @@ tpc_hits::~tpc_hits() int tpc_hits::Init(PHCompositeNode * /*topNode*/) { std::cout << "tpc_hits::Init(PHCompositeNode *topNode) Initializing" << std::endl; + hm = new Fun4AllHistoManager("HITHIST"); + + _h_hit_XY = new TH2F("_h_hit_XY" ,"_h_hit_XY;X, [m];Y, [m]", 400, -800, 800, 400, -800, 800); + + hm->registerHisto(_h_hit_XY ); + return Fun4AllReturnCodes::EVENT_OK; } //____________________________________________________________________________.. int tpc_hits::InitRun(PHCompositeNode *topNode) { - // std::cout << "tpc_hits::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl; + // get dst node + PHNodeIterator iter(topNode); + auto dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << "tpc_hits::InitRun - DST Node missing, doing nothing." << std::endl; + exit(1); + } + + // create hitset container if needed + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + if (!hitsetcontainer) + { + std::cout << "tpc_hits::InitRun - creating TRKR_HITSET." << std::endl; + + // find or create TRKR node + PHNodeIterator dstiter(dstNode); + auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + if (!trkrnode) + { + trkrnode = new PHCompositeNode("TRKR"); + dstNode->addNode(trkrnode); + } + + // create container and add to the tree + hitsetcontainer = new TrkrHitSetContainerv1; + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + trkrnode->addNode(newNode); + } topNode->print(); // we reset the BCO for the new run @@ -57,7 +101,7 @@ int tpc_hits::InitRun(PHCompositeNode *topNode) rollover_value = 0; current_BCOBIN = 0; - m_hits = new TrkrHitSetContainerv1(); + //m_hits = new TrkrHitSetContainerv1(); return Fun4AllReturnCodes::EVENT_OK; } @@ -65,9 +109,15 @@ int tpc_hits::InitRun(PHCompositeNode *topNode) //____________________________________________________________________________.. int tpc_hits::process_event(PHCompositeNode *topNode) { - std::cout << "tpc_hits::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; + //std::cout << "tpc_hits::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; + // load relevant nodes + // Get the TrkrHitSetContainer node + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + assert(trkrhitsetcontainer); Event *_event = findNode::getClass(topNode, "PRDF"); + assert( _event ); + if (_event == nullptr) { std::cout << "tpc_hits::Process_Event - Event not found" << std::endl; @@ -78,61 +128,126 @@ int tpc_hits::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::DISCARDEVENT; } - Packet *p = _event->getPacket(4001); - if (!p) - { - return Fun4AllReturnCodes::DISCARDEVENT; - } + // check all possible TPC packets that we need to analyze + for(int ep=0;ep<2;ep++){ + for (int sector = 0; sector<=23; sector++) + { + const int packet = 4000 + sector*10 + ep; - int nr_of_waveforms = p->iValue(0, "NR_WF"); + // Reading packet + Packet *p = _event->getPacket(packet); - for (auto &l : m_hitset) - { - l = new TrkrHitSetv1(); + // Figure out which side + int side = 0; + if(sector>11) side=1; - int wf; - for (wf = 0; wf < nr_of_waveforms; wf++) + if (p) { - int current_BCO = p->iValue(wf, "BCO") + rollover_value; + std::cout << "tpc_hits:: Event getPacket: "<< packet << "| Sector"<< sector << "| EndPoint "<< ep << std::endl; + }else{ + continue; + } - if (starting_BCO < 0) - { - starting_BCO = current_BCO; - } + int nr_of_waveforms = p->iValue(0, "NR_WF"); - if (current_BCO < starting_BCO) // we have a rollover - { - rollover_value += 0x100000; - current_BCO = p->iValue(wf, "BCO") + rollover_value; - starting_BCO = current_BCO; - current_BCOBIN++; - } - int sampa_nr = p->iValue(wf, "SAMPAADDRESS"); - int channel = p->iValue(wf, "CHANNEL"); - int layer; - if (channel < 128) - { - layer = sampa_nr * 2; - } - else - { - layer = sampa_nr * 2 + 1; - } - m_hit = new TrkrHitv2(); - // mhit->setAdc( - int sector = 0; - int side = 0; - TrkrDefs::hitsetkey hitsetkey = TpcDefs::genHitSetKey(layer, sector, side); - TrkrHitSetContainer::Iterator hitsetit = m_hits->findOrAddHitSet(hitsetkey); - for (int s = 0; s < p->iValue(wf, "SAMPLES"); s++) + for (auto &l : m_hitset) + { + l = new TrkrHitSetv1(); + + int wf; + for (wf = 0; wf < nr_of_waveforms; wf++) { - int pad = 0; - TrkrDefs::hitkey hitkey = TpcDefs::genHitKey(pad, s + 2 * (current_BCO - starting_BCO)); - TrkrHit *hit = hitsetit->second->getHit(hitkey); - hit->setAdc(0); + int current_BCO = p->iValue(wf, "BCO") + rollover_value; + + if (starting_BCO < 0) + { + starting_BCO = current_BCO; + } + + if (current_BCO < starting_BCO) // we have a rollover + { + rollover_value += 0x100000; + current_BCO = p->iValue(wf, "BCO") + rollover_value; + starting_BCO = current_BCO; + current_BCOBIN++; + } + int sampa_nr = p->iValue(wf, "SAMPAADDRESS"); + int channel = p->iValue(wf, "CHANNEL"); + + int fee = p->iValue(wf, "FEE"); + int samples = p->iValue( wf, "SAMPLES" ); + // clockwise FEE mapping + //int FEE_map[26]={5, 6, 1, 3, 2, 12, 10, 11, 9, 8, 7, 1, 2, 4, 8, 7, 6, 5, 4, 3, 1, 3, 2, 4, 6, 5}; + int FEE_R[26]={2, 2, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3}; + // conter clockwise FEE mapping (From Takao) + int FEE_map[26]={3, 2, 5, 3, 4, 0, 2, 1, 3, 4, 5, 7, 6, 2, 0, 1, 0, 1, 4, 5, 11, 9, 10, 8, 6, 7}; + int pads_per_sector[3] = {96, 128, 192}; + + // setting the mapp of the FEE + int feeM = FEE_map[fee]-1; + if(FEE_R[fee]==2) feeM += 6; + if(FEE_R[fee]==3) feeM += 14; + int layer = M.getLayer(feeM, channel); + + double R = M.getR(feeM, channel); + double phi = M.getPhi(feeM, channel) + sector * M_PI / 6 ; + + TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(layer, sector, side); + TrkrHitSetContainer::Iterator hitsetit = trkrhitsetcontainer->findOrAddHitSet(tpcHitSetKey); + + if( Verbosity() ) + { + int sampaAddress = p->iValue(wf, "SAMPAADDRESS"); + int sampaChannel = p->iValue(wf, "SAMPACHANNEL"); + int checksum = p->iValue(wf, "CHECKSUM"); + int checksumError = p->iValue(wf, "CHECKSUMERROR"); + std::cout << "tpc_hits::Process_Event Samples "<< samples + <<" Chn:"<< channel + <<" layer: " << layer + << " sampa: "<< sampa_nr + << " fee: "<< fee + << " Mapped fee: "<< feeM + << " sampaAddress: "<< sampaAddress + << " sampaChannel: "<< sampaChannel + << " checksum: "<< checksum + << " checksumError: "<< checksumError + << " hitsetkey "<< tpcHitSetKey + << " R = " << R + << " phi = " << phi + << std::endl; + } + for (int s = 0; s < samples; s++) + { + int pad = M.getPad(feeM, channel); + int t = s + 2 * (current_BCO - starting_BCO); + int adc = p->iValue(wf,s); + // generate hit key + TrkrDefs::hitkey hitkey = TpcDefs::genHitKey((unsigned int) pad + sector*pads_per_sector[FEE_R[sector]-1], (unsigned int) t); + // find existing hit, or create + auto hit = hitsetit->second->getHit(hitkey); + + // create hit, assign adc and insert in hitset + if (!hit) + { + // create a new one + hit = new TrkrHitv2(); + hit->setAdc(adc); + hitsetit->second->addHitSpecificKey(hitkey, hit); + } + //else{ + // hit->setAdc(adc); + // hitsetit->second->addHitSpecificKey(hitkey, hit); + //} + + _h_hit_XY->Fill(R*cos(phi),R*sin(phi),adc); + + } + } } - } + + }// End of run over packets + }//End of ep loop // we skip the mapping to real pads at first. We just say // that we get 16 rows (segment R2) with 128 pads // so each FEE fills 2 rows. Not right, but one step at a time. @@ -141,35 +256,37 @@ int tpc_hits::process_event(PHCompositeNode *topNode) } //____________________________________________________________________________.. -int tpc_hits::ResetEvent(PHCompositeNode * /*topNode*/) -{ - std::cout << "tpc_hits::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} +//int tpc_hits::ResetEvent(PHCompositeNode * /*topNode*/) +//{ +// std::cout << "tpc_hits::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl; +// return Fun4AllReturnCodes::EVENT_OK; +//} //____________________________________________________________________________.. -int tpc_hits::EndRun(const int runnumber) -{ - std::cout << "tpc_hits::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} +//int tpc_hits::EndRun(const int runnumber) +//{ +// std::cout << "tpc_hits::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl; +// return Fun4AllReturnCodes::EVENT_OK; +//} //____________________________________________________________________________.. int tpc_hits::End(PHCompositeNode * /*topNode*/) { std::cout << "tpc_hits::End(PHCompositeNode *topNode) This is the End..." << std::endl; + hm->dumpHistos(_filename, "RECREATE"); + return Fun4AllReturnCodes::EVENT_OK; } //____________________________________________________________________________.. -int tpc_hits::Reset(PHCompositeNode * /*topNode*/) -{ - std::cout << "tpc_hits::Reset(PHCompositeNode *topNode) being Reset" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} +//int tpc_hits::Reset(PHCompositeNode * /*topNode*/) +//{ +// std::cout << "tpc_hits::Reset(PHCompositeNode *topNode) being Reset" << std::endl; +// return Fun4AllReturnCodes::EVENT_OK; +//} //____________________________________________________________________________.. -void tpc_hits::Print(const std::string &what) const -{ - std::cout << "tpc_hits::Print(const std::string &what) const Printing info for " << what << std::endl; -} +//void tpc_hits::Print(const std::string &what) const +//{ +// std::cout << "tpc_hits::Print(const std::string &what) const Printing info for " << what << std::endl; +//} diff --git a/offline/packages/rawtodst/tpc_hits.h b/offline/packages/rawtodst/tpc_hits.h index a82c4e8871..07b1a18302 100644 --- a/offline/packages/rawtodst/tpc_hits.h +++ b/offline/packages/rawtodst/tpc_hits.h @@ -6,14 +6,20 @@ #include "TPCMap.h" #include "TPC_RawHit.h" +#include +#include + #include +#include #include class PHCompositeNode; -class TrkrHitSetContainer; -class TrkrHitSet; -class TrkrHit; +class Fun4AllHistoManager; +//class TrkrHitSetContainer; +//class TrkrHitSet; +//class TrkrHit; +class TH2; class tpc_hits : public SubsysReco { @@ -37,26 +43,29 @@ class tpc_hits : public SubsysReco int process_event(PHCompositeNode *topNode) override; /// Clean up internals after each event. - int ResetEvent(PHCompositeNode *topNode) override; + //int ResetEvent(PHCompositeNode *topNode) override; /// Called at the end of each run. - int EndRun(const int runnumber) override; + //int EndRun(const int runnumber) override; /// Called at the end of all processing. int End(PHCompositeNode *topNode) override; /// Reset - int Reset(PHCompositeNode * /*topNode*/) override; + //int Reset(PHCompositeNode * /*topNode*/) override; - void Print(const std::string &what = "ALL") const override; + //void Print(const std::string &what = "ALL") const override; protected: + Fun4AllHistoManager *hm = nullptr; + std::string _filename; + static const int layercount = 16; static const int layeroffset = 7 + 16; - TrkrHitSetContainer *m_hits = nullptr; + //TrkrHitSetContainer *m_hits = nullptr; TrkrHitSet *m_hitset[layercount] = {}; - TrkrHit *m_hit = nullptr; + //TrkrHit *m_hit = nullptr; // RawHitSetContainer *m_rawhits __attribute__ ((unused)) = nullptr; @@ -65,6 +74,11 @@ class tpc_hits : public SubsysReco int starting_BCO; int rollover_value; int current_BCOBIN; + + private: + + TH2* _h_hit_XY = nullptr; + }; #endif // TPC_HITS_H diff --git a/offline/packages/tpc/Makefile.am b/offline/packages/tpc/Makefile.am index d44c81b744..9e523aaa25 100644 --- a/offline/packages/tpc/Makefile.am +++ b/offline/packages/tpc/Makefile.am @@ -10,7 +10,7 @@ lib_LTLIBRARIES = \ AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ - -I$(ROOTSYS)/include + -isystem$(ROOTSYS)/include AM_LDFLAGS = \ -L$(libdir) \ @@ -19,6 +19,7 @@ AM_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib64 pkginclude_HEADERS = \ + TpcRawDataTree.h \ TpcClusterCleaner.h \ TpcClusterizer.h \ TpcClusterMover.h \ @@ -26,6 +27,8 @@ pkginclude_HEADERS = \ TpcDistortionCorrection.h \ TpcDistortionCorrectionContainer.h \ TpcLoadDistortionCorrection.h \ + TpcMap.h \ + TpcRawDataDecoder.h \ TpcRawWriter.h \ TpcSimpleClusterizer.h @@ -33,9 +36,12 @@ pcmdir = $(libdir) # sources for tpc library libtpc_la_SOURCES = \ + TpcRawDataTree.cc \ TpcClusterCleaner.cc \ TpcClusterizer.cc \ TpcLoadDistortionCorrection.cc \ + TpcMap.cc \ + TpcRawDataDecoder.cc \ TpcRawWriter.cc \ TpcSimpleClusterizer.cc diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 73e8372e46..05467c81c1 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -2,22 +2,23 @@ #include #include +#include #include #include #include -#include #include // for hitkey, getLayer #include #include #include +#include #include #include -#include #include +#include #include -#include // for SubsysReco +#include // for SubsysReco #include #include @@ -26,10 +27,10 @@ #include #include -#include // for PHIODataNode -#include // for PHNode +#include // for PHIODataNode +#include // for PHNode #include -#include // for PHObject +#include // for PHObject #include #include // for PHWHERE @@ -37,23 +38,28 @@ #include // for TMatrixT, ope... #include // for TMatrixTRow -#include +#include +#include +#include #include // for sqrt, cos, sin #include +#include #include // for _Rb_tree_cons... #include #include // for pair -#include #include -#include // Terra incognita.... #include -namespace +namespace { - template inline constexpr T square( const T& x ) { return x*x; } - + template + inline constexpr T square(const T &x) + { + return x * x; + } + using assoc = std::pair; struct ihit @@ -64,7 +70,7 @@ namespace unsigned short edge = 0; }; - struct thread_data + struct thread_data { PHG4TpcCylinderGeom *layergeom = nullptr; TrkrHitSet *hitset = nullptr; @@ -92,405 +98,443 @@ namespace double sampa_tbias = 0; int cluster_version = 4; std::vector association_vector; - std::vector cluster_vector; + std::vector cluster_vector; int verbosity = 0; }; - + pthread_mutex_t mythreadlock; - + void remove_hit(double adc, int phibin, int tbin, int edge, std::multimap &all_hit_map, std::vector> &adcval) { typedef std::multimap::iterator hit_iterator; std::pair iterpair = all_hit_map.equal_range(adc); hit_iterator it = iterpair.first; - for (; it != iterpair.second; ++it) { - if (it->second.iphi == phibin && it->second.it == tbin) { - all_hit_map.erase(it); - break; + for (; it != iterpair.second; ++it) + { + if (it->second.iphi == phibin && it->second.it == tbin) + { + all_hit_map.erase(it); + break; } } - if(edge) + if (edge) adcval[phibin][tbin] = USHRT_MAX; else adcval[phibin][tbin] = 0; } - - void remove_hits(std::vector &ihit_list, std::multimap &all_hit_map,std::vector> &adcval) + + void remove_hits(std::vector &ihit_list, std::multimap &all_hit_map, std::vector> &adcval) { - for(auto iter = ihit_list.begin(); iter != ihit_list.end();++iter){ - unsigned short adc = iter->adc; + for (auto iter = ihit_list.begin(); iter != ihit_list.end(); ++iter) + { + unsigned short adc = iter->adc; unsigned short phibin = iter->iphi; - unsigned short tbin = iter->it; - unsigned short edge = iter->edge; - remove_hit(adc,phibin,tbin,edge,all_hit_map,adcval); + unsigned short tbin = iter->it; + unsigned short edge = iter->edge; + remove_hit(adc, phibin, tbin, edge, all_hit_map, adcval); } } - - void find_t_range(int phibin, int tbin, const thread_data& my_data, const std::vector> &adcval, int& tdown, int& tup, int &touch, int &edge){ - - const int FitRangeT= (int) my_data.maxHalfSizeT; + + void find_t_range(int phibin, int tbin, const thread_data &my_data, const std::vector> &adcval, int &tdown, int &tup, int &touch, int &edge) + { + const int FitRangeT = (int) my_data.maxHalfSizeT; const int NTBinsMax = (int) my_data.tbins; tup = 0; tdown = 0; - for(int it=0; it< FitRangeT; it++){ + for (int it = 0; it < FitRangeT; it++) + { int ct = tbin + it; - - if(ct <= 0 || ct >= NTBinsMax){ - // tup = it; - edge++; - break; // truncate edge + + if (ct <= 0 || ct >= NTBinsMax) + { + // tup = it; + edge++; + break; // truncate edge } - - if(adcval[phibin][ct] <= 0) { - break; + + if (adcval[phibin][ct] <= 0) + { + break; } - if(adcval[phibin][ct] == USHRT_MAX) { - touch++; - break; + if (adcval[phibin][ct] == USHRT_MAX) + { + touch++; + break; } - //check local minima and break at minimum. - if(ct= NTBinsMax){ - // tdown = it; - edge++; - break; // truncate edge + if (ct <= 0 || ct >= NTBinsMax) + { + // tdown = it; + edge++; + break; // truncate edge } - if(adcval[phibin][ct] <= 0) { - break; + if (adcval[phibin][ct] <= 0) + { + break; } - if(adcval[phibin][ct] == USHRT_MAX) { - touch++; - break; + if (adcval[phibin][ct] == USHRT_MAX) + { + touch++; + break; } - if(ct>4){//make sure we stay clear from the edge - if(adcval[phibin][ct]+adcval[phibin][ct-1] < - adcval[phibin][ct-2]+adcval[phibin][ct-3]){//rising again - tdown = it+1; - touch++; - break; - } + if (ct > 4) + { // make sure we stay clear from the edge + if (adcval[phibin][ct] + adcval[phibin][ct - 1] < + adcval[phibin][ct - 2] + adcval[phibin][ct - 3]) + { // rising again + tdown = it + 1; + touch++; + break; + } } tdown = it; } return; } - - void find_phi_range(int phibin, int tbin, const thread_data& my_data, const std::vector> &adcval, int& phidown, int& phiup, int &touch, int &edge) + + void find_phi_range(int phibin, int tbin, const thread_data &my_data, const std::vector> &adcval, int &phidown, int &phiup, int &touch, int &edge) { - int FitRangePHI = (int) my_data.maxHalfSizePhi; int NPhiBinsMax = (int) my_data.phibins; phidown = 0; phiup = 0; - for(int iphi=0; iphi< FitRangePHI; iphi++){ + for (int iphi = 0; iphi < FitRangePHI; iphi++) + { int cphi = phibin + iphi; - if(cphi < 0 || cphi >= NPhiBinsMax){ - // phiup = iphi; - edge++; - break; // truncate edge + if (cphi < 0 || cphi >= NPhiBinsMax) + { + // phiup = iphi; + edge++; + break; // truncate edge } - - //break when below minimum - if(adcval[cphi][tbin] <= 0) { - // phiup = iphi; - break; + + // break when below minimum + if (adcval[cphi][tbin] <= 0) + { + // phiup = iphi; + break; } - if(adcval[cphi][tbin] == USHRT_MAX) { - touch++; - break; + if (adcval[cphi][tbin] == USHRT_MAX) + { + touch++; + break; } - //check local minima and break at minimum. - if(cphi= NPhiBinsMax){ - // phidown = iphi; - edge++; - break; // truncate edge + if (cphi < 0 || cphi >= NPhiBinsMax) + { + // phidown = iphi; + edge++; + break; // truncate edge } - - if(adcval[cphi][tbin] <= 0) { - //phidown = iphi; - break; + + if (adcval[cphi][tbin] <= 0) + { + // phidown = iphi; + break; } - if(adcval[cphi][tbin] == USHRT_MAX) { - touch++; - break; + if (adcval[cphi][tbin] == USHRT_MAX) + { + touch++; + break; } - if(cphi>4){//make sure we stay clear from the edge - if(adcval[cphi][tbin]+adcval[cphi-1][tbin] < - adcval[cphi-2][tbin]+adcval[cphi-3][tbin]){//rising again - phidown = iphi+1; - touch++; - break; - } + if (cphi > 4) + { // make sure we stay clear from the edge + if (adcval[cphi][tbin] + adcval[cphi - 1][tbin] < + adcval[cphi - 2][tbin] + adcval[cphi - 3][tbin]) + { // rising again + phidown = iphi + 1; + touch++; + break; + } } phidown = iphi; } return; } - - void get_cluster(int phibin, int tbin, const thread_data& my_data, const std::vector> &adcval, std::vector &ihit_list, int &touch, int &edge) - { - // search along phi at the peak in t - - int tup =0; - int tdown =0; - find_t_range(phibin, tbin, my_data, adcval, tdown, tup, touch, edge); - //now we have the t extent of the cluster, go find the phi edges - - for(int it=tbin - tdown ; it<= tbin + tup; it++){ - int phiup = 0; - int phidown = 0; - find_phi_range(phibin, it, my_data, adcval, phidown, phiup, touch, edge); - for (int iphi = phibin - phidown; iphi <= (phibin + phiup); iphi++){ - if(adcval[iphi][it]>0 && adcval[iphi][it]!=USHRT_MAX){ - ihit hit; - hit.iphi = iphi; - hit.it = it; - hit.adc = adcval[iphi][it]; - if(touch>0){ - if((iphi == (phibin - phidown))|| - (iphi == (phibin + phiup))){ - hit.edge = 1; - } - } - ihit_list.push_back(hit); - } - } - } - return; - } - - void calc_cluster_parameter(const std::vector &ihit_list, thread_data& my_data, int ntouch, int nedge ) + + void get_cluster(int phibin, int tbin, const thread_data &my_data, const std::vector> &adcval, std::vector &ihit_list, int &touch, int &edge) + { + // search along phi at the peak in t + + int tup = 0; + int tdown = 0; + find_t_range(phibin, tbin, my_data, adcval, tdown, tup, touch, edge); + // now we have the t extent of the cluster, go find the phi edges + + for (int it = tbin - tdown; it <= tbin + tup; it++) { - // - // get z range from layer geometry - /* these are used for rescaling the drift velocity */ - //const double z_min = -105.5; - //const double z_max = 105.5; - // std::cout << "calc clus" << std::endl; - // loop over the hits in this cluster - double t_sum = 0.0; - //double phi_sum = 0.0; - double adc_sum = 0.0; - double t2_sum = 0.0; - // double phi2_sum = 0.0; - - double iphi_sum = 0.0; - double iphi2_sum = 0.0; - - double radius = my_data.layergeom->get_radius(); // returns center of layer - - int phibinhi = -1; - int phibinlo = 666666; - int tbinhi = -1; - int tbinlo = 666666; - int clus_size = ihit_list.size(); - int max_adc = 0; - if(clus_size == 1) return; - // std::cout << "process list" << std::endl; - std::vector hitkeyvec; - for(auto iter = ihit_list.begin(); iter != ihit_list.end();++iter){ - double adc = iter->adc; - - if (adc <= 0) continue; - if(adc > max_adc) - max_adc = adc; - int iphi = iter->iphi + my_data.phioffset; - int it = iter->it + my_data.toffset; - if(iphi > phibinhi) phibinhi = iphi; - if(iphi < phibinlo) phibinlo = iphi; - if(it > tbinhi) tbinhi = it; - if(it < tbinlo) tbinlo = it; - - // update phi sums - // double phi_center = my_data.layergeom->get_phicenter(iphi); - - //phi_sum += phi_center * adc; - //phi2_sum += square(phi_center)*adc; - // std::cout << "phi_center: " << phi_center << " adc: " << adc <get_zcenter(it); - t_sum += t*adc; - t2_sum += square(t)*adc; - - adc_sum += adc; - - // capture the hitkeys for all adc values above a certain threshold - TrkrDefs::hitkey hitkey = TpcDefs::genHitKey(iphi, it); - // if(adc>5) - hitkeyvec.push_back(hitkey); - } - // std::cout << "done process list" << std::endl; - if (adc_sum < 10){ - hitkeyvec.clear(); - return; // skip obvious noise "clusters" - } - // This is the global position - double clusiphi = iphi_sum / adc_sum; - double clusphi = my_data.layergeom->get_phi(clusiphi); - - float clusx = radius * cos(clusphi); - float clusy = radius * sin(clusphi); - double clust = t_sum / adc_sum; - // needed for surface identification - double zdriftlength = clust * my_data.tGeometry->get_drift_velocity(); - // convert z drift length to z position in the TPC - double clusz = my_data.m_tdriftmax * my_data.tGeometry->get_drift_velocity() - zdriftlength; - if(my_data.side == 0) - clusz = -clusz; - - const double phi_cov = (iphi2_sum/adc_sum - square(clusiphi))* pow(my_data.layergeom->get_phistep(),2); - const double t_cov = t2_sum/adc_sum - square(clust); - - // Get the surface key to find the surface from the - TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey( my_data.layer, my_data.sector, my_data.side ); - Acts::Vector3 global(clusx, clusy, clusz); - TrkrDefs::subsurfkey subsurfkey = 0; - - Surface surface = my_data.tGeometry->get_tpc_surface_from_coords( - tpcHitSetKey, - global, - subsurfkey); - - if(!surface) - { - /// If the surface can't be found, we can't track with it. So - /// just return and don't add the cluster to the container - hitkeyvec.clear(); - return; - } - - // Estimate the errors - const double phi_err_square = (phibinhi == phibinlo) ? - square(radius*my_data.layergeom->get_phistep())/12: - square(radius)*phi_cov/(adc_sum*0.14); - - const double t_err_square = (tbinhi == tbinlo) ? - square(my_data.layergeom->get_zstep())/12: - t_cov/(adc_sum*0.14); - - char tsize = tbinhi - tbinlo + 1; - char phisize = phibinhi - phibinlo + 1; - // phi_cov = (weighted mean of dphi^2) - (weighted mean of dphi)^2, which is essentially the weighted mean of dphi^2. The error is then: - // e_phi = sigma_dphi/sqrt(N) = sqrt( sigma_dphi^2 / N ) -- where N is the number of samples of the distribution with standard deviation sigma_dphi - // - N is the number of electrons that drift to the readout plane - // We have to convert (sum of adc units for all bins in the cluster) to number of ionization electrons N - // Conversion gain is 20 mV/fC - relates total charge collected on pad to PEAK voltage out of ADC. The GEM gain is assumed to be 2000 - // To get equivalent charge per T bin, so that summing ADC input voltage over all T bins returns total input charge, divide voltages by 2.4 for 80 ns SAMPA - // Equivalent charge per T bin is then (ADU x 2200 mV / 1024) / 2.4 x (1/20) fC/mV x (1/1.6e-04) electrons/fC x (1/2000) = ADU x 0.14 - - // SAMPA shaping bias correction - clust = clust + my_data.sampa_tbias; - - /// convert to Acts units - global *= Acts::UnitConstants::cm; - //std::cout << "transform" << std::endl; - Acts::Vector3 local = surface->transform(my_data.tGeometry->geometry().getGeoContext()).inverse() * global; - local /= Acts::UnitConstants::cm; - //std::cout << "done transform" << std::endl; - // we need the cluster key and all associated hit keys (note: the cluster key includes the hitset key) - - if(my_data.cluster_version==3){ - // std::cout << "ver3" << std::endl; - // Fill in the cluster details - //================ - auto clus = new TrkrClusterv3; - //auto clus = std::make_unique(); - clus->setAdc(adc_sum); - clus->setSubSurfKey(subsurfkey); - clus->setLocalX(local(0)); - clus->setLocalY(clust); - clus->setActsLocalError(0,0, phi_err_square); - clus->setActsLocalError(1,0, 0); - clus->setActsLocalError(0,1, 0); - clus->setActsLocalError(1,1, t_err_square * pow(my_data.tGeometry->get_drift_velocity(),2)); - my_data.cluster_vector.push_back(clus); - }else if(my_data.cluster_version==4){ - // std::cout << "ver4" << std::endl; - // std::cout << "clus num" << my_data.cluster_vector.size() << " X " << local(0) << " Y " << clust << std::endl; - if(sqrt(phi_err_square) > 0.01){ - auto clus = new TrkrClusterv4; - //auto clus = std::make_unique(); - clus->setAdc(adc_sum); - clus->setMaxAdc(max_adc); - clus->setOverlap(ntouch); - clus->setEdge(nedge); - clus->setPhiSize(phisize); - clus->setZSize(tsize); - clus->setSubSurfKey(subsurfkey); - clus->setLocalX(local(0)); - clus->setLocalY(clust); - // clus->setPhiErr(sqrt(phi_err_square)); - //clus->setZErr(sqrt(t_err_square * pow(my_data.tGeometry->get_drift_velocity(),2))); - my_data.cluster_vector.push_back(clus); - } - }else if(my_data.cluster_version==5){ - // std::cout << "clus num" << my_data.cluster_vector.size() << " X " << local(0) << " Y " << clust << std::endl; - if(sqrt(phi_err_square) > 0.01){ - auto clus = new TrkrClusterv5; - //auto clus = std::make_unique(); - clus->setAdc(adc_sum); - clus->setMaxAdc(max_adc); - clus->setEdge(nedge); - clus->setPhiSize(phisize); - clus->setZSize(tsize); - clus->setSubSurfKey(subsurfkey); - clus->setLocalX(local(0)); - clus->setLocalY(clust); - clus->setPhiError(sqrt(phi_err_square)); - clus->setZError(sqrt(t_err_square * pow(my_data.tGeometry->get_drift_velocity(),2))); - my_data.cluster_vector.push_back(clus); - } - } - - //std::cout << "end clus out" << std::endl; - // if(my_data.do_assoc && my_data.clusterhitassoc){ - if(my_data.do_assoc) - { - // get cluster index in vector. It is used to store associations, and build relevant cluster keys when filling the containers - uint32_t index = my_data.cluster_vector.size()-1; - for (unsigned int i = 0; i < hitkeyvec.size(); i++){ - my_data.association_vector.emplace_back(index, hitkeyvec[i]); + int phiup = 0; + int phidown = 0; + find_phi_range(phibin, it, my_data, adcval, phidown, phiup, touch, edge); + for (int iphi = phibin - phidown; iphi <= (phibin + phiup); iphi++) + { + if (adcval[iphi][it] > 0 && adcval[iphi][it] != USHRT_MAX) + { + ihit hit; + hit.iphi = iphi; + hit.it = it; + hit.adc = adcval[iphi][it]; + if (touch > 0) + { + if ((iphi == (phibin - phidown)) || + (iphi == (phibin + phiup))) + { + hit.edge = 1; + } + } + ihit_list.push_back(hit); } } + } + return; + } + + void calc_cluster_parameter(const std::vector &ihit_list, thread_data &my_data, int ntouch, int nedge) + { + // + // get z range from layer geometry + /* these are used for rescaling the drift velocity */ + // const double z_min = -105.5; + // const double z_max = 105.5; + // std::cout << "calc clus" << std::endl; + // loop over the hits in this cluster + double t_sum = 0.0; + // double phi_sum = 0.0; + double adc_sum = 0.0; + double t2_sum = 0.0; + // double phi2_sum = 0.0; + + double iphi_sum = 0.0; + double iphi2_sum = 0.0; + + double radius = my_data.layergeom->get_radius(); // returns center of layer + + int phibinhi = -1; + int phibinlo = 666666; + int tbinhi = -1; + int tbinlo = 666666; + int clus_size = ihit_list.size(); + int max_adc = 0; + if (clus_size == 1) return; + // std::cout << "process list" << std::endl; + std::vector hitkeyvec; + for (auto iter = ihit_list.begin(); iter != ihit_list.end(); ++iter) + { + double adc = iter->adc; + + if (adc <= 0) continue; + if (adc > max_adc) + max_adc = adc; + int iphi = iter->iphi + my_data.phioffset; + int it = iter->it + my_data.toffset; + if (iphi > phibinhi) phibinhi = iphi; + if (iphi < phibinlo) phibinlo = iphi; + if (it > tbinhi) tbinhi = it; + if (it < tbinlo) tbinlo = it; + + // update phi sums + // double phi_center = my_data.layergeom->get_phicenter(iphi); + + // phi_sum += phi_center * adc; + // phi2_sum += square(phi_center)*adc; + // std::cout << "phi_center: " << phi_center << " adc: " << adc <get_zcenter(it); + t_sum += t * adc; + t2_sum += square(t) * adc; + + adc_sum += adc; + + // capture the hitkeys for all adc values above a certain threshold + TrkrDefs::hitkey hitkey = TpcDefs::genHitKey(iphi, it); + // if(adc>5) + hitkeyvec.push_back(hitkey); + } + // std::cout << "done process list" << std::endl; + if (adc_sum < 10) + { + hitkeyvec.clear(); + return; // skip obvious noise "clusters" + } + // This is the global position + double clusiphi = iphi_sum / adc_sum; + double clusphi = my_data.layergeom->get_phi(clusiphi); + + float clusx = radius * cos(clusphi); + float clusy = radius * sin(clusphi); + double clust = t_sum / adc_sum; + // needed for surface identification + double zdriftlength = clust * my_data.tGeometry->get_drift_velocity(); + // convert z drift length to z position in the TPC + double clusz = my_data.m_tdriftmax * my_data.tGeometry->get_drift_velocity() - zdriftlength; + if (my_data.side == 0) + clusz = -clusz; + + const double phi_cov = (iphi2_sum / adc_sum - square(clusiphi)) * pow(my_data.layergeom->get_phistep(), 2); + const double t_cov = t2_sum / adc_sum - square(clust); + + // Get the surface key to find the surface from the + TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(my_data.layer, my_data.sector, my_data.side); + Acts::Vector3 global(clusx, clusy, clusz); + TrkrDefs::subsurfkey subsurfkey = 0; + + Surface surface = my_data.tGeometry->get_tpc_surface_from_coords( + tpcHitSetKey, + global, + subsurfkey); + + if (!surface) + { + /// If the surface can't be found, we can't track with it. So + /// just return and don't add the cluster to the container hitkeyvec.clear(); - // std::cout << "done calc" << std::endl; + return; + } + + // Estimate the errors + const double phi_err_square = (phibinhi == phibinlo) ? square(radius * my_data.layergeom->get_phistep()) / 12 : square(radius) * phi_cov / (adc_sum * 0.14); + + const double t_err_square = (tbinhi == tbinlo) ? square(my_data.layergeom->get_zstep()) / 12 : t_cov / (adc_sum * 0.14); + + char tsize = tbinhi - tbinlo + 1; + char phisize = phibinhi - phibinlo + 1; + // phi_cov = (weighted mean of dphi^2) - (weighted mean of dphi)^2, which is essentially the weighted mean of dphi^2. The error is then: + // e_phi = sigma_dphi/sqrt(N) = sqrt( sigma_dphi^2 / N ) -- where N is the number of samples of the distribution with standard deviation sigma_dphi + // - N is the number of electrons that drift to the readout plane + // We have to convert (sum of adc units for all bins in the cluster) to number of ionization electrons N + // Conversion gain is 20 mV/fC - relates total charge collected on pad to PEAK voltage out of ADC. The GEM gain is assumed to be 2000 + // To get equivalent charge per T bin, so that summing ADC input voltage over all T bins returns total input charge, divide voltages by 2.4 for 80 ns SAMPA + // Equivalent charge per T bin is then (ADU x 2200 mV / 1024) / 2.4 x (1/20) fC/mV x (1/1.6e-04) electrons/fC x (1/2000) = ADU x 0.14 + + // SAMPA shaping bias correction + clust = clust + my_data.sampa_tbias; + + /// convert to Acts units + global *= Acts::UnitConstants::cm; + // std::cout << "transform" << std::endl; + Acts::Vector3 local = surface->transform(my_data.tGeometry->geometry().getGeoContext()).inverse() * global; + local /= Acts::UnitConstants::cm; + // std::cout << "done transform" << std::endl; + // we need the cluster key and all associated hit keys (note: the cluster key includes the hitset key) + + if (my_data.cluster_version == 3) + { + // std::cout << "ver3" << std::endl; + // Fill in the cluster details + //================ + auto clus = new TrkrClusterv3; + // auto clus = std::make_unique(); + clus->setAdc(adc_sum); + clus->setSubSurfKey(subsurfkey); + clus->setLocalX(local(0)); + clus->setLocalY(clust); + clus->setActsLocalError(0, 0, phi_err_square); + clus->setActsLocalError(1, 0, 0); + clus->setActsLocalError(0, 1, 0); + clus->setActsLocalError(1, 1, t_err_square * pow(my_data.tGeometry->get_drift_velocity(), 2)); + my_data.cluster_vector.push_back(clus); + } + else if (my_data.cluster_version == 4) + { + // std::cout << "ver4" << std::endl; + // std::cout << "clus num" << my_data.cluster_vector.size() << " X " << local(0) << " Y " << clust << std::endl; + if (sqrt(phi_err_square) > 0.01) + { + auto clus = new TrkrClusterv4; + // auto clus = std::make_unique(); + clus->setAdc(adc_sum); + clus->setMaxAdc(max_adc); + clus->setOverlap(ntouch); + clus->setEdge(nedge); + clus->setPhiSize(phisize); + clus->setZSize(tsize); + clus->setSubSurfKey(subsurfkey); + clus->setLocalX(local(0)); + clus->setLocalY(clust); + // clus->setPhiErr(sqrt(phi_err_square)); + // clus->setZErr(sqrt(t_err_square * pow(my_data.tGeometry->get_drift_velocity(),2))); + my_data.cluster_vector.push_back(clus); + } + } + else if (my_data.cluster_version == 5) + { + // std::cout << "ver5" << std::endl; + // std::cout << "clus num" << my_data.cluster_vector.size() << " X " << local(0) << " Y " << clust << std::endl; + if (sqrt(phi_err_square) > 0.01) + { + auto clus = new TrkrClusterv5; + // auto clus = std::make_unique(); + clus->setAdc(adc_sum); + clus->setMaxAdc(max_adc); + clus->setEdge(nedge); + clus->setPhiSize(phisize); + clus->setZSize(tsize); + clus->setSubSurfKey(subsurfkey); + clus->setLocalX(local(0)); + clus->setLocalY(clust); + clus->setPhiError(sqrt(phi_err_square)); + clus->setZError(sqrt(t_err_square * pow(my_data.tGeometry->get_drift_velocity(), 2))); + my_data.cluster_vector.push_back(clus); + } + } + + // std::cout << "end clus out" << std::endl; + // if(my_data.do_assoc && my_data.clusterhitassoc){ + if (my_data.do_assoc) + { + // get cluster index in vector. It is used to store associations, and build relevant cluster keys when filling the containers + uint32_t index = my_data.cluster_vector.size() - 1; + for (unsigned int i = 0; i < hitkeyvec.size(); i++) + { + my_data.association_vector.emplace_back(index, hitkeyvec[i]); + } } - - void ProcessSectorData(thread_data* my_data) { - - const auto& pedestal = my_data->pedestal; - const auto& phibins = my_data->phibins; - const auto& phioffset = my_data->phioffset; - const auto& tbins = my_data->tbins ; - const auto& toffset = my_data->toffset ; - const auto& layer = my_data->layer ; + hitkeyvec.clear(); + // std::cout << "done calc" << std::endl; + } + + void ProcessSectorData(thread_data *my_data) + { + const auto &pedestal = my_data->pedestal; + const auto &phibins = my_data->phibins; + const auto &phioffset = my_data->phioffset; + const auto &tbins = my_data->tbins; + const auto &toffset = my_data->toffset; + const auto &layer = my_data->layer; // int nhits = 0; // for convenience, create a 2D vector to store adc values in and initialize to zero std::vector> adcval(phibins, std::vector(tbins, 0)); @@ -499,195 +543,300 @@ namespace int tbinmax = 498; int tbinmin = 0; - if(my_data->do_wedge_emulation){ - if(layer>=7 && layer <22){ - int etacut = 249 - ((50+(layer-7))/105.5)*249; - tbinmin = etacut; - tbinmax -= etacut; + if (my_data->do_wedge_emulation) + { + if (layer >= 7 && layer < 22) + { + int etacut = 249 - ((50 + (layer - 7)) / 105.5) * 249; + tbinmin = etacut; + tbinmax -= etacut; } - if(layer>=22 && layer <=48){ - int etacut = 249 - ((65+((40.5/26)*(layer-22)))/105.5)*249; - tbinmin = etacut; - tbinmax -= etacut; + if (layer >= 22 && layer <= 48) + { + int etacut = 249 - ((65 + ((40.5 / 26) * (layer - 22))) / 105.5) * 249; + tbinmin = etacut; + tbinmax -= etacut; } } - if( my_data->hitset!=nullptr){ - TrkrHitSet *hitset = my_data->hitset; - TrkrHitSet::ConstRange hitrangei = hitset->getHits(); - - for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr){ - - if( TpcDefs::getPad(hitr->first) - phioffset < 0 ){ - //std::cout << "WARNING phibin out of range: " << TpcDefs::getPad(hitr->first) - phioffset << " | " << phibins << std::endl; - continue; - } - if( TpcDefs::getTBin(hitr->first) - toffset < 0 ){ - //std::cout << "WARNING tbin out of range: " << TpcDefs::getTBin(hitr->first) - toffset << " | " << tbins <first) - phioffset; - unsigned short tbin = TpcDefs::getTBin(hitr->first) - toffset; - unsigned short tbinorg = TpcDefs::getTBin(hitr->first); - if(phibin>=phibins){ - //std::cout << "WARNING phibin out of range: " << phibin << " | " << phibins << std::endl; - continue; - } - if(tbin>=tbins){ - //std::cout << "WARNING z bin out of range: " << tbin << " | " << tbins << std::endl; - continue; - } - if(tbinorg>tbinmax||tbinorgsecond->getAdc()) - pedestal; // proper int rounding +0.5 - unsigned short adc = 0; - if(fadc>0) adc = (unsigned short) fadc; - if(phibin >= phibins) continue; - if(tbin >= tbins) continue; // tbin is unsigned int, <0 cannot happen - - if(adc>0){ - if(adc>(5+my_data->threshold)){ - ihit thisHit; - - thisHit.iphi = phibin; - thisHit.it = tbin; - thisHit.adc = adc; - thisHit.edge = 0; - all_hit_map.insert(std::make_pair(adc, thisHit)); - } - if(adc>my_data->threshold){ - adcval[phibin][tbin] = (unsigned short) adc; - } - } - } - }else if( my_data->rawhitset!=nullptr){ + if (my_data->hitset != nullptr) + { + if (dynamic_cast(my_data->hitset)) + { + // TPC specific hit set format + + TrkrHitSetTpc *hitset = dynamic_cast(my_data->hitset); + assert(hitset); + + const TrkrHitSetTpc::TimeFrameADCDataType &dataframe = hitset->getTimeFrameAdcData(); + + for (unsigned int local_pad = 0; local_pad < dataframe.size(); ++local_pad) + { + const std::vector &pad_data = dataframe[local_pad]; + + for (unsigned int local_tbin = 0; local_tbin < pad_data.size(); ++local_tbin) + { + const TpcDefs::ADCDataType &rawadc = pad_data[local_tbin]; + TrkrDefs::hitkey hitkey = hitset->getHitKeyfromLocalBin(local_pad, local_tbin); + + if (TpcDefs::getPad(hitkey) - phioffset < 0) + { + std::cout << __PRETTY_FUNCTION__ << ": WARNING phibin out of range: " << TpcDefs::getPad(hitkey) - phioffset << " | " << phibins << std::endl; + continue; + } + if (TpcDefs::getTBin(hitkey) - toffset < 0) + { + std::cout << __PRETTY_FUNCTION__ << ": WARNING tbin out of range: " << TpcDefs::getTBin(hitkey) - toffset << " | " << tbins << std::endl; + } + unsigned short phibin = TpcDefs::getPad(hitkey) - phioffset; + unsigned short tbin = TpcDefs::getTBin(hitkey) - toffset; + unsigned short tbinorg = TpcDefs::getTBin(hitkey); + if (phibin >= phibins) + { + // std::cout << "WARNING phibin out of range: " << phibin << " | " << phibins << std::endl; + continue; + } + if (tbin >= tbins) + { + // std::cout << "WARNING z bin out of range: " << tbin << " | " << tbins << std::endl; + continue; + } + if (tbinorg > tbinmax || tbinorg < tbinmin) + continue; + float_t fadc = rawadc - pedestal; // proper int rounding +0.5 + unsigned short adc = 0; + if (fadc > 0) adc = (unsigned short) fadc; + if (phibin >= phibins) continue; + if (tbin >= tbins) continue; // tbin is unsigned int, <0 cannot happen + + if (adc > 0) + { + if (adc > (5 + my_data->threshold)) + { + ihit thisHit; + + thisHit.iphi = phibin; + thisHit.it = tbin; + thisHit.adc = adc; + thisHit.edge = 0; + all_hit_map.insert(std::make_pair(adc, thisHit)); + } + if (adc > my_data->threshold) + { + adcval[phibin][tbin] = (unsigned short) adc; + } + } + + } // for (int local_tbin = 0; local_tbin < pad_data.size(); ++local_tbin) + + } // for (int local_pad = 0; local_pad < dataframe.size(); ++local_pad) + + } // if (dynamic_cast(my_data->hitset)) + else + { + // generic hitset format + + TrkrHitSet *hitset = my_data->hitset; + TrkrHitSet::ConstRange hitrangei = hitset->getHits(); + + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) + { + if (TpcDefs::getPad(hitr->first) - phioffset < 0) + { + // std::cout << "WARNING phibin out of range: " << TpcDefs::getPad(hitr->first) - phioffset << " | " << phibins << std::endl; + continue; + } + if (TpcDefs::getTBin(hitr->first) - toffset < 0) + { + // std::cout << "WARNING tbin out of range: " << TpcDefs::getTBin(hitr->first) - toffset << " | " << tbins <first) - phioffset; + unsigned short tbin = TpcDefs::getTBin(hitr->first) - toffset; + unsigned short tbinorg = TpcDefs::getTBin(hitr->first); + if (phibin >= phibins) + { + // std::cout << "WARNING phibin out of range: " << phibin << " | " << phibins << std::endl; + continue; + } + if (tbin >= tbins) + { + // std::cout << "WARNING z bin out of range: " << tbin << " | " << tbins << std::endl; + continue; + } + if (tbinorg > tbinmax || tbinorg < tbinmin) + continue; + float_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 + unsigned short adc = 0; + if (fadc > 0) adc = (unsigned short) fadc; + if (phibin >= phibins) continue; + if (tbin >= tbins) continue; // tbin is unsigned int, <0 cannot happen + + if (adc > 0) + { + if (adc > (5 + my_data->threshold)) + { + ihit thisHit; + + thisHit.iphi = phibin; + thisHit.it = tbin; + thisHit.adc = adc; + thisHit.edge = 0; + all_hit_map.insert(std::make_pair(adc, thisHit)); + } + if (adc > my_data->threshold) + { + adcval[phibin][tbin] = (unsigned short) adc; + } + } + } + } // else -> if (dynamic_cast(my_data->hitset)) + + } // if (my_data->hitset != nullptr) + else if (my_data->rawhitset != nullptr) + { RawHitSetv1 *hitset = my_data->rawhitset; - /*std::cout << "Layer: " << my_data->layer - << "Side: " << my_data->side - << "Sector: " << my_data->sector - << " nhits: " << hitset.size() - << std::endl; + /*std::cout << "Layer: " << my_data->layer + << "Side: " << my_data->side + << "Sector: " << my_data->sector + << " nhits: " << hitset.size() + << std::endl; */ - for(int nphi= 0; nphi < phibins;nphi++){ - // nhits += hitset->m_tpchits[nphi].size(); - if(hitset->m_tpchits[nphi].size()==0) continue; - - int pindex = 0; - for(unsigned int nt = 0;ntm_tpchits[nphi].size();nt++){ - unsigned short val = hitset->m_tpchits[nphi][nt]; - - if(val==0) - pindex++; - else{ - if(nt==0){ - if(val>5){ - ihit thisHit; - thisHit.iphi = nphi; - thisHit.it = pindex; - thisHit.adc = val; - thisHit.edge = 0; - all_hit_map.insert(std::make_pair(val, thisHit)); - } - adcval[nphi][pindex++]=val; - }else{ - if((hitset->m_tpchits[nphi][nt-1]==0)&&(hitset->m_tpchits[nphi][nt+1]==0))//found zero count - pindex+=val; - else{ - if(val>5){ - ihit thisHit; - thisHit.iphi = nphi; - thisHit.it = pindex; - thisHit.adc = val; - thisHit.edge = 0; - all_hit_map.insert(std::make_pair(val, thisHit)); - } - adcval[nphi][pindex++]=val; - } - } - } - } + for (int nphi = 0; nphi < phibins; nphi++) + { + // nhits += hitset->m_tpchits[nphi].size(); + if (hitset->m_tpchits[nphi].size() == 0) continue; + + int pindex = 0; + for (unsigned int nt = 0; nt < hitset->m_tpchits[nphi].size(); nt++) + { + unsigned short val = hitset->m_tpchits[nphi][nt]; + + if (val == 0) + pindex++; + else + { + if (nt == 0) + { + if (val > 5) + { + ihit thisHit; + thisHit.iphi = nphi; + thisHit.it = pindex; + thisHit.adc = val; + thisHit.edge = 0; + all_hit_map.insert(std::make_pair(val, thisHit)); + } + adcval[nphi][pindex++] = val; + } + else + { + if ((hitset->m_tpchits[nphi][nt - 1] == 0) && (hitset->m_tpchits[nphi][nt + 1] == 0)) // found zero count + pindex += val; + else + { + if (val > 5) + { + ihit thisHit; + thisHit.iphi = nphi; + thisHit.it = pindex; + thisHit.adc = val; + thisHit.edge = 0; + all_hit_map.insert(std::make_pair(val, thisHit)); + } + adcval[nphi][pindex++] = val; + } + } + } + } } } - - if(my_data->do_singles){ - for(auto ahit:all_hit_map){ - ihit hiHit = ahit.second; - int iphi = hiHit.iphi; - int it = hiHit.it; - unsigned short edge = hiHit.edge; - double adc = hiHit.adc; - if(it>0&&itdo_singles) + { + for (auto ahit : all_hit_map) + { + ihit hiHit = ahit.second; + int iphi = hiHit.iphi; + int it = hiHit.it; + unsigned short edge = hiHit.edge; + double adc = hiHit.adc; + if (it > 0 && it < tbins) + { + if (adcval[iphi][it - 1] == 0 && + adcval[iphi][it + 1] == 0) + { + remove_hit(adc, iphi, it, edge, all_hit_map, adcval); + } + } } } - + // std::cout << "done filling " << std::endl; - while(all_hit_map.size()>0){ - //std::cout << "all hit map size: " << all_hit_map.size() << std::endl; + while (all_hit_map.size() > 0) + { + // std::cout << "all hit map size: " << all_hit_map.size() << std::endl; auto iter = all_hit_map.rbegin(); - if(iter == all_hit_map.rend()){ - break; + if (iter == all_hit_map.rend()) + { + break; } ihit hiHit = iter->second; int iphi = hiHit.iphi; int it = hiHit.it; - //put all hits in the all_hit_map (sorted by adc) - //start with highest adc hit - // -> cluster around it and get vector of hits + // put all hits in the all_hit_map (sorted by adc) + // start with highest adc hit + // -> cluster around it and get vector of hits std::vector ihit_list; int ntouch = 0; - int nedge =0; - get_cluster(iphi, it, *my_data, adcval, ihit_list, ntouch, nedge ); - + int nedge = 0; + get_cluster(iphi, it, *my_data, adcval, ihit_list, ntouch, nedge); + // -> calculate cluster parameters // -> add hits to truth association // remove hits from all_hit_map // repeat untill all_hit_map empty - calc_cluster_parameter(ihit_list, *my_data, ntouch, nedge ); - remove_hits(ihit_list,all_hit_map, adcval); + calc_cluster_parameter(ihit_list, *my_data, ntouch, nedge); + remove_hits(ihit_list, all_hit_map, adcval); ihit_list.clear(); } /* if( my_data->rawhitset!=nullptr){ RawHitSetv1 *hitset = my_data->rawhitset; - std::cout << "Layer: " << my_data->layer - << " Side: " << my_data->side - << " Sector: " << my_data->sector - << " nhits: " << hitset->size() - << " nhits coutn : " << nhits - << " nclus: " << my_data->cluster_vector.size() - << std::endl; + std::cout << "Layer: " << my_data->layer + << " Side: " << my_data->side + << " Sector: " << my_data->sector + << " nhits: " << hitset->size() + << " nhits coutn : " << nhits + << " nclus: " << my_data->cluster_vector.size() + << std::endl; } */ // pthread_exit(nullptr); } - void *ProcessSector(void *threadarg) { - - auto my_data = static_cast(threadarg); + void *ProcessSector(void *threadarg) + { + auto my_data = static_cast(threadarg); ProcessSectorData(my_data); pthread_exit(nullptr); } -} +} // namespace TpcClusterizer::TpcClusterizer(const std::string &name) : SubsysReco(name) -{} +{ +} bool TpcClusterizer::is_in_sector_boundary(int phibin, int sector, PHG4TpcCylinderGeom *layergeom) const { bool reject_it = false; - // sector boundaries occur every 1/12 of the full phi bin range + // sector boundaries occur every 1/12 of the full phi bin range int PhiBins = layergeom->get_phibins(); - int PhiBinsSector = PhiBins/12; + int PhiBinsSector = PhiBins / 12; double radius = layergeom->get_radius(); - double PhiBinSize = 2.0* radius * M_PI / (double) PhiBins; + double PhiBinSize = 2.0 * radius * M_PI / (double) PhiBins; // sector starts where? int sector_lo = sector * PhiBinsSector; @@ -695,24 +844,22 @@ bool TpcClusterizer::is_in_sector_boundary(int phibin, int sector, PHG4TpcCylind int sector_fiducial_bins = (int) (SectorFiducialCut / PhiBinSize); - if(phibin < sector_lo + sector_fiducial_bins || phibin > sector_hi - sector_fiducial_bins) - { - reject_it = true; - /* - int layer = layergeom->get_layer(); - std::cout << " local maximum is in sector fiducial boundary: layer " << layer << " radius " << radius << " sector " << sector - << " PhiBins " << PhiBins << " sector_fiducial_bins " << sector_fiducial_bins - << " PhiBinSize " << PhiBinSize << " phibin " << phibin << " sector_lo " << sector_lo << " sector_hi " << sector_hi << std::endl; - */ - } + if (phibin < sector_lo + sector_fiducial_bins || phibin > sector_hi - sector_fiducial_bins) + { + reject_it = true; + /* + int layer = layergeom->get_layer(); + std::cout << " local maximum is in sector fiducial boundary: layer " << layer << " radius " << radius << " sector " << sector + << " PhiBins " << PhiBins << " sector_fiducial_bins " << sector_fiducial_bins + << " PhiBinSize " << PhiBinSize << " phibin " << phibin << " sector_lo " << sector_lo << " sector_hi " << sector_hi << std::endl; + */ + } return reject_it; } - int TpcClusterizer::InitRun(PHCompositeNode *topNode) { - PHNodeIterator iter(topNode); // Looking for the DST node @@ -776,22 +923,25 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - if(!do_read_raw){ + if (!do_read_raw) + { // get node containing the digitized hits - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (!m_hits) - { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - }else{ + { + std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_TPC" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + } + else + { // get node containing the digitized hits m_rawhits = findNode::getClass(topNode, "TRKR_RAWHITSET"); if (!m_rawhits) - { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } + { + std::cout << PHWHERE << "ERROR: Can't find node TRKR_RAWHITSET" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } } // get node for clusters @@ -819,14 +969,14 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) } m_tGeometry = findNode::getClass(topNode, - "ActsGeometry"); - if(!m_tGeometry) - { - std::cout << PHWHERE - << "ActsGeometry not found on node tree. Exiting" - << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } + "ActsGeometry"); + if (!m_tGeometry) + { + std::cout << PHWHERE + << "ActsGeometry not found on node tree. Exiting" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } // The hits are stored in hitsets, where each hitset contains all hits in a given TPC readout (layer, sector, side), so clusters are confined to a hitset // The TPC clustering is more complicated than for the silicon, because we have to deal with overlapping clusters @@ -835,12 +985,15 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) RawHitSetContainer::ConstRange rawhitsetrange; int num_hitsets = 0; - if(!do_read_raw){ + if (!do_read_raw) + { hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId); - num_hitsets = std::distance(hitsetrange.first,hitsetrange.second); - }else{ + num_hitsets = std::distance(hitsetrange.first, hitsetrange.second); + } + else + { rawhitsetrange = m_rawhits->getHitSets(TrkrDefs::TrkrId::tpcId); - num_hitsets = std::distance(rawhitsetrange.first,rawhitsetrange.second); + num_hitsets = std::distance(rawhitsetrange.first, rawhitsetrange.second); } // create structure to store given thread and associated data @@ -849,133 +1002,140 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) pthread_t thread; thread_data data; }; - + // create vector of thread pairs and reserve the right size upfront to avoid reallocation std::vector threads; - threads.reserve( num_hitsets ); + threads.reserve(num_hitsets); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - + if (pthread_mutex_init(&mythreadlock, nullptr) != 0) - { - printf("\n mutex init failed\n"); - return 1; - } + { + printf("\n mutex init failed\n"); + return 1; + } int count = 0; - if(!do_read_raw){ + if (!do_read_raw) + { for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; - hitsetitr != hitsetrange.second; - ++hitsetitr) + hitsetitr != hitsetrange.second; + ++hitsetitr) + { + // if(count>0)continue; + TrkrHitSet *hitset = hitsetitr->second; + unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); + int side = TpcDefs::getSide(hitsetitr->first); + unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); + PHG4TpcCylinderGeom *layergeom = geom_container->GetLayerCellGeom(layer); + + // instanciate new thread pair, at the end of thread vector + thread_pair_t &thread_pair = threads.emplace_back(); + + thread_pair.data.layergeom = layergeom; + thread_pair.data.hitset = hitset; + thread_pair.data.rawhitset = nullptr; + thread_pair.data.layer = layer; + thread_pair.data.pedestal = pedestal; + thread_pair.data.threshold = threshold; + thread_pair.data.sector = sector; + thread_pair.data.side = side; + thread_pair.data.do_assoc = do_hit_assoc; + thread_pair.data.do_wedge_emulation = do_wedge_emulation; + thread_pair.data.do_singles = do_singles; + thread_pair.data.tGeometry = m_tGeometry; + thread_pair.data.maxHalfSizeT = MaxClusterHalfSizeT; + thread_pair.data.maxHalfSizePhi = MaxClusterHalfSizePhi; + thread_pair.data.sampa_tbias = m_sampa_tbias; + thread_pair.data.cluster_version = cluster_version; + thread_pair.data.verbosity = Verbosity(); + + unsigned short NPhiBins = (unsigned short) layergeom->get_phibins(); + unsigned short NPhiBinsSector = NPhiBins / 12; + unsigned short NTBins = (unsigned short) layergeom->get_zbins(); + unsigned short NTBinsSide = NTBins; + unsigned short NTBinsMin = 0; + unsigned short PhiOffset = NPhiBinsSector * sector; + unsigned short TOffset = NTBinsMin; + + m_tdriftmax = AdcClockPeriod * NTBins / 2.0; + thread_pair.data.m_tdriftmax = m_tdriftmax; + + thread_pair.data.phibins = NPhiBinsSector; + thread_pair.data.phioffset = PhiOffset; + thread_pair.data.tbins = NTBinsSide; + thread_pair.data.toffset = TOffset; + + thread_pair.data.radius = layergeom->get_radius(); + thread_pair.data.drift_velocity = m_tGeometry->get_drift_velocity(); + thread_pair.data.pads_per_sector = 0; + thread_pair.data.phistep = 0; + int rc; + rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (void *) &thread_pair.data); + + if (rc) { - //if(count>0)continue; - TrkrHitSet *hitset = hitsetitr->second; - unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); - int side = TpcDefs::getSide(hitsetitr->first); - unsigned int sector= TpcDefs::getSectorId(hitsetitr->first); - PHG4TpcCylinderGeom *layergeom = geom_container->GetLayerCellGeom(layer); - - // instanciate new thread pair, at the end of thread vector - thread_pair_t& thread_pair = threads.emplace_back(); - - thread_pair.data.layergeom = layergeom; - thread_pair.data.hitset = hitset; - thread_pair.data.rawhitset = nullptr; - thread_pair.data.layer = layer; - thread_pair.data.pedestal = pedestal; - thread_pair.data.threshold = threshold; - thread_pair.data.sector = sector; - thread_pair.data.side = side; - thread_pair.data.do_assoc = do_hit_assoc; - thread_pair.data.do_wedge_emulation = do_wedge_emulation; - thread_pair.data.do_singles = do_singles; - thread_pair.data.tGeometry = m_tGeometry; - thread_pair.data.maxHalfSizeT = MaxClusterHalfSizeT; - thread_pair.data.maxHalfSizePhi = MaxClusterHalfSizePhi; - thread_pair.data.sampa_tbias = m_sampa_tbias; - thread_pair.data.cluster_version = cluster_version; - thread_pair.data.verbosity = Verbosity(); - - unsigned short NPhiBins = (unsigned short) layergeom->get_phibins(); - unsigned short NPhiBinsSector = NPhiBins/12; - unsigned short NTBins = (unsigned short)layergeom->get_zbins(); - unsigned short NTBinsSide = NTBins; - unsigned short NTBinsMin = 0; - unsigned short PhiOffset = NPhiBinsSector * sector; - unsigned short TOffset = NTBinsMin; - - m_tdriftmax = AdcClockPeriod * NTBins / 2.0; - thread_pair.data.m_tdriftmax = m_tdriftmax; - - thread_pair.data.phibins = NPhiBinsSector; - thread_pair.data.phioffset = PhiOffset; - thread_pair.data.tbins = NTBinsSide; - thread_pair.data.toffset = TOffset ; - - thread_pair.data.radius = layergeom->get_radius(); - thread_pair.data.drift_velocity = m_tGeometry->get_drift_velocity(); - thread_pair.data.pads_per_sector = 0; - thread_pair.data.phistep = 0; - int rc; - rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (void *)&thread_pair.data); - - if (rc) { - std::cout << "Error:unable to create thread," << rc << std::endl; - } - if(do_sequential){ - int rc2 = pthread_join(thread_pair.thread, nullptr); - if (rc2) - { std::cout << "Error:unable to join," << rc2 << std::endl; } - - // get the hitsetkey from thread data - const auto& data( thread_pair.data ); - const auto hitsetkey = TpcDefs::genHitSetKey( data.layer, data.sector, data.side ); - - // copy clusters to map - for( uint32_t index = 0; index < data.cluster_vector.size(); ++index ) - { - // generate cluster key - const auto ckey = TrkrDefs::genClusKey( hitsetkey, index ); - - // get cluster - auto cluster = data.cluster_vector[index]; - - // insert in map - m_clusterlist->addClusterSpecifyKey(ckey, cluster); - } - - // copy hit associations to map - for( const auto& [index,hkey]:thread_pair.data.association_vector) - { - // generate cluster key - const auto ckey = TrkrDefs::genClusKey( hitsetkey, index ); - - // add to association table - m_clusterhitassoc->addAssoc(ckey,hkey); - } - } - count++; + std::cout << "Error:unable to create thread," << rc << std::endl; } - }else{ + if (do_sequential) + { + int rc2 = pthread_join(thread_pair.thread, nullptr); + if (rc2) + { + std::cout << "Error:unable to join," << rc2 << std::endl; + } + + // get the hitsetkey from thread data + const auto &data(thread_pair.data); + const auto hitsetkey = TpcDefs::genHitSetKey(data.layer, data.sector, data.side); + // copy clusters to map + for (uint32_t index = 0; index < data.cluster_vector.size(); ++index) + { + // generate cluster key + const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); + + // get cluster + auto cluster = data.cluster_vector[index]; + + // insert in map + m_clusterlist->addClusterSpecifyKey(ckey, cluster); + } + + // copy hit associations to map + for (const auto &[index, hkey] : thread_pair.data.association_vector) + { + // generate cluster key + const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); + + // add to association table + m_clusterhitassoc->addAssoc(ckey, hkey); + } + } + count++; + } + } + else + { for (RawHitSetContainer::ConstIterator hitsetitr = rawhitsetrange.first; - hitsetitr != rawhitsetrange.second; - ++hitsetitr){ + hitsetitr != rawhitsetrange.second; + ++hitsetitr) + { // if(count>0)continue; - // const auto hitsetid = hitsetitr->first; + // const auto hitsetid = hitsetitr->first; // std::cout << " starting thread # " << count << std::endl; - RawHitSet *hitset = hitsetitr->second; + RawHitSet *hitset = hitsetitr->second; unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); int side = TpcDefs::getSide(hitsetitr->first); - unsigned int sector= TpcDefs::getSectorId(hitsetitr->first); + unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); PHG4TpcCylinderGeom *layergeom = geom_container->GetLayerCellGeom(layer); - + // instanciate new thread pair, at the end of thread vector - thread_pair_t& thread_pair = threads.emplace_back(); - + thread_pair_t &thread_pair = threads.emplace_back(); + thread_pair.data.layergeom = layergeom; thread_pair.data.hitset = nullptr; thread_pair.data.rawhitset = dynamic_cast(hitset); @@ -986,145 +1146,150 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) thread_pair.data.do_assoc = do_hit_assoc; thread_pair.data.do_wedge_emulation = do_wedge_emulation; thread_pair.data.tGeometry = m_tGeometry; - thread_pair.data.maxHalfSizeT = MaxClusterHalfSizeT; + thread_pair.data.maxHalfSizeT = MaxClusterHalfSizeT; thread_pair.data.maxHalfSizePhi = MaxClusterHalfSizePhi; thread_pair.data.sampa_tbias = m_sampa_tbias; thread_pair.data.cluster_version = cluster_version; thread_pair.data.verbosity = Verbosity(); unsigned short NPhiBins = (unsigned short) layergeom->get_phibins(); - unsigned short NPhiBinsSector = NPhiBins/12; - unsigned short NTBins = (unsigned short)layergeom->get_zbins(); + unsigned short NPhiBinsSector = NPhiBins / 12; + unsigned short NTBins = (unsigned short) layergeom->get_zbins(); unsigned short NTBinsSide = NTBins; unsigned short NTBinsMin = 0; unsigned short PhiOffset = NPhiBinsSector * sector; unsigned short TOffset = NTBinsMin; - m_tdriftmax = AdcClockPeriod * NTBins / 2.0; + m_tdriftmax = AdcClockPeriod * NTBins / 2.0; thread_pair.data.m_tdriftmax = m_tdriftmax; - thread_pair.data.phibins = NPhiBinsSector; + thread_pair.data.phibins = NPhiBinsSector; thread_pair.data.phioffset = PhiOffset; - thread_pair.data.tbins = NTBinsSide; - thread_pair.data.toffset = TOffset ; + thread_pair.data.tbins = NTBinsSide; + thread_pair.data.toffset = TOffset; /* PHG4TpcCylinderGeom *testlayergeom = geom_container->GetLayerCellGeom(32); for( float iphi = 1408; iphi < 1408+ 128;iphi+=0.1){ - double clusiphi = iphi; - double clusphi = testlayergeom->get_phi(clusiphi); - double radius = layergeom->get_radius(); - float clusx = radius * cos(clusphi); - float clusy = radius * sin(clusphi); - float clusz = -37.524; - - TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey( 32,11, 0 ); - Acts::Vector3 global(clusx, clusy, clusz); - TrkrDefs::subsurfkey subsurfkey = 0; - - Surface surface = m_tGeometry->get_tpc_surface_from_coords( - tpcHitSetKey, - global, - subsurfkey); - std::cout << " iphi: " << iphi << " clusphi: " << clusphi << " surfkey " << subsurfkey << std::endl; - // std::cout << "surfkey" << subsurfkey << std::endl; + double clusiphi = iphi; + double clusphi = testlayergeom->get_phi(clusiphi); + double radius = layergeom->get_radius(); + float clusx = radius * cos(clusphi); + float clusy = radius * sin(clusphi); + float clusz = -37.524; + + TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey( 32,11, 0 ); + Acts::Vector3 global(clusx, clusy, clusz); + TrkrDefs::subsurfkey subsurfkey = 0; + + Surface surface = m_tGeometry->get_tpc_surface_from_coords( + tpcHitSetKey, + global, + subsurfkey); + std::cout << " iphi: " << iphi << " clusphi: " << clusphi << " surfkey " << subsurfkey << std::endl; + // std::cout << "surfkey" << subsurfkey << std::endl; } continue; */ int rc = 0; // if(layer==32) - rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (void *)&thread_pair.data); + rc = pthread_create(&thread_pair.thread, &attr, ProcessSector, (void *) &thread_pair.data); // else - //continue; - - if (rc) { - std::cout << "Error:unable to create thread," << rc << std::endl; + // continue; + + if (rc) + { + std::cout << "Error:unable to create thread," << rc << std::endl; + } + + if (do_sequential) + { + int rc2 = pthread_join(thread_pair.thread, nullptr); + if (rc2) + { + std::cout << "Error:unable to join," << rc2 << std::endl; + } + + // get the hitsetkey from thread data + const auto &data(thread_pair.data); + const auto hitsetkey = TpcDefs::genHitSetKey(data.layer, data.sector, data.side); + + // copy clusters to map + for (uint32_t index = 0; index < data.cluster_vector.size(); ++index) + { + // generate cluster key + const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); + + // get cluster + auto cluster = data.cluster_vector[index]; + + // insert in map + m_clusterlist->addClusterSpecifyKey(ckey, cluster); + } + + // copy hit associations to map + for (const auto &[index, hkey] : thread_pair.data.association_vector) + { + // generate cluster key + const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); + + // add to association table + m_clusterhitassoc->addAssoc(ckey, hkey); + } } - - if(do_sequential){ - int rc2 = pthread_join(thread_pair.thread, nullptr); - if (rc2) - { std::cout << "Error:unable to join," << rc2 << std::endl; } - - // get the hitsetkey from thread data - const auto& data( thread_pair.data ); - const auto hitsetkey = TpcDefs::genHitSetKey( data.layer, data.sector, data.side ); - - // copy clusters to map - for( uint32_t index = 0; index < data.cluster_vector.size(); ++index ) - { - // generate cluster key - const auto ckey = TrkrDefs::genClusKey( hitsetkey, index ); - - // get cluster - auto cluster = data.cluster_vector[index]; - - // insert in map - m_clusterlist->addClusterSpecifyKey(ckey, cluster); - } - - // copy hit associations to map - for( const auto& [index,hkey]:thread_pair.data.association_vector) - { - // generate cluster key - const auto ckey = TrkrDefs::genClusKey( hitsetkey, index ); - - // add to association table - m_clusterhitassoc->addAssoc(ckey,hkey); - } - } count++; } } - pthread_attr_destroy(&attr); - count =0; + count = 0; // wait for completion of all threads - if(!do_sequential){ - for( const auto& thread_pair:threads ) - { - int rc2 = pthread_join(thread_pair.thread, nullptr); - if (rc2) - { std::cout << "Error:unable to join," << rc2 << std::endl; } - - // get the hitsetkey from thread data - const auto& data( thread_pair.data ); - const auto hitsetkey = TpcDefs::genHitSetKey( data.layer, data.sector, data.side ); - - // copy clusters to map - for( uint32_t index = 0; index < data.cluster_vector.size(); ++index ) - { - // generate cluster key - const auto ckey = TrkrDefs::genClusKey( hitsetkey, index ); - - // get cluster - auto cluster = data.cluster_vector[index]; - - // insert in map - //std::cout << "X: " << cluster->getLocalX() << "Y: " << cluster->getLocalY() << std::endl; - m_clusterlist->addClusterSpecifyKey(ckey, cluster); - } - - // copy hit associations to map - for( const auto& [index,hkey]:thread_pair.data.association_vector) - { - // generate cluster key - const auto ckey = TrkrDefs::genClusKey( hitsetkey, index ); - - // add to association table - m_clusterhitassoc->addAssoc(ckey,hkey); - } + if (!do_sequential) + { + for (const auto &thread_pair : threads) + { + int rc2 = pthread_join(thread_pair.thread, nullptr); + if (rc2) + { + std::cout << "Error:unable to join," << rc2 << std::endl; + } + + // get the hitsetkey from thread data + const auto &data(thread_pair.data); + const auto hitsetkey = TpcDefs::genHitSetKey(data.layer, data.sector, data.side); + + // copy clusters to map + for (uint32_t index = 0; index < data.cluster_vector.size(); ++index) + { + // generate cluster key + const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); + // get cluster + auto cluster = data.cluster_vector[index]; + + // insert in map + // std::cout << "X: " << cluster->getLocalX() << "Y: " << cluster->getLocalY() << std::endl; + m_clusterlist->addClusterSpecifyKey(ckey, cluster); + } + + // copy hit associations to map + for (const auto &[index, hkey] : thread_pair.data.association_vector) + { + // generate cluster key + const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); + + // add to association table + m_clusterhitassoc->addAssoc(ckey, hkey); } + } } if (Verbosity() > 0) - std::cout << "TPC Clusterizer found " << m_clusterlist->size() << " Clusters " << std::endl; + std::cout << "TPC Clusterizer found " << m_clusterlist->size() << " Clusters " << std::endl; return Fun4AllReturnCodes::EVENT_OK; } -int TpcClusterizer::End(PHCompositeNode */*topNode*/) +int TpcClusterizer::End(PHCompositeNode * /*topNode*/) { return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index f6c56a970e..ff41168e63 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -2,12 +2,12 @@ #define TPC_TPCCLUSTERIZER_H #include -#include #include +#include -#include -#include +#include #include +#include class PHCompositeNode; class TrkrHitSet; @@ -19,8 +19,8 @@ class TrkrClusterHitAssoc; class PHG4TpcCylinderGeom; class PHG4TpcCylinderGeomContainer; -//typedef std::pair iphiz; -//typedef std::pair ihit; +// typedef std::pair iphiz; +// typedef std::pair ihit; typedef std::pair iphiz; typedef std::pair ihit; @@ -34,17 +34,17 @@ class TpcClusterizer : public SubsysReco int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - void set_sector_fiducial_cut(const double cut){SectorFiducialCut = cut; } - void set_do_hit_association(bool do_assoc){do_hit_assoc = do_assoc;} - void set_do_wedge_emulation(bool do_wedge){ do_wedge_emulation = do_wedge;} - void set_do_sequential(bool do_seq){ do_sequential = do_seq;} - void set_threshold(float val) { threshold = val;} - void set_remove_singles(bool do_sing){ do_singles = do_sing;} - void set_read_raw(bool read_raw){ do_read_raw = read_raw;} - void set_max_cluster_half_size_phi(unsigned short size) { MaxClusterHalfSizePhi = size ;} - void set_max_cluster_half_size_z(unsigned short size) { MaxClusterHalfSizeT = size ;} + void set_sector_fiducial_cut(const double cut) { SectorFiducialCut = cut; } + void set_do_hit_association(bool do_assoc) { do_hit_assoc = do_assoc; } + void set_do_wedge_emulation(bool do_wedge) { do_wedge_emulation = do_wedge; } + void set_do_sequential(bool do_seq) { do_sequential = do_seq; } + void set_threshold(float val) { threshold = val; } + void set_remove_singles(bool do_sing) { do_singles = do_sing; } + void set_read_raw(bool read_raw) { do_read_raw = read_raw; } + void set_max_cluster_half_size_phi(unsigned short size) { MaxClusterHalfSizePhi = size; } + void set_max_cluster_half_size_z(unsigned short size) { MaxClusterHalfSizeT = size; } void set_cluster_version(int value) { cluster_version = value; } - + private: bool is_in_sector_boundary(int phibin, int sector, PHG4TpcCylinderGeom *layergeom) const; @@ -65,11 +65,11 @@ class TpcClusterizer : public SubsysReco unsigned short MaxClusterHalfSizeT = 5; int cluster_version = 4; double m_tdriftmax = 0; - double AdcClockPeriod = 53.0; // ns + double AdcClockPeriod = 53.0; // ns // TPC shaping offset correction parameter // From Tony Frawley July 5, 2022 - double m_sampa_tbias = 39.6; // ns + double m_sampa_tbias = 39.6; // ns }; #endif diff --git a/offline/packages/tpc/TpcLoadDistortionCorrection.cc b/offline/packages/tpc/TpcLoadDistortionCorrection.cc index 99447abbe9..70a6f16b2c 100644 --- a/offline/packages/tpc/TpcLoadDistortionCorrection.cc +++ b/offline/packages/tpc/TpcLoadDistortionCorrection.cc @@ -53,22 +53,14 @@ int TpcLoadDistortionCorrection::InitRun(PHCompositeNode* topNode) // look for distortion calibration object PHNodeIterator iter(topNode); - /// Get the DST node and check - auto dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); - if (!dstNode) + /// Get the RUN node and check + auto runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) { - std::cout << "TpcLoadDistortionCorrection::InitRun - DST Node missing, quitting" << std::endl; + std::cout << "TpcLoadDistortionCorrection::InitRun - RUN Node missing, quitting" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - // Get the tracking subnode and create if not found - auto svtxNode = dynamic_cast(iter.findFirst("PHCompositeNode", "SVTX")); - if (!svtxNode) - { - svtxNode = new PHCompositeNode("SVTX"); - dstNode->addNode(svtxNode); - } - //create and populate the nodes for each distortion, if present: for (int i=0;i<3;i++){ @@ -81,7 +73,7 @@ int TpcLoadDistortionCorrection::InitRun(PHCompositeNode* topNode) std::cout << "TpcLoadDistortionCorrection::InitRun - creating TpcDistortionCorrectionContainer in node " << m_node_name[i] << std::endl; distortion_correction_object = new TpcDistortionCorrectionContainer; auto node = new PHDataNode(distortion_correction_object, m_node_name[i]); - svtxNode->addNode(node); + runNode->addNode(node); } std::cout << "TpcLoadDistortionCorrection::InitRun - reading corrections from " << m_correction_filename[i] << std::endl; diff --git a/offline/packages/tpc/TpcMap.cc b/offline/packages/tpc/TpcMap.cc new file mode 100644 index 0000000000..37054e2706 --- /dev/null +++ b/offline/packages/tpc/TpcMap.cc @@ -0,0 +1,223 @@ +#include "TpcMap.h" + +#include +#include +#include +#include +#include +#include + +void TpcMap::setMapNames(const std::string &r1, const std::string &r2, const std::string &r3) +{ + const char *calibrationroot = getenv("CALIBRATIONROOT"); + std::string full_path; + if (calibrationroot) + { + full_path = std::string(calibrationroot) + "/TPC/Mapping/PadPlane/"; + } + else + { + full_path = "./"; + } + std::string full_path_r1 = full_path + r1; + std::string full_path_r2 = full_path + r2; + std::string full_path_r3 = full_path + r3; + int status; + status = digest_map(full_path_r1, 0); + if (status) + { + std::cout << "reading " << full_path_r1 << " failed" << std::endl; + } + status = digest_map(full_path_r2, 1); + if (status) + { + std::cout << "reading " << full_path_r2 << " failed" << std::endl; + } + status = digest_map(full_path_r3, 2); + if (status) + { + std::cout << "reading " << full_path_r3 << " failed" << std::endl; + } +} + +int TpcMap::digest_map(const std::string &fileName, const unsigned int section_offset) +{ + std::ifstream infile(fileName, std::ios::in); + + if (!infile.is_open()) + { + std::cout << "Could not open file: "<< fileName << std::endl; + _broken = 1; + return -1; + } + + std::string line; + getline(infile, line); // throwaway - we skip the first line + // cout << __FILE__<< " " << __LINE__ << ": " << line << endl; + + int abs_pad = INT_MAX; + int Radius = INT_MAX; + // int Pad; + // int U; + // int G; + // string Pin; + // int PinColID; + // int PinRowID; + // string PadName; + int FEE = INT_MAX; + // int FEE_Connector; + int FEE_Chan = INT_MAX; + // double phi; + // double x; + // double y; + // double PadX; + // double PadY; + double PadR = NAN; + double PadPhi = NAN; + + while (getline(infile, line)) + { + // cout << line<< endl; + std::stringstream ss(line); + std::string next; + + // 0 26 26 + // 1 0 0 + // 2 0 0 + // 3 1 1 + // 4 1 1 + // 5 0 C5 + // 6 2 2 + // 7 5 5 + // 8 0 ZZ.00.000 + // 9 5 5.0 + // 10 0 J2 + // 11 147 147 + // 12 0 0.005570199740407434 + // 13 69 69.99891405342764 + // 14 0 0.38991196551332985 + // 15 77 77.86043476908294 + // 16 305 305.14820499531316 + // 17 314 314.9248709046211 + // 18 0 0.24982557215053805 + + int index = 0; + while (ss.good()) + { + getline(ss, next, ','); + if (index == 0) + { + abs_pad = std::stoul(next); + } + else if (index == 1) + { + Radius = stoul(next); + } + else if (index == 9) + { + FEE = stoul(next); + } + else if (index == 11) + { + FEE_Chan = stoul(next); + } + else if (index == 17) + { + PadR = stod(next); + } + else if (index == 18) + { + PadPhi = stod(next); + } + index++; + } + + if (section_offset == 1) + { + FEE += 6; + } + if (section_offset == 2) + { + FEE += 14; + } + + struct tpc_map x + { + }; + x.padnr = abs_pad; + x.layer = Radius + section_offset * 16 + 7; + x.FEE = FEE; + x.FEEChannel = FEE_Chan; + x.PadR = PadR; + x.PadPhi = PadPhi; + + unsigned int key = 256 * (FEE) + FEE_Chan; + tmap[key] = x; + // cout << setw(5) << key << setw(5) << FEE << setw(5) << FEE_Chan << " " << PadR << " " << PadPhi << endl; + } + return 0; +} + +unsigned int TpcMap::getLayer(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int /* packetid */) const +{ + if (FEE >= 26 || FEEChannel > 255) + { + return 0.; + } + unsigned int key = 256 * FEE + FEEChannel; + + std::map::const_iterator itr = tmap.find(key); + if (itr == tmap.end()) + { + return 0; + } + return itr->second.layer; +} + +unsigned int TpcMap::getPad(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int /* packetid */) const +{ + if (FEE >= 26 || FEEChannel > 255) + { + return 0.; + } + unsigned int key = 256 * FEE + FEEChannel; + + std::map::const_iterator itr = tmap.find(key); + if (itr == tmap.end()) + { + return -100; + } + return itr->second.padnr; +} + +double TpcMap::getR(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int /* packetid */) const +{ + if (FEE >= 26 || FEEChannel > 255) + { + return 0.; + } + unsigned int key = 256 * FEE + FEEChannel; + + std::map::const_iterator itr = tmap.find(key); + if (itr == tmap.end()) + { + return -100; + } + return itr->second.PadR; +} + +double TpcMap::getPhi(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int /* packetid */) const +{ + if (FEE > 25 || FEEChannel > 255) + { + return 0.; + } + unsigned int key = 256 * FEE + FEEChannel; + + std::map::const_iterator itr = tmap.find(key); + if (itr == tmap.end()) + { + return -100; + } + return itr->second.PadPhi; +} diff --git a/offline/packages/tpc/TpcMap.h b/offline/packages/tpc/TpcMap.h new file mode 100644 index 0000000000..c48d98cc63 --- /dev/null +++ b/offline/packages/tpc/TpcMap.h @@ -0,0 +1,37 @@ +#ifndef __TpcMap_H__ +#define __TpcMap_H__ + +#include +#include + +class TpcMap +{ + public: + // constructors and destructors + TpcMap() = default; + virtual ~TpcMap() = default; + + virtual unsigned int getLayer(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; + virtual unsigned int getPad(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; + virtual double getR(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; + virtual double getPhi(const unsigned int FEE, const unsigned int FEEChannel, const unsigned int packetid = 0) const; + virtual void setMapNames(const std::string &r1, const std::string &r2, const std::string &r3); + + private: + int digest_map(const std::string &fileName, const unsigned int section_offset); + + int _broken = 0; + struct tpc_map + { + unsigned int padnr; + unsigned int layer; + unsigned int FEE; + unsigned int FEEChannel; + double PadR; + double PadPhi; + }; + + std::map tmap; +}; + +#endif diff --git a/offline/packages/tpc/TpcRawDataDecoder.cc b/offline/packages/tpc/TpcRawDataDecoder.cc new file mode 100644 index 0000000000..faef235725 --- /dev/null +++ b/offline/packages/tpc/TpcRawDataDecoder.cc @@ -0,0 +1,348 @@ + +#include "TpcRawDataDecoder.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include // for PHIODataNode +#include // for PHNodeIterator +#include // for PHObject +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +//____________________________________________________________________________.. +TpcRawDataDecoder::TpcRawDataDecoder(const std::string &name) + : SubsysReco(name) + , hm(nullptr) + , _filename("./outputfile.root") + { + std::cout << "TpcRawDataDecoder::TpcRawDataDecoder(const std::string &name)" << std::endl; + starting_BCO = -1; + rollover_value = 0; + current_BCOBIN = 0; + M.setMapNames("AutoPad-R1-RevA.sch.ChannelMapping.csv", "AutoPad-R2-RevA-Pads.sch.ChannelMapping.csv", "AutoPad-R3-RevA.sch.ChannelMapping.csv"); + + + + + // Open a file, save the ntuple and close the file + TFile in_file("/sphenix/user/shulga/Work/Files/pedestal-10616-outfile.root"); + in_file.GetObject("h_Alive",h_Alive); + float chan_id,fee_id,module_id,pedMean,pedStdi, sec_id; float* row_content; + + if( Verbosity() )std::cout << "chan_id\t fee_id\t module_id\t pedMean\t pedStdi\t sec_id\n"; + for (int irow=0;irowGetEntries();++irow) + { + h_Alive->GetEntry(irow); + row_content = h_Alive->GetArgs(); + chan_id = row_content[0]; + fee_id = row_content[1]; + module_id = row_content[2]; + pedMean = row_content[3]; + pedStdi = row_content[4]; + sec_id = row_content[5]; + if( Verbosity() ) + { + std::cout + << chan_id << "\t" + << fee_id << "\t" + << module_id << "\t" + << pedMean << "\t" + << pedStdi << "\t" + << sec_id << "\t" + << std::endl; + } + + struct tpc_map x + { + }; + + x.CHN_ID = chan_id ; + x.FEE_ID = fee_id ; + x.MOD_ID = module_id; + x.PedMean = pedMean ; + x.PedStdi = pedStdi ; + x.SEC_ID = sec_id ; + + unsigned int key = 256 * (fee_id) + chan_id; + tmap[key] = x; + } +} + +//____________________________________________________________________________.. +TpcRawDataDecoder::~TpcRawDataDecoder() +{ + delete hm; + std::cout << "TpcRawDataDecoder::~TpcRawDataDecoder() Calling dtor" << std::endl; +} + +//____________________________________________________________________________.. +int TpcRawDataDecoder::Init(PHCompositeNode * /*topNode*/) +{ + std::cout << "TpcRawDataDecoder::Init(PHCompositeNode *topNode) Initializing" << std::endl; + hm = new Fun4AllHistoManager("HITHIST"); + + _h_hit_XY = new TH2F("_h_hit_XY" ,"_h_hit_XY;X, [m];Y, [m]", 400, -800, 800, 400, -800, 800); + + hm->registerHisto(_h_hit_XY ); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TpcRawDataDecoder::InitRun(PHCompositeNode *topNode) +{ + + // get dst node + PHNodeIterator iter(topNode); + auto dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << "TpcRawDataDecoder::InitRun - DST Node missing, doing nothing." << std::endl; + exit(1); + } + + // create hitset container if needed + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + if (!hitsetcontainer) + { + std::cout << "TpcRawDataDecoder::InitRun - creating TRKR_HITSET." << std::endl; + + // find or create TRKR node + PHNodeIterator dstiter(dstNode); + auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + if (!trkrnode) + { + trkrnode = new PHCompositeNode("TRKR"); + dstNode->addNode(trkrnode); + } + + // create container and add to the tree + hitsetcontainer = new TrkrHitSetContainerv1; + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + trkrnode->addNode(newNode); + } + topNode->print(); + + // we reset the BCO for the new run + starting_BCO = -1; + rollover_value = 0; + current_BCOBIN = 0; + + //m_hits = new TrkrHitSetContainerv1(); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TpcRawDataDecoder::process_event(PHCompositeNode *topNode) +{ + //std::cout << "TpcRawDataDecoder::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; + // load relevant nodes + // Get the TrkrHitSetContainer node + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + assert(trkrhitsetcontainer); + + Event *_event = findNode::getClass(topNode, "PRDF"); + assert( _event ); + + if (_event == nullptr) + { + std::cout << "TpcRawDataDecoder::Process_Event - Event not found" << std::endl; + return -1; + } + if (_event->getEvtType() >= 8) /// special events + { + return Fun4AllReturnCodes::DISCARDEVENT; + } + + // check all possible TPC packets that we need to analyze + for(int ep=0;ep<2;ep++){ + for (int sector = 0; sector<=23; sector++) + { + const int packet = 4000 + sector*10 + ep; + + // Reading packet + Packet *p = _event->getPacket(packet); + + // Figure out which side + int side = 0; + if(sector>11) side=1; + + if (p) + { + std::cout << "TpcRawDataDecoder:: Event getPacket: "<< packet << "| Sector"<< sector << "| EndPoint "<< ep << std::endl; + }else{ + continue; + } + + int nr_of_waveforms = p->iValue(0, "NR_WF"); + + for (auto &l : m_hitset) + { + l = new TrkrHitSetv1(); + + int wf; + for (wf = 0; wf < nr_of_waveforms; wf++) + { + int current_BCO = p->iValue(wf, "BCO") + rollover_value; + + if (starting_BCO < 0) + { + starting_BCO = current_BCO; + } + + if (current_BCO < starting_BCO) // we have a rollover + { + rollover_value += 0x100000; + current_BCO = p->iValue(wf, "BCO") + rollover_value; + starting_BCO = current_BCO; + current_BCOBIN++; + } + int sampa_nr = p->iValue(wf, "SAMPAADDRESS"); + int channel = p->iValue(wf, "CHANNEL"); + + int fee = p->iValue(wf, "FEE"); + int samples = p->iValue( wf, "SAMPLES" ); + // clockwise FEE mapping + //int FEE_map[26]={5, 6, 1, 3, 2, 12, 10, 11, 9, 8, 7, 1, 2, 4, 8, 7, 6, 5, 4, 3, 1, 3, 2, 4, 6, 5}; + int FEE_R[26]={2, 2, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3}; + // conter clockwise FEE mapping (From Takao) + int FEE_map[26]={3, 2, 5, 3, 4, 0, 2, 1, 3, 4, 5, 7, 6, 2, 0, 1, 0, 1, 4, 5, 11, 9, 10, 8, 6, 7}; + int pads_per_sector[3] = {96, 128, 192}; + + // setting the mapp of the FEE + int feeM = FEE_map[fee]-1; + if(FEE_R[fee]==2) feeM += 6; + if(FEE_R[fee]==3) feeM += 14; + int layer = M.getLayer(feeM, channel); + + double R = M.getR(feeM, channel); + double phi = M.getPhi(feeM, channel) + sector * M_PI / 6 ; + unsigned int key = 256 * (feeM) + channel; + int pedestal = round(tmap[key].PedMean); + TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(layer, sector, side); + TrkrHitSetContainer::Iterator hitsetit = trkrhitsetcontainer->findOrAddHitSet(tpcHitSetKey); + + if( Verbosity() ) + { + int sampaAddress = p->iValue(wf, "SAMPAADDRESS"); + int sampaChannel = p->iValue(wf, "SAMPACHANNEL"); + int checksum = p->iValue(wf, "CHECKSUM"); + int checksumError = p->iValue(wf, "CHECKSUMERROR"); + std::cout << "TpcRawDataDecoder::Process_Event Samples "<< samples + <<" Chn:"<< channel + <<" layer: " << layer + << " sampa: "<< sampa_nr + << " fee: "<< fee + << " Mapped fee: "<< feeM + << " sampaAddress: "<< sampaAddress + << " sampaChannel: "<< sampaChannel + << " checksum: "<< checksum + << " checksumError: "<< checksumError + << " hitsetkey "<< tpcHitSetKey + << " R = " << R + << " phi = " << phi + << std::endl; + } + for (int s = 0; s < samples; s++) + { + int pad = M.getPad(feeM, channel); + int t = s + 2 * (current_BCO - starting_BCO); + int adc = p->iValue(wf,s); + // generate hit key + TrkrDefs::hitkey hitkey = TpcDefs::genHitKey((unsigned int) pad + sector*pads_per_sector[FEE_R[sector]-1], (unsigned int) t); + // find existing hit, or create + auto hit = hitsetit->second->getHit(hitkey); + + // create hit, assign adc and insert in hitset + if (!hit) + { + // create a new one + hit = new TrkrHitv2(); + hit->setAdc(adc-pedestal); + //std::cout<< "ADC = " << adc << " Pedestal = "<< pedestal << "delta = "<< adc-pedestal << std::endl; + hitsetit->second->addHitSpecificKey(hitkey, hit); + } + //else{ + // hit->setAdc(adc); + // hitsetit->second->addHitSpecificKey(hitkey, hit); + //} + + _h_hit_XY->Fill(R*cos(phi),R*sin(phi),adc); + + } + + } + } + + }// End of run over packets + }//End of ep loop + // we skip the mapping to real pads at first. We just say + // that we get 16 rows (segment R2) with 128 pads + // so each FEE fills 2 rows. Not right, but one step at a time. + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +//int TpcRawDataDecoder::ResetEvent(PHCompositeNode * /*topNode*/) +//{ +// std::cout << "TpcRawDataDecoder::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl; +// return Fun4AllReturnCodes::EVENT_OK; +//} + +//____________________________________________________________________________.. +//int TpcRawDataDecoder::EndRun(const int runnumber) +//{ +// std::cout << "TpcRawDataDecoder::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl; +// return Fun4AllReturnCodes::EVENT_OK; +//} + +//____________________________________________________________________________.. +int TpcRawDataDecoder::End(PHCompositeNode * /*topNode*/) +{ + std::cout << "TpcRawDataDecoder::End(PHCompositeNode *topNode) This is the End..." << std::endl; + hm->dumpHistos(_filename, "RECREATE"); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +//int TpcRawDataDecoder::Reset(PHCompositeNode * /*topNode*/) +//{ +// std::cout << "TpcRawDataDecoder::Reset(PHCompositeNode *topNode) being Reset" << std::endl; +// return Fun4AllReturnCodes::EVENT_OK; +//} + +//____________________________________________________________________________.. +//void TpcRawDataDecoder::Print(const std::string &what) const +//{ +// std::cout << "TpcRawDataDecoder::Print(const std::string &what) const Printing info for " << what << std::endl; +//} + +//____________________________________________________________________________.. +void TpcRawDataDecoder::setHistoFileName(const std::string &what) +{ + _filename = what; + std::cout << "TpcRawDataDecoder::setHistoFileName(const std::string &what) Histogram File Name is " << what << std::endl; +} \ No newline at end of file diff --git a/offline/packages/tpc/TpcRawDataDecoder.h b/offline/packages/tpc/TpcRawDataDecoder.h new file mode 100644 index 0000000000..f368a20cbd --- /dev/null +++ b/offline/packages/tpc/TpcRawDataDecoder.h @@ -0,0 +1,98 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef TPCRAWDATADECODER_H +#define TPCRAWDATADECODER_H + +#include "TpcMap.h" + +#include +#include + +#include + +#include +#include + +class PHCompositeNode; +class Fun4AllHistoManager; +//class TrkrHitSetContainer; +//class TrkrHitSet; +//class TrkrHit; +class TH2; +class TNtuple; + +class TpcRawDataDecoder : public SubsysReco +{ + public: + TpcRawDataDecoder(const std::string &name = "TpcRawDataDecoder"); + + ~TpcRawDataDecoder() override; + + int Init(PHCompositeNode *topNode) override; + + /** Called for first event when run number is known. + Typically this is where you may want to fetch data from + database, because you know the run number. A place + to book histograms which have to know the run number. + */ + int InitRun(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode *topNode) override; + + /// Clean up internals after each event. + //int ResetEvent(PHCompositeNode *topNode) override; + + /// Called at the end of each run. + //int EndRun(const int runnumber) override; + + /// Called at the end of all processing. + int End(PHCompositeNode *topNode) override; + + /// Reset + //int Reset(PHCompositeNode * /*topNode*/) override; + + //void Print(const std::string &what = "ALL") const override; + void setHistoFileName(const std::string &what = "./outputfile.root"); + + protected: + Fun4AllHistoManager *hm = nullptr; + std::string _filename; + + static const int layercount = 16; + static const int layeroffset = 7 + 16; + + //TrkrHitSetContainer *m_hits = nullptr; + TrkrHitSet *m_hitset[layercount] = {}; + //TrkrHit *m_hit = nullptr; + + // RawHitSetContainer *m_rawhits __attribute__ ((unused)) = nullptr; + + TpcMap M; + TNtuple *h_Alive = nullptr; + + struct tpc_map + { + unsigned int CHN_ID; + unsigned int FEE_ID; + unsigned int MOD_ID; + double PedMean; + double PedStdi; + unsigned int SEC_ID; + }; + + std::map tmap; + + int starting_BCO; + int rollover_value; + int current_BCOBIN; + + private: + + TH2* _h_hit_XY = nullptr; + +}; + +#endif // TPC_RAWDATADECODER_H diff --git a/offline/packages/tpc/TpcRawDataTree.cc b/offline/packages/tpc/TpcRawDataTree.cc new file mode 100644 index 0000000000..ba2e30bfef --- /dev/null +++ b/offline/packages/tpc/TpcRawDataTree.cc @@ -0,0 +1,150 @@ + +#include "TpcRawDataTree.h" + +#include +#include +#include // for PHIODataNode +#include // for PHNodeIterator +#include // for PHObject +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +//____________________________________________________________________________.. +TpcRawDataTree::TpcRawDataTree(const std::string &name) + : SubsysReco("TpcRawDataTree") + , m_fname(name) +{ + // reserve memory for max ADC samples + m_adcSamples.resize(1024, 0); + + // add all possible TPC packet that we need to analyze + // if a subset is needed, call RemoveAllPackets() + for (int packet = 4001; packet <= 4231; packet += 10) + { + m_packets.push_back(packet); + m_packets.push_back(packet+1); + } +} + +//____________________________________________________________________________.. +int TpcRawDataTree::InitRun(PHCompositeNode *) +{ + m_file = TFile::Open(m_fname.c_str(), "recreate"); + assert(m_file->IsOpen()); + + m_PacketTree = new TTree("PacketTree", "Each entry is one packet"); + + m_PacketTree->Branch("packet", &m_packet, "packet/I"); + m_PacketTree->Branch("frame", &m_frame, "frame/I"); + m_PacketTree->Branch("nWaveormInFrame", &m_nWaveormInFrame, "nWaveormInFrame/I"); + m_PacketTree->Branch("maxFEECount", &m_maxFEECount, "maxFEECount/I"); + + m_SampleTree = new TTree("SampleTree", "Each entry is one waveform"); + + m_SampleTree->Branch("packet", &m_packet, "packet/I"); + m_SampleTree->Branch("frame", &m_frame, "frame/I"); + m_SampleTree->Branch("nWaveormInFrame", &m_nWaveormInFrame, "nWaveormInFrame/I"); + m_SampleTree->Branch("maxFEECount", &m_maxFEECount, "maxFEECount/I"); + + m_SampleTree->Branch("nSamples", &m_nSamples, "nSamples/I"); + m_SampleTree->Branch("adcSamples", &m_adcSamples[0], "adcSamples[nSamples]/s"); + m_SampleTree->Branch("fee", &m_fee, "fee/I"); + m_SampleTree->Branch("sampaAddress", &m_sampaAddress, "sampaAddress/I"); + m_SampleTree->Branch("sampaChannel", &m_sampaChannel, "sampaChannel/I"); + m_SampleTree->Branch("Channel", &m_Channel, "Channel/I"); + m_SampleTree->Branch("BCO", &m_BCO, "BCO/I"); + m_SampleTree->Branch("checksum", &m_checksum, "checksum/I"); + m_SampleTree->Branch("checksumError", &m_checksumError, "checksumError/I"); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TpcRawDataTree::process_event(PHCompositeNode *topNode) +{ + Event *_event = findNode::getClass(topNode, "PRDF"); + if (_event == nullptr) + { + std::cout << "TpcRawDataTree::Process_Event Event not found" << std::endl; + return -1; + } + if (_event->getEvtType() >= 8) /// special events + { + return Fun4AllReturnCodes::DISCARDEVENT; + } + + m_frame = _event->getEvtSequence(); + + for (int packet : m_packets) + { + if (Verbosity()) + { + std::cout << __PRETTY_FUNCTION__ << " : decoding packet " << packet << std::endl; + } + + m_packet = packet; + + std::unique_ptr p(_event->getPacket(m_packet)); + if (!p) + { + if (Verbosity()) + { + std::cout << __PRETTY_FUNCTION__ << " : missing packet " << packet << std::endl; + } + + continue; + } + + m_nWaveormInFrame = p->iValue(0, "NR_WF"); + m_maxFEECount = p->iValue(0, "MAX_FEECOUNT"); + + for (int wf = 0; wf < m_nWaveormInFrame; wf++) + { + m_BCO = p->iValue(wf, "BCO"); + m_nSamples = p->iValue(wf, "SAMPLES"); + m_fee = p->iValue(wf, "FEE"); + + m_sampaAddress = p->iValue(wf, "SAMPAADDRESS"); + m_sampaChannel = p->iValue(wf, "SAMPACHANNEL"); + m_Channel = p->iValue(wf, "CHANNEL"); + m_checksum = p->iValue(wf, "CHECKSUM"); + m_checksumError = p->iValue(wf, "CHECKSUMERROR"); + + assert(m_nSamples < (int) m_adcSamples.size()); // no need for movements in memory allocation + for (int s = 0; s < m_nSamples; s++) + { + m_adcSamples[s] = p->iValue(wf, s); + } + + m_SampleTree->Fill(); + } + + m_PacketTree->Fill(); + } // for (int packet : m_packets) + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int TpcRawDataTree::End(PHCompositeNode * /*topNode*/) +{ + m_file->Write(); + + std::cout << __PRETTY_FUNCTION__ << " : completed saving to " << m_file->GetName() << std::endl; + m_file->ls(); + + m_file->Close(); + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/tpc/TpcRawDataTree.h b/offline/packages/tpc/TpcRawDataTree.h new file mode 100644 index 0000000000..735fd59e47 --- /dev/null +++ b/offline/packages/tpc/TpcRawDataTree.h @@ -0,0 +1,73 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef TpcRawDataTree_H +#define TpcRawDataTree_H + +#include + +#include +#include + +class PHCompositeNode; +class TFile; +class TTree; + +//! Dump TPC raw data in PRDF format to a TTree for online debugging and seeding formal Fun4All reco/calib modules +class TpcRawDataTree : public SubsysReco +{ + public: + explicit TpcRawDataTree(const std::string &fname = "TpcRawDataTree.root"); + + ~TpcRawDataTree() override {} + + /** Called for first event when run number is known. + Typically this is where you may want to fetch data from + database, because you know the run number. A place + to book histograms which have to know the run number. + */ + int InitRun(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode *topNode) override; + + /// Called at the end of all processing. + int End(PHCompositeNode *topNode) override; + + void AddPacket(int packet) + { + m_packets.push_back(packet); + } + void RemoveAllPackets() + { + m_packets.clear(); + } + + protected: + //! which packet to decode + std::vector m_packets; + + private: + + std::string m_fname; + TFile * m_file = nullptr; + TTree * m_SampleTree = nullptr; + TTree * m_PacketTree = nullptr; + + int m_packet = 0; + int m_frame = 0; + int m_nWaveormInFrame = 0; + int m_maxFEECount = 0; + int m_nSamples = 0; + int m_fee = 0; + int m_sampaAddress = 0; + int m_sampaChannel = 0; + int m_Channel = 0; + int m_BCO = 0; + int m_checksum = 0; + int m_checksumError = 0; + std::vector m_adcSamples; +}; + +#endif // TpcRawDataTree_H diff --git a/offline/packages/tpc/TpcRawWriter.cc b/offline/packages/tpc/TpcRawWriter.cc index ce66a38c7f..8a3bd51546 100644 --- a/offline/packages/tpc/TpcRawWriter.cc +++ b/offline/packages/tpc/TpcRawWriter.cc @@ -148,10 +148,10 @@ int TpcRawWriter::process_event(PHCompositeNode *topNode) } // get node containing the digitized hits - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (!m_hits) { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_TPC" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } @@ -159,7 +159,7 @@ int TpcRawWriter::process_event(PHCompositeNode *topNode) m_rawhits = findNode::getClass(topNode, "TRKR_RAWHITSET"); if (!m_rawhits) { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + std::cout << PHWHERE << "ERROR: Can't find node TRKR_RAWHITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } diff --git a/offline/packages/tpc/TpcSimpleClusterizer.cc b/offline/packages/tpc/TpcSimpleClusterizer.cc index bdaff199c7..9af08bd46e 100644 --- a/offline/packages/tpc/TpcSimpleClusterizer.cc +++ b/offline/packages/tpc/TpcSimpleClusterizer.cc @@ -438,10 +438,10 @@ int TpcSimpleClusterizer::process_event(PHCompositeNode *topNode) } // get node containing the digitized hits - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (!m_hits) { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_TPC" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } diff --git a/offline/packages/tpccalib/Makefile.am b/offline/packages/tpccalib/Makefile.am index 14485cca1b..34d3fc4182 100644 --- a/offline/packages/tpccalib/Makefile.am +++ b/offline/packages/tpccalib/Makefile.am @@ -30,6 +30,7 @@ libtpccalib_la_LIBADD = \ -lg4detectors_io \ -ltrack_io \ -ltrackbase_historic_io \ + -ltrack_reco \ -ltpc_io pkginclude_HEADERS = \ diff --git a/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.cc b/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.cc index 1aa2351963..6ce2370f0d 100644 --- a/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.cc +++ b/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.cc @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -22,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -59,6 +58,9 @@ int PHTpcCentralMembraneClusterizer::InitRun(PHCompositeNode *topNode) henergy = new TH1F("henergy", "cluster energy", 200, 0, 2000); hxy = new TH2F("hxy","cluster x:y",800,-100,100,800,-80,80); hz = new TH1F("hz","cluster z", 220, -2,2); + + hz_pos = new TH1F("hz_pos","cluster z>0", 400, 0,110); + hz_neg = new TH1F("hz_neg","cluster z<0", 400, -110,0); hClustE[0]= new TH1F("hRawClusterEnergy","Cluster Energy Before Merging;E[?]",200,0,2000); hClustE[1] = new TH1F("hMatchedClusterEnergy","Pair Cluster Energy After Merging;E[?]",200,0,2000); @@ -70,6 +72,20 @@ int PHTpcCentralMembraneClusterizer::InitRun(PHCompositeNode *topNode) hDistRowAdj=new TH2F("hDistRowAdj","phi distance to nearby clusters vs (lower)row;dist[rad];(lower) padrow",100,-0.001,0.01,60,-0.5,59.5); hDist2Adj=new TH1F("hDist2Adj","phi distance to nearby clusters on adjacent padrow;dist[rad]",100,-0.001,0.01); } + + hrPhi_reco_petalModulo_pos = new TH2F("hrPhi_reco_petalModulo_pos","Reco R vs #phi Z > 0;#phi;R (cm)",50,0.0,M_PI/9,400,20,78); + hrPhi_reco_petalModulo_neg = new TH2F("hrPhi_reco_petalModulo_neg","Reco R vs #phi;#phi Z < 0;R (cm)",50,0.0,M_PI/9,400,20,78); + + for(int i=0; i<48; i++){ + hphi_reco_pos[i] = new TH1F(Form("hphi_reco_pos_layer%02d",7+i),Form("Reco #phi for Layer %02d Z > 0;#phi;counts",7+i),50,0.0,M_PI/9); + hphi_reco_neg[i] = new TH1F(Form("hphi_reco_neg_layer%02d",7+i),Form("Reco #phi for Layer %02d Z < 0;#phi;counts",7+i),50,0.0,M_PI/9); + + if(i<47){ + hphi_reco_pair_pos[i] = new TH1F(Form("hphi_reco_pair_pos_layers%02d_%02d",7+i,8+i),Form("Reco #phi for Layers %02d and %02d Z > 0;#phi;counts",7+i,8+i),50,0.0,M_PI/9); + hphi_reco_pair_neg[i] = new TH1F(Form("hphi_reco_pair_neg_layers%02d_%02d",7+i,8+i),Form("Reco #phi for Layers %02d and %02d Z < 0;#phi;counts",7+i,8+i),50,0.0,M_PI/9); + + } + } return ret; } @@ -93,8 +109,94 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) std::vector side; // cluster side std::vectori_pair; //vector for pair matching std::vectorenergy;//vector for energy values of clusters + std::vectorisAcrossGap; int nTpcClust = 0; + + double mean_z_content_plus = 0.0; + double mean_z_content_minus = 0.0; + //first loop over clusters to make mod phi histograms of each layer and each pair of layers + for(const auto& hitsetkey:_cluster_map->getHitSetKeys(TrkrDefs::TrkrId::tpcId)) + { + auto clusRange = _cluster_map->getClusters(hitsetkey); + for (auto clusiter = clusRange.first; + clusiter != clusRange.second; ++clusiter) + { + + const auto& [cluskey, cluster] = *clusiter; + auto glob = tgeometry->getGlobalPosition(cluskey, cluster); + TVector3 tmp_pos(glob(0),glob(1),glob(2)); + + unsigned int layer = TrkrDefs::getLayer(cluskey); + + double phi = tmp_pos.Phi(); + + double phiMod = phi; + + //make sure phiMod is between 0 and pi/9 + while(phiMod < 0.0 || phiMod > M_PI/9){ + if(phiMod < 0.0) phiMod += M_PI/9; + else if(phiMod > M_PI/9) phiMod -= M_PI/9; + } + + if(tmp_pos.Z() >= 0.0){ + + hz_pos->Fill(tmp_pos.Z()); + + //mean_z_content_plus += tmp_pos.Z(); + + hrPhi_reco_petalModulo_pos->Fill(phiMod, tmp_pos.Perp()); + hphi_reco_pos[layer-7]->Fill(phiMod); + //for layer pairs, if last layer can only go in layer 53-54 pair, if first layer can only go in layer 7-8 pair + if(layer < 54) hphi_reco_pair_pos[layer-7]->Fill(phiMod); + if(layer > 7) hphi_reco_pair_pos[layer-8]->Fill(phiMod); + }else{ + + hz_neg->Fill(tmp_pos.Z()); + + //mean_z_content_minus += tmp_pos.Z(); + + hrPhi_reco_petalModulo_neg->Fill(phiMod, tmp_pos.Perp()); + hphi_reco_neg[layer-7]->Fill(phiMod); + //for layer pairs, if last layer can only go in layer 53-54 pair, if first layer can only go in layer 7-8 pair + if(layer < 54) hphi_reco_pair_neg[layer-7]->Fill(phiMod); + if(layer > 7) hphi_reco_pair_neg[layer-8]->Fill(phiMod); + } + + } + } + + for(int i=1; iGetNbinsX(); i++){ + mean_z_content_plus += hz_pos->GetBinContent(i); + } + for(int i=1; iGetNbinsX(); i++){ + mean_z_content_minus += hz_neg->GetBinContent(i); + } + + mean_z_content_plus = mean_z_content_plus/hz_pos->GetNbinsX(); + mean_z_content_minus = mean_z_content_minus/hz_neg->GetNbinsX(); + + + //use peak in z distributions to identify if there is a CM Flash. Peak should be >20% of entries (needs to be tuned) + if(hz_pos->GetMaximum() < 5*mean_z_content_plus || hz_neg->GetMaximum() < 5*mean_z_content_minus) return Fun4AllReturnCodes::EVENT_OK; + + //loop over histos for each pair of layers, count number of bins above threshold + //for a given layer, layer pair with higher average value above threshold will be better match for meta-clustering + for(int i=0; i<47; i++){ + for(int j=1; jGetNbinsX(); j++){ + if(hphi_reco_pair_pos[i]->GetBinContent(j) > (m_metaClusterThreshold + (mean_z_content_plus/18.0))){ + nPairAbove_pos[i]++; + pairAboveContent_pos[i] += (hphi_reco_pair_pos[i]->GetBinContent(j)-(m_metaClusterThreshold + (mean_z_content_plus/18.0))); + } + if(hphi_reco_pair_neg[i]->GetBinContent(j) > (m_metaClusterThreshold + (mean_z_content_minus/18.0))){ + nPairAbove_neg[i]++; + pairAboveContent_neg[i] += (hphi_reco_pair_neg[i]->GetBinContent(j)-(m_metaClusterThreshold + (mean_z_content_minus/18.0))); + } + } + } + + + //loop over clusters again for(const auto& hitsetkey:_cluster_map->getHitSetKeys(TrkrDefs::TrkrId::tpcId)) { auto clusRange = _cluster_map->getClusters(hitsetkey); @@ -106,7 +208,7 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) const auto& [cluskey, cluster] = *clusiter; auto glob = tgeometry->getGlobalPosition(cluskey, cluster); - // std::cout << "PHTpcCentralMembraneClusterizer::process_event - key: " << cluskey << "z: " << glob.z() << std::endl; + // std::cout << "PHTpcCentralMembraneClusterizer::process_event - key: " << cluskey << "z: " << glob.z() << std::endl; float x = glob(0); float y = glob(1); @@ -118,10 +220,40 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) unsigned short side = TpcDefs::getSide(cluskey); std::cout << " z " << z << " side " << side << " layer " << lyr << " Adc " << cluster->getAdc() << " x " << x << " y " << y << std::endl; } + + TVector3 tmp_pos(x,y,z); + + unsigned int lay = TrkrDefs::getLayer(cluskey); + + double phi = tmp_pos.Phi(); + double phiMod = phi; + + while(phiMod < 0.0 || phiMod > M_PI/9){ + if(phiMod < 0.0) phiMod += M_PI/9; + else if(phiMod > M_PI/9) phiMod -= M_PI/9; + } + + int phiBin = -1; + + bool aboveThreshold = true; + + //Find which phiMod bin cluster is in (with given layer) and if counts below threshold don't use + if(z >= 0){ + phiBin = hphi_reco_pos[lay-7]->GetXaxis()->FindBin(phiMod); + if(hphi_reco_pos[lay-7]->GetBinContent(phiBin) < m_moduloThreshold) aboveThreshold = false; + }else{ + phiBin = hphi_reco_neg[lay-7]->GetXaxis()->FindBin(phiMod); + if(hphi_reco_neg[lay-7]->GetBinContent(phiBin) < m_moduloThreshold) aboveThreshold = false; + } + + if( !aboveThreshold ) continue; if(cluster->getAdc() < _min_adc_value) continue; if( std::abs(z) < _min_z_value) continue; - + + //require that z be within 1cm of peak in z distributions (separate for each side) + if( (z>=0 && std::abs(z - hz_pos->GetBinCenter(hz_pos->GetMaximumBin())) > 1.0) || (z<0 && std::abs(z - hz_neg->GetBinCenter(hz_neg->GetMaximumBin())) > 1.0) ) continue; + ++m_accepted_clusters; i_pair.push_back(-1); @@ -130,7 +262,7 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) pos.push_back(TVector3(x,y,z)); layer.push_back((int)(TrkrDefs::getLayer(cluskey))); side.push_back(TpcDefs::getSide(cluskey)); - + isAcrossGap.push_back(false); if(Verbosity() > 0) std::cout << ":\t" << x << "\t" << y << "\t" << z <= 39) nRowsMatch = 4; + else if(layer[i] >= 23) nRowsMatch = 3; + + if( pos[i].Z() >= 0 ){ + if(layer[i] == 7){ + //if layer is 7, can only get one layer match + if(nPairAbove_pos[layer[i]-7] >= nRowsMatch) layerMatch = layer[i]+1; + }else if(layer[i] == 54){ + //if layer is 8, can only get one layer match + if(nPairAbove_pos[layer[i]-8] >= nRowsMatch) layerMatch = layer[i]-1; + }else{ + //if both pairs of rows have enough bins above threshold, match to pair with higher average + if(nPairAbove_pos[layer[i]-7] >= nRowsMatch && nPairAbove_pos[layer[i]-8] >= nRowsMatch){ + if(pairAboveContent_pos[layer[i]-7]/nPairAbove_pos[layer[i]-7] > pairAboveContent_pos[layer[i]-8]/nPairAbove_pos[layer[i]-8]) layerMatch = layer[i]+1; + else layerMatch = layer[i]-1; + //otherwise just use the one that is above threshold + }else if(nPairAbove_pos[layer[i]-7] >= nRowsMatch) layerMatch = layer[i]+1; + else if(nPairAbove_pos[layer[i]-8] >= nRowsMatch) layerMatch = layer[i]-1; + } + }else{ + if(layer[i] == 7){ + if(nPairAbove_neg[layer[i]-7] >= nRowsMatch) layerMatch = layer[i]+1; + }else if(layer[i] == 54){ + if(nPairAbove_neg[layer[i]-8] >= nRowsMatch) layerMatch = layer[i]-1; + }else{ + if(nPairAbove_neg[layer[i]-7] >= nRowsMatch && nPairAbove_neg[layer[i]-8] >= nRowsMatch){ + if(pairAboveContent_neg[layer[i]-7]/nPairAbove_neg[layer[i]-7] > pairAboveContent_neg[layer[i]-8]/nPairAbove_neg[layer[i]-8]) layerMatch = layer[i]+1; + else layerMatch = layer[i]-1; + }else if(nPairAbove_neg[layer[i]-7] >= nRowsMatch) layerMatch = layer[i]+1; + else if(nPairAbove_neg[layer[i]-8] >= nRowsMatch) layerMatch = layer[i]-1; + } + } + + //if the match is default and the layer is on the edge of a module, identify it as being across the gap + // if(layerMatch == -1 && (layer[i] == 22 || layer[i] == 23 || layer[i] == 38 || layer[i] == 39 || layer[i] == 7) ) isAcrossGap[i] = true; + if(layer[i] == 22 || layer[i] == 23 || layer[i] == 38 || layer[i] == 39 || layer[i] == 7) isAcrossGap[i] = true; + float bestphidist=maxphidist; for (int j=0;j 0.5) continue; const float newphidist=std::abs(pos[i].DeltaPhi(pos[j])); if (newphidistaveenergy; std::vector avepos; std::vector nclusters; + std::vector isREdge; + std::vector > pairNums; + + // int nR2 = 0; + //int nR3 = 0; + + // double R2AveE = 0.0; + //double R3AveE = 0.0; + + std::pair tmp_pair; + for (int i=0;iFill(energy[i]); @@ -242,6 +437,9 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) if(_histos) hClustE[1]->Fill(energy[i]+energy[i_pair[i]]); aveenergy.push_back(energy[i]+energy[i_pair[i]]); + + // if( + // The pads measure phi and z accurately // They do not measure R! It is taken as the center of the padrow @@ -264,18 +462,9 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) double rad1 = layergeom1->get_radius(); PHG4TpcCylinderGeom *layergeom2 = _geom_container->GetLayerCellGeom(layer[i_pair[i]]); double rad2 = layergeom2->get_radius(); - PHG4TpcCylinderGeom *layergeom0; - double layer_dr; - if(layer[i] != 7 && layer[i] != 23 && layer[i] != 39) - { - layergeom0 = _geom_container->GetLayerCellGeom(layer[i]-1); - layer_dr = rad1 - layergeom0->get_radius(); - } - else - { - layergeom0 = _geom_container->GetLayerCellGeom(layer[i]+1); - layer_dr = layergeom0->get_radius() - rad1; - } + //matching done correctly now, so distance between layers should be directly calculable + double layer_dr = std::abs(rad1 - rad2); + double rad_lyr_boundary = rad1 + layer_dr / 2.0; @@ -284,11 +473,18 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) if( _dcc) dist_pos = _distortionCorrection.get_corrected_position( dist_pos, _dcc ); double dist_r = sqrt(dist_pos[0]*dist_pos[0] + dist_pos[1] * dist_pos[1]); double cmclus_dr = _cmclus_dr_outer; - if(dist_r < 41.0) - cmclus_dr = _cmclus_dr_inner; - else if(dist_r >= 41.0 && rad2 < 58.0) - cmclus_dr = _cmclus_dr_mid; - // Use radial width of stripe and efrac to determine where radius at center of distribution must be + + if(dist_r < 41.0){ + //if across boundary, use average + if(rad2 >= 41.0) cmclus_dr = 0.5*(_cmclus_dr_inner + _cmclus_dr_mid); + else cmclus_dr = _cmclus_dr_inner; + }else if(dist_r >= 41.0 && dist_r < 58.0){ + //if across boundary, use average + if(rad2 >= 58.0) cmclus_dr = 0.5*(_cmclus_dr_mid + _cmclus_dr_outer); + else cmclus_dr = _cmclus_dr_mid; + } + + // Use radial width of stripe and efrac to determine where radius at center of distribution must be double aveR = rad_lyr_boundary - efrac * cmclus_dr + cmclus_dr/2.0; if(Verbosity() > 0) @@ -298,20 +494,36 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) TVector3 temppos(aveR*cos(avePhi), aveR*sin(avePhi), aveZ); avepos.push_back(temppos); nclusters.push_back(2); - + if(isAcrossGap[i] && isAcrossGap[i_pair[i]]) isREdge.push_back(true); + else isREdge.push_back(false); + + tmp_pair.first = i; + tmp_pair.second = i_pair[i]; + pairNums.push_back(tmp_pair); + + + if(Verbosity() > 0) std::cout << " layer i " << layer[i] << " energy " << energy[i] << " pos i " << pos[i].X() << " " << pos[i].Y() << " " << pos[i].Z() << " layer i_pair " << layer[i_pair[i]] << " energy i_pair " << energy[i_pair[i]] << " pos i_pair " << pos[i_pair[i]].X() << " " << pos[i_pair[i]].Y() << " " << pos[i_pair[i]].Z() - << " reco pos " << temppos.x() << " " << temppos.Y() << " " << temppos.Z() - << std::endl; + << " reco pos " << temppos.X() << " " << temppos.Y() << " " << temppos.Z() + << std::endl; } } else { + if(_histos) hClustE[2]->Fill(energy[i]); - // These single cluster cases have good phi, but do not have a good radius centroid estimate - may want to skip them, record nclusters + // These single cluster cases have good phi, but do not have a good radius centroid estimate - may want to skip them, record nclusters and identify if across gap + // if(layer[i] == 7) isAcrossGap[i] = true; + aveenergy.push_back(energy[i]); avepos.push_back(pos[i]); nclusters.push_back(1); + isREdge.push_back(isAcrossGap[i]); + tmp_pair.first = i; + tmp_pair.second = -1; + pairNums.push_back(tmp_pair); + } } @@ -321,14 +533,38 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) for(unsigned int iv = 0; iv setX(avepos[iv].X()); cmfc->setY(avepos[iv].Y()); cmfc->setZ(avepos[iv].Z()); cmfc->setAdc(aveenergy[iv]); cmfc->setNclusters(nclusters[iv]); + cmfc->setIsRGap(isREdge[iv]); + int pair1 = pairNums[iv].first; + int pair2 = pairNums[iv].second; + + cmfc->setX1(pos[pair1].X()); + cmfc->setY1(pos[pair1].Y()); + cmfc->setZ1(pos[pair1].Z()); + cmfc->setLayer1(layer[pair1]); + cmfc->setAdc1(energy[pair1]); + if(pair2 != -1){ + cmfc->setX2(pos[pair2].X()); + cmfc->setY2(pos[pair2].Y()); + cmfc->setZ2(pos[pair2].Z()); + cmfc->setLayer2(layer[pair2]); + cmfc->setAdc2(energy[pair2]); + }else{ + cmfc->setX2(0); + cmfc->setY2(0); + cmfc->setZ2(0); + cmfc->setLayer2(0); + cmfc->setAdc2(0); + } + _corrected_CMcluster_map->addClusterSpecifyKey(iv, cmfc); ++m_cm_clusters; @@ -353,7 +589,7 @@ int PHTpcCentralMembraneClusterizer::process_event(PHCompositeNode *topNode) << " x " << cmclus->getX() << " y " << cmclus->getY() << " z " << cmclus->getZ() << " nclusters " << cmclus->getNclusters() << std::endl; - + if(_histos) { henergy->Fill(cmclus->getAdc()); @@ -377,6 +613,9 @@ int PHTpcCentralMembraneClusterizer::End(PHCompositeNode * /*topNode*/ ) hxy->Write(); hz->Write(); + hz_pos->Write(); + hz_neg->Write(); + hClustE[0]->Write(); hClustE[1]->Write(); hClustE[2]->Write(); @@ -386,9 +625,14 @@ int PHTpcCentralMembraneClusterizer::End(PHCompositeNode * /*topNode*/ ) hDistRowAdj->Write(); hDist2Adj->Write(); + for(int i=0; i<47; i++){ + hphi_reco_pair_pos[i]->Write(); + hphi_reco_pair_neg[i]->Write(); + } + m_histogramfile->Close(); } - + // print statistics if( Verbosity() ) { diff --git a/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.h b/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.h index b78e9b5b87..4994ac75e5 100644 --- a/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.h +++ b/offline/packages/tpccalib/PHTpcCentralMembraneClusterizer.h @@ -24,7 +24,6 @@ class CMFlashClusterContainer; class PHG4TpcCylinderGeomContainer; class TF1; -class TNtuple; class TFile; class TH1F; class TH2F; @@ -45,6 +44,9 @@ class PHTpcCentralMembraneClusterizer : public SubsysReco void set_min_z_value(const double val) {_min_z_value = val;} void set_stripe_dr_values(const double dr1, const double dr2, const double dr3){ _cmclus_dr_inner = dr1; _cmclus_dr_mid = dr2; _cmclus_dr_outer = dr3;} + void set_modulo_threshold( int val ) { m_moduloThreshold = val; } + void set_metaCluster_threshold( int val ) { m_metaClusterThreshold = val; } + //! run initialization int InitRun(PHCompositeNode *topNode); @@ -78,10 +80,15 @@ class PHTpcCentralMembraneClusterizer : public SubsysReco int m_cm_clusters_size1 = 0; int m_cm_clusters_size2 = 0; //@} + + int m_moduloThreshold = 5; + int m_metaClusterThreshold = 18; bool _histos = false; TH1F *henergy = nullptr; TH1F *hz = nullptr; + TH1F *hz_pos = nullptr; + TH1F *hz_neg = nullptr; TH2F *hxy = nullptr; TH1F *hDist = nullptr; TH2F *hDistRow = nullptr; @@ -89,18 +96,31 @@ class PHTpcCentralMembraneClusterizer : public SubsysReco TH2F *hDistRowAdj = nullptr; TH1F *hDist2Adj = nullptr; TH1F *hClustE[3] = {nullptr}; + + TH2F *hrPhi_reco_petalModulo_pos = nullptr; + TH2F *hrPhi_reco_petalModulo_neg = nullptr; + TH1F *hphi_reco_pos[48] = {nullptr}; + TH1F *hphi_reco_neg[48] = {nullptr}; + + TH1F *hphi_reco_pair_pos[47] = {nullptr}; + TH1F *hphi_reco_pair_neg[47] = {nullptr}; + + int nPairAbove_pos[47] = {0}; + int nPairAbove_neg[47] = {0}; + + double pairAboveContent_pos[47] = {0.0}; + double pairAboveContent_neg[47] = {0.0}; + std::string m_histogramfilename = "PHTpcCentralMembraneClusterizer.root"; std::unique_ptr m_histogramfile; - + unsigned int _min_adc_value = 0; double _min_z_value = 0.0; double _cmclus_dr_inner = 0.51; //cm double _cmclus_dr_mid = 0.95; //cm double _cmclus_dr_outer = 1.025; //cm - - }; #endif // PHTPCCENTRALMEMBRANECLUSTERIZER_H diff --git a/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.cc b/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.cc index 639980862a..4000e4a1de 100644 --- a/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.cc +++ b/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.cc @@ -11,19 +11,21 @@ #include #include #include -#include +#include #include #include #include -#include #include #include #include +#include #include +#include #include #include #include +#include #include #include @@ -139,13 +141,101 @@ void PHTpcCentralMembraneMatcher::set_grid_dimensions( int phibins, int rbins ) m_rbins = rbins; } +/* +std::vector PHTpcCentralMembraneMatcher::getRGaps( TH2F *r_phi ){ + + TH1D *proj = r_phi->ProjectionY("R_proj",1,360); + + std::vector pass1; + + for(int i=2; iGetNbinsX(); i++){ + if(proj->GetBinContent(i) > 0.15*proj->GetMaximum() && proj->GetBinContent(i) >= proj->GetBinContent(i-1) && proj->GetBinContent(i) >= proj->GetBinContent(i+1)) pass1.push_back(proj->GetBinCenter(i)); + } + + for(int i=0; i<(int)pass1.size()-1; i++){ + if(pass1[i+1]-pass1[i] > 0.75) continue; + + if(proj->GetBinContent(proj->FindBin(pass1[i])) > proj->GetBinContent(proj->FindBin(pass1[i+1]))) pass1.erase(std::next(pass1.begin(), i+1)); + else pass1.erase(std::next(pass1.begin(), i)); + + i--; + } + + return pass1; + +} +*/ + +//get the average phi rotation using smoothed histograms +double PHTpcCentralMembraneMatcher::getPhiRotation_smoothed(TH1D *hitHist, TH1D *clustHist){ + + //smooth the truth and cluster histograms + hitHist->Smooth(); + clustHist->Smooth(); + + //make a TF1 with a lambda function to make a function out of the truth histogram and shift it by a constant + TF1 *f1 = new TF1("f1",[&](double *x, double *p){ return p[0] * hitHist->GetBinContent(hitHist->FindBin((x[0] - p[1])>M_PI?x[0] - p[1] - 2*M_PI: x[0] - p[1])); }, -M_PI, M_PI, 2); + f1->SetParNames("A","shift"); + f1->SetParameters(1.0,0.0); + // f1->SetParLimits(1,-M_PI/18,M_PI/18); + + f1->SetNpx(500); + + clustHist->Fit("f1","IQ"); + + // clustHist->Draw(); + //f1->Draw("same"); + + return f1->GetParameter(1); +} + +//get vector with peak positions in Y (R) of histogram +std::vector PHTpcCentralMembraneMatcher::getRPeaks(TH2F *r_phi){ + + TH1D *proj = r_phi->ProjectionY("R_proj"); + + std::vector rPeaks; + + for(int i=2; iGetNbinsX(); i++){ + //peak is when content is higher than 0.15* maximum value and content is greater than or equal to both adjacent bins + if(proj->GetBinContent(i) > 0.15*proj->GetMaximum() && proj->GetBinContent(i) >= proj->GetBinContent(i-1) && proj->GetBinContent(i) >= proj->GetBinContent(i+1)) rPeaks.push_back(proj->GetBinCenter(i)); + } + + //if two peaks are within 0.75 cm of eachother, remove one with fewer counts + for(int i=0; i<(int)rPeaks.size()-1; i++){ + if(rPeaks[i+1]-rPeaks[i] > 0.75) continue; + if(proj->GetBinContent(proj->FindBin(rPeaks[i])) > proj->GetBinContent(proj->FindBin(rPeaks[i+1]))) rPeaks.erase(rPeaks.begin()+i+1); + else rPeaks.erase(rPeaks.begin()+i); + i--; + } + return rPeaks; +} + +int PHTpcCentralMembraneMatcher::getClusterRMatch( std::vector hitMatches, std::vector clusterPeaks, double clusterR){ + + double closestDist = 100.; + int closestPeak = -1; + //find cluster peak closest to position of passed cluster + for(int j=0; j<(int)clusterPeaks.size(); j++){ + if(std::abs(clusterR - clusterPeaks[j]) < closestDist){ + closestDist = std::abs(clusterR - clusterPeaks[j]); + closestPeak = j; + } + } + + //return hit match to cluster peak or -1 if closest peak failed (shouldn't be possible) + if(closestPeak != -1) return hitMatches[closestPeak]; + else return -1; + +} + //____________________________________________________________________________.. int PHTpcCentralMembraneMatcher::InitRun(PHCompositeNode *topNode) { if( m_savehistograms ) { - static constexpr float max_dr = 1.0; + static constexpr float max_dr = 5.0; static constexpr float max_dphi = 0.05; fout.reset( new TFile(m_histogramfilename.c_str(),"RECREATE") ); @@ -175,13 +265,23 @@ int PHTpcCentralMembraneMatcher::InitRun(PHCompositeNode *topNode) hdr3_double = new TH1F("hdr3_double", "outer dr double", 200,-max_dr, max_dr); hdrphi = new TH1F("hdrphi","r * dphi", 200, -0.05, 0.05); hnclus = new TH1F("hnclus", " nclusters ", 3, 0., 3.); + + fout2.reset ( new TFile(m_histogramfilename2.c_str(),"RECREATE") ); + match_ntup = new TNtuple("match_ntup","Match NTuple","event:truthR:truthPhi:recoR:recoPhi:recoZ:nclus:r1:phi1:e1:layer1:r2:phi2:e2:layer2"); } + + hit_r_phi = new TH2F("hit_r_phi","hit r vs #phi;#phi (rad); r (cm)",360,-M_PI,M_PI,500,0,100); + + clust_r_phi_pos = new TH2F("clust_r_phi_pos","clust R vs #phi Z>0;#phi (rad); r (cm)",360,-M_PI,M_PI,500,0,100); + clust_r_phi_neg = new TH2F("clust_r_phi_neg","clust R vs #phi Z<0;#phi (rad); r (cm)",360,-M_PI,M_PI,500,0,100); + // Get truth cluster positions //===================== const double phi_petal = M_PI / 9.0; // angle span of one petal + /* * utility function to * - duplicate generated truth position to cover both sides of the central membrane @@ -192,9 +292,13 @@ int PHTpcCentralMembraneMatcher::InitRun(PHCompositeNode *topNode) { source.SetZ( +1 ); m_truth_pos.push_back( source ); - + + hit_r_phi->Fill(source.Phi(), source.Perp()); + source.SetZ( -1 ); m_truth_pos.push_back( source ); + + hit_r_phi->Fill(source.Phi(), source.Perp()); }; // inner region extended is the 8 layers inside 30 cm @@ -251,14 +355,14 @@ int PHTpcCentralMembraneMatcher::InitRun(PHCompositeNode *topNode) TVector3 dummyPos(cx3[i][j], cy3[i][j], 0.0); dummyPos.RotateZ(k * phi_petal); save_truth_position(dummyPos); - + if(Verbosity() > 2) std::cout << " i " << i << " j " << j << " k " << k << " x1 " << dummyPos.X() << " y1 " << dummyPos.Y() << " theta " << std::atan2(dummyPos.Y(), dummyPos.X()) << " radius " << get_r( dummyPos.X(), dummyPos.y()) << std::endl; if(m_savehistograms) hxy_truth->Fill(dummyPos.X(),dummyPos.Y()); - } - + } + int ret = GetNodes(topNode); return ret; } @@ -267,28 +371,83 @@ int PHTpcCentralMembraneMatcher::InitRun(PHCompositeNode *topNode) int PHTpcCentralMembraneMatcher::process_event(PHCompositeNode * /*topNode*/) { std::vector reco_pos; + std::vector pos1; + std::vector pos2; std::vector reco_nclusters; - + std::vector reco_adc; + std::vector adc1; + std::vector adc2; + std::vector layer1; + std::vector layer2; + // reset output distortion correction container histograms for( const auto& harray:{m_dcc_out->m_hDRint, m_dcc_out->m_hDPint, m_dcc_out->m_hDZint, m_dcc_out->m_hentries} ) - { for( const auto& h:harray ) { h->Reset(); } } + { + + clust_r_phi_pos->Reset(); + clust_r_phi_neg->Reset(); + + if(!m_corrected_CMcluster_map || m_corrected_CMcluster_map->size() < 100){ + m_event_index++; + return Fun4AllReturnCodes::EVENT_OK; + } + for( const auto& h:harray ) { h->Reset(); } } + // read the reconstructed CM clusters auto clusrange = m_corrected_CMcluster_map->getClusters(); for (auto cmitr = clusrange.first; cmitr !=clusrange.second; ++cmitr) { - const auto& [cmkey, cmclus] = *cmitr; + const auto& [cmkey, cmclus_orig] = *cmitr; + CMFlashCluster *cmclus = cmclus_orig; const unsigned int nclus = cmclus->getNclusters(); + const unsigned int adc = cmclus->getAdc(); + + if(m_useOnly_nClus2 && nclus != 2) continue; + + const bool isRGap = cmclus->getIsRGap(); + - // Do the static + average distortion corrections if the container was found + // Do the static + average distortion corrections if the container was found Acts::Vector3 pos(cmclus->getX(), cmclus->getY(), cmclus->getZ()); - if( m_dcc_in) pos = m_distortionCorrection.get_corrected_position( pos, m_dcc_in ); + Acts::Vector3 apos1(cmclus->getX1(), cmclus->getY1(), cmclus->getZ1()); + Acts::Vector3 apos2(cmclus->getX2(), cmclus->getY2(), cmclus->getZ2()); + if( m_dcc_in_static){ + pos = m_distortionCorrection.get_corrected_position( pos, m_dcc_in_static ); + apos1 = m_distortionCorrection.get_corrected_position( apos1, m_dcc_in_static ); + apos2 = m_distortionCorrection.get_corrected_position( apos2, m_dcc_in_static ); + } + if( m_dcc_in_average){ + pos = m_distortionCorrection.get_corrected_position( pos, m_dcc_in_average ); + apos1 = m_distortionCorrection.get_corrected_position( apos1, m_dcc_in_average ); + apos2 = m_distortionCorrection.get_corrected_position( apos2, m_dcc_in_average ); + } + + TVector3 tmp_pos(pos[0], pos[1], pos[2]); + TVector3 tmp_pos1(apos1[0], apos1[1], apos1[2]); + TVector3 tmp_pos2(apos2[0], apos2[1], apos2[2]); + + + if(nclus == 1 && isRGap) continue; + reco_pos.push_back(tmp_pos); + pos1.push_back(tmp_pos1); + pos2.push_back(tmp_pos2); reco_nclusters.push_back(nclus); + reco_adc.push_back(adc); + adc1.push_back(cmclus->getAdc1()); + adc2.push_back(cmclus->getAdc2()); + layer1.push_back(cmclus->getLayer1()); + layer2.push_back(cmclus->getLayer2()); + + if(tmp_pos.Z() < 0) clust_r_phi_neg->Fill(tmp_pos.Phi(),tmp_pos.Perp()); + else clust_r_phi_pos->Fill(tmp_pos.Phi(),tmp_pos.Perp()); + + if(Verbosity()) { @@ -304,80 +463,210 @@ int PHTpcCentralMembraneMatcher::process_event(PHCompositeNode * /*topNode*/) } } + + //get global phi rotation for each module + m_clustRotation_pos[0] = getPhiRotation_smoothed(hit_r_phi->ProjectionX("hR1",151,206),clust_r_phi_pos->ProjectionX("cR1_pos",151,206)); + m_clustRotation_pos[1] = getPhiRotation_smoothed(hit_r_phi->ProjectionX("hR2",206,290),clust_r_phi_pos->ProjectionX("cR2_pos",206,290)); + m_clustRotation_pos[2] = getPhiRotation_smoothed(hit_r_phi->ProjectionX("hR3",290,499),clust_r_phi_pos->ProjectionX("cR3_pos",290,499)); + + m_clustRotation_neg[0] = getPhiRotation_smoothed(hit_r_phi->ProjectionX("hR1",151,206),clust_r_phi_neg->ProjectionX("cR1_neg",151,206)); + m_clustRotation_neg[1] = getPhiRotation_smoothed(hit_r_phi->ProjectionX("hR2",206,290),clust_r_phi_neg->ProjectionX("cR2_neg",206,290)); + m_clustRotation_neg[2] = getPhiRotation_smoothed(hit_r_phi->ProjectionX("hR3",290,499),clust_r_phi_neg->ProjectionX("cR3_neg",290,499)); + + + //get hit and cluster peaks + std::vector hit_RPeaks = getRPeaks(hit_r_phi); + std::vector clust_RPeaks_pos = getRPeaks(clust_r_phi_pos); + std::vector clust_RPeaks_neg = getRPeaks(clust_r_phi_neg); + + //identify where gaps between module 1&2 and 2&3 are by finding largest distances between peaks + std::vector clust_RGaps_pos; + int R12Gap_pos = -1; + int R23Gap_pos = -1; + for(int i=0; i<(int)clust_RPeaks_pos.size()-1; i++) clust_RGaps_pos.push_back(clust_RPeaks_pos[i+1] - clust_RPeaks_pos[i]); + int tmpGap_pos = std::distance(clust_RGaps_pos.begin(),std::max_element(clust_RGaps_pos.begin(),clust_RGaps_pos.end())); + if(tmpGap_pos > (int)clust_RGaps_pos.size()/2){ + R23Gap_pos = tmpGap_pos; + R12Gap_pos = std::distance(clust_RGaps_pos.begin(),std::max_element(clust_RGaps_pos.begin(),clust_RGaps_pos.begin()+R23Gap_pos)); + }else{ + R12Gap_pos = tmpGap_pos; + R23Gap_pos = std::distance(clust_RGaps_pos.begin(),std::max_element(clust_RGaps_pos.begin()+R12Gap_pos+1,clust_RGaps_pos.end())); + } + + std::vector clust_RGaps_neg; + int R12Gap_neg = -1; + int R23Gap_neg = -1; + for(int i=0; i<(int)clust_RPeaks_neg.size()-1; i++) clust_RGaps_neg.push_back(clust_RPeaks_neg[i+1] - clust_RPeaks_neg[i]); + int tmpGap_neg = std::distance(clust_RGaps_neg.begin(),std::max_element(clust_RGaps_neg.begin(),clust_RGaps_neg.end())); + if(tmpGap_neg > (int)clust_RGaps_neg.size()/2){ + R23Gap_neg = tmpGap_neg; + R12Gap_neg = std::distance(clust_RGaps_neg.begin(),std::max_element(clust_RGaps_neg.begin(),clust_RGaps_neg.begin()+R23Gap_neg)); + }else{ + R12Gap_neg = tmpGap_neg; + R23Gap_neg = std::distance(clust_RGaps_neg.begin(),std::max_element(clust_RGaps_neg.begin()+R12Gap_neg+1,clust_RGaps_neg.end())); + } + + std::vector hitMatches_pos; + //match cluster peaks to hit peaks using gap positions + for(int i=0; i<(int)clust_RPeaks_pos.size(); i++){ + + //Module 1 + if(i < (R12Gap_pos+1)){ + //module 1-2 gap is between 15 & 16 in hitPeaks + hitMatches_pos.push_back(15 + i - R12Gap_pos ); + //if multiple rows missing, offset for each one + if(clust_RGaps_pos[R12Gap_pos] > 3.6) hitMatches_pos[i] -= 1; + if(clust_RGaps_pos[R12Gap_pos] > 4.6) hitMatches_pos[i] -= 1; + if(clust_RGaps_pos[R12Gap_pos] > 5.8) hitMatches_pos[i] -= 1; + } + //module 1-2 gap is between 15 & 16 + else if(i < (R23Gap_pos+1) && i >= (R12Gap_pos+1)) hitMatches_pos.push_back(15+1 + i - (R12Gap_pos+1)); + //module 2-3 gap is between 22 & 23 + else if(i >= R23Gap_pos+1) hitMatches_pos.push_back(23+1 + i - (R23Gap_pos+1)); + } + + std::vector hitMatches_neg; + for(int i=0; i<(int)clust_RPeaks_neg.size(); i++){ + + if(i < (R12Gap_neg+1)){ + + hitMatches_neg.push_back(15 + i - R12Gap_neg ); + if(clust_RGaps_neg[R12Gap_neg] > 3.6) hitMatches_neg[i] -= 1; + if(clust_RGaps_neg[R12Gap_neg] > 4.6) hitMatches_neg[i] -= 1; + if(clust_RGaps_neg[R12Gap_neg] > 5.8) hitMatches_neg[i] -= 1; + } + else if(i < (R23Gap_neg+1) && i >= (R12Gap_neg+1)) hitMatches_neg.push_back(15+1 + i - (R12Gap_neg+1)); + else if(i >= R23Gap_neg+1) hitMatches_neg.push_back(23+1 + i - (R23Gap_neg+1)); + } + + // Match reco and truth positions //std::map matched_pair; std::vector> matched_pair; std::vector matched_nclus; - - // loop over truth positions - for(unsigned int i=0; i0)==(z2>0)); - if( !accepted_z ) continue; - - const auto dr = rad1-rad2; - const bool accepted_r = std::abs(dr) < m_rad_cut; - - const auto dphi = delta_phi(phi1-phi2); - const bool accepted_phi = std::abs(dphi) < m_phi_cut; - - if(m_savehistograms) - { - - hnclus->Fill( (float) nclus); - double r = rad2; + std::vector hits_matched(m_truth_pos.size()); + std::vector clusts_matched(reco_pos.size()); - if( accepted_r ) - { - hdrphi->Fill(r * dphi); - hdphi->Fill(dphi); - hrdphi->Fill(r,dphi); - } + //do iterative matching m_nMatchIter times + for(int matchIt=0; matchItFill(dr, dphi); } + if(hits_matched[i]) continue; - if( accepted_phi ) - { - hrdr->Fill(r,dr); - if(nclus==1) - { - if(r < 40.0) hdr1_single->Fill(dr); - if(r >= 40.0 && r < 58.0) hdr2_single->Fill(dr); - if(r >= 58.0) hdr3_single->Fill(dr); - } - else - { - if(r < 40.0) hdr1_double->Fill(dr); - if(r >= 40.0 && r < 58.0) hdr2_double->Fill(dr); - if(r >= 58.0) hdr3_double->Fill(dr); - } - } - } + const double z1 = m_truth_pos[i].Z(); + const double rad1= get_r( m_truth_pos[i].X(),m_truth_pos[i].Y()); + const double phi1 = m_truth_pos[i].Phi(); - if( accepted_r && accepted_phi ) - { - matched_pair.emplace_back(i,j); - matched_nclus.push_back(nclus); - break; + int hitRadIndex = -1; + + //get which hit radial index this it + for(int k=0; k<(int)hit_RPeaks.size(); k++){ + if(std::abs(rad1 - hit_RPeaks[k]) < 0.5){ + hitRadIndex = k; + break; + } } - } - } + + //for iterative looping: identify closest phi + double prev_dphi = 1.1*m_phi_cut; + int matchJ = -1; + + // loop over cluster positions + for(unsigned int j = 0; j < reco_pos.size(); ++j) + { + if(clusts_matched[j]) continue; + + int angleR = -1; + + if(reco_pos[j].Perp() < 41) angleR = 0; + else if(reco_pos[j].Perp() >= 41 && reco_pos[j].Perp() < 58) angleR = 1; + if(reco_pos[j].Perp() >= 58) angleR = 2; + + + //const auto& nclus = reco_nclusters[j]; + double phi2 = reco_pos[j].Phi(); + const double z2 = reco_pos[j].Z(); + const double rad2=get_r(reco_pos[j].X(), reco_pos[j].Y()); + if(angleR != -1){ + if(z2 > 0) phi2 -= m_clustRotation_pos[angleR]; + else phi2 -= m_clustRotation_neg[angleR]; + } + + + int clustRMatchIndex = -1; + if(z2 > 0) clustRMatchIndex = getClusterRMatch(hitMatches_pos, clust_RPeaks_pos, rad2); + else clustRMatchIndex = getClusterRMatch(hitMatches_neg, clust_RPeaks_neg, rad2); + + + if(clustRMatchIndex == -1) continue; + + //const double phi2 = reco_pos[j].Phi(); + + // only match pairs that are on the same side of the TPC + const bool accepted_z = ((z1>0)==(z2>0)); + if( !accepted_z ) continue; + + + + const bool accepted_r = (hitRadIndex == clustRMatchIndex); + + const auto dphi = delta_phi(phi1-phi2); + const bool accepted_phi = std::abs(dphi) < m_phi_cut; + + if(!accepted_r || !accepted_phi) continue; + + + + if(fabs(dphi)Fill( (float) nclus); + + double r = rad2; + + hdrphi->Fill(r * dphi); + hdphi->Fill(dphi); + hrdphi->Fill(r,dphi); + hdrdphi->Fill(dr, dphi); + hrdr->Fill(r,dr); + if(nclus==1) + { + if(r < 40.0) hdr1_single->Fill(dr); + if(r >= 40.0 && r < 58.0) hdr2_single->Fill(dr); + if(r >= 58.0) hdr3_single->Fill(dr); + } + else + { + if(r < 40.0) hdr1_double->Fill(dr); + if(r >= 40.0 && r < 58.0) hdr2_double->Fill(dr); + if(r >= 58.0) hdr3_double->Fill(dr); + } + }//end save histos + }//end if match was found + }//end loop over truth pos + }//end loop over matching iterations // print some statistics: if( Verbosity() ) @@ -413,6 +702,8 @@ int PHTpcCentralMembraneMatcher::process_event(PHCompositeNode * /*topNode*/) m_cm_flash_diffs->addDifferenceSpecifyKey(key, cmdiff); + if(m_savehistograms) match_ntup->Fill(m_event_index,m_truth_pos[p.first].Perp(),m_truth_pos[p.first].Phi(),reco_pos[p.second].Perp(),reco_pos[p.second].Phi(),reco_pos[p.second].Z(),nclus,pos1[p.second].Perp(),pos1[p.second].Phi(),adc1[p.second],layer1[p.second],pos2[p.second].Perp(),pos2[p.second].Phi(),adc2[p.second],layer2[p.second]); + // store cluster position const double clus_r = reco_pos[p.second].Perp(); double clus_phi = reco_pos[p.second].Phi(); @@ -474,6 +765,8 @@ int PHTpcCentralMembraneMatcher::process_event(PHCompositeNode * /*topNode*/) << std::endl; } } + + m_event_index++; return Fun4AllReturnCodes::EVENT_OK; } @@ -525,6 +818,16 @@ int PHTpcCentralMembraneMatcher::End(PHCompositeNode * /*topNode*/ ) fout->Close(); } + if(m_savehistograms && fout2) + { + fout2->cd(); + + match_ntup->Write(); + hit_r_phi->Write(); + clust_r_phi_pos->Write(); + clust_r_phi_neg->Write(); + } + return Fun4AllReturnCodes::EVENT_OK; } @@ -543,11 +846,18 @@ int PHTpcCentralMembraneMatcher::GetNodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTRUN; } - // input tpc distortion correction - m_dcc_in = findNode::getClass(topNode,"TpcDistortionCorrectionContainer"); - if( m_dcc_in ) + // input tpc distortion correction static + m_dcc_in_static = findNode::getClass(topNode,"TpcDistortionCorrectionContainerStatic"); + if( m_dcc_in_static ) + { + std::cout << "PHTpcCentralMembraneMatcher: found TPC distortion correction container static" << std::endl; + } + + // input tpc distortion correction average + m_dcc_in_average = findNode::getClass(topNode,"TpcDistortionCorrectionContainerAverage"); + if( m_dcc_in_average ) { - std::cout << "PHTpcCentralMembraneMatcher: found TPC distortion correction container" << std::endl; + std::cout << "PHTpcCentralMembraneMatcher: found TPC distortion correction container average" << std::endl; } // create node for results of matching @@ -574,38 +884,32 @@ int PHTpcCentralMembraneMatcher::GetNodes(PHCompositeNode* topNode) PHIODataNode *CMFlashDifferenceNode = new PHIODataNode(m_cm_flash_diffs, "CM_FLASH_DIFFERENCES", "PHObject"); DetNode->addNode(CMFlashDifferenceNode); + + + //// output tpc fluctuation distortion container + //// this one is filled on the fly on a per-CM-event basis, and applied in the tracking chain + const std::string dcc_out_node_name = "TpcDistortionCorrectionContainerFluctuation"; + m_dcc_out = findNode::getClass(topNode,dcc_out_node_name); + if( !m_dcc_out ) + { + + /// Get the RUN node and check + auto runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) + { + std::cout << "PHTpcCentralMembraneMatcher::InitRun - RUN Node missing, quitting" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + std::cout << "PHTpcCentralMembraneMatcher::GetNodes - creating TpcDistortionCorrectionContainer in node " << dcc_out_node_name << std::endl; + m_dcc_out = new TpcDistortionCorrectionContainer; + auto node = new PHDataNode(m_dcc_out, dcc_out_node_name); + runNode->addNode(node); + } -// // output tpc fluctuation distortion container -// // this one is filled on the fly on a per-CM-event basis, and applied in the tracking chain -// const std::string dcc_out_node_name = "TpcDistortionCorrectionContainerFluctuation"; -// m_dcc_out = findNode::getClass(topNode,dcc_out_node_name); -// if( !m_dcc_out ) -// { -// -// /// Get the DST node and check -// auto dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); -// if (!dstNode) -// { -// std::cout << "PHTpcCentralMembraneMatcher::InitRun - DST Node missing, quitting" << std::endl; -// return Fun4AllReturnCodes::ABORTRUN; -// } -// -// // Get the tracking subnode and create if not found -// auto svtxNode = dynamic_cast(iter.findFirst("PHCompositeNode", "SVTX")); -// if (!svtxNode) -// { -// svtxNode = new PHCompositeNode("SVTX"); -// dstNode->addNode(svtxNode); -// } -// -// std::cout << "PHTpcCentralMembraneMatcher::GetNodes - creating TpcDistortionCorrectionContainer in node " << dcc_out_node_name << std::endl; -// m_dcc_out = new TpcDistortionCorrectionContainer; -// auto node = new PHDataNode(m_dcc_out, dcc_out_node_name); -// svtxNode->addNode(node); -// } // create per event distortions. Do not put on the node tree - m_dcc_out = new TpcDistortionCorrectionContainer; + //m_dcc_out = new TpcDistortionCorrectionContainer; // also prepare the local distortion container, used to aggregate multple events m_dcc_out_aggregated.reset( new TpcDistortionCorrectionContainer ); @@ -616,6 +920,38 @@ int PHTpcCentralMembraneMatcher::GetNodes(PHCompositeNode* topNode) const float rMin = m_rMin - (m_rMax-m_rMin)/m_rbins; const float rMax = m_rMax + (m_rMax-m_rMin)/m_rbins; + + /* + double r_bins_mm[69] = {217.83-2,217.83, + 223.83, 229.83, 235.83, 241.83, 247.83, 253.83, 259.83, 265.83, 271.83, 277.83, 283.83, 289.83, 295.83, 301.83, 306.83, + 311.05, 317.92, 323.31, 329.27, 334.63, 340.59, 345.95, 351.91, 357.27, 363.23, 368.59, 374.55, 379.91, 385.87, 391.23, 397.19, 402.49, + 411.53, 421.70, 431.90, 442.11, 452.32, 462.52, 472.73, 482.94, 493.14, 503.35, 513.56, 523.76, 533.97, 544.18, 554.39, 564.59, 574.76, + 583.67, 594.59, 605.57, 616.54, 627.51, 638.48, 649.45, 660.42, 671.39, 682.36, 693.33, 704.30, 715.27, 726.24, 737.21, 748.18, 759.11, 759.11+2}; + + double r_bins[69]; + + for(int i=0; i<69; i++){ + r_bins[i] = r_bins_mm[i]/10.0; + } + + + + double phiBins[206] = { 0., 6.3083-2 * M_PI, 6.3401-2 * M_PI, 6.372-2 * M_PI, 6.4039-2 * M_PI, 6.4358-2 * M_PI, 6.4676-2 * M_PI, 6.4995-2 * M_PI, 6.5314-2 * M_PI, + 0.2618, 0.2937, 0.3256, 0.3574, 0.3893, 0.4212, 0.453, 0.4849, 0.5168, 0.5487, 0.5805, 0.6124, 0.6443, 0.6762, 0.7081, + 0.7399, 0.7718, 0.7854, 0.8173, 0.8491, 0.881, 0.9129, 0.9448, 0.9767, 1.0085, 1.0404, 1.0723, 1.1041, 1.136, 1.1679, + 1.1998, 1.2317, 1.2635, 1.2954, 1.309, 1.3409, 1.3727, 1.4046, 1.4365, 1.4684, 1.5002, 1.5321, 1.564, 1.5959, 1.6277, + 1.6596, 1.6915, 1.7234, 1.7552, 1.7871, 1.819, 1.8326, 1.8645, 1.8963, 1.9282, 1.9601, 1.992, 2.0238, 2.0557, 2.0876, + 2.1195, 2.1513, 2.1832, 2.2151, 2.247, 2.2788, 2.3107, 2.3426, 2.3562, 2.3881, 2.42, 2.4518, 2.4837, 2.5156, 2.5474, + 2.5793, 2.6112, 2.6431, 2.6749, 2.7068, 2.7387, 2.7706, 2.8024, 2.8343, 2.8662, 2.8798, 2.9117, 2.9436, 2.9754, 3.0073, + 3.0392, 3.0711, 3.1029, 3.1348, 3.1667, 3.1986, 3.2304, 3.2623, 3.2942, 3.326, 3.3579, 3.3898, 3.4034, 3.4353, 3.4671, + 3.499, 3.5309, 3.5628, 3.5946, 3.6265, 3.6584, 3.6903, 3.7221, 3.754, 3.7859, 3.8178, 3.8496, 3.8815, 3.9134, 3.927, + 3.9589, 3.9907, 4.0226, 4.0545, 4.0864, 4.1182, 4.1501, 4.182, 4.2139, 4.2457, 4.2776, 4.3095, 4.3414, 4.3732, 4.4051, + 4.437, 4.4506, 4.4825, 4.5143, 4.5462, 4.5781, 4.61, 4.6418, 4.6737, 4.7056, 4.7375, 4.7693, 4.8012, 4.8331, 4.865, + 4.8968, 4.9287, 4.9606, 4.9742, 5.0061, 5.0379, 5.0698, 5.1017, 5.1336, 5.1654, 5.1973, 5.2292, 5.2611, 5.2929, 5.3248, + 5.3567, 5.3886, 5.4204, 5.4523, 5.4842, 5.4978, 5.5297, 5.5615, 5.5934, 5.6253, 5.6572, 5.689, 5.7209, 5.7528, 5.7847, + 5.8165, 5.8484, 5.8803, 5.9122, 5.944, 5.9759, 6.0078, 6.0214, 6.0533, 6.0851, 6.117, 6.1489, 6.1808, 6.2127, 6.2445, + 6.2764, 2 * M_PI}; + */ // reset all output distortion container so that they match the requested grid size const std::array extension = {{ "_negz", "_posz" }}; @@ -631,6 +967,12 @@ int PHTpcCentralMembraneMatcher::GetNodes(PHCompositeNode* topNode) delete dcc->m_hDRint[i]; dcc->m_hDRint[i] = new TH2F( Form("hIntDistortionR%s", extension[i].c_str()), Form("hIntDistortionR%s", extension[i].c_str()), m_phibins+2, phiMin, phiMax, m_rbins+2, rMin, rMax ); delete dcc->m_hDZint[i]; dcc->m_hDZint[i] = new TH2F( Form("hIntDistortionZ%s", extension[i].c_str()), Form("hIntDistortionZ%s", extension[i].c_str()), m_phibins+2, phiMin, phiMax, m_rbins+2, rMin, rMax ); delete dcc->m_hentries[i]; dcc->m_hentries[i] = new TH2I( Form("hEntries%s", extension[i].c_str()), Form("hEntries%s", extension[i].c_str()), m_phibins+2, phiMin, phiMax, m_rbins+2, rMin, rMax ); + + + //delete dcc->m_hDPint[i]; dcc->m_hDPint[i] = new TH2F( Form("hIntDistortionP%s", extension[i].c_str()), Form("hIntDistortionP%s", extension[i].c_str()), 205, phiBins, 68, r_bins ); + //delete dcc->m_hDRint[i]; dcc->m_hDRint[i] = new TH2F( Form("hIntDistortionR%s", extension[i].c_str()), Form("hIntDistortionR%s", extension[i].c_str()), 205, phiBins, 68, r_bins ); + //delete dcc->m_hDZint[i]; dcc->m_hDZint[i] = new TH2F( Form("hIntDistortionZ%s", extension[i].c_str()), Form("hIntDistortionZ%s", extension[i].c_str()), 205, phiBins, 68, r_bins ); + //delete dcc->m_hentries[i]; dcc->m_hentries[i] = new TH2I( Form("hEntries%s", extension[i].c_str()), Form("hEntries%s", extension[i].c_str()), 205, phiBins, 68, r_bins); } } diff --git a/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.h b/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.h index 6f3bdd000a..6d2d4f1308 100644 --- a/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.h +++ b/offline/packages/tpccalib/PHTpcCentralMembraneMatcher.h @@ -23,10 +23,12 @@ class CMFlashClusterContainer; class CMFlashDifferenceContainer; class TF1; -class TNtuple; class TFile; class TH1F; +class TH1D; class TH2F; +class TGraph; +class TNtuple; class TVector3; class PHTpcCentralMembraneMatcher : public SubsysReco @@ -48,6 +50,10 @@ class PHTpcCentralMembraneMatcher : public SubsysReco /// output file name for storing the space charge reconstruction matrices void setOutputfile(const std::string &outputfile) {m_outputfile = outputfile;} + + void setNMatchIter( int val ){ m_nMatchIter = val; } + + void set_useOnly_nClus2( bool val ){ m_useOnly_nClus2 = val; } void set_grid_dimensions( int phibins, int rbins ); @@ -72,7 +78,8 @@ class PHTpcCentralMembraneMatcher : public SubsysReco /// static distortion container /** used in input to correct CM clusters before calculating residuals */ - TpcDistortionCorrectionContainer* m_dcc_in{nullptr}; + TpcDistortionCorrectionContainer* m_dcc_in_static{nullptr}; + TpcDistortionCorrectionContainer* m_dcc_in_average{nullptr}; /// fluctuation distortion container /** used in output to write fluctuation distortions */ @@ -110,10 +117,23 @@ class PHTpcCentralMembraneMatcher : public SubsysReco std::unique_ptr fout; + + std::unique_ptr fout2; + std::string m_histogramfilename2 = "CMMatcher.root"; + + TH2F *hit_r_phi; + + TH2F *clust_r_phi_pos; + TH2F *clust_r_phi_neg; + + TNtuple *match_ntup = nullptr; + + int m_event_index = 0; + //@} /// radius cut for matching clusters to pad, for size 2 clusters - double m_rad_cut= 0.5; + // double m_rad_cut= 0.5; /// phi cut for matching clusters to pad /** TODO: this will need to be adjusted to match beam-induced time averaged distortions */ @@ -123,16 +143,16 @@ class PHTpcCentralMembraneMatcher : public SubsysReco //@{ /// distortion correction grid size along phi - int m_phibins = 36; + int m_phibins = 24; static constexpr float m_phiMin = 0; static constexpr float m_phiMax = 2.*M_PI; /// distortion correction grid size along r - int m_rbins = 16; + int m_rbins = 12; static constexpr float m_rMin = 20; // cm - static constexpr float m_rMax = 78; // cm + static constexpr float m_rMax = 80; // cm //@} @@ -208,6 +228,18 @@ class PHTpcCentralMembraneMatcher : public SubsysReco //@} + bool m_useOnly_nClus2 = false; + + int m_nMatchIter = 2; + + double m_clustRotation_pos[3]; + double m_clustRotation_neg[3]; + + double getPhiRotation_smoothed( TH1D *hitHist, TH1D *clustHist ); + + std::vector getRPeaks(TH2F *r_phi); + + int getClusterRMatch( std::vector hitMatches, std::vector clusterPeaks, double clusterR); }; #endif // PHTPCCENTRALMEMBRANEMATCHER_H diff --git a/offline/packages/tpccalib/PHTpcResiduals.cc b/offline/packages/tpccalib/PHTpcResiduals.cc index e75599d9ab..33b9d4dc04 100644 --- a/offline/packages/tpccalib/PHTpcResiduals.cc +++ b/offline/packages/tpccalib/PHTpcResiduals.cc @@ -20,6 +20,8 @@ #include #include +#include + #include #include @@ -106,7 +108,13 @@ PHTpcResiduals::PHTpcResiduals(const std::string &name) //___________________________________________________________________________________ int PHTpcResiduals::Init(PHCompositeNode */*topNode*/) { - if( m_savehistograms ) makeHistograms(); + + // configuration printout + std::cout << "PHTpcResiduals::Init - m_maxTAlpha: " << m_maxTAlpha << std::endl; + std::cout << "PHTpcResiduals::Init - m_maxTBeta: " << m_maxTBeta << std::endl; + std::cout << "PHTpcResiduals::Init - m_maxResidualDrphi: " << m_maxResidualDrphi << " cm" << std::endl; + std::cout << "PHTpcResiduals::Init - m_maxResidualDz: " << m_maxResidualDz << " cm" << std::endl; + std::cout << "PHTpcResiduals::Init - m_minPt: " << m_minPt << " GeV/c" << std::endl; // reset counters m_total_tracks = 0; @@ -151,22 +159,6 @@ int PHTpcResiduals::End(PHCompositeNode */*topNode*/) outputfile->cd(); m_matrix_container->Write( "TpcSpaceChargeMatrixContainer" ); } - - // save histograms - if( m_savehistograms && m_histogramfile ) - { - m_histogramfile->cd(); - for( const auto o:std::initializer_list({ h_rphiResid, h_zResid, h_etaResidLayer, h_zResidLayer, h_etaResid, h_index, h_alpha, h_beta, h_deltarphi_layer, h_deltaz_layer, residTup }) ) - { if( o ) o->Write(); } - - // also write histograms from vectors - for( const auto& [cell,h]:h_drphi ) { if(h) h->Write(); } - for( const auto& [cell,h]:h_dz ) { if(h) h->Write(); } - for( const auto& [cell,h]:h_drphi_alpha ) { if(h) h->Write(); } - for( const auto& [cell,h]:h_dz_beta ) { if(h) h->Write(); } - - m_histogramfile->Close(); - } // print counters std::cout @@ -215,8 +207,8 @@ bool PHTpcResiduals::checkTrack(SvtxTrack* track) const if(Verbosity() > 2) { std::cout << "PHTpcResiduals::checkTrack - pt: " << track->get_pt() << std::endl; } - if(track->get_pt() < 0.5) - return false; + if(track->get_pt() < m_minPt) + { return false; } // ignore tracks with too few mvtx, intt and micromegas hits const auto cluster_keys( get_cluster_keys( track ) ); @@ -233,8 +225,8 @@ bool PHTpcResiduals::checkTrack(SvtxTrack* track) const Acts::BoundTrackParameters PHTpcResiduals::makeTrackParams(SvtxTrack* track) const { Acts::Vector3 momentum(track->get_px(), - track->get_py(), - track->get_pz()); + track->get_py(), + track->get_pz()); double trackQ = track->get_charge() * Acts::UnitConstants::e; double p = track->get_p(); @@ -265,20 +257,17 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) << " position: (" << track->get_x() << ", " << track->get_y() << ", " << track->get_z() << ")" << std::endl; } - + ActsPropagator propagator(m_tGeometry); + // create ACTS parameters from track parameters at origin auto trackParams = makeTrackParams(track); // store crossing. It is used in calculating cluster's global position m_crossing = track->get_crossing(); assert( m_crossing != SHRT_MAX ); - - for( const auto& key:get_cluster_keys( track ) ) - { - - // assign to static cluskey - cluskey = key; + for( const auto& cluskey:get_cluster_keys( track ) ) + { // increment counter ++m_total_clusters; @@ -288,10 +277,10 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) const auto cluster = m_clusterContainer->findCluster(cluskey); const auto surface = m_tGeometry->maps().getSurface( cluskey, cluster ); - const auto result = propagateTrackState(trackParams, surface); + auto result = propagator.propagateTrack(trackParams, surface); // skip if propagation failed - if(!result) + if(!result.ok()) { if( Verbosity() > 1 ) { @@ -311,7 +300,9 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) } // get extrapolated track state, convert to sPHENIX and add to track - const auto& [pathLength, trackStateParams] = *result; + auto& [pathLength, trackStateParams] = result.value(); + pathLength /= Acts::UnitConstants::cm; + if(Verbosity() > 1) { std::cout << "PHTpcResiduals::processTrack -" @@ -322,20 +313,23 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) << trackStateParams.momentum() << std::endl; } - - addTrackState( track, pathLength, trackStateParams ); + + + addTrackState( track, cluskey, pathLength, trackStateParams ); // calculate residuals with respect to cluster // Get all the relevant information for residual calculation const auto globClusPos = getGlobalPosition(cluskey, cluster, m_crossing); - clusR = get_r(globClusPos(0),globClusPos(1)); - clusPhi = std::atan2(globClusPos(1), globClusPos(0)); - clusZ = globClusPos(2); + const double clusR = get_r(globClusPos(0),globClusPos(1)); + const double clusPhi = std::atan2(globClusPos(1), globClusPos(0)); + const double clusZ = globClusPos(2); // cluster errors - if( m_cluster_version >= 4 ) + double clusRPhiErr = 0; + double clusZErr = 0; + if( m_cluster_version == 4 ) { - const auto errors_square = m_cluster_error_parametrization.get_cluster_error( track->get_tpc_seed(), cluster, clusR, cluskey ); + const auto errors_square = m_cluster_error_parametrization.get_cluster_error( cluster, clusR, cluskey, track->get_tpc_seed()->get_qOverR(), track->get_tpc_seed()->get_slope() ); clusRPhiErr = std::sqrt( errors_square.first ); clusZErr = std::sqrt( errors_square.second ); } else { @@ -372,58 +366,46 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) const auto globalStateMom = trackStateParams.momentum(); const auto globalStateCov = *trackStateParams.covariance(); - stateRPhiErr = std::sqrt(globalStateCov(Acts::eBoundLoc0, Acts::eBoundLoc0))/Acts::UnitConstants::cm; - stateZErr = sqrt(globalStateCov(Acts::eBoundLoc1, Acts::eBoundLoc1))/Acts::UnitConstants::cm; - - stateZ = globalStatePos.z()/Acts::UnitConstants::cm; + const double trackRPhiErr = std::sqrt(globalStateCov(Acts::eBoundLoc0, Acts::eBoundLoc0))/Acts::UnitConstants::cm; + const double trackZErr = sqrt(globalStateCov(Acts::eBoundLoc1, Acts::eBoundLoc1))/Acts::UnitConstants::cm; - const auto globStateX = globalStatePos.x()/Acts::UnitConstants::cm; - const auto globStateY = globalStatePos.y()/Acts::UnitConstants::cm; - const auto globStateZ = stateZ; + const double globStateX = globalStatePos.x()/Acts::UnitConstants::cm; + const double globStateY = globalStatePos.y()/Acts::UnitConstants::cm; + const double globStateZ = globalStatePos.z()/Acts::UnitConstants::cm; - stateR = std::sqrt(square(globStateX) + square(globStateY)); + const double trackR = std::sqrt(square(globStateX) + square(globStateY)); - const auto dr = clusR - stateR; - const auto trackDrDt = (globStateX * globalStateMom(0) + globStateY * globalStateMom(1)) / stateR; - const auto trackDxDr = globalStateMom(0) / trackDrDt; - const auto trackDyDr = globalStateMom(1) / trackDrDt; - const auto trackDzDr = globalStateMom(2) / trackDrDt; + const double dr = clusR - trackR; + const double trackDrDt = (globStateX * globalStateMom(0) + globStateY * globalStateMom(1)) / trackR; + const double trackDxDr = globalStateMom(0) / trackDrDt; + const double trackDyDr = globalStateMom(1) / trackDrDt; + const double trackDzDr = globalStateMom(2) / trackDrDt; - const auto trackX = globStateX + dr * trackDxDr; - const auto trackY = globStateY + dr * trackDyDr; - const auto trackZ = globStateZ + dr * trackDzDr; + const double trackX = globStateX + dr * trackDxDr; + const double trackY = globStateY + dr * trackDyDr; + const double trackZ = globStateZ + dr * trackDzDr; + const double trackPhi = std::atan2(trackY, trackX); if(Verbosity() > 2) { std::cout << "PHTpcResiduals::processTrack -" - << " stateR: " << stateR + << " trackR: " << trackR << " dr: " << dr << " trackDrDt: " << trackDrDt << " trackDxDr: " << trackDxDr << " trackDyDr: " << trackDyDr << " trackDzDr: " << trackDzDr + << " trackPhi: " << trackPhi << "+/-" << trackRPhiErr << " track position: (" << trackX << ", " << trackY << ", " << trackZ << ")" << std::endl; } - - statePhi = std::atan2(trackY, trackX); - stateZ = trackZ; - - if(Verbosity() > 3) - { - std::cout << "PHTpcResiduals::processTrack -" - << " stateR: " << stateR - << " statePhi: " << statePhi << "+/-" << stateRPhiErr - << " stateZ: " << stateZ << "+/-" << stateZErr - << std::endl; - } - - const auto erp = square(clusRPhiErr) + square(stateRPhiErr); - const auto ez = square(clusZErr) + square(stateZErr); + + const double erp = square(clusRPhiErr) + square(trackRPhiErr); + const double ez = square(clusZErr) + square(trackZErr); // Calculate residuals - drphi = clusR * deltaPhi(clusPhi - statePhi); - dz = clusZ - stateZ; + const double drphi = clusR * deltaPhi(clusPhi - trackPhi); + const double dz = clusZ - trackZ; if(Verbosity() > 3) { @@ -432,19 +414,13 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) << " dz: " << dz << std::endl; } + + const double trackPPhi = -trackStateParams.momentum()(0) * std::sin(trackPhi) + trackStateParams.momentum()(1) * std::cos(trackPhi); + const double trackPR = trackStateParams.momentum()(0) * std::cos(trackPhi) + trackStateParams.momentum()(1) * std::sin(trackPhi); + const double trackPZ = trackStateParams.momentum()(2); - const auto trackEta = std::atanh(trackStateParams.momentum().z() / trackStateParams.absoluteMomentum()); - const auto clusEta = std::atanh(clusZ / std::sqrt( - square(globClusPos(0)) + - square(globClusPos(1)) + - square(globClusPos(2)))); - - const auto trackPPhi = -trackStateParams.momentum()(0) * std::sin(statePhi) + trackStateParams.momentum()(1) * std::cos(statePhi); - const auto trackPR = trackStateParams.momentum()(0) * std::cos(statePhi) + trackStateParams.momentum()(1) * std::sin(statePhi); - const auto trackPZ = trackStateParams.momentum()(2); - - const auto trackAlpha = -trackPPhi / trackPR; - const auto trackBeta = -trackPZ / trackPR; + const double trackAlpha = -trackPPhi / trackPR; + const double trackBeta = -trackPZ / trackPR; if(Verbosity() > 3) { @@ -457,10 +433,7 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) << " trackBeta: " << trackBeta << std::endl; } - - tanBeta = trackBeta; - tanAlpha = trackAlpha; - + // get cell index const auto index = getCell(globClusPos); if(Verbosity() > 3) @@ -470,43 +443,20 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) if(Verbosity() > 3) { - std::cout << "PHTpcResiduals::processTrack - layer: " << (int) TrkrDefs::getLayer(key) << std::endl; + std::cout << "PHTpcResiduals::processTrack - layer: " << (int) TrkrDefs::getLayer(cluskey) << std::endl; std::cout << "PHTpcResiduals::processTrack -" << " cluster: (" << clusR << ", " << clusR*clusPhi << ", " << clusZ << ")" << " (" << clusRPhiErr << ", " << clusZErr << ")" << std::endl; std::cout << "PHTpcResiduals::processTrack -" - << " track: (" << stateR << ", " << clusR*statePhi << ", " << stateZ << ")" - << " (" << tanAlpha << ", " << tanBeta << ")" - << " (" << stateRPhiErr << ", " << stateZErr << ")" + << " track: (" << trackR << ", " << clusR*trackPhi << ", " << trackZ << ")" + << " (" << trackAlpha << ", " << trackBeta << ")" + << " (" << trackRPhiErr << ", " << trackZErr << ")" << std::endl; std::cout << std::endl; } - if( m_savehistograms ) - { - h_index->Fill(index); - h_alpha->Fill(tanAlpha, drphi); - h_beta->Fill(tanBeta, dz); - h_rphiResid->Fill(clusR , drphi); - h_zResid->Fill(stateZ , dz); - h_etaResid->Fill(trackEta, clusEta - trackEta); - h_zResidLayer->Fill(clusR , dz); - h_etaResidLayer->Fill(clusR , clusEta - trackEta); - - const auto layer = TrkrDefs::getLayer(key); - h_deltarphi_layer->Fill( layer, drphi ); - h_deltaz_layer->Fill( layer, dz ); - - { const auto iter = h_drphi.find( index ); if( iter != h_drphi.end() ) iter->second->Fill( drphi ); } - { const auto iter = h_drphi_alpha.find( index ); if( iter != h_drphi_alpha.end() ) iter->second->Fill( tanAlpha, drphi ); } - { const auto iter = h_dz.find( index ); if( iter != h_dz.end() ) iter->second->Fill( dz ); } - { const auto iter = h_dz_beta.find( index ); if( iter != h_dz_beta.end() ) iter->second->Fill( tanBeta, dz ); } - - residTup->Fill(); - } - // check track angles and residuals agains cuts if(std::abs(trackAlpha) > m_maxTAlpha || std::abs(drphi) > m_maxResidualDrphi) { continue; } @@ -541,44 +491,8 @@ void PHTpcResiduals::processTrack(SvtxTrack* track) } -//__________________________________________________________________________________________________________________________________________ -std::optional PHTpcResiduals::propagateTrackState( const Acts::BoundTrackParameters& params, const Surface& surface) const -{ - - - using Stepper = Acts::EigenStepper<>; - using Propagator = Acts::Propagator; - - Stepper stepper(m_tGeometry->geometry().magField); - Acts::Navigator::Config cfg{m_tGeometry->geometry().tGeometry}; - Acts::Navigator navigator(cfg); - Propagator propagator(stepper, navigator); - - Acts::Logging::Level logLevel = Acts::Logging::FATAL; - if(Verbosity() > 10) - logLevel = Acts::Logging::VERBOSE; - - auto logger = Acts::getDefaultLogger("PHTpcResiduals", logLevel); - - Acts::PropagatorOptions<> options(m_tGeometry->geometry().getGeoContext(), - m_tGeometry->geometry().magFieldContext, - Acts::LoggerWrapper{*logger}); - - auto result = propagator.propagate(params, *surface, options); - - if(result.ok()) - { - const Acts::BoundTrackParameters params = *result.value().endParameters; - double pathlength = result.value().pathLength / Acts::UnitConstants::cm; - // return both path length and extrapolated parameters - return std::make_pair( pathlength, params ); - } else { - return std::nullopt; - } -} - //_______________________________________________________________________________________________________ -void PHTpcResiduals::addTrackState( SvtxTrack* track, float pathlength, const Acts::BoundTrackParameters& params ) +void PHTpcResiduals::addTrackState( SvtxTrack* track, TrkrDefs::cluskey key, float pathlength, const Acts::BoundTrackParameters& params ) { /* this is essentially a copy of the code from trackbase_historic/ActsTransformations::fillSvtxTrackStates */ @@ -603,6 +517,8 @@ void PHTpcResiduals::addTrackState( SvtxTrack* track, float pathlength, const Ac for (int i = 0; i < 6; ++i) for (int j = 0; j < 6; ++j) { state.set_error(i, j, globalCov(i,j)); } + + state.set_name(std::to_string((TrkrDefs::cluskey) key)); track->insert_state(&state); } @@ -707,107 +623,6 @@ Acts::Vector3 PHTpcResiduals::getGlobalPosition( TrkrDefs::cluskey key, TrkrClus return globalPosition; } -//_______________________________________________________________________________ -void PHTpcResiduals::makeHistograms() -{ - - m_histogramfile.reset( new TFile(m_histogramfilename.c_str(), "RECREATE") ); - m_histogramfile->cd(); - - const auto total_bins = m_matrix_container->get_grid_size(); - h_beta = new TH2F("betadz",";tan#beta; #Deltaz [cm]",100,-0.5,0.5,100,-0.5,0.5); - h_alpha = new TH2F("alphardphi",";tan#alpha; r#Delta#phi [cm]", 100,-0.5,0.5,100,-0.5,0.5); - h_index = new TH1F("index",";index",total_bins, 0, total_bins); - h_rphiResid = new TH2F("rphiResid", ";r [cm]; #Deltar#phi [cm]", 60, 20, 80, 500, -2, 2); - h_zResid = new TH2F("zResid", ";z [cm]; #Deltaz [cm]", 200, -100, 100, 1000, -2, 2); - h_etaResid = new TH2F("etaResid", ";#eta;#Delta#eta", 20, -1, 1, 500, -0.2, 0.2); - h_etaResidLayer = new TH2F("etaResidLayer", ";r [cm]; #Delta#eta", 60, 20, 80, 500, -0.2, 0.2); - h_zResidLayer = new TH2F("zResidLayer", ";r [cm]; #Deltaz [cm]", 60, 20, 80, 1000, -2, 2); - h_deltarphi_layer = new TH2F( "deltarphi_layer", ";layer; r.#Delta#phi_{track-cluster} (cm)", 57, 0, 57, 500, -2, 2 ); - h_deltaz_layer = new TH2F( "deltaz_layer", ";layer; #Deltaz_{track-cluster} (cm)", 57, 0, 57, 100, -2, 2 ); - - { - - // get grid dimensions from matrix container - int phibins = 0; - int rbins = 0; - int zbins = 0; - m_matrix_container->get_grid_dimensions( phibins, rbins, zbins ); - - // get bins corresponding to selected angles - std::set phibin_rec; - std::transform( phi_rec.begin(), phi_rec.end(), std::inserter( phibin_rec, phibin_rec.end() ), [&]( const float& phi ) { return phibins*(phi-m_phiMin)/(m_phiMax-m_phiMin); } ); - - std::set zbin_rec; - std::transform( z_rec.begin(), z_rec.end(), std::inserter( zbin_rec, zbin_rec.end() ), [&]( const float& z ) { return zbins*(z-m_zMin)/(m_zMax-m_zMin); } ); - - // keep track of all cell ids that match selected histograms - for( int iphi = 0; iphi < phibins; ++iphi ) - for( int ir = 0; ir < rbins; ++ir ) - for( int iz = 0; iz < zbins; ++iz ) - { - - if( phibin_rec.find( iphi ) == phibin_rec.end() || zbin_rec.find( iz ) == zbin_rec.end() ) continue; - const auto icell = m_matrix_container->get_cell_index( iphi, ir, iz ); - - { - // rphi residuals - const auto hname = Form( "residual_drphi_p%i_r%i_z%i", iphi, ir, iz ); - auto h = new TH1F( hname, hname, 100, -m_maxResidualDrphi, +m_maxResidualDrphi ); - h->GetXaxis()->SetTitle( "r.#Delta#phi_{cluster-track} (cm)" ); - h_drphi.insert( std::make_pair( icell, h ) ); - } - - { - // 2D histograms - const auto hname = Form( "residual_2d_drphi_p%i_r%i_z%i", iphi, ir, iz ); - auto h = new TH2F( hname, hname, 100, -m_maxTAlpha, m_maxTAlpha, 100, -m_maxResidualDrphi, +m_maxResidualDrphi ); - h->GetXaxis()->SetTitle( "tan#alpha" ); - h->GetYaxis()->SetTitle( "r.#Delta#phi_{cluster-track} (cm)" ); - h_drphi_alpha.insert( std::make_pair( icell, h ) ); - } - - { - // z residuals - const auto hname = Form( "residual_dz_p%i_r%i_z%i", iphi, ir, iz ); - auto h = new TH1F( hname, hname, 100, -m_maxResidualDz, +m_maxResidualDz ); - h->GetXaxis()->SetTitle( "#Deltaz_{cluster-track} (cm)" ); - h_dz.insert( std::make_pair( icell, h ) ); - } - - { - // 2D histograms - static constexpr double maxTBeta = 0.5; - const auto hname = Form( "residual_2d_dz_p%i_r%i_z%i", iphi, ir, iz ); - auto h = new TH2F( hname, hname, 100, -maxTBeta, maxTBeta, 100, -m_maxResidualDz, +m_maxResidualDz ); - h->GetXaxis()->SetTitle( "tan#beta" ); - h->GetYaxis()->SetTitle( "#Deltaz_{cluster-track} (cm)" ); - h_dz_beta.insert( std::make_pair( icell, h ) ); - } - } - - } - - residTup = new TTree("residTree","tpc residual info"); - residTup->Branch("tanAlpha",&tanAlpha,"tanAlpha/D"); - residTup->Branch("tanBeta",&tanBeta,"tanBeta/D"); - residTup->Branch("drphi",&drphi,"drphi/D"); - residTup->Branch("dz",&dz,"dz/D"); - residTup->Branch("clusR",&clusR,"clusR/D"); - residTup->Branch("clusPhi",&clusPhi,"clusPhi/D"); - residTup->Branch("clusZ",&clusZ,"clusZ/D"); - residTup->Branch("statePhi",&statePhi,"statePhi/D"); - residTup->Branch("stateZ",&stateZ,"stateZ/D"); - residTup->Branch("stateR",&stateR,"stateR/D"); - residTup->Branch("stateRPhiErr",&stateRPhiErr,"stateRPhiErr/D"); - residTup->Branch("stateZErr",&stateZErr,"stateZErr/D"); - residTup->Branch("clusRPhiErr",&clusRPhiErr,"clusRPhiErr/D"); - residTup->Branch("clusZErr",&clusZErr,"clusZErr/D"); - residTup->Branch("cluskey",&cluskey,"cluskey/l"); - residTup->Branch("event",&m_event,"event/I"); - -} - void PHTpcResiduals::setGridDimensions(const int phiBins, const int rBins, const int zBins) { m_matrix_container->set_grid_dimensions( phiBins, rBins, zBins ); } diff --git a/offline/packages/tpccalib/PHTpcResiduals.h b/offline/packages/tpccalib/PHTpcResiduals.h index b7986a5f69..76de6976d8 100644 --- a/offline/packages/tpccalib/PHTpcResiduals.h +++ b/offline/packages/tpccalib/PHTpcResiduals.h @@ -46,27 +46,38 @@ class PHTpcResiduals : public SubsysReco int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - /// Option for setting distortion correction calculation limits + ///@name Option for setting distortion correction calculation limits + //@{ void setMaxTrackAlpha(float maxTAlpha) - { m_maxTAlpha = maxTAlpha;} + { m_maxTAlpha = maxTAlpha;} + void setMaxTrackBeta(float maxTBeta) - { m_maxTBeta = maxTBeta; } + { m_maxTBeta = maxTBeta; } + void setMaxTrackResidualDrphi(float maxResidualDrphi) - { m_maxResidualDrphi = maxResidualDrphi;} + { m_maxResidualDrphi = maxResidualDrphi;} void setMaxTrackResidualDz(float maxResidualDz) - { m_maxResidualDz = maxResidualDz; } + { m_maxResidualDz = maxResidualDz; } + + //@} + + /// track min pT + void setMinPt( double value ) + { m_minPt = value; } + /// Grid dimensions void setGridDimensions(const int phiBins, const int rBins, const int zBins); /// set to true to store evaluation histograms and ntuples - void setSavehistograms( bool value ) { m_savehistograms = value; } + void setSavehistograms( bool ) {} /// output file name for evaluation histograms - void setHistogramOutputfile(const std::string &outputfile) {m_histogramfilename = outputfile;} + void setHistogramOutputfile(const std::string&) {} /// output file name for storing the space charge reconstruction matrices - void setOutputfile(const std::string &outputfile) {m_outputfile = outputfile;} + void setOutputfile(const std::string &outputfile) + {m_outputfile = outputfile;} /// require micromegas to be present when extrapolating tracks to the TPC void setUseMicromegas( bool value ) @@ -99,23 +110,13 @@ class PHTpcResiduals : public SubsysReco void processTrack(SvtxTrack* track); /// fill track state from bound track parameters - void addTrackState( SvtxTrack* track, float pathlength, const Acts::BoundTrackParameters& params ); + void addTrackState( SvtxTrack* track, TrkrDefs::cluskey key, float pathlength, const Acts::BoundTrackParameters& params ); - /** \brief - * Propagates the silicon+MM track fit to the surface on which - * an available source link in the TPC exists, added from the stub - * matching propagation - * returns the path lenght and the resulting parameters - */ - std::optional propagateTrackState( const Acts::BoundTrackParameters& params, const Surface& surf ) const; - /// Gets distortion cell for identifying bins in TPC int getCell(const Acts::Vector3& loc); - /// create histograms - void makeHistograms(); - - Acts::BoundTrackParameters makeTrackParams(SvtxTrack* track) const; + //! create ACTS track parameters from Svtx track + Acts::BoundTrackParameters makeTrackParams(SvtxTrack* ) const; /// actis transformation ActsTransformations m_transformer; @@ -170,6 +171,10 @@ class PHTpcResiduals : public SubsysReco /// require micromegas to be present when extrapolating tracks to the TPC bool m_useMicromegas = true; + /// minimum pT required for track to be considered in residuals calculation (GeV/c) + double m_minPt = 0.5; + + /// output file std::string m_outputfile = "TpcSpaceChargeMatrices.root"; /// running track crossing id @@ -184,55 +189,6 @@ class PHTpcResiduals : public SubsysReco int m_accepted_clusters = 0; //@} - /// Output root histograms - bool m_savehistograms = false; - TH2 *h_rphiResid = nullptr; - TH2 *h_zResid = nullptr; - TH2 *h_etaResidLayer = nullptr; - TH2 *h_zResidLayer = nullptr; - TH2 *h_etaResid = nullptr; - TH1 *h_index = nullptr; - TH2 *h_alpha = nullptr; - TH2 *h_beta = nullptr; - - //@name additional histograms that copy the per-cell data used to extract the distortions - //@{ - using TH1_map_t = std::map; - using TH2_map_t = std::map; - - TH1_map_t h_drphi; - TH1_map_t h_dz; - TH2_map_t h_drphi_alpha; - TH2_map_t h_dz_beta; - //@} - - TTree *residTup = nullptr; - - /// delta rphi vs layer number - TH2 *h_deltarphi_layer = nullptr; - - /// delta z vs layer number - TH2 *h_deltaz_layer = nullptr; - - std::string m_histogramfilename = "PHTpcResiduals.root"; - std::unique_ptr m_histogramfile = nullptr; - - /// For diagnostics - double tanAlpha = 0; - double tanBeta = 0; - double drphi = 0; - double dz = 0; - double clusR = 0; - double clusPhi = 0; - double clusZ = 0; - double statePhi = 0; - double stateZ = 0; - double stateRPhiErr = 0; - double stateZErr = 0; - double clusRPhiErr = 0; - double clusZErr = 0; - double stateR = 0; - TrkrDefs::cluskey cluskey = 0; }; #endif diff --git a/offline/packages/tpccalib/TpcDirectLaserReconstruction.cc b/offline/packages/tpccalib/TpcDirectLaserReconstruction.cc index 74ad8ea05d..59b030dda5 100644 --- a/offline/packages/tpccalib/TpcDirectLaserReconstruction.cc +++ b/offline/packages/tpccalib/TpcDirectLaserReconstruction.cc @@ -22,6 +22,7 @@ #include #include // for TrkrHit #include +#include #include #include @@ -236,7 +237,7 @@ int TpcDirectLaserReconstruction::load_nodes( PHCompositeNode* topNode ) assert(m_track_map); // get node containing the digitized hits - m_hit_map = findNode::getClass(topNode, "TRKR_HITSET"); + m_hit_map = findNode::getClass(topNode, "TRKR_HITSET_TPC"); assert(m_hit_map); return Fun4AllReturnCodes::EVENT_OK; @@ -374,7 +375,9 @@ void TpcDirectLaserReconstruction::process_track( SvtxTrack* track ) const TrkrDefs::hitsetkey& hitsetkey = hitsetitr->first; const int side = TpcDefs::getSide(hitsetkey); - auto hitset = hitsetitr->second; + auto hitset = dynamic_cast(hitsetitr->second); + assert(hitset); + const unsigned int layer = TrkrDefs::getLayer(hitsetkey); const auto layergeom = m_geom_container->GetLayerCellGeom(layer); const auto layer_center_radius = layergeom->get_radius(); @@ -385,15 +388,23 @@ void TpcDirectLaserReconstruction::process_track( SvtxTrack* track ) const unsigned short NTBins = (unsigned short)layergeom->get_zbins(); const float tdriftmax = AdcClockPeriod * NTBins / 2.0; - // get corresponding hits - TrkrHitSet::ConstRange hitrangei = hitset->getHits(); - - for (auto hitr = hitrangei.first; hitr != hitrangei.second; ++hitr) + const TrkrHitSetTpc::TimeFrameADCDataType &dataframe = hitset->getTimeFrameAdcData(); + + for (unsigned int local_pad = 0; local_pad < dataframe.size(); ++local_pad) + { + const std::vector &pad_data = dataframe[local_pad]; + + for (unsigned int local_tbin = 0; local_tbin < pad_data.size(); ++local_tbin) { + const TpcDefs::ADCDataType &rawadc = pad_data[local_tbin]; + TrkrDefs::hitkey hitkey = hitset->getHitKeyfromLocalBin(local_pad, local_tbin); + + if (rawadc<=0) continue; + ++m_total_hits; - const unsigned short phibin = TpcDefs::getPad(hitr->first); - const unsigned short zbin = TpcDefs::getTBin(hitr->first); + const unsigned short phibin = TpcDefs::getPad(hitkey); + const unsigned short zbin = TpcDefs::getTBin(hitkey); const double phi = layergeom->get_phicenter(phibin); const double x = layer_center_radius * cos(phi); @@ -410,7 +421,7 @@ void TpcDirectLaserReconstruction::process_track( SvtxTrack* track ) h_hits->Fill(x,y,z); } - float adc = (hitr->second->getAdc()) - m_pedestal; + float adc = rawadc - m_pedestal; // calculate dca // origin is track origin, direction is track direction @@ -480,6 +491,9 @@ void TpcDirectLaserReconstruction::process_track( SvtxTrack* track ) cluspos_map.insert(std::make_pair(layer, cluspos_pair)); layer_bin_set.insert(layer); } + }// for (unsigned int local_pad = 0; local_pad < dataframe.size(); ++local_pad) + + } for(int GEMS_iter = 0; GEMS_iter < 72; GEMS_iter++) diff --git a/offline/packages/tpccalib/TpcSpaceChargeReconstruction.cc b/offline/packages/tpccalib/TpcSpaceChargeReconstruction.cc index 8cabb6afd8..b5821c32b2 100644 --- a/offline/packages/tpccalib/TpcSpaceChargeReconstruction.cc +++ b/offline/packages/tpccalib/TpcSpaceChargeReconstruction.cc @@ -448,7 +448,7 @@ void TpcSpaceChargeReconstruction::process_track( SvtxTrack* track ) double cluster_z_error = 0; if( m_cluster_version >= 4 ) { - const auto errors_square = m_cluster_error_parametrization.get_cluster_error( track->get_tpc_seed(), cluster, cluster_r, cluster_key ); + const auto errors_square = m_cluster_error_parametrization.get_cluster_error(cluster, cluster_r, cluster_key, track->get_tpc_seed()->get_qOverR(), track->get_tpc_seed()->get_slope() ); cluster_rphi_error = std::sqrt( errors_square.first ); cluster_z_error = std::sqrt( errors_square.second ); } else { diff --git a/offline/packages/trackbase/AlignmentTransformation.cc b/offline/packages/trackbase/AlignmentTransformation.cc index dc4f1781cc..326778e695 100644 --- a/offline/packages/trackbase/AlignmentTransformation.cc +++ b/offline/packages/trackbase/AlignmentTransformation.cc @@ -4,7 +4,7 @@ #include "TpcDefs.h" #include "TrkrDefs.h" -#include +#include #include @@ -32,6 +32,12 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) { + localVerbosity = 0; + + // The default is to use translation parameters that are in global coordinates + use_global_millepede_translations = true; + std::cout << "AlignmentTransformation: use global translation perturbations = " << use_global_millepede_translations << std::endl; + getNodes(topNode); // Use construction transforms as a reference for making the map @@ -47,13 +53,13 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) if(datafile.is_open()) { std::cout << "AlignmentTransformation: Reading alignment parameters from disk file: " - << alignmentParamsFile << std::endl; + << alignmentParamsFile << " localVerbosity = " << localVerbosity << std::endl; } else { datafile.clear(); // load alignment constants file from database - alignmentParamsFile = XploadInterface::instance()->getUrl("TRACKINGALIGNMENT"); + alignmentParamsFile = CDBInterface::instance()->getUrl("TRACKINGALIGNMENT"); std::cout << "AlignmentTransformation: Reading alignment parameters from database file: " << alignmentParamsFile << std::endl; datafile.open(alignmentParamsFile); } @@ -86,17 +92,21 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) } surf = surfMaps.getSiliconSurface(hitsetkey); - Acts::Transform3 transform = makeTransform(surf, millepedeTranslation, sensorAngles); - Acts::GeometryIdentifier id = surf->geometryId(); + + Acts::Transform3 transform; + transform = newMakeTransform(surf, millepedeTranslation, sensorAngles); + Acts::GeometryIdentifier id = surf->geometryId(); + if(localVerbosity) { - std::cout << " Add transform for MVTX with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl; - std::cout << "mvtx transform" << transform.matrix() << std::endl; + + std::cout << " Add transform for MVTX with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl; + std::cout << " final mvtx transform:" << std::endl << transform.matrix() << std::endl; } transformMap->addTransform(id,transform); } - + else if(trkrId == TrkrDefs::inttId) { @@ -108,9 +118,11 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) } surf = surfMaps.getSiliconSurface(hitsetkey); - Acts::Transform3 transform = makeTransform(surf, millepedeTranslation, sensorAngles); + + Acts::Transform3 transform; + transform = newMakeTransform(surf, millepedeTranslation, sensorAngles); Acts::GeometryIdentifier id = surf->geometryId(); - + if(localVerbosity) { std::cout << " Add transform for INTT with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl; @@ -136,9 +148,11 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) for(unsigned int subsurfkey = subsurfkey_min; subsurfkeygeometryId(); - + + Acts::Transform3 transform; + transform = newMakeTransform(surf, millepedeTranslation, sensorAngles); + Acts::GeometryIdentifier id = surf->geometryId(); + if(localVerbosity) { std::cout << " Add transform for TPC with surface GeometryIdentifier " << id << " trkrid " << trkrId << std::endl; @@ -156,7 +170,9 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) millepedeTranslation = millepedeTranslation + perturbationTranslation; } surf = surfMaps.getMMSurface(hitsetkey); - Acts::Transform3 transform = makeTransform(surf, millepedeTranslation, sensorAngles); + + Acts::Transform3 transform; + transform = newMakeTransform(surf, millepedeTranslation, sensorAngles); Acts::GeometryIdentifier id = surf->geometryId(); if(localVerbosity) @@ -182,107 +198,104 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) } -Eigen::Matrix3d AlignmentTransformation::rotateToGlobal(Surface surf) -{ - /* - Get ideal geometry rotation, by aligning surface to surface normal vector in global coordinates - URL: https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d - */ - - Eigen::Vector3d ylocal(0,1,0); - Eigen::Vector3d sensorNormal = -surf->normal(m_tGeometry->geometry().getGeoContext()); - sensorNormal = sensorNormal/sensorNormal.norm(); // make unit vector - double cosTheta = ylocal.dot(sensorNormal); - double sinTheta = (ylocal.cross(sensorNormal)).norm(); - Eigen::Vector3d vectorRejection = (sensorNormal - (ylocal.dot(sensorNormal))*ylocal)/(sensorNormal - (ylocal.dot(sensorNormal))*ylocal).norm(); - Eigen::Vector3d perpVector = sensorNormal.cross(ylocal); - - // Initialize and fill matrices (row,col) - Eigen::Matrix3d fInverse; - fInverse(0,0) = ylocal(0); - fInverse(1,0) = ylocal(1); - fInverse(2,0) = ylocal(2); - fInverse(0,1) = vectorRejection(0); - fInverse(1,1) = vectorRejection(1); - fInverse(2,1) = vectorRejection(2); - fInverse(0,2) = perpVector(0); - fInverse(1,2) = perpVector(1); - fInverse(2,2) = perpVector(2); - - Eigen::Matrix3d G; - G(0,0) = cosTheta; - G(0,1) = -sinTheta; - G(0,2) = 0; - G(1,0) = sinTheta; - G(1,1) = cosTheta; - G(1,2) = 0; - G(2,0) = 0; - G(2,1) = 0; - G(2,2) = 1; - - Eigen::Matrix3d globalRotation = fInverse * G * (fInverse.inverse()); - - if(localVerbosity > 2) - { - std::cout<< " global rotation: "<< std::endl << globalRotation < qnull = g*b*a; + Eigen::Matrix3d nullRotation = qnull.matrix(); -Acts::Transform3 AlignmentTransformation::makeTransform(Surface surf, Eigen::Vector3d millepedeTranslation, Eigen::Vector3d sensorAngles) -{ // Create alignment rotation matrix + + // Note that Acts transforms local coordinates of (x,z,y) to global (x,y,z) + //===================================================== + // If we use a local alignment translation vector (dx,dy,dz) it + // should be converted to (dx,dz,dy) before applying the Acts transform to global + // It seems we can just interchange the x and y coordinates for this + // Swapping y and z is a rotation around the x axis, resulting in a left handed coordinate system + // why is this not a problem??? + // It does mean that the order of the rotations is different from (x,y,z), but they are just fitted free parameters + //===================================================== + Eigen::AngleAxisd alpha(sensorAngles(0), Eigen::Vector3d::UnitX()); Eigen::AngleAxisd beta(sensorAngles(1), Eigen::Vector3d::UnitY()); Eigen::AngleAxisd gamma(sensorAngles(2), Eigen::Vector3d::UnitZ()); Eigen::Quaternion q = gamma*beta*alpha; Eigen::Matrix3d millepedeRotation = q.matrix(); - // Create ideal rotation matrix from ActsGeometry - Eigen::Matrix3d globalRotation = AlignmentTransformation::rotateToGlobal(surf); - Eigen::Matrix3d combinedRotation = globalRotation * millepedeRotation; - Eigen::Vector3d sensorCenter = surf->center(m_tGeometry->geometry().getGeoContext());//*0.1; - Eigen::Vector3d globalTranslation = sensorCenter + millepedeTranslation; - Acts::Transform3 transformation = AlignmentTransformation::makeAffineMatrix(combinedRotation,globalTranslation); + Acts::Transform3 mpRotationAffine; + mpRotationAffine.linear() = millepedeRotation; + mpRotationAffine.translation() = nullTranslation; + + // create alignment translation matrix + Acts::Transform3 mpTranslationAffine; + mpTranslationAffine.linear() = nullRotation; + if(use_global_millepede_translations > 0) + { + mpTranslationAffine.translation() = millepedeTranslation; + } + else + { + // offsets should now be in local frame, so (dx,dz,dy) + Eigen::Vector3d millepedeTranslationxzy(millepedeTranslation(0), millepedeTranslation(2), millepedeTranslation(1)); + mpTranslationAffine.translation() = millepedeTranslationxzy; + } + + // get the acts transform components + Acts::Transform3 actsTransform = surf->transform(m_tGeometry->geometry().getGeoContext()); + Eigen::Matrix3d actsRotationPart = actsTransform.rotation(); + Eigen::Vector3d actsTranslationPart = actsTransform.translation(); + + // and make affine matrices from each + Acts::Transform3 actsRotationAffine; + actsRotationAffine.linear() = actsRotationPart; + actsRotationAffine.translation() = nullTranslation; + Acts::Transform3 actsTranslationAffine; + actsTranslationAffine.linear() = nullRotation; + actsTranslationAffine.translation() = actsTranslationPart; + + //Put them together into a combined transform + + + Acts::Transform3 transform; + if(use_global_millepede_translations > 0) + { + // put the mp translations in the global frame + transform = mpTranslationAffine * actsTranslationAffine * actsRotationAffine * mpRotationAffine; + } + else + { + // put the mp translations in the local coordinate frame + transform = actsTranslationAffine * actsRotationAffine * mpTranslationAffine * mpRotationAffine; + } if(localVerbosity > 2) { - std::cout << "sensor center: " << sensorCenter << " millepede translation: " << millepedeTranslation < 0) + { + std::cout << "mpTranslationAffine: " << std::endl << mpTranslationAffine.matrix() <(topNode, "ActsGeometry"); @@ -297,9 +310,9 @@ int AlignmentTransformation::getNodes(PHCompositeNode* topNode) return 0; } -void AlignmentTransformation::misalignmentFactor(TrkrDefs::TrkrId id, const double factor) +void AlignmentTransformation::misalignmentFactor(uint8_t layer, const double factor) { - transformMap->setMisalignmentFactor(id, factor); + transformMap->setMisalignmentFactor(layer, factor); } void AlignmentTransformation::createAlignmentTransformContainer(PHCompositeNode* topNode) { diff --git a/offline/packages/trackbase/AlignmentTransformation.h b/offline/packages/trackbase/AlignmentTransformation.h index 24bf5fd690..652b25841d 100644 --- a/offline/packages/trackbase/AlignmentTransformation.h +++ b/offline/packages/trackbase/AlignmentTransformation.h @@ -103,7 +103,7 @@ void setTPCParams(double tpcDevs[6]) } } - void misalignmentFactor(TrkrDefs::TrkrId id, const double factor); + void misalignmentFactor(uint8_t layer, const double factor); private: @@ -122,11 +122,9 @@ void setTPCParams(double tpcDevs[6]) int localVerbosity = 0; - Acts::Transform3 makeTransform(Surface surf, Eigen::Vector3d millepedeTranslation, Eigen::Vector3d sensorAngles); + bool use_global_millepede_translations = true; - Acts::Transform3 makeAffineMatrix(Eigen::Matrix3d rotationMatrix, Eigen::Vector3d translationVector); - - Eigen::Matrix3d rotateToGlobal(Surface surf); + Acts::Transform3 newMakeTransform(Surface surf, Eigen::Vector3d millepedeTranslation, Eigen::Vector3d sensorAngles); alignmentTransformationContainer* transformMap = NULL; ActsGeometry* m_tGeometry = NULL; diff --git a/offline/packages/trackbase/CMFlashCluster.h b/offline/packages/trackbase/CMFlashCluster.h index 411b2b2e9e..0de1ed2bc3 100644 --- a/offline/packages/trackbase/CMFlashCluster.h +++ b/offline/packages/trackbase/CMFlashCluster.h @@ -52,13 +52,48 @@ class CMFlashCluster : public PHObject virtual void setY(float) {} virtual float getZ() const { return NAN; } virtual void setZ(float) {} + + virtual float getX1() const { return NAN; } + virtual void setX1(float) {} + virtual float getY1() const { return NAN; } + virtual void setY1(float) {} + virtual float getZ1() const { return NAN; } + virtual void setZ1(float) {} + + virtual float getX2() const { return NAN; } + virtual void setX2(float) {} + virtual float getY2() const { return NAN; } + virtual void setY2(float) {} + virtual float getZ2() const { return NAN; } + virtual void setZ2(float) {} + + + virtual void setLayer1(unsigned int) {} + virtual unsigned int getLayer1() const { return UINT_MAX; } + + virtual void setLayer2(unsigned int) {} + virtual unsigned int getLayer2() const { return UINT_MAX; } + // // cluster info // virtual void setAdc(unsigned int) {} virtual unsigned int getAdc() const { return UINT_MAX; } + + + virtual void setAdc1(unsigned int) {} + virtual unsigned int getAdc1() const { return UINT_MAX; } + + virtual void setAdc2(unsigned int) {} + virtual unsigned int getAdc2() const { return UINT_MAX; } + virtual unsigned int getNclusters() const {return UINT_MAX;} virtual void setNclusters( unsigned int) {} + virtual void setIsRGap(bool) {} + virtual bool getIsRGap() const { return false; } + virtual void setIsPhiGap(bool) {} + virtual bool getIsPhiGap() const { return false; } + protected: CMFlashCluster() = default; diff --git a/offline/packages/trackbase/CMFlashClusterContainerv1.cc b/offline/packages/trackbase/CMFlashClusterContainerv1.cc index f2d8bbbdca..f7389278cd 100644 --- a/offline/packages/trackbase/CMFlashClusterContainerv1.cc +++ b/offline/packages/trackbase/CMFlashClusterContainerv1.cc @@ -6,7 +6,6 @@ */ #include "CMFlashClusterContainerv1.h" #include "CMFlashCluster.h" -#include "CMFlashClusterv1.h" #include diff --git a/offline/packages/trackbase/CMFlashClusterv2.cc b/offline/packages/trackbase/CMFlashClusterv2.cc new file mode 100644 index 0000000000..978ef70e5b --- /dev/null +++ b/offline/packages/trackbase/CMFlashClusterv2.cc @@ -0,0 +1,55 @@ +/** + * @file trackbase/CMFlashClusterv2.cc + * @author Ben Kimelman + * @date March 2023 + * @brief Implementation of CMFlashClusterv2 + */ +#include "CMFlashClusterv2.h" + +#include +#include // for swap + +void CMFlashClusterv2::identify(std::ostream& os) const +{ + os << "---CMFlashClusterv2--------------------" << std::endl; + + os << " (x,y,z) = (" << m_pos[0]; + os << ", " << m_pos[1] << ", "; + os << m_pos[2] << ") cm"; + + os << " adc = " << getAdc() << std::endl; + + os << std::endl; + os << "-----------------------------------------------" << std::endl; + + return; +} + +int CMFlashClusterv2::isValid() const +{ + if(std::isnan(getX())) return 0; + if(std::isnan(getY())) return 0; + if(std::isnan(getZ())) return 0; + + if (m_adc == 0xFFFFFFFF) return 0; + + return 1; +} + +void CMFlashClusterv2::CopyFrom( const CMFlashCluster& source ) +{ + // do nothing if copying onto oneself + if( this == &source ) return; + + // parent class method + CMFlashCluster::CopyFrom( source ); + + setX( source.getX() ); + setY( source.getY() ); + setZ( source.getZ() ); + setAdc( source.getAdc() ); + setIsRGap( source.getIsRGap() ); + setIsPhiGap( source.getIsPhiGap() ); + +} + diff --git a/offline/packages/trackbase/CMFlashClusterv2.h b/offline/packages/trackbase/CMFlashClusterv2.h new file mode 100644 index 0000000000..cfeb71ec73 --- /dev/null +++ b/offline/packages/trackbase/CMFlashClusterv2.h @@ -0,0 +1,84 @@ +/** + * @file trackbase/CMFlashClusterv2.h + * @author Ben Kimelman + * @date March 2023 + * @brief Version 2 of CMFlashCluster + */ +#ifndef TRACKBASE_CMFLASHCLUSTERV2_H +#define TRACKBASE_CMFLASHCLUSTERV2_H + +#include "CMFlashCluster.h" + +#include + +class PHObject; + +/** + * @brief Version 2 of CMFlashCluster + * + * Adding bool variables to identify if + * meta-cluster contains sub-clusters from + * both sides of sector (phi) or module (R) + * gaps + * + */ +class CMFlashClusterv2 : public CMFlashCluster +{ + public: + //! ctor + CMFlashClusterv2() = default; + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override {} + int isValid() const override; + PHObject* CloneMe() const override { return new CMFlashClusterv2(*this); } + + //! copy content from base class + void CopyFrom( const CMFlashCluster& ) override; + + //! copy content from base class + void CopyFrom( CMFlashCluster* source ) override + { CopyFrom( *source ); } + + // + // cluster position + // + float getX() const override { return m_pos[0]; } + void setX(float x) override { m_pos[0] = x; } + float getY() const override { return m_pos[1]; } + void setY(float y) override { m_pos[1] = y; } + float getZ() const override { return m_pos[2]; } + void setZ(float z) override { m_pos[2] = z; } + unsigned int getNclusters() const override {return m_nclusters;} + void setNclusters(unsigned int n) override { m_nclusters = n;} + bool getIsRGap() const override { return m_isRGap; } + void setIsRGap(bool isRGap) override { m_isRGap = isRGap;} + bool getIsPhiGap() const override { return m_isPhiGap; } + void setIsPhiGap(bool isPhiGap) override { m_isPhiGap = isPhiGap;} + + // + // cluster info + // + unsigned int getAdc() const override { return m_adc; } + void setAdc(unsigned int adc) override { m_adc = adc; } + + protected: + + /// mean cluster position + float m_pos[3] = {NAN, NAN, NAN}; + + /// cluster sum adc + unsigned int m_adc = 0xFFFFFFFF; + + /// number of TPC clusters used to create this central mebrane cluster + unsigned int m_nclusters = UINT_MAX; + + /// bools to identify if meta-cluster is across sector/module gaps + bool m_isRGap = false; + bool m_isPhiGap = false; + + ClassDefOverride(CMFlashClusterv2, 1) +}; + +#endif //TRACKBASE_CMFLASHCLUSTERV2_H diff --git a/offline/packages/trackbase/CMFlashClusterv2LinkDef.h b/offline/packages/trackbase/CMFlashClusterv2LinkDef.h new file mode 100644 index 0000000000..e7df16928f --- /dev/null +++ b/offline/packages/trackbase/CMFlashClusterv2LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class CMFlashClusterv2+; + +#endif diff --git a/offline/packages/trackbase/CMFlashClusterv3.cc b/offline/packages/trackbase/CMFlashClusterv3.cc new file mode 100644 index 0000000000..122e8d0c90 --- /dev/null +++ b/offline/packages/trackbase/CMFlashClusterv3.cc @@ -0,0 +1,82 @@ +/** + * @file trackbase/CMFlashClusterv3.cc + * @author Ben Kimelman + * @date March 2023 + * @brief Implementation of CMFlashClusterv3 + */ +#include "CMFlashClusterv3.h" + +#include +#include // for swap + +void CMFlashClusterv3::identify(std::ostream& os) const +{ + os << "---CMFlashClusterv3--------------------" << std::endl; + + os << " (x,y,z) = (" << m_pos[0]; + os << ", " << m_pos[1] << ", "; + os << m_pos[2] << ") cm"; + + os << " adc = " << getAdc() << std::endl; + + os << std::endl; + os << "-----------------------------------------------" << std::endl; + + return; +} + +int CMFlashClusterv3::isValid() const +{ + if(std::isnan(getX())) return 0; + if(std::isnan(getY())) return 0; + if(std::isnan(getZ())) return 0; + + + if(std::isnan(getX1())) return 0; + if(std::isnan(getY1())) return 0; + if(std::isnan(getZ1())) return 0; + + + if(std::isnan(getX2())) return 0; + if(std::isnan(getY2())) return 0; + if(std::isnan(getZ2())) return 0; + + if (m_adc == 0xFFFFFFFF) return 0; + if (m_adc1 == 0xFFFFFFFF) return 0; + if (m_adc2 == 0xFFFFFFFF) return 0; + + return 1; +} + +void CMFlashClusterv3::CopyFrom( const CMFlashCluster& source ) +{ + // do nothing if copying onto oneself + if( this == &source ) return; + + // parent class method + CMFlashCluster::CopyFrom( source ); + + setX( source.getX() ); + setY( source.getY() ); + setZ( source.getZ() ); + + + setX1( source.getX1() ); + setY1( source.getY1() ); + setZ1( source.getZ1() ); + + setX2( source.getX2() ); + setY2( source.getY2() ); + setZ2( source.getZ2() ); + + setLayer1( source.getLayer1() ); + setLayer2( source.getLayer2() ); + + setAdc( source.getAdc() ); + setAdc1( source.getAdc1() ); + setAdc2( source.getAdc2() ); + setIsRGap( source.getIsRGap() ); + setIsPhiGap( source.getIsPhiGap() ); + +} + diff --git a/offline/packages/trackbase/CMFlashClusterv3.h b/offline/packages/trackbase/CMFlashClusterv3.h new file mode 100644 index 0000000000..c107220d3d --- /dev/null +++ b/offline/packages/trackbase/CMFlashClusterv3.h @@ -0,0 +1,117 @@ +/** + * @file trackbase/CMFlashClusterv3.h + * @author Ben Kimelman + * @date March 2023 + * @brief Version 3 of CMFlashCluster + */ +#ifndef TRACKBASE_CMFLASHCLUSTERV3_H +#define TRACKBASE_CMFLASHCLUSTERV3_H + +#include "CMFlashCluster.h" + +#include + +class PHObject; + +/** + * @brief Version 3 of CMFlashCluster + * + *Adding variable to keep track of clusters + *put into metaclusters + * + */ +class CMFlashClusterv3 : public CMFlashCluster +{ + public: + //! ctor + CMFlashClusterv3() = default; + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override {} + int isValid() const override; + PHObject* CloneMe() const override { return new CMFlashClusterv3(*this); } + + //! copy content from base class + void CopyFrom( const CMFlashCluster& ) override; + + //! copy content from base class + void CopyFrom( CMFlashCluster* source ) override + { CopyFrom( *source ); } + + // + // cluster position + // + float getX() const override { return m_pos[0]; } + void setX(float x) override { m_pos[0] = x; } + float getY() const override { return m_pos[1]; } + void setY(float y) override { m_pos[1] = y; } + float getZ() const override { return m_pos[2]; } + void setZ(float z) override { m_pos[2] = z; } + + + float getX1() const override { return m_pos1[0]; } + void setX1(float x) override { m_pos1[0] = x; } + float getY1() const override { return m_pos1[1]; } + void setY1(float y) override { m_pos1[1] = y; } + float getZ1() const override { return m_pos1[2]; } + void setZ1(float z) override { m_pos1[2] = z; } + + float getX2() const override { return m_pos2[0]; } + void setX2(float x) override { m_pos2[0] = x; } + float getY2() const override { return m_pos2[1]; } + void setY2(float y) override { m_pos2[1] = y; } + float getZ2() const override { return m_pos2[2]; } + void setZ2(float z) override { m_pos2[2] = z; } + + unsigned int getLayer1() const override {return m_layer1;} + void setLayer1(unsigned int layer) override { m_layer1 = layer;} + unsigned int getLayer2() const override {return m_layer2;} + void setLayer2(unsigned int layer) override { m_layer2 = layer;} + + unsigned int getNclusters() const override {return m_nclusters;} + void setNclusters(unsigned int n) override { m_nclusters = n;} + bool getIsRGap() const override { return m_isRGap; } + void setIsRGap(bool isRGap) override { m_isRGap = isRGap;} + bool getIsPhiGap() const override { return m_isPhiGap; } + void setIsPhiGap(bool isPhiGap) override { m_isPhiGap = isPhiGap;} + + // + // cluster info + // + unsigned int getAdc() const override { return m_adc; } + void setAdc(unsigned int adc) override { m_adc = adc; } + + unsigned int getAdc1() const override { return m_adc1; } + void setAdc1(unsigned int adc) override { m_adc1 = adc; } + + unsigned int getAdc2() const override { return m_adc2; } + void setAdc2(unsigned int adc) override { m_adc2 = adc; } + + protected: + + /// mean cluster position + float m_pos[3] = {NAN, NAN, NAN}; + + float m_pos1[3] = {NAN, NAN, NAN}; + float m_pos2[3] = {NAN, NAN, NAN}; + + /// cluster sum adc + unsigned int m_adc = 0xFFFFFFFF; + unsigned int m_adc1 = 0xFFFFFFFF; + unsigned int m_adc2 = 0xFFFFFFFF; + + unsigned int m_layer1 = UINT_MAX; + unsigned int m_layer2 = UINT_MAX; + + /// number of TPC clusters used to create this central mebrane cluster + unsigned int m_nclusters = UINT_MAX; + + /// bools to identify if meta-cluster is across sector/module gaps + bool m_isRGap = false; + bool m_isPhiGap = false; + + ClassDefOverride(CMFlashClusterv3, 1) +}; + +#endif //TRACKBASE_CMFLASHCLUSTERV3_H diff --git a/offline/packages/trackbase/CMFlashClusterv3LinkDef.h b/offline/packages/trackbase/CMFlashClusterv3LinkDef.h new file mode 100644 index 0000000000..baa1677ab2 --- /dev/null +++ b/offline/packages/trackbase/CMFlashClusterv3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class CMFlashClusterv3+; + +#endif diff --git a/offline/packages/trackbase/Calibrator.h b/offline/packages/trackbase/Calibrator.h index 2ffaf83960..b03076a38c 100644 --- a/offline/packages/trackbase/Calibrator.h +++ b/offline/packages/trackbase/Calibrator.h @@ -61,8 +61,8 @@ class Calibrator auto cov = uncalibmeas.covariance(); const auto& cluskey = sourceLink.cluskey(); - const auto trkrid = TrkrDefs::getTrkrId(cluskey); - const double misalignmentFactor = gctx.get()->getMisalignmentFactor(trkrid); + const auto layer = TrkrDefs::getLayer(cluskey); + const double misalignmentFactor = gctx.get()->getMisalignmentFactor(layer); Acts::ActsSymMatrix<2> expandedCov = Acts::ActsSymMatrix<2>::Zero(); diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 8f5b7bf9e1..497b12903f 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -1,5 +1,4 @@ #include "ClusterErrorPara.h" -#include #include #include @@ -21,7 +20,6 @@ ClusterErrorPara::ClusterErrorPara() f0 = new TF1("f0","pol1",0,10); f0->SetParameter(0,0.0163943); f0->SetParameter(1,0.0192931); - // f0->SetParameter(2,-5.2042); f1 = new TF1("f1","pol2",0,10); f1->SetParameter(0,0.0119384); @@ -474,16 +472,8 @@ ClusterErrorPara::ClusterErrorPara() } //_________________________________________________________________________________ -ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_error(TrackSeed *seed, TrkrClusterv5* clusterv5, double cluster_r, TrkrDefs::cluskey key) -{/* - float r = cluster_r; - float R = TMath::Abs(1.0/seed->get_qOverR()); - double alpha = (r*r) /(2*r*R); - double beta = TMath::Abs(atan(seed->get_slope())); - */ - if(seed==0) std::cout << "hallo" << std::endl; - if(cluster_r==0) std::cout << "hallo" << std::endl; - if(key==0) std::cout << "hallo" << std::endl; +ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClusterv5* clusterv5, double, TrkrDefs::cluskey key) +{ int layer = TrkrDefs::getLayer(key); @@ -491,28 +481,31 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_error(TrackSeed *seed, double zerror = clusterv5->getZError(); if( TrkrDefs::getTrkrId( key )== TrkrDefs::tpcId){ if(layer==7||layer==22||layer==23||layer==38||layer==39){ - phierror *= 3.5; - zerror*= 3.5; + phierror *= 4; + zerror*= 4; } - if(clusterv5->getEdge()>=5) - phierror *= 2; + if(clusterv5->getEdge()>=3) + phierror *= 4; if(clusterv5->getOverlap()>=2) phierror *= 2; - + if(clusterv5->getPhiSize()==1) + phierror *= 10; + if(clusterv5->getPhiSize()>=5) + phierror *= 10; + if(phierror>0.1) phierror = 0.1; if(phierror<0.0005) phierror = 0.1; } return std::make_pair(square(phierror),square(zerror)); - // return get_cluster_error(cluster, key, alpha, beta); } //_________________________________________________________________________________ -ClusterErrorPara::error_t ClusterErrorPara::get_cluster_error(TrackSeed *seed, TrkrCluster* cluster, double cluster_r, TrkrDefs::cluskey key) +ClusterErrorPara::error_t ClusterErrorPara::get_cluster_error(TrkrCluster* cluster, double cluster_r, TrkrDefs::cluskey key, float qOverR, float slope) { float r = cluster_r; - float R = TMath::Abs(1.0/seed->get_qOverR()); + float R = TMath::Abs(1.0/qOverR); double alpha = (r*r) /(2*r*R); - double beta = TMath::Abs(atan(seed->get_slope())); + double beta = TMath::Abs(atan(slope)); return get_cluster_error(cluster, key, alpha, beta); } @@ -520,7 +513,8 @@ double ClusterErrorPara::tpc_phi_error(int layer, double alpha, TrkrCluster* clu double phierror = 0; TrkrClusterv4 *clusterv4 = dynamic_cast(cluster); - + assert( clusterv4 ); + int sector = -1; if(layer >=7 && layer < 23){ sector = 0; @@ -623,6 +617,7 @@ double ClusterErrorPara::tpc_phi_error(int layer, double alpha, TrkrCluster* clu double ClusterErrorPara::tpc_z_error(int layer, double beta, TrkrCluster* cluster){ double zerror = 0.05; TrkrClusterv4 *clusterv4 = dynamic_cast(cluster); + assert( clusterv4 ); int sector = -1; if(layer >=7 && layer < 23){ diff --git a/offline/packages/trackbase/ClusterErrorPara.h b/offline/packages/trackbase/ClusterErrorPara.h index ed1b1c6f1c..54915b90c3 100644 --- a/offline/packages/trackbase/ClusterErrorPara.h +++ b/offline/packages/trackbase/ClusterErrorPara.h @@ -10,7 +10,6 @@ #include #include //class TF1; -class TrackSeed; class TrkrCluster; class ClusterErrorPara @@ -56,8 +55,8 @@ class ClusterErrorPara using error_t = std::pair; - error_t get_clusterv5_error(TrackSeed *seed, TrkrClusterv5* clusterv5, double cluster_r, TrkrDefs::cluskey key); - error_t get_cluster_error(TrackSeed *seed, TrkrCluster* cluster, double cluster_r, TrkrDefs::cluskey key); + error_t get_clusterv5_modified_error(TrkrClusterv5* clusterv5, double cluster_r, TrkrDefs::cluskey key); + error_t get_cluster_error(TrkrCluster* cluster, double cluster_r, TrkrDefs::cluskey key, float qOverR, float slope); error_t get_cluster_error(TrkrCluster* cluster, TrkrDefs::cluskey key, double alpha, double beta); error_t get_simple_cluster_error(TrkrCluster* cluster, double cluster_r, TrkrDefs::cluskey key); diff --git a/offline/packages/trackbase/Makefile.am b/offline/packages/trackbase/Makefile.am index 937245aa6c..03c183c294 100644 --- a/offline/packages/trackbase/Makefile.am +++ b/offline/packages/trackbase/Makefile.am @@ -7,6 +7,15 @@ AUTOMAKE_OPTIONS = foreign lib_LTLIBRARIES = \ libtrack_io.la +if USE_ONLINE +pkginclude_HEADERS = \ + TrkrDefs.h + +libtrack_io_la_SOURCES = \ + TrkrDefs.cc + +else + AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ @@ -18,6 +27,7 @@ AM_LDFLAGS = \ -L$(ROOTSYS)/lib \ -L$(OFFLINE_MAIN)/lib64 + pkginclude_HEADERS = \ ActsAborter.h \ ActsGeometry.h \ @@ -26,11 +36,14 @@ pkginclude_HEADERS = \ ActsSurfaceMaps.h \ ActsTrackFittingAlgorithm.h \ ActsTrackingGeometry.h \ + alignmentTransformationContainer.h \ AlignmentTransformation.h \ CMFlashCluster.h \ CMFlashClusterContainer.h \ CMFlashClusterContainerv1.h \ CMFlashClusterv1.h \ + CMFlashClusterv2.h \ + CMFlashClusterv3.h \ CMFlashDifference.h \ CMFlashDifferenceContainer.h \ CMFlashDifferenceContainerv1.h \ @@ -48,6 +61,7 @@ pkginclude_HEADERS = \ RawHitv1.h \ ResidualOutlierFinder.h \ SpacePoint.h \ + sPHENIXActsDetectorElement.h \ TpcDefs.h \ TpcSeedTrackMap.h \ TpcSeedTrackMapv1.h \ @@ -76,19 +90,24 @@ pkginclude_HEADERS = \ TrkrHitSet.h \ TrkrHitSetContainer.h \ TrkrHitSetContainerv1.h \ + TrkrHitSetContainerv2.h \ TrkrHitSetv1.h \ + TrkrHitSetTpc.h \ + TrkrHitSetTpcv1.h \ TrkrHitTruthAssoc.h \ TrkrHitTruthAssocv1.h \ TrkrHitv1.h \ - TrkrHitv2.h \ - alignmentTransformationContainer.h \ - sPHENIXActsDetectorElement.h + TrkrHitv2.h + ROOTDICTS = \ + alignmentTransformationContainer_Dict.cc \ CMFlashClusterContainer_Dict.cc \ CMFlashClusterContainerv1_Dict.cc \ CMFlashCluster_Dict.cc \ CMFlashClusterv1_Dict.cc \ + CMFlashClusterv2_Dict.cc \ + CMFlashClusterv3_Dict.cc \ CMFlashDifferenceContainer_Dict.cc \ CMFlashDifferenceContainerv1_Dict.cc \ CMFlashDifference_Dict.cc \ @@ -123,23 +142,27 @@ ROOTDICTS = \ TrkrClusterv5_Dict.cc \ TrkrHitSetContainer_Dict.cc \ TrkrHitSetContainerv1_Dict.cc \ + TrkrHitSetContainerv2_Dict.cc \ TrkrHitSet_Dict.cc \ TrkrHitSetv1_Dict.cc \ + TrkrHitSetTpc_Dict.cc \ + TrkrHitSetTpcv1_Dict.cc \ TrkrHitTruthAssoc_Dict.cc \ TrkrHitTruthAssocv1_Dict.cc \ TrkrHit_Dict.cc \ TrkrHitv1_Dict.cc \ - TrkrHitv2_Dict.cc \ - alignmentTransformationContainer_Dict.cc \ - sPHENIXActsDetectorElement.cc + TrkrHitv2_Dict.cc pcmdir = $(libdir) nobase_dist_pcm_DATA = \ + alignmentTransformationContainer_Dict_rdict.pcm \ CMFlashClusterContainer_Dict_rdict.pcm \ CMFlashClusterContainerv1_Dict_rdict.pcm \ CMFlashCluster_Dict_rdict.pcm \ CMFlashClusterv1_Dict_rdict.pcm \ + CMFlashClusterv2_Dict_rdict.pcm \ + CMFlashClusterv3_Dict_rdict.pcm \ CMFlashDifferenceContainer_Dict_rdict.pcm \ CMFlashDifferenceContainerv1_Dict_rdict.pcm \ CMFlashDifference_Dict_rdict.pcm \ @@ -174,23 +197,28 @@ nobase_dist_pcm_DATA = \ TrkrClusterv5_Dict_rdict.pcm \ TrkrHitSetContainer_Dict_rdict.pcm \ TrkrHitSetContainerv1_Dict_rdict.pcm \ + TrkrHitSetContainerv2_Dict_rdict.pcm \ TrkrHitSet_Dict_rdict.pcm \ TrkrHitSetv1_Dict_rdict.pcm \ + TrkrHitSetTpc_Dict_rdict.pcm \ + TrkrHitSetTpcv1_Dict_rdict.pcm \ TrkrHitTruthAssoc_Dict_rdict.pcm \ TrkrHitTruthAssocv1_Dict_rdict.pcm \ TrkrHit_Dict_rdict.pcm \ TrkrHitv1_Dict_rdict.pcm \ - TrkrHitv2_Dict_rdict.pcm \ - alignmentTransformationContainer_Dict_rdict.pcm + TrkrHitv2_Dict_rdict.pcm # sources for io library libtrack_io_la_SOURCES = \ $(ROOTDICTS) \ ActsGeometry.cc \ ActsSurfaceMaps.cc \ + alignmentTransformationContainer.cc \ AlignmentTransformation.cc \ CMFlashClusterContainerv1.cc \ CMFlashClusterv1.cc \ + CMFlashClusterv2.cc \ + CMFlashClusterv3.cc \ CMFlashDifferenceContainerv1.cc \ CMFlashDifferencev1.cc \ ClusterErrorPara.cc \ @@ -202,6 +230,7 @@ libtrack_io_la_SOURCES = \ RawHitSetv1.cc \ RawHitTpc.cc \ RawHitv1.cc \ + sPHENIXActsDetectorElement.cc \ TpcDefs.cc \ TpcSeedTrackMap.cc \ TpcSeedTrackMapv1.cc \ @@ -230,19 +259,22 @@ libtrack_io_la_SOURCES = \ TrkrHitSet.cc \ TrkrHitSetContainer.cc \ TrkrHitSetContainerv1.cc \ + TrkrHitSetContainerv2.cc \ TrkrHitSetv1.cc \ + TrkrHitSetTpc.cc \ + TrkrHitSetTpcv1.cc \ TrkrHitTruthAssocv1.cc \ TrkrHitv1.cc \ - TrkrHitv2.cc \ - alignmentTransformationContainer.cc + TrkrHitv2.cc libtrack_io_la_LIBADD = \ -lphool \ -lActsCore \ -lActsPluginTGeo \ -lffamodules \ - -lphg4hit + -lphg4hit +endif # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h diff --git a/offline/packages/trackbase/TpcDefs.h b/offline/packages/trackbase/TpcDefs.h index 9766753370..41e211e47e 100644 --- a/offline/packages/trackbase/TpcDefs.h +++ b/offline/packages/trackbase/TpcDefs.h @@ -9,7 +9,7 @@ #include "TrkrDefs.h" -#include // for uint8_t, uint16_t, uint32_t +#include // for uint8_t, uint16_t, uint32_t /** * @brief Utility functions for TPC @@ -19,76 +19,88 @@ */ namespace TpcDefs { -// hitsetkey layout: -// Tpc specific lower 16 bits -// 24 - 32 tracker id -// 16 - 24 layer -// 8 - 16 sector id -// 0 - 8 side -static const unsigned int kBitShiftSectorId __attribute__((unused)) = 8; -static const unsigned int kBitShiftSide __attribute__((unused)) = 0; - -// bit shift for hitkey -// 16 - 32 pad id -// 0 - 16 time bin -static const unsigned int kBitShiftPad __attribute__((unused)) = 16; -static const unsigned int kBitShiftTBin __attribute__((unused)) = 0; - -// max values for pad and time bin -static const uint16_t MAXPAD __attribute__((unused)) = 1024; -static const uint16_t MAXTBIN __attribute__((unused)) = 512; -/** + constexpr int NSides = 2; + constexpr int NSectors = 12; + constexpr int NRSectors = 3; + + //! in memory representation of TPC ADC data: 10bit ADC value as 16bit signed integer. + // This is signed to allow pedestal subtraction when needed + typedef int16_t ADCDataType; + + //! in memory representation of BCO clock using standard 64bit sPHENIX time stamp precision + typedef uint64_t BCODataType; + + // hitsetkey layout: + // Tpc specific lower 16 bits + // 24 - 32 tracker id + // 16 - 24 layer + // 8 - 16 sector id + // 0 - 8 side + static const unsigned int kBitShiftSectorId __attribute__((unused)) = 8; + static const unsigned int kBitShiftSide __attribute__((unused)) = 0; + + // bit shift for hitkey + // 16 - 32 pad id + // 0 - 16 time bin + static const unsigned int kBitShiftPad __attribute__((unused)) = 16; + static const unsigned int kBitShiftTBin __attribute__((unused)) = 0; + + // max values for pad and time bin + static const uint16_t MAXPAD __attribute__((unused)) = 1024; + static const uint16_t MAXTBIN __attribute__((unused)) = 512; + + /** * @brief Get the sector id from hitsetkey * @param[in] hitsetkey * @param[out] sector id */ -uint8_t getSectorId(TrkrDefs::hitsetkey key); + uint8_t getSectorId(TrkrDefs::hitsetkey key); -/** + /** * @brief Get the sector id from cluskey * @param[in] cluskey * @param[out] sector id */ -uint8_t getSectorId(TrkrDefs::cluskey key); + uint8_t getSectorId(TrkrDefs::cluskey key); -/** + /** * @brief Get the side from hitsetkey * @param[in] hitsetkey * @param[out] side */ -uint8_t getSide(TrkrDefs::hitsetkey key); + uint8_t getSide(TrkrDefs::hitsetkey key); -/** + /** * @brief Get the side id from cluskey * @param[in] cluskey * @param[out] side id */ -uint8_t getSide(TrkrDefs::cluskey key); + uint8_t getSide(TrkrDefs::cluskey key); -/** + /** * @brief Get the pad index from hitkey * @param[in] hitkey * @param[out] pad index */ -uint16_t getPad(TrkrDefs::hitkey key); + uint16_t getPad(TrkrDefs::hitkey key); -/** + /** * @brief Get the time bin from hitkey * @param[in] hitkey * @param[out] time bin */ -uint16_t getTBin(TrkrDefs::hitkey key); + uint16_t getTBin(TrkrDefs::hitkey key); -/** + /** * @brief Generate a hitkey from a pad index and time bin * @param[in] pad Pad index * @param[in] tbin Time bin * @param[out] hitkey */ -TrkrDefs::hitkey genHitKey(const uint16_t pad, const uint16_t tbin); + TrkrDefs::hitkey genHitKey(const uint16_t pad, const uint16_t tbin); -/** + /** * @brief Generate a hitsetkey for the tpc * @param[in] lyr Layer index * @param[in] sector Sector index @@ -98,18 +110,18 @@ TrkrDefs::hitkey genHitKey(const uint16_t pad, const uint16_t tbin); * Generate a hitsetkey for the tpc. The tracker id is known * implicitly and used in the function. */ -TrkrDefs::hitsetkey genHitSetKey(const uint8_t lyr, const uint8_t sector, const uint8_t side); + TrkrDefs::hitsetkey genHitSetKey(const uint8_t lyr, const uint8_t sector, const uint8_t side); -/** - * @brief Generate a cluster key from indeces + /** + * @brief Generate a cluster key from indeces * @param[in] lyr Layer index * @param[in] sector Sector index * @param[in] side Side index * @param[in] clusid Cluster id * @param[out] cluskey */ -TrkrDefs::cluskey genClusKey(const uint8_t lyr, const uint8_t sector, const uint8_t side, const uint32_t clusid); + TrkrDefs::cluskey genClusKey(const uint8_t lyr, const uint8_t sector, const uint8_t side, const uint32_t clusid); } // namespace TpcDefs -#endif //TPC_TPCDEFS_H +#endif // TPC_TPCDEFS_H diff --git a/offline/packages/trackbase/TrackFitUtils.cc b/offline/packages/trackbase/TrackFitUtils.cc index 55128a89f9..7bf68d8df8 100644 --- a/offline/packages/trackbase/TrackFitUtils.cc +++ b/offline/packages/trackbase/TrackFitUtils.cc @@ -1,6 +1,5 @@ #include "TrackFitUtils.h" -#include #include "ActsGeometry.h" #include "TrkrDefs.h" // for cluskey, getTrkrId, tpcId #include "TpcDefs.h" @@ -370,6 +369,14 @@ Acts::Vector3 TrackFitUtils::getPCALinePoint(Acts::Vector3 global, Acts::Vector3 // The position of the closest point on the line to global is: // posref + projection of difference between the point and posref on the tangent vector Acts::Vector3 pca = posref + ( (global - posref).dot(tangent) ) * tangent; + /* + if( (pca-posref).norm() > 0.001) + { + std::cout << " getPCALinePoint: old pca " << posref(0) << " " << posref(1) << " " << posref(2) << std::endl; + std::cout << " getPCALinePoint: new pca " << pca(0) << " " << pca(1) << " " << pca(2) << std::endl; + std::cout << " getPCALinePoint: delta pca " << pca(0) - posref(0) << " " << pca(1)-posref(1) << " " << pca(2) -posref(2) << std::endl; + } + */ return pca; } diff --git a/offline/packages/trackbase/TrkrCluster.h b/offline/packages/trackbase/TrkrCluster.h index d3bf6aef46..46edfc90ce 100644 --- a/offline/packages/trackbase/TrkrCluster.h +++ b/offline/packages/trackbase/TrkrCluster.h @@ -62,9 +62,16 @@ class TrkrCluster : public PHObject // virtual void setAdc(unsigned int) {} virtual unsigned int getAdc() const { return UINT_MAX; } - + virtual void setMaxAdc(uint16_t) {} + virtual unsigned int getMaxAdc() const {return UINT_MAX; } + virtual char getOverlap() const { return std::numeric_limits::max(); } + virtual void setOverlap(char) {} + virtual char getEdge() const { return std::numeric_limits::max(); } + virtual void setEdge(char) {} virtual void setTime(const float) {} virtual float getTime() const { return NAN;} + virtual char getSize() const {return std::numeric_limits::max(); } + // // convenience interface diff --git a/offline/packages/trackbase/TrkrClusterv4.cc b/offline/packages/trackbase/TrkrClusterv4.cc index 7d390f4520..c76a4cce1c 100644 --- a/offline/packages/trackbase/TrkrClusterv4.cc +++ b/offline/packages/trackbase/TrkrClusterv4.cc @@ -69,5 +69,9 @@ void TrkrClusterv4::CopyFrom( const TrkrCluster& source ) setSubSurfKey( source.getSubSurfKey() ); setAdc( source.getAdc() ); + setPhiSize(source.getPhiSize()); + setZSize(source.getZSize()); + setOverlap(source.getOverlap()); + setEdge(source.getEdge()); } diff --git a/offline/packages/trackbase/TrkrClusterv4.h b/offline/packages/trackbase/TrkrClusterv4.h index 19f89a8041..870e0f74aa 100644 --- a/offline/packages/trackbase/TrkrClusterv4.h +++ b/offline/packages/trackbase/TrkrClusterv4.h @@ -77,14 +77,14 @@ class TrkrClusterv4 : public TrkrCluster m_adc |= tmp; } - unsigned int getMaxAdc() const { + unsigned int getMaxAdc() const override { uint8_t tmp = (m_adc >> 8); unsigned int out = 0; out |= tmp; return out; } - void setMaxAdc(uint16_t maxadc) { + void setMaxAdc(uint16_t maxadc) override { if(maxadc>0xff)maxadc=0xff; uint16_t tmp = (maxadc << 8); m_adc |= tmp; @@ -120,7 +120,7 @@ class TrkrClusterv4 : public TrkrCluster void setError(unsigned int, unsigned int, float) override { std::cout << "Deprecated seterr trkrcluster function!" << std::endl; } - char getSize() { return m_phisize * m_zsize; } + char getSize() const override { return m_phisize * m_zsize; } // void setSize(char size) { m_size = size; } float getPhiSize() const override { return (float) m_phisize; } @@ -129,11 +129,11 @@ class TrkrClusterv4 : public TrkrCluster float getZSize() const override { return (float) m_zsize; } void setZSize(char zsize) { m_zsize = zsize; } - char getOverlap() { return m_overlap; } - void setOverlap(char overlap) { m_overlap = overlap; } + char getOverlap() const override { return m_overlap; } + void setOverlap(char overlap) override { m_overlap = overlap; } - char getEdge() { return m_edge; } - void setEdge(char edge) { m_edge = edge; } + char getEdge() const override { return m_edge; } + void setEdge(char edge) override { m_edge = edge; } //float getPhiSize() const override //{ std::cout << "Deprecated size function"<< std::endl; return NAN;} diff --git a/offline/packages/trackbase/TrkrClusterv5.cc b/offline/packages/trackbase/TrkrClusterv5.cc index da851f9d29..0a4371b9bd 100644 --- a/offline/packages/trackbase/TrkrClusterv5.cc +++ b/offline/packages/trackbase/TrkrClusterv5.cc @@ -69,25 +69,15 @@ void TrkrClusterv5::CopyFrom( const TrkrCluster& source ) setLocalX( source.getLocalX() ); setLocalY( source.getLocalY() ); - setSubSurfKey( source.getSubSurfKey() ); setAdc( source.getAdc() ); + setMaxAdc( source.getMaxAdc()); + setPhiError(source.getPhiError()); + setZError(source.getZError()); + setPhiSize(source.getPhiSize()); + setZSize(source.getZSize()); + setOverlap(source.getOverlap()); + setEdge(source.getEdge()); } -void TrkrClusterv5::CopyFrom( TrkrClusterv5* source ) -{ - - setLocalX( source->getLocalX() ); - setLocalY( source->getLocalY() ); - setSubSurfKey( source->getSubSurfKey() ); - setAdc( source->getAdc() ); - setMaxAdc( source->getMaxAdc() ); - setPhiError( source->getPhiError() ); - setZError( source->getZError() ); - setPhiSize( source->getPhiSize() ); - setZSize( source->getZSize() ); - setOverlap( source->getOverlap() ); - setEdge( source->getEdge() ); - -} diff --git a/offline/packages/trackbase/TrkrClusterv5.h b/offline/packages/trackbase/TrkrClusterv5.h index 196015be33..faf27caf94 100644 --- a/offline/packages/trackbase/TrkrClusterv5.h +++ b/offline/packages/trackbase/TrkrClusterv5.h @@ -46,9 +46,6 @@ class TrkrClusterv5 : public TrkrCluster void CopyFrom( TrkrCluster* source ) override { CopyFrom( *source ); } - //! copy content - void CopyFrom( TrkrClusterv5* source ); - // // cluster position // @@ -66,20 +63,18 @@ class TrkrClusterv5 : public TrkrCluster // cluster info // unsigned int getAdc() const override { - uint8_t tmp = m_adc; - return tmp ; - + return m_adc ; } void setAdc(unsigned int adc) override { m_adc = adc; } - unsigned int getMaxAdc() const { + unsigned int getMaxAdc() const override { return m_maxadc; } - void setMaxAdc(uint16_t maxadc) { + void setMaxAdc(uint16_t maxadc) override { m_maxadc = maxadc; } @@ -118,7 +113,7 @@ class TrkrClusterv5 : public TrkrCluster void setError(unsigned int, unsigned int, float) override { std::cout << "Deprecated seterr trkrcluster function!" << std::endl; } - char getSize() { return m_phisize * m_zsize; } + char getSize() const override { return m_phisize * m_zsize; } // void setSize(char size) { m_size = size; } float getPhiSize() const override { return (float) m_phisize; } @@ -127,11 +122,11 @@ class TrkrClusterv5 : public TrkrCluster float getZSize() const override { return (float) m_zsize; } void setZSize(char zsize) { m_zsize = zsize; } - char getOverlap() { return m_overlap; } - void setOverlap(char overlap) { m_overlap = overlap; } + char getOverlap() const override { return m_overlap; } + void setOverlap(char overlap) override { m_overlap = overlap; } - char getEdge() { return m_edge; } - void setEdge(char edge) { m_edge = edge; } + char getEdge() const override{ return m_edge; } + void setEdge(char edge) override { m_edge = edge; } //float getPhiSize() const override //{ std::cout << "Deprecated size function"<< std::endl; return NAN;} diff --git a/offline/packages/trackbase/TrkrDefs.h b/offline/packages/trackbase/TrkrDefs.h index bc072e5209..9e322174d0 100644 --- a/offline/packages/trackbase/TrkrDefs.h +++ b/offline/packages/trackbase/TrkrDefs.h @@ -4,11 +4,13 @@ * @date June 2018 * @brief Namespace with Trkr key types and utility functions */ -#ifndef TRACKBASE_TRKRDEFUTIL_H -#define TRACKBASE_TRKRDEFUTIL_H +#ifndef TRACKBASE_TRKRDEFS_H +#define TRACKBASE_TRKRDEFS_H #include #include +#include +#include /** * @brief Define a namespace for Trkr typedefs @@ -56,6 +58,15 @@ namespace TrkrDefs ttl = 4, }; + //! Standard names for trackers + static const std::map TrkrNames = + { + {mvtxId, "MVTX"}, + {inttId, "INTT"}, + {tpcId, "TPC"}, + {micromegasId, "MICROMEGAS"}, + {ttl, "TTL"} + }; /// Print the bits for each key type void printBits(const TrkrDefs::hitsetkey key, std::ostream& os = std::cout); @@ -104,4 +115,4 @@ namespace TrkrDefs } -#endif //TRACKBASE_TRKRDEFUTIL_H +#endif //TRACKBASE_TRKRDEFS_H diff --git a/offline/packages/trackbase/TrkrHitSetContainer.cc b/offline/packages/trackbase/TrkrHitSetContainer.cc index 8198db015f..fe727fd73c 100644 --- a/offline/packages/trackbase/TrkrHitSetContainer.cc +++ b/offline/packages/trackbase/TrkrHitSetContainer.cc @@ -30,7 +30,7 @@ TrkrHitSetContainer::addHitSet(TrkrHitSet* /*newhit*/) TrkrHitSetContainer::ConstIterator TrkrHitSetContainer::addHitSetSpecifyKey(const TrkrDefs::hitsetkey /*key*/, TrkrHitSet* /*newhit*/) { return dummy_map.cbegin(); } - + TrkrHitSetContainer::Iterator TrkrHitSetContainer::findOrAddHitSet(TrkrDefs::hitsetkey /*key*/) { return dummy_map.begin(); } diff --git a/offline/packages/trackbase/TrkrHitSetContainerv2.cc b/offline/packages/trackbase/TrkrHitSetContainerv2.cc new file mode 100644 index 0000000000..92d788f5dd --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetContainerv2.cc @@ -0,0 +1,186 @@ +/** + * @file trackbase/TrkrHitSetContainerv2.cc + * @author D. McGlinchey, H. PEREIRA DA COSTA + * @date June 2018 + * @brief Implementation for TrkrHitSetContainerv2 + */ +#include "TrkrHitSetContainerv2.h" + +#include "TrkrDefs.h" +#include "TrkrHitSetv1.h" + +#include + +#include +#include + +TrkrHitSetContainerv2:: + TrkrHitSetContainerv2(const std::string& hitsetclass, const size_t estimated_size) + : m_hitArray(hitsetclass.c_str(), estimated_size) +{ +} + +void TrkrHitSetContainerv2::Reset() +{ + // force rebuild of indexing map + m_hitmap.clear(); + + //! fast clear without calling destructor and without marking hitsets removed. + //! This is inspired by but even faster than TClonesArray::Clear() + //! We just reset hitset values and reuse the hitset objects + Int_t n = m_hitArray.GetEntriesFast(); + for (Int_t i = 0; i < n; i++) { + TObject *obj = m_hitArray.UncheckedAt(i); + if (obj) { + obj->Clear(); + obj->ResetBit( kHasUUID ); + obj->ResetBit( kIsReferenced ); + obj->SetUniqueID( 0 ); + } + } + + // alternative is to also marking hitset removed, which is not used here but optional for a v3 container + // m_hitArray.Clear("C"); +} + +void TrkrHitSetContainerv2::identify(std::ostream& os) const +{ + syncMapArray(); + + os << "TrkrHitSetContainerv2 with class " + << m_hitArray.GetClass()->GetName() + << ": Number of hits: " << size() << " index map size = " << m_hitmap.size() << std::endl; + ConstIterator iter; + for (const auto& pair : m_hitmap) + { + int layer = TrkrDefs::getLayer(pair.first); + os << "hitsetkey " << pair.first << " layer " << layer << std::endl; + pair.second->identify(); + } + return; +} + +TrkrHitSetContainerv2::ConstIterator +TrkrHitSetContainerv2::addHitSet(TrkrHitSet* newhit) +{ + std::cout << __PRETTY_FUNCTION__ + << " : deprecated. Use findOrAddHitSet()." << std::endl; + return addHitSetSpecifyKey(newhit->getHitSetKey(), newhit); +} + +TrkrHitSetContainerv2::ConstIterator +TrkrHitSetContainerv2::addHitSetSpecifyKey(const TrkrDefs::hitsetkey key, TrkrHitSet* newhit) +{ + std::cout << __PRETTY_FUNCTION__ + << " : deprecated. Use findOrAddHitSet()." << std::endl; + + exit(1); + + return TrkrHitSetContainer::addHitSetSpecifyKey(key, newhit); +} + +void TrkrHitSetContainerv2::removeHitSet(TrkrDefs::hitsetkey ) +{ + std::cout << __PRETTY_FUNCTION__ + << " : deprecated. This function still works but slows down operation." << std::endl; + + exit(1); +} + +void TrkrHitSetContainerv2::removeHitSet(TrkrHitSet* hitset) +{ + removeHitSet(hitset->getHitSetKey()); +} + +TrkrHitSetContainerv2::ConstRange +TrkrHitSetContainerv2::getHitSets(const TrkrDefs::TrkrId trackerid) const +{ + syncMapArray(); + const TrkrDefs::hitsetkey keylo = TrkrDefs::getHitSetKeyLo(trackerid); + const TrkrDefs::hitsetkey keyhi = TrkrDefs::getHitSetKeyHi(trackerid); + return std::make_pair(m_hitmap.lower_bound(keylo), m_hitmap.upper_bound(keyhi)); +} + +TrkrHitSetContainerv2::ConstRange +TrkrHitSetContainerv2::getHitSets(const TrkrDefs::TrkrId trackerid, const uint8_t layer) const +{ + syncMapArray(); + TrkrDefs::hitsetkey keylo = TrkrDefs::getHitSetKeyLo(trackerid, layer); + TrkrDefs::hitsetkey keyhi = TrkrDefs::getHitSetKeyHi(trackerid, layer); + return std::make_pair(m_hitmap.lower_bound(keylo), m_hitmap.upper_bound(keyhi)); +} + +TrkrHitSetContainerv2::ConstRange +TrkrHitSetContainerv2::getHitSets() const +{ + syncMapArray(); + return std::make_pair(m_hitmap.cbegin(), m_hitmap.cend()); +} + +TrkrHitSetContainerv2::Iterator +TrkrHitSetContainerv2::findOrAddHitSet(TrkrDefs::hitsetkey key) +{ + syncMapArray(); + auto it = m_hitmap.lower_bound(key); + if (it == m_hitmap.end() || (key < it->first)) + { + TrkrHitSet* hitset = (TrkrHitSet*) m_hitArray.ConstructedAt(m_hitArray.GetLast() + 1); + assert(hitset); + hitset -> setHitSetKey(key); + it = m_hitmap.insert(it, std::make_pair(key, hitset)); + } + return it; +} + +TrkrHitSet* +TrkrHitSetContainerv2::findHitSet(TrkrDefs::hitsetkey key) +{ + syncMapArray(); + auto it = m_hitmap.find(key); + if (it != m_hitmap.end()) + { + return it->second; + } + else + { + return nullptr; + } +} + +void TrkrHitSetContainerv2::syncMapArray(void) const +{ + if (m_hitmap.size() == (size_t) size()) return; + + if (m_hitmap.size() > 0) + { + std::cout + << __PRETTY_FUNCTION__ << " Error: m_hitmap and m_hitArray get out of sync, which should not happen unless DST readback. " + << " size() = " << size() + << " m_hitmap.size( ) = " << m_hitmap.size() + << " m_hitArray.GetSize() = " << m_hitArray.GetSize() + << " m_hitArray.GetLast() = " << m_hitArray.GetLast() + << " m_hitArray.GetEntries() = " << m_hitArray.GetEntries() + << std::endl; + + assert(m_hitmap.size() == 0); + } + + for (unsigned int i = 0; i < size(); ++i) + { + TrkrHitSet* hitset = dynamic_cast(m_hitArray[i]); + + if (hitset == nullptr) + { + std::cout << __PRETTY_FUNCTION__ << " : fatal error, invalid hitset in m_hitArray at position " << i << ". " + << " size() = " << size() + << " m_hitmap.size( ) = " << m_hitmap.size() + << " m_hitArray.GetSize() = " << m_hitArray.GetSize() + << " m_hitArray.GetLast() = " << m_hitArray.GetLast() + << " m_hitArray.GetEntries() = " << m_hitArray.GetEntries() + << std::endl; + assert(hitset); + } + else + m_hitmap[hitset->getHitSetKey()] = hitset; + } +} diff --git a/offline/packages/trackbase/TrkrHitSetContainerv2.h b/offline/packages/trackbase/TrkrHitSetContainerv2.h new file mode 100644 index 0000000000..e2f31594a4 --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetContainerv2.h @@ -0,0 +1,73 @@ +#ifndef TRACKBASE_TrkrHitSetContainerv2_H +#define TRACKBASE_TrkrHitSetContainerv2_H + +#include "TrkrDefs.h" +#include "TrkrHitSetContainer.h" + +#include +#include // for cout, ostream +#include +#include // for pair +#include // for pair + +class TrkrHitSet; + +/** + * IO and memory efficient container using TClonesArray + * TrkrHitSet used in this container must impliment TrkrHitSet::Clear() function for fast reset without calling ~TrkrHitSet() + */ +class TrkrHitSetContainerv2 final : public TrkrHitSetContainer +{ +public: + //! only used in ROOT IO. Do NOT use this constructor in user code + TrkrHitSetContainerv2() = default; + + TrkrHitSetContainerv2(const std::string& hitsetclass, const size_t estimated_size); + + ~TrkrHitSetContainerv2() override + { + } + + void Reset() override; + + void identify(std::ostream& = std::cout) const override; + + ConstIterator addHitSet(TrkrHitSet*) override; + + ConstIterator addHitSetSpecifyKey(const TrkrDefs::hitsetkey, TrkrHitSet*) override; + + //! Add a TrkrHitSet to TrkrHitSetContainerv2, return the iterater to the newly constructed TrkrHitSet + ConstIterator addHitSetSpecifyKey(const TrkrDefs::hitsetkey key); + + void removeHitSet(TrkrDefs::hitsetkey) override; + + void removeHitSet(TrkrHitSet*) override; + + Iterator findOrAddHitSet(TrkrDefs::hitsetkey key) override; + + ConstRange getHitSets(const TrkrDefs::TrkrId trackerid) const override; + + ConstRange getHitSets(const TrkrDefs::TrkrId trackerid, const uint8_t layer) const override; + + ConstRange getHitSets() const override; + + TrkrHitSet* findHitSet(TrkrDefs::hitsetkey key) override; + + unsigned int size() const override + { + return m_hitArray.GetEntriesFast(); + } + + private: + //! endure m_hitmap and m_hitArray are in sync, in particular m_hitmap need rebuild after reading back from the DST + void syncMapArray(void) const; + + //! used for indexing only, not used in storage. syncMapArray(void) rebuilds the map after DST readback + mutable Map m_hitmap; //! + + TClonesArray m_hitArray; + + ClassDefOverride(TrkrHitSetContainerv2, 1) +}; + +#endif // TRACKBASE_TrkrHitSetContainerv2_H diff --git a/offline/packages/trackbase/TrkrHitSetContainerv2LinkDef.h b/offline/packages/trackbase/TrkrHitSetContainerv2LinkDef.h new file mode 100644 index 0000000000..19ca55e5ca --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetContainerv2LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class TrkrHitSetContainerv2+; + +#endif /* __CINT__ */ diff --git a/offline/packages/trackbase/TrkrHitSetTpc.cc b/offline/packages/trackbase/TrkrHitSetTpc.cc new file mode 100644 index 0000000000..c9baf7116b --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetTpc.cc @@ -0,0 +1,114 @@ +/** + * @file trackbase/TrkrHitSetTpc.cc + * @author D. McGlinchey + * @date June 2018 + * @brief Implementation of TrkrHitSetTpc + */ +#include "TrkrHitSetTpc.h" +#include "TrkrHit.h" + +#include +#include +#include // for exit +#include +#include // for __decay_and_strip<>::__type + +void TrkrHitSetTpc::identify(std::ostream& os) const +{ + os + << "TrkrHitSetTpc: " + << " hitsetkey " << getHitSetKey() + << std::endl; +} + +TpcDefs::ADCDataType& TrkrHitSetTpc::getTpcADC(TrkrDefs::hitkey key) +{ + std::pair local_phi_t = getLocalPhiTBin(key); + + return getTpcADC(local_phi_t.first, local_phi_t.second); +} + +const TpcDefs::ADCDataType& TrkrHitSetTpc::getTpcADC(TrkrDefs::hitkey key) const +{ + std::pair local_phi_t = getLocalPhiTBin(key); + + return getTpcADC(local_phi_t.first, local_phi_t.second); +} + +std::pair TrkrHitSetTpc::getLocalPhiTBin(TrkrDefs::hitkey key) const +{ + const uint16_t pad = TpcDefs ::getPad(key); + const uint16_t tbin = TpcDefs ::getTBin(key); + const uint16_t side = TpcDefs::getSide(getHitSetKey()); + + uint16_t local_pad = 0; + uint16_t local_tbin = 0; + + if (side == 0) + { + local_pad = pad - getPadIndexStart(); + local_tbin = tbin - getTBinIndexStart(); + } + else + { + local_pad = getNPads() - 1 - pad + getPadIndexStart(); + local_tbin = -tbin + getTBinIndexStart(); + } + + if (local_pad >= getNPads()) + { + std::cout << __PRETTY_FUNCTION__ << " fatal error local_pad >= getNPads()" + << " getHitSetKey() = " << getHitSetKey() + << " pad = " << pad + << " tbin = " << tbin + << " side = " << side + << " local_pad = " << local_pad + << " local_tbin = " << local_tbin + << " getPadIndexStart() = " << getPadIndexStart() + << " getTBinIndexStart() = " << getTBinIndexStart() + << std::endl; + identify(); + } + assert(local_pad < getNPads()); + + if (local_tbin >= getNTBins()) + { + std::cout << __PRETTY_FUNCTION__ << " fatal error local_tbin >= getNTBins()" + << " getHitSetKey() = " << getHitSetKey() + << " pad = " << pad + << " tbin = " << tbin + << " side = " << side + << " local_pad = " << local_pad + << " local_tbin = " << local_tbin + << " getPadIndexStart() = " << getPadIndexStart() + << " getTBinIndexStart() = " << getTBinIndexStart() + << std::endl; + identify(); + } + assert(local_tbin < getNTBins()); + + return std::make_pair(local_pad, local_tbin); +} + +TrkrDefs::hitkey TrkrHitSetTpc::getHitKeyfromLocalBin( + const uint16_t local_pad, + const uint16_t local_tbin) + const +{ + const uint8_t side = TpcDefs::getSide(getHitSetKey()); + + if (side == 0) + { + const uint16_t pad = local_pad + getPadIndexStart(); + const uint16_t tbin = local_tbin + getTBinIndexStart(); + + return TpcDefs::genHitKey(pad, tbin); + } + else + { + const uint16_t pad = getNPads() - 1 - local_pad + getPadIndexStart(); + const uint16_t tbin = -local_tbin + getTBinIndexStart(); + + return TpcDefs::genHitKey(pad, tbin); + } +} diff --git a/offline/packages/trackbase/TrkrHitSetTpc.h b/offline/packages/trackbase/TrkrHitSetTpc.h new file mode 100644 index 0000000000..06bb388185 --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetTpc.h @@ -0,0 +1,121 @@ +#ifndef TRACKBASE_TrkrHitSetTpc_H +#define TRACKBASE_TrkrHitSetTpc_H + +#include "TpcDefs.h" +#include "TrkrDefs.h" +#include "TrkrHitSet.h" + +#include // for pair +#include + +// forward declaration +class TrkrHit; + +//! Generalized interface class for vectorized TPC data time frame storage +class TrkrHitSetTpc : public TrkrHitSet +{ + public: + typedef std::vector > TimeFrameADCDataType; + + TrkrHitSetTpc() = default; + + TrkrHitSetTpc(const uint16_t /*n_pad*/, const uint16_t /*n_tbin*/) {} + + ~TrkrHitSetTpc() override + { + } + + virtual void identify(std::ostream& os = std::cout) const override; + + //! resize to fit getNPads and getNTBins + virtual void Resize() {} + + //! global -> local conversion + std::pair getLocalPhiTBin(const TrkrDefs::hitkey) const; + + //! local -> global conversion + TrkrDefs::hitkey getHitKeyfromLocalBin(const uint16_t /*local_pad*/, const uint16_t /*local_tbin*/) const; + + TpcDefs::ADCDataType& getTpcADC(const TrkrDefs::hitkey); + + const TpcDefs::ADCDataType& getTpcADC(const TrkrDefs::hitkey) const; + + virtual TpcDefs::ADCDataType& getTpcADC(const uint16_t /*local_pad*/, const uint16_t /*local_tbin*/) + { + static TpcDefs::ADCDataType v = 0; + return v; + }; + + virtual const TpcDefs::ADCDataType& getTpcADC(const uint16_t /*local_pad*/, const uint16_t /*local_tbin*/) const + { + static TpcDefs::ADCDataType v = 0; + return v; + }; + + virtual uint16_t getNPads() const + { + return 0; + } + + virtual void setNPads(uint16_t /*nPads*/) + { + } + + virtual const TimeFrameADCDataType& getTimeFrameAdcData() const + { + static TimeFrameADCDataType tmp; + + return tmp; + } + virtual TimeFrameADCDataType& getTimeFrameAdcData() + { + static TimeFrameADCDataType tmp; + + return tmp; + } + + virtual void setTimeFrameAdcData(const TimeFrameADCDataType&) + { + } + + virtual uint16_t getNTBins() const + { + return 0; + } + + virtual void setNTBins(uint16_t /*tBins*/) + { + } + + virtual uint16_t getPadIndexStart() const + { + return 0; + } + + virtual void setPadIndexStart(uint16_t ) + { + } + + virtual TpcDefs::BCODataType getStartingBco() const + { + return 0; + } + + virtual void setStartingBco(TpcDefs::BCODataType ) + { + } + + virtual uint16_t getTBinIndexStart() const + { + return 0; + } + + virtual void setTBinIndexStart(uint16_t) + { + } + + private: + ClassDefOverride(TrkrHitSetTpc, 1); +}; + +#endif // TRACKBASE_TrkrHitSetTpc_H diff --git a/offline/packages/trackbase/TrkrHitSetTpcLinkDef.h b/offline/packages/trackbase/TrkrHitSetTpcLinkDef.h new file mode 100644 index 0000000000..2a997986ab --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetTpcLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class TrkrHitSetTpc+; + +#endif diff --git a/offline/packages/trackbase/TrkrHitSetTpcv1.cc b/offline/packages/trackbase/TrkrHitSetTpcv1.cc new file mode 100644 index 0000000000..e4faa7a50f --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetTpcv1.cc @@ -0,0 +1,154 @@ +/** + * @file trackbase/TrkrHitSetTpcv1.cc + * @author D. McGlinchey + * @date June 2018 + * @brief Implementation of TrkrHitSetTpcv1 + */ +#include "TrkrHitSetTpcv1.h" +#include "TrkrHit.h" + +#include +#include +#include // for exit +#include +#include // for __decay_and_strip<>::__type + +void TrkrHitSetTpcv1::Reset() +{ + // not resetting properties as the hitset are used in the next events + // m_hitSetKey = TrkrDefs::HITSETKEYMAX; + // m_StartingBCO = 0; + // m_padIndexStart = 0; + // m_tBinIndexStart = 0; + + // ADC 2D array is zeroed but intentionally NOT deleted, + // which potentially save memory allocation-deallocation ops in the next event + for (auto& pad : m_timeFrameADCData) + { + std::fill(pad.begin(), pad.end(), 0); + } +} +void TrkrHitSetTpcv1::Resize() +{ + const uint16_t n_pad = getNPads(); + const uint16_t n_tbin = getNTBins(); + + if (n_pad != m_timeFrameADCData.size()) + m_timeFrameADCData.resize(n_pad); + + for (auto& pad : m_timeFrameADCData) + { + if (n_tbin != pad.size()) + { + pad.reserve(n_tbin); + pad.resize(n_tbin, 0); + } + } +} + +void TrkrHitSetTpcv1::identify(std::ostream& os) const +{ + const uint16_t layer = TrkrDefs::getLayer(m_hitSetKey); + const uint16_t trkrid = TrkrDefs::getTrkrId(m_hitSetKey); + + os + << "TrkrHitSetTpcv1: " + << " hitsetkey " << getHitSetKey() + << " TrkrId: " << trkrid + << " layer: " << layer + << " m_nPads: " << m_nPads + << " n_tBins: " << m_nTBins + << " m_padIndexStart: " << m_padIndexStart + << " m_tBinIndexStart: " << m_tBinIndexStart + << " m_StartingBCO: " << m_StartingBCO + << std::endl; + + // for( const auto& entry : m_hits ) + // { + // std::cout << " hitkey " << entry.first << std::endl; + // (entry.second)->identify(os); + // } + + for (uint16_t i = 0; i < m_nPads; ++i) + { + if (m_timeFrameADCData[i].size() == 0) + { + os << "Pad " << i << " ADC vector is zero-sized" << std::endl; + continue; + } + + // skip empty pads + if (*std::max_element(m_timeFrameADCData[i].begin(), m_timeFrameADCData[i].end()) == 0) continue; + + os << "Pad " << i << ":"; + + int j = 0; + for (const auto& adc : m_timeFrameADCData[i]) + { + if (adc) + { + os << "\t[" << j << "]:" << adc; + } + ++j; + } + os << std::endl; + } +} + +TpcDefs::ADCDataType& TrkrHitSetTpcv1::getTpcADC(const uint16_t pad, const uint16_t tbin) +{ + assert(pad < m_nPads); + assert(tbin < m_nTBins); + assert(m_timeFrameADCData.size() == m_nPads); + assert(m_timeFrameADCData[pad].size() == m_nTBins); + + return m_timeFrameADCData[pad][tbin]; +} + +const TpcDefs::ADCDataType& TrkrHitSetTpcv1::getTpcADC(const uint16_t pad, const uint16_t tbin) const +{ + assert(pad < m_nPads); + assert(tbin < m_nTBins); + assert(m_timeFrameADCData.size() == m_nPads); + assert(m_timeFrameADCData[pad].size() == m_nTBins); + + return m_timeFrameADCData[pad][tbin]; +} + +void TrkrHitSetTpcv1::removeHit(TrkrDefs::hitkey key) +{ + getTpcADC(key) = 0; +} + +TrkrHitSetTpcv1::ConstIterator +TrkrHitSetTpcv1::addHitSpecificKey(const TrkrDefs::hitkey key, TrkrHit* hit) +{ + std::cout << __PRETTY_FUNCTION__ + << " : This function is deprecated! Please use getTpcADC(TrkrDefs::hitkey key)" << std::endl; + + exit(1); + + return TrkrHitSetTpc::addHitSpecificKey(key, hit); +} + +TrkrHit* +TrkrHitSetTpcv1::getHit(const TrkrDefs::hitkey key) const +{ + std::cout << __PRETTY_FUNCTION__ + << " : This function is deprecated! Please use getTpcADC(TrkrDefs::hitkey key)" << std::endl; + + exit(1); + + return TrkrHitSetTpc::getHit(key); +} + +TrkrHitSetTpcv1::ConstRange +TrkrHitSetTpcv1::getHits() const +{ + std::cout << __PRETTY_FUNCTION__ + << " : This function is deprecated! Please use getTpcADC(TrkrDefs::hitkey key)" << std::endl; + + exit(1); + + return TrkrHitSetTpc::getHits(); +} diff --git a/offline/packages/trackbase/TrkrHitSetTpcv1.h b/offline/packages/trackbase/TrkrHitSetTpcv1.h new file mode 100644 index 0000000000..025230f4e4 --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetTpcv1.h @@ -0,0 +1,157 @@ +#ifndef TRACKBASE_TrkrHitSetTpcv1_H +#define TRACKBASE_TrkrHitSetTpcv1_H + +#include "TrkrHitSetTpc.h" + +#include // for pair +#include + +// forward declaration +class TrkrHit; + +//! Vectorized TPC data time frame storage +class TrkrHitSetTpcv1 final : public TrkrHitSetTpc +{ + public: + TrkrHitSetTpcv1() = default; + + TrkrHitSetTpcv1(const uint16_t n_pad, const uint16_t n_tbin) + : TrkrHitSetTpc(n_pad, n_tbin), m_nPads(n_pad), m_nTBins(n_tbin) + { + Resize(); + } + + ~TrkrHitSetTpcv1() override + { + } + + void identify(std::ostream& os = std::cout) const override; + + void Resize() override; + + //! For ROOT TClonesArray end of event Operation + void Clear(Option_t* /*option*/ = "") override { Reset(); } + + void Reset() override; + + void setHitSetKey(const TrkrDefs::hitsetkey key) override + { + m_hitSetKey = key; + } + + TrkrDefs::hitsetkey getHitSetKey() const override + { + return m_hitSetKey; + } + + // legacy TrkrDefs::hitkey accesses + using TrkrHitSetTpc::getTpcADC; + + TpcDefs::ADCDataType& getTpcADC(const uint16_t local_pad, const uint16_t local_tbin) override; + + const TpcDefs::ADCDataType& getTpcADC(const uint16_t local_pad, const uint16_t local_tbin) const override; + + ConstIterator addHitSpecificKey(const TrkrDefs::hitkey, TrkrHit*) override; + + void removeHit(TrkrDefs::hitkey) override; + + TrkrHit* getHit(const TrkrDefs::hitkey) const override; + + ConstRange getHits() const override; + + unsigned int size() const override + { + return m_nPads * m_nTBins; + } + + uint16_t getNPads() const override + { + return m_nPads; + } + + void setNPads(uint16_t nPads = 0) override + { + m_nPads = nPads; + Resize(); + } + + uint16_t getNTBins() const override + { + return m_nTBins; + } + + void setNTBins(uint16_t tBins = 0) override + { + m_nTBins = tBins; + Resize(); + } + + uint16_t getPadIndexStart() const override + { + return m_padIndexStart; + } + + void setPadIndexStart(uint16_t padIndexStart) override + { + m_padIndexStart = padIndexStart; + } + + TpcDefs::BCODataType getStartingBco() const override + { + return m_StartingBCO; + } + + void setStartingBco(TpcDefs::BCODataType startingBco) override + { + m_StartingBCO = startingBco; + } + + uint16_t getTBinIndexStart() const override + { + return m_tBinIndexStart; + } + + void setTBinIndexStart(uint16_t tBinIndexStart) override + { + m_tBinIndexStart = tBinIndexStart; + } + + const TimeFrameADCDataType& getTimeFrameAdcData() const override + { + return m_timeFrameADCData; + } + + TimeFrameADCDataType& getTimeFrameAdcData() override + { + return m_timeFrameADCData; + } + + void setTimeFrameAdcData(const TimeFrameADCDataType& timeFrameAdcData) override + { + m_timeFrameADCData = timeFrameAdcData; + } + + private: + /// unique key for this object + TrkrDefs::hitsetkey m_hitSetKey = TrkrDefs::HITSETKEYMAX; + + /// vector storage of TPC timeframe without zero suppression + // Top level indexes are vectors of pads + // Lower level indexes are vectors of time bin + TimeFrameADCDataType m_timeFrameADCData; + + //! beam collision (BCO) clock counter at the start of the time frame + TpcDefs::BCODataType m_StartingBCO = 0; + + //! local to global index conversion + uint16_t m_padIndexStart = 0; + uint16_t m_tBinIndexStart = 0; + + //! size of the local index + uint16_t m_nPads = 0; + uint16_t m_nTBins = 0; + + ClassDefOverride(TrkrHitSetTpcv1, 1); +}; + +#endif // TRACKBASE_TrkrHitSetTpcv1_H diff --git a/offline/packages/trackbase/TrkrHitSetTpcv1LinkDef.h b/offline/packages/trackbase/TrkrHitSetTpcv1LinkDef.h new file mode 100644 index 0000000000..e6e64918c2 --- /dev/null +++ b/offline/packages/trackbase/TrkrHitSetTpcv1LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class TrkrHitSetTpcv1+; + +#endif diff --git a/offline/packages/trackbase/alignmentTransformationContainer.cc b/offline/packages/trackbase/alignmentTransformationContainer.cc index aef2683729..09e7aee510 100644 --- a/offline/packages/trackbase/alignmentTransformationContainer.cc +++ b/offline/packages/trackbase/alignmentTransformationContainer.cc @@ -17,20 +17,20 @@ bool alignmentTransformationContainer::use_alignment = false; alignmentTransformationContainer::alignmentTransformationContainer() { - for ( const auto id : { TrkrDefs::mvtxId, TrkrDefs::inttId, TrkrDefs::tpcId, TrkrDefs::micromegasId }) + for ( uint8_t layer = 0; layer < 57; layer++) { - m_misalignmentFactor.insert(std::make_pair(id, 1.)); + m_misalignmentFactor.insert(std::make_pair(layer, 1.)); } } -void alignmentTransformationContainer::setMisalignmentFactor(uint8_t id, double factor) +void alignmentTransformationContainer::setMisalignmentFactor(uint8_t layer, double factor) { - auto it = m_misalignmentFactor.find(id); + auto it = m_misalignmentFactor.find(layer); if(it != m_misalignmentFactor.end()) { it->second = factor; return; } - std::cout << "You provided a nonexistent TrkrDefs::TrkrId in alignmentTransformationContainer::setMisalignmentFactor..." + std::cout << "You provided a nonexistent layer in alignmentTransformationContainer::setMisalignmentFactor..." << std::endl; } void alignmentTransformationContainer::Reset() diff --git a/offline/packages/trackbase/alignmentTransformationContainer.h b/offline/packages/trackbase/alignmentTransformationContainer.h index c9dac5e171..e885aa4483 100644 --- a/offline/packages/trackbase/alignmentTransformationContainer.h +++ b/offline/packages/trackbase/alignmentTransformationContainer.h @@ -41,8 +41,8 @@ class alignmentTransformationContainer : public Acts::GeometryContext void addTransform(Acts::GeometryIdentifier, Acts::Transform3); Acts::Transform3& getTransform(Acts::GeometryIdentifier id); const std::vector>& getMap() const; - void setMisalignmentFactor(uint8_t id, double factor); - const double& getMisalignmentFactor(uint8_t id) const { return m_misalignmentFactor.find(id)->second; } + void setMisalignmentFactor(uint8_t layer, double factor); + const double& getMisalignmentFactor(uint8_t layer) const { return m_misalignmentFactor.find(layer)->second; } static bool use_alignment; private: @@ -53,7 +53,7 @@ class alignmentTransformationContainer : public Acts::GeometryContext std::vector< std::vector> transformVec; - /// Map of TrkrDefs::TrkrId to misalignment factor + /// Map of TrkrDefs::Layer to misalignment factor std::map m_misalignmentFactor; ClassDef(alignmentTransformationContainer,1); diff --git a/offline/packages/trackbase/configure.ac b/offline/packages/trackbase/configure.ac index 2efc6c8e16..19f8ea89d4 100644 --- a/offline/packages/trackbase/configure.ac +++ b/offline/packages/trackbase/configure.ac @@ -21,5 +21,15 @@ esac CINTDEFS=" -noIncludePaths -inlineInputHeader " AC_SUBST(CINTDEFS) +AC_ARG_ENABLE(online, + [ --enable-online build using for online [default=no]], + [case "${enableval}" in + yes) online=true ;; + no) online=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-online) ;; + esac], + online=false) +AM_CONDITIONAL(USE_ONLINE, test "x$online" = xtrue) + AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/offline/packages/trackbase_historic/Makefile.am b/offline/packages/trackbase_historic/Makefile.am index 186a621837..3086da04e8 100644 --- a/offline/packages/trackbase_historic/Makefile.am +++ b/offline/packages/trackbase_historic/Makefile.am @@ -54,7 +54,8 @@ pkginclude_HEADERS = \ SvtxVertex.h \ SvtxVertex_v1.h \ SvtxVertexMap.h \ - SvtxVertexMap_v1.h + SvtxVertexMap_v1.h \ + TrackAnalysisUtils.h ROOTDICTS = \ TrackSeed_Dict.cc \ @@ -165,7 +166,8 @@ libtrackbase_historic_io_la_SOURCES = \ SvtxVertex.cc \ SvtxVertex_v1.cc \ SvtxVertexMap.cc \ - SvtxVertexMap_v1.cc + SvtxVertexMap_v1.cc \ + TrackAnalysisUtils.cc libtrackbase_historic_io_la_LDFLAGS = \ -L$(libdir) \ diff --git a/offline/packages/trackbase_historic/SvtxAlignmentState.h b/offline/packages/trackbase_historic/SvtxAlignmentState.h index a3d82e261d..a1b207800c 100644 --- a/offline/packages/trackbase_historic/SvtxAlignmentState.h +++ b/offline/packages/trackbase_historic/SvtxAlignmentState.h @@ -16,7 +16,7 @@ class SvtxAlignmentState : public PHObject /// the definition in millepede (track state parameters) const static int NLOC = 6; /// Number of residual parameters - const static int NRES = 3; + const static int NRES = 2; typedef Eigen::Matrix GlobalMatrix; typedef Eigen::Matrix LocalMatrix; diff --git a/offline/packages/trackbase_historic/SvtxTrack.h b/offline/packages/trackbase_historic/SvtxTrack.h index 5c62e7bffa..e2779b25d8 100644 --- a/offline/packages/trackbase_historic/SvtxTrack.h +++ b/offline/packages/trackbase_historic/SvtxTrack.h @@ -35,7 +35,10 @@ class SvtxTrack : public PHObject PRES = 0, CEMC = 1, HCALIN = 2, - HCALOUT = 3 + HCALOUT = 3, + OUTER_CEMC = 4, + OUTER_HCALIN = 5, + OUTER_HCALOUT = 6 }; ~SvtxTrack() override = default; diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc new file mode 100644 index 0000000000..d67e5898fd --- /dev/null +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -0,0 +1,66 @@ +#include "TrackAnalysisUtils.h" +#include "SvtxTrack.h" +#include "SvtxVertex.h" + +TrackAnalysisUtils::DCAPair TrackAnalysisUtils::get_dca(SvtxTrack* track, + SvtxVertex* svtxVertex) +{ + TrackAnalysisUtils::DCAPair pair; + if (!track or !svtxVertex) + { + std::cout << "You passed a nullptr, can't calculate DCA" << std::endl; + return pair; + } + + Acts::Vector3 pos(track->get_x(), + track->get_y(), + track->get_z()); + Acts::Vector3 mom(track->get_px(), + track->get_py(), + track->get_pz()); + + Acts::Vector3 vertex(svtxVertex->get_x(), + svtxVertex->get_y(), + svtxVertex->get_z()); + + pos -= vertex; + + Acts::ActsSymMatrix<3> posCov; + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + posCov(i, j) = track->get_error(i, j); + } + } + + Acts::Vector3 r = mom.cross(Acts::Vector3(0., 0., 1.)); + float phi = atan2(r(1), r(0)); + + Acts::RotationMatrix3 rot; + Acts::RotationMatrix3 rot_T; + rot(0, 0) = cos(phi); + rot(0, 1) = -sin(phi); + rot(0, 2) = 0; + rot(1, 0) = sin(phi); + rot(1, 1) = cos(phi); + rot(1, 2) = 0; + rot(2, 0) = 0; + rot(2, 1) = 0; + rot(2, 2) = 1; + + rot_T = rot.transpose(); + + Acts::Vector3 pos_R = rot * pos; + Acts::ActsSymMatrix<3> rotCov = rot * posCov * rot_T; + + //! First pair is DCA_xy +/- DCA_xy_err + pair.first.first = pos_R(0); + pair.first.second = sqrt(rotCov(0, 0)); + + //! Second pair is DCA_z +/- DCA_z_err + pair.second.first = pos_R(2); + pair.second.second = sqrt(rotCov(2, 2)); + + return pair; +} diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h new file mode 100644 index 0000000000..f1e3d2aecd --- /dev/null +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -0,0 +1,23 @@ +#ifndef _TRACKBASEHISTORIC_TRACKANALYSISUTILS_H +#define _TRACKBASEHISTORIC_TRACKANALYSISUTILS_H + +#include + +class SvtxTrack; +class SvtxVertex; + +class TrackAnalysisUtils +{ + public: + using DCA = std::pair; + using DCAPair = std::pair; + + TrackAnalysisUtils() = default; + ~TrackAnalysisUtils() {} + + DCAPair get_dca(SvtxTrack* track, SvtxVertex* svtxVertex); + + private: +}; + +#endif diff --git a/offline/packages/trackbase_historic/TrackSeed_v1.cc b/offline/packages/trackbase_historic/TrackSeed_v1.cc index 9746b249c5..41cf08997a 100644 --- a/offline/packages/trackbase_historic/TrackSeed_v1.cc +++ b/offline/packages/trackbase_historic/TrackSeed_v1.cc @@ -1,4 +1,5 @@ #include "TrackSeed_v1.h" +#include #include @@ -89,11 +90,19 @@ void TrackSeed_v1::circleFitByTaubin(TrkrClusterContainer *clusters, if(layer < startLayer or layer > endLayer) { continue; } + auto clus = clusters->findCluster(key); + + if(clus->getEdge() > 0) + { continue; } Acts::Vector3 pos = tGeometry->getGlobalPosition( - key, clusters->findCluster(key)); + key, clus); positions.insert(std::make_pair(key, pos)); } + if(positions.size() < 3) + { + return; + } circleFitByTaubin(positions, startLayer, endLayer); diff --git a/offline/packages/trackreco/ALICEKF.cc b/offline/packages/trackreco/ALICEKF.cc index 30324edd4a..6848c40e04 100644 --- a/offline/packages/trackreco/ALICEKF.cc +++ b/offline/packages/trackreco/ALICEKF.cc @@ -83,15 +83,19 @@ double ALICEKF::getClusterError(TrkrCluster* c, TrkrDefs::cluskey key, Acts::Vec localErr[2][1] = 0.; localErr[2][2] = para_errors.second; }else if(m_cluster_version==5){ + double clusRadius = sqrt(global[0]*global[0] + global[1]*global[1]); + TrkrClusterv5* clusterv5 = dynamic_cast(c); + auto para_errors = _ClusErrPara->get_clusterv5_modified_error(clusterv5,clusRadius,key); + localErr[0][0] = 0.; localErr[0][1] = 0.; localErr[0][2] = 0.; localErr[1][0] = 0.; - localErr[1][1] = pow(c->getRPhiError(),2); + localErr[1][1] = para_errors.first; localErr[1][2] = 0.; localErr[2][0] = 0.; localErr[2][1] = 0.; - localErr[2][2] = pow(c->getZError(),2); + localErr[2][2] = para_errors.second; } float clusphi = atan2(global(1), global(0)); TMatrixF ROT(3,3); diff --git a/offline/packages/trackreco/ActsAlignmentStates.cc b/offline/packages/trackreco/ActsAlignmentStates.cc index 06c1e18e42..2d3d69d496 100644 --- a/offline/packages/trackreco/ActsAlignmentStates.cc +++ b/offline/packages/trackreco/ActsAlignmentStates.cc @@ -1,4 +1,5 @@ #include "ActsAlignmentStates.h" +#include "ActsPropagator.h" #include #include @@ -21,6 +22,7 @@ #include #include +#include #include #include #include @@ -34,15 +36,25 @@ namespace } } // namespace -void ActsAlignmentStates::fillAlignmentStateMap(Trajectory traj, - SvtxTrack* track) +void ActsAlignmentStates::fillAlignmentStateMap(const Trajectory& traj, + SvtxTrack* track, + const ActsTrackFittingAlgorithm::MeasurementContainer& measurements) { const auto mj = traj.multiTrajectory(); const auto& tips = traj.tips(); const auto& trackTip = tips.front(); const auto crossing = track->get_silicon_seed()->get_crossing(); + + ActsPropagator propagator(m_tGeometry); + SvtxAlignmentStateMap::StateVec statevec; + if (m_verbosity > 2) + { + std::cout << "Beginning alignment state creation for track " + << track->get_id() << std::endl; + } + std::vector indices{Acts::eBoundLoc0, Acts::eBoundLoc1, Acts::eBoundPhi, Acts::eBoundTheta, Acts::eBoundQOverP, Acts::eBoundTime}; mj.visitBackwards(trackTip, [&](const auto& state) { /// Collect only track states which were used in smoothing of KF and are measurements @@ -51,49 +63,54 @@ void ActsAlignmentStates::fillAlignmentStateMap(Trajectory traj, { return true; } - + const auto& surface = state.referenceSurface(); const auto& sl = static_cast(state.uncalibrated()); auto ckey = sl.cluskey(); - + Acts::Vector2 localMeas = Acts::Vector2::Zero(); + /// get the local measurement that acts used + std::visit([&](const auto& meas) { + localMeas(0) = meas.parameters()[0]; + localMeas(1) = meas.parameters()[1]; + }, measurements[sl.index()]); + if (m_verbosity > 2) { std::cout << "sl index and ckey " << sl.index() << ", " - << sl.cluskey() << std::endl; + << sl.cluskey() << " with local position " + << localMeas.transpose() << std::endl; } auto clus = m_clusterMap->findCluster(ckey); const auto trkrId = TrkrDefs::getTrkrId(ckey); - - /// Gets the global parameters from the state - const Acts::FreeVector freeParams = - Acts::MultiTrajectoryHelpers::freeSmoothed(m_tGeometry->geometry().getGeoContext(), state); - /// Calculate the residual in global coordinates + const Acts::Vector2 localState = state.effectiveProjector() * state.smoothed(); + /// Local residual between measurement and smoothed Acts state + const Acts::Vector2 localResidual = localMeas - localState; + Acts::Vector3 clusGlobal = m_tGeometry->getGlobalPosition(ckey, clus); if (trkrId == TrkrDefs::tpcId) { makeTpcGlobalCorrections(ckey, crossing, clusGlobal); } - + /// convert to acts units clusGlobal *= Acts::UnitConstants::cm; const Acts::FreeVector globalStateParams = Acts::detail::transformBoundToFreeParameters(surface, m_tGeometry->geometry().getGeoContext(), state.smoothed()); Acts::Vector3 stateGlobal = globalStateParams.segment<3>(Acts::eFreePos0); - Acts::Vector3 residual = clusGlobal - stateGlobal; Acts::Vector3 clus_sigma(0, 0, 0); - if (m_clusterVersion == 3 || m_clusterVersion == 5) + if (m_clusterVersion != 4) { clus_sigma(2) = clus->getZError() * Acts::UnitConstants::cm; clus_sigma(0) = clus->getRPhiError() / sqrt(2) * Acts::UnitConstants::cm; clus_sigma(1) = clus->getRPhiError() / sqrt(2) * Acts::UnitConstants::cm; } - else if (m_clusterVersion == 4) + else { - double clusRadius = sqrt(clusGlobal(0) * clusGlobal(0) + clusGlobal(1) * clusGlobal(1)); + double clusRadius = sqrt(clusGlobal(0) * clusGlobal(0) + clusGlobal(1) * clusGlobal(1)) / Acts::UnitConstants::cm; auto para_errors = m_clusErrPara.get_simple_cluster_error(clus, clusRadius, ckey); float exy2 = para_errors.first * Acts::UnitConstants::cm2; float ez2 = para_errors.second * Acts::UnitConstants::cm2; @@ -101,112 +118,67 @@ void ActsAlignmentStates::fillAlignmentStateMap(Trajectory traj, clus_sigma(0) = sqrt(exy2 / 2.0); clus_sigma(1) = sqrt(exy2 / 2.0); } + + if (m_verbosity > 2) { - std::cout << "clus global is " << clusGlobal.transpose() << std::endl - << "state global is " << stateGlobal.transpose() << std::endl - << "Residual is " << residual.transpose() << std::endl; + << "state global is " << stateGlobal.transpose() << std::endl; std::cout << " clus errors are " << clus_sigma.transpose() << std::endl; + std::cout << " clus loc is " << localMeas.transpose() << std::endl; + std::cout << " state loc is " << localState << std::endl; + std::cout << " local residual is " << localResidual.transpose() << std::endl; } // Get the derivative of alignment (global) parameters w.r.t. measurement or residual - const Acts::Vector3 direction = freeParams.segment<3>(Acts::eFreeDir0); - // The derivative of free parameters w.r.t. path length. @note Here, we - // assumes a linear track model, i.e. negecting the change of track - // direction. Otherwise, we need to know the magnetic field at the free - // parameters - Acts::FreeVector pathDerivative = Acts::FreeVector::Zero(); - pathDerivative.head<3>() = direction; - - const Acts::ActsDynamicMatrix H = state.effectiveProjector(); - - /// Acts residual, in local coordinates - //auto actslocres = state.effectiveCalibrated() - H * state.smoothed(); - - // Get the derivative of bound parameters w.r.t. alignment parameters - Acts::AlignmentToBoundMatrix d = - surface.alignmentToBoundDerivative(m_tGeometry->geometry().getGeoContext(), freeParams, pathDerivative); - // Get the derivative of bound parameters wrt track parameters - Acts::FreeToBoundMatrix j = surface.freeToBoundJacobian(m_tGeometry->geometry().getGeoContext(), freeParams); - - // derivative of residual wrt track parameters - auto dLocResTrack = -H * j; - // derivative of residual wrt alignment parameters - auto dLocResAlignment = -H * d; - - if (m_verbosity > 4) - { - std::cout << " derivative of resiudal wrt track params " << std::endl - << dLocResTrack << std::endl - << " derivative of residual wrt alignment params " << std::endl - << dLocResAlignment << std::endl; - } + /// The local bound parameters still have access to global phi/theta + double phi = state.smoothed()[Acts::eBoundPhi]; + double theta = state.smoothed()[Acts::eBoundTheta]; - /// The above matrices are in Acts local coordinates, so we need to convert them to - /// global coordinates with a rotation d(l0,l1)/d(x,y,z) - - const double cosTheta = direction.z(); - const double sinTheta = std::sqrt(square(direction.x()) + square(direction.y())); - const double invSinTheta = 1. / sinTheta; - const double cosPhi = direction.x() * invSinTheta; - const double sinPhi = direction.y() * invSinTheta; - Acts::ActsMatrix<3, 2> rot = Acts::ActsMatrix<3, 2>::Zero(); - rot(0, 0) = -sinPhi; - rot(0, 1) = -cosPhi * cosTheta; - rot(1, 0) = cosPhi; - rot(1, 1) = -sinPhi * cosTheta; - rot(2, 1) = sinTheta; - - /// this is a 3x6 matrix now of d(x_res,y_res,z_res)/d(dx,dy,dz,alpha,beta,gamma) - const auto dGlobResAlignment = rot * dLocResAlignment; - - /// Acts global coordinates are (x,y,z,t,hatx,haty,hatz,q/p) - /// So now rotate to x,y,z, px,py,pz - const double p = 1. / abs(globalStateParams[Acts::eFreeQOverP]); - const double p2 = square(p); - Acts::ActsMatrix<6, 8> sphenixRot = Acts::ActsMatrix<6, 8>::Zero(); - sphenixRot(0, 0) = 1; - sphenixRot(1, 1) = 1; - sphenixRot(2, 2) = 1; - sphenixRot(3, 4) = p; - sphenixRot(4, 5) = p; - sphenixRot(5, 6) = p; - sphenixRot(3, 7) = direction.x() * p2; - sphenixRot(4, 7) = direction.y() * p2; - sphenixRot(5, 7) = direction.z() * p2; - - const auto dGlobResTrack = rot * dLocResTrack * sphenixRot.transpose(); - - if (m_verbosity > 3) - { - std::cout << "derivative of residual wrt alignment parameters glob " << std::endl - << dGlobResAlignment << std::endl; - std::cout << "derivative of residual wrt track parameters glob " << std::endl - << dGlobResTrack << std::endl; - } + Acts::Vector3 tangent = Acts::makeDirectionUnitFromPhiTheta(phi,theta); + //! opposite convention for coordinates in Acts + tangent *= -1; + if(m_verbosity > 2) + { + std::cout << "tangent vector to track state is " << tangent.transpose() << std::endl; + } - auto svtxstate = std::make_unique(); - svtxstate->set_residual(residual); - svtxstate->set_local_derivative_matrix(dGlobResTrack); - svtxstate->set_global_derivative_matrix(dGlobResAlignment); - svtxstate->set_cluster_key(ckey); - - if(m_analytic) + std::pair projxy = + get_projectionXY(surface, tangent); + + Acts::Vector3 sensorCenter = surface.center(m_tGeometry->geometry().getGeoContext()); + Acts::Vector3 OM = stateGlobal - sensorCenter; + + auto globDeriv = makeGlobalDerivatives(OM, projxy); + + if(m_verbosity > 2) { - auto surf = m_tGeometry->maps().getSurface(ckey, clus); - auto anglederivs = getDerivativesAlignmentAngles(clusGlobal, ckey, - clus, surf, - crossing); - SvtxAlignmentState::GlobalMatrix analytic = SvtxAlignmentState::GlobalMatrix::Zero(); - - getGlobalDerivatives(anglederivs,analytic); - svtxstate->set_global_derivative_matrix(analytic); + std::cout << " global deriv calcs" << std::endl + << "stateGlobal: " << stateGlobal.transpose() + << ", sensor center " << sensorCenter.transpose() << std::endl + << ", OM " << OM.transpose() << std::endl << " projxy " + << projxy.first.transpose() << ", " + << projxy.second.transpose() << std::endl + << "global derivatives " << std::endl << globDeriv << std::endl; } - statevec.push_back(svtxstate.release()); + //! this is the derivative of the state wrt to Acts track parameters + //! e.g. (d_0, z_0, phi, theta, q/p, t) + auto localDeriv = state.effectiveProjector() * state.jacobian(); + if(m_verbosity > 2) + { + std::cout << "local deriv " << std::endl << localDeriv << std::endl; + } + auto svtxstate = std::make_unique(); + + svtxstate->set_residual(localResidual); + svtxstate->set_local_derivative_matrix(localDeriv); + svtxstate->set_global_derivative_matrix(globDeriv); + svtxstate->set_cluster_key(ckey); + + statevec.push_back(svtxstate.release()); return true; }); if (m_verbosity > 2) @@ -220,21 +192,60 @@ void ActsAlignmentStates::fillAlignmentStateMap(Trajectory traj, return; } -void ActsAlignmentStates::getGlobalDerivatives(std::vector& anglederivs, SvtxAlignmentState::GlobalMatrix& analytic) +SvtxAlignmentState::GlobalMatrix +ActsAlignmentStates::makeGlobalDerivatives(const Acts::Vector3& OM, + const std::pair& projxy) { - analytic(0,0) = 1; - analytic(1,1) = 1; - analytic(2,2) = 1; - - for(int res = 0; res < SvtxAlignmentState::NRES; ++res) - { - for(int gl = 3; gl < SvtxAlignmentState::NGL; ++gl) - { - // this is not backwards - the angle derivs is transposed - analytic(res,gl) = anglederivs.at(gl-3)(res) * Acts::UnitConstants::cm; - } - } - + SvtxAlignmentState::GlobalMatrix globalder = SvtxAlignmentState::GlobalMatrix::Zero(); + Acts::SymMatrix3 unit = Acts::SymMatrix3::Identity(); + + //! x residual rotations + globalder(0, 0) = ((unit.col(0)).cross(OM)).dot(projxy.first); + globalder(0, 1) = ((unit.col(1)).cross(OM)).dot(projxy.first); + globalder(0, 2) = ((unit.col(2)).cross(OM)).dot(projxy.first); + //! x residual translations + globalder(0, 3) = unit.col(0).dot(projxy.first); + globalder(0, 4) = unit.col(1).dot(projxy.first); + globalder(0, 5) = unit.col(2).dot(projxy.first); + + //! y residual rotations + globalder(1, 0) = ((unit.col(0)).cross(OM)).dot(projxy.second); + globalder(1, 1) = ((unit.col(1)).cross(OM)).dot(projxy.second); + globalder(1, 2) = ((unit.col(2)).cross(OM)).dot(projxy.second); + //! y residual translations + globalder(1, 3) = unit.col(0).dot(projxy.second); + globalder(1, 4) = unit.col(1).dot(projxy.second); + globalder(1, 5) = unit.col(2).dot(projxy.second); + + return globalder; +} + +std::pair ActsAlignmentStates::get_projectionXY(const Acts::Surface& surface, const Acts::Vector3& tangent) +{ + Acts::Vector3 projx = Acts::Vector3::Zero(); + Acts::Vector3 projy = Acts::Vector3::Zero(); + + // get the plane of the surface + Acts::Vector3 sensorCenter = surface.center(m_tGeometry->geometry().getGeoContext()); + // sensorNormal is the Z vector + Acts::Vector3 Z = -surface.normal(m_tGeometry->geometry().getGeoContext()); + + // get surface X and Y unit vectors in global frame + // transform Xlocal = 1.0 to global, subtract the surface center, normalize to 1 + Acts::Vector3 xloc(1.0, 0.0, 0.0); + Acts::Vector3 xglob = surface.transform(m_tGeometry->geometry().getGeoContext()) * xloc; + + Acts::Vector3 yloc(0.0, 1.0, 0.0); + Acts::Vector3 yglob = surface.transform(m_tGeometry->geometry().getGeoContext()) * yloc; + + Acts::Vector3 X = (xglob - sensorCenter) / (xglob - sensorCenter).norm(); + Acts::Vector3 Y = (yglob - sensorCenter) / (yglob - sensorCenter).norm(); + + projx = X - (tangent.dot(X) / tangent.dot(Z)) * Z; + projy = Y - (tangent.dot(Y) / tangent.dot(Z)) * Z; + if(m_verbosity > 2) + std::cout << "projxy " << projx.transpose() << ", " << projy.transpose() << std::endl; + return std::make_pair(projx, projy); } void ActsAlignmentStates::makeTpcGlobalCorrections(TrkrDefs::cluskey cluster_key, short int crossing, Acts::Vector3& global) @@ -258,133 +269,3 @@ void ActsAlignmentStates::makeTpcGlobalCorrections(TrkrDefs::cluskey cluster_key global = m_distortionCorrection.get_corrected_position(global, m_dcc_fluctuation); } } - -std::vector ActsAlignmentStates::getDerivativesAlignmentAngles(Acts::Vector3& global, TrkrDefs::cluskey cluster_key, TrkrCluster* cluster, Surface surface, int crossing) -{ - // The value of global is from the geocontext transformation - // we add to that transformation a small rotation around the relevant axis in the surface frame - - std::vector derivs_vector; - - // get the transformation from the geocontext - Acts::Transform3 transform = surface->transform(m_tGeometry->geometry().getGeoContext()); - - // Make an additional transform that applies a small rotation angle in the surface frame - for (unsigned int iangle = 0; iangle < 3; ++iangle) - { - // creates transform that adds a perturbation rotation around one axis, uses it to estimate derivative wrt perturbation rotation - - unsigned int trkrId = TrkrDefs::getTrkrId(cluster_key); - unsigned int layer = TrkrDefs::getLayer(cluster_key); - - Acts::Vector3 derivs(0, 0, 0); - Eigen::Vector3d theseAngles(0, 0, 0); - theseAngles[iangle] = sensorAngles[iangle]; // set the one we want to be non-zero - - Acts::Vector3 keeper(0, 0, 0); - for (int ip = 0; ip < 2; ++ip) - { - if (ip == 1) - { - theseAngles[iangle] *= -1; - } // test both sides of zero - - if (m_verbosity > 1) - { - std::cout << " trkrId " << trkrId << " layer " << layer << " cluster_key " << cluster_key - << " sensorAngles " << theseAngles[0] << " " << theseAngles[1] << " " << theseAngles[2] << std::endl; - } - - Acts::Transform3 perturbationTransformation = makePerturbationTransformation(theseAngles); - Acts::Transform3 overallTransformation = transform * perturbationTransformation; - - // transform the cluster local position to global coords with this additional rotation added - auto x = cluster->getLocalX() * 10; // mm - auto y = cluster->getLocalY() * 10; - if (trkrId == TrkrDefs::tpcId) - { - y = convertTimeToZ(cluster_key, cluster); - } - - Eigen::Vector3d clusterLocalPosition(x, y, 0); // follows the convention for the acts transform of local = (x,z,y) - Eigen::Vector3d finalCoords = overallTransformation * clusterLocalPosition / 10.0; // convert mm back to cm - - // have to add corrections for TPC clusters after transformation to global - if (trkrId == TrkrDefs::tpcId) - { - makeTpcGlobalCorrections(cluster_key, crossing, global); - } - - if (ip == 0) - { - keeper(0) = (finalCoords(0) - global(0)); - keeper(1) = (finalCoords(1) - global(1)); - keeper(2) = (finalCoords(2) - global(2)); - } - else - { - keeper(0) -= (finalCoords(0) - global(0)); - keeper(1) -= (finalCoords(1) - global(1)); - keeper(2) -= (finalCoords(2) - global(2)); - } - - if (m_verbosity > 1) - { - std::cout << " finalCoords(0) " << finalCoords(0) << " global(0) " << global(0) << " finalCoords(1) " << finalCoords(1) - << " global(1) " << global(1) << " finalCoords(2) " << finalCoords(2) << " global(2) " << global(2) << std::endl; - std::cout << " keeper now: keeper(0) " << keeper(0) << " keeper(1) " << keeper(1) << " keeper(2) " << keeper(2) << std::endl; - } - } - - // derivs vector contains: - // (dx/dalpha, dy/dalpha, dz/dalpha) (for iangle = 0) - // (dx/dbeta, dy/dbeta, dz/dbeta) (for iangle = 1) - // (dx/dgamma, dy/dgamma, dz/dgamma) (for iangle = 2) - - // Average the changes to get the estimate of the derivative - // Check what the sign of this should be !!!! - derivs(0) = keeper(0) / (2.0 * fabs(theseAngles[iangle])); - derivs(1) = keeper(1) / (2.0 * fabs(theseAngles[iangle])); - derivs(2) = keeper(2) / (2.0 * fabs(theseAngles[iangle])); - derivs_vector.push_back(derivs); - - if (m_verbosity > 1) - { - std::cout << " derivs(0) " << derivs(0) << " derivs(1) " << derivs(1) << " derivs(2) " << derivs(2) << std::endl; - } - } - - return derivs_vector; -} - -Acts::Transform3 ActsAlignmentStates::makePerturbationTransformation(Acts::Vector3 angles) -{ - // Note: Here beta is apllied to the z axis and gamma is applied to the y axis because the geocontext transform - // will flip those axes when transforming to global coordinates - Eigen::AngleAxisd alpha(angles(0), Eigen::Vector3d::UnitX()); - Eigen::AngleAxisd beta(angles(2), Eigen::Vector3d::UnitY()); - Eigen::AngleAxisd gamma(angles(1), Eigen::Vector3d::UnitZ()); - Eigen::Quaternion q = gamma * beta * alpha; - Eigen::Matrix3d perturbationRotation = q.matrix(); - - // combine rotation and translation into an affine matrix - Eigen::Vector3d nullTranslation(0, 0, 0); - Acts::Transform3 perturbationTransformation; - perturbationTransformation.linear() = perturbationRotation; - perturbationTransformation.translation() = nullTranslation; - - return perturbationTransformation; -} -float ActsAlignmentStates::convertTimeToZ(TrkrDefs::cluskey cluster_key, TrkrCluster* cluster) -{ - // must convert local Y from cluster average time of arival to local cluster z position - double drift_velocity = m_tGeometry->get_drift_velocity(); - double zdriftlength = cluster->getLocalY() * drift_velocity; - double surfCenterZ = 52.89; // 52.89 is where G4 thinks the surface center is - double zloc = surfCenterZ - zdriftlength; // converts z drift length to local z position in the TPC in north - unsigned int side = TpcDefs::getSide(cluster_key); - if (side == 0) zloc = -zloc; - float z = zloc * 10.0; - - return z; -} diff --git a/offline/packages/trackreco/ActsAlignmentStates.h b/offline/packages/trackreco/ActsAlignmentStates.h index 0eed5655dc..81d232649e 100644 --- a/offline/packages/trackreco/ActsAlignmentStates.h +++ b/offline/packages/trackreco/ActsAlignmentStates.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -32,10 +33,10 @@ class ActsAlignmentStates ActsAlignmentStates() {} ~ActsAlignmentStates() {} void clusterVersion(const int v) { m_clusterVersion = v; } - void fillAlignmentStateMap(Trajectory traj, - SvtxTrack* track); + void fillAlignmentStateMap(const Trajectory& traj, + SvtxTrack* track, + const ActsTrackFittingAlgorithm::MeasurementContainer& measurements); void verbosity(const int verb) { m_verbosity = verb; } - void analyticGlobalDer(bool a) { m_analytic = a; } void distortionContainers(TpcDistortionCorrectionContainer* stat, TpcDistortionCorrectionContainer* average, TpcDistortionCorrectionContainer* fluc) @@ -47,15 +48,13 @@ class ActsAlignmentStates void actsGeometry(ActsGeometry* geom) { m_tGeometry = geom; } void clusters(TrkrClusterContainer* clus) { m_clusterMap = clus; } void stateMap(SvtxAlignmentStateMap* map) { m_alignmentStateMap = map; } - + private: void makeTpcGlobalCorrections(TrkrDefs::cluskey cluster_key, short int crossing, Acts::Vector3& global); - std::vector getDerivativesAlignmentAngles(Acts::Vector3& global, TrkrDefs::cluskey cluster_key, TrkrCluster* cluster, Surface surface, int crossing); - void getGlobalDerivatives(std::vector& anglederivs, SvtxAlignmentState::GlobalMatrix& analytic); - Acts::Transform3 makePerturbationTransformation(Acts::Vector3 angles); - float convertTimeToZ(TrkrDefs::cluskey cluster_key, TrkrCluster* cluster); - bool m_analytic = true; + std::pair get_projectionXY(const Acts::Surface& surface, const Acts::Vector3& tangent); + SvtxAlignmentState::GlobalMatrix makeGlobalDerivatives(const Acts::Vector3& OM, const std::pair& projxy); + int m_verbosity = 0; int m_clusterVersion = 4; diff --git a/offline/packages/trackreco/ActsPropagator.cc b/offline/packages/trackreco/ActsPropagator.cc index b5273dfd64..d04c13ed34 100644 --- a/offline/packages/trackreco/ActsPropagator.cc +++ b/offline/packages/trackreco/ActsPropagator.cc @@ -8,12 +8,22 @@ #include #include #include +#include #include #include #include #include +ActsPropagator::SurfacePtr +ActsPropagator::makeVertexSurface(const SvtxVertex* vertex) +{ + return Acts::Surface::makeShared( + Acts::Vector3(vertex->get_x() * Acts::UnitConstants::cm, + vertex->get_y() * Acts::UnitConstants::cm, + vertex->get_z() * Acts::UnitConstants::cm)); +} + ActsPropagator::BoundTrackParam ActsPropagator::makeTrackParams(SvtxTrack* track, SvtxVertexMap* vertexMap) @@ -69,7 +79,7 @@ ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, auto propagator = makePropagator(); - Acts::Logging::Level logLevel = Acts::Logging::INFO; + Acts::Logging::Level logLevel = Acts::Logging::FATAL; if (m_verbosity > 3) { logLevel = Acts::Logging::VERBOSE; @@ -93,7 +103,7 @@ ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, if (result.ok()) { auto finalparams = *result.value().endParameters; - auto pathlength = result.value().pathLength / Acts::UnitConstants::cm; + auto pathlength = result.value().pathLength; auto pair = std::make_pair(pathlength, finalparams); return Acts::Result::success(pair); @@ -113,7 +123,7 @@ ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, auto propagator = makePropagator(); - Acts::Logging::Level logLevel = Acts::Logging::INFO; + Acts::Logging::Level logLevel = Acts::Logging::FATAL; if (m_verbosity > 3) { logLevel = Acts::Logging::VERBOSE; @@ -132,7 +142,7 @@ ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, if (result.ok()) { auto finalparams = *result.value().endParameters; - auto pathlength = result.value().pathLength / Acts::UnitConstants::cm; + auto pathlength = result.value().pathLength; auto pair = std::make_pair(pathlength, finalparams); return Acts::Result::success(pair); @@ -152,7 +162,7 @@ ActsPropagator::propagateTrackFast(const Acts::BoundTrackParameters& params, auto propagator = makeFastPropagator(); - Acts::Logging::Level logLevel = Acts::Logging::INFO; + Acts::Logging::Level logLevel = Acts::Logging::FATAL; if (m_verbosity > 3) { logLevel = Acts::Logging::VERBOSE; @@ -171,7 +181,7 @@ ActsPropagator::propagateTrackFast(const Acts::BoundTrackParameters& params, if (result.ok()) { auto finalparams = *result.value().endParameters; - auto pathlength = result.value().pathLength / Acts::UnitConstants::cm; + auto pathlength = result.value().pathLength; auto pair = std::make_pair(pathlength, finalparams); return Acts::Result::success(pair); diff --git a/offline/packages/trackreco/ActsPropagator.h b/offline/packages/trackreco/ActsPropagator.h index 97a1a15f9e..61bd4f2a38 100644 --- a/offline/packages/trackreco/ActsPropagator.h +++ b/offline/packages/trackreco/ActsPropagator.h @@ -23,12 +23,14 @@ #include class SvtxTrack; +class SvtxVertex; class SvtxVertexMap; class ActsPropagator { public: using BoundTrackParam = const Acts::BoundTrackParameters; + /// Return type of std::pair using BoundTrackParamPair = std::pair; using BoundTrackParamResult = Acts::Result; using SurfacePtr = std::shared_ptr; @@ -43,14 +45,20 @@ class ActsPropagator } ~ActsPropagator() {} + /// Helper functions for creating needed input for track propagation + /// functions below + SurfacePtr makeVertexSurface(const SvtxVertex* vertex); BoundTrackParam makeTrackParams(SvtxTrack* track, SvtxVertexMap* vertexMap); + /// The return type is an Acts::Result of a std::pair, where the pair is + /// a path length and the track parameters at the surface in units of mm + /// and GeV. For an example of how to unpack this, see + /// PHActsTrackProjection::propagateTrack and + /// PHActsTrackProjection::updateSvtxTrack BoundTrackParamResult propagateTrack(const Acts::BoundTrackParameters& params, const unsigned int sphenixLayer); - BoundTrackParamResult propagateTrack(const Acts::BoundTrackParameters& params, const SurfacePtr& surface); - /// The following function takes the track parameters at the vertex and /// propagates them in isolation to the requested surface, i.e. it does /// NOT stop at each layer in the sPHENIX detector on the way to the diff --git a/offline/packages/trackreco/MakeActsGeometry.cc b/offline/packages/trackreco/MakeActsGeometry.cc index 4824a22b0a..dd07de6a77 100644 --- a/offline/packages/trackreco/MakeActsGeometry.cc +++ b/offline/packages/trackreco/MakeActsGeometry.cc @@ -35,6 +35,8 @@ #include #include +#include + #include #include #include @@ -113,9 +115,9 @@ namespace MakeActsGeometry::MakeActsGeometry(const std::string &name) : SubsysReco(name) { - for ( const auto id : { TrkrDefs::mvtxId, TrkrDefs::inttId, TrkrDefs::tpcId, TrkrDefs::micromegasId }) + for ( int layer = 0; layer < 57; layer++) { - m_misalignmentFactor.insert(std::make_pair(id, 1.)); + m_misalignmentFactor.insert(std::make_pair(layer, 1.)); } } @@ -172,9 +174,9 @@ int MakeActsGeometry::InitRun(PHCompositeNode *topNode) m_actsGeometry->set_drift_velocity(m_drift_velocity); alignment_transformation.createMap(topNode); - for(auto& [id, factor] : m_misalignmentFactor) + for(auto& [layer, factor] : m_misalignmentFactor) { - alignment_transformation.misalignmentFactor(id, factor); + alignment_transformation.misalignmentFactor(layer, factor); } // print @@ -471,19 +473,17 @@ void MakeActsGeometry::buildActsSurfaces() /// Alter args if using field map if(m_magField.find(".root") != std::string::npos) { - if(m_magField.find("2d") != std::string::npos) - { - m_magFieldRescale = 1; - } + char *calibrationsroot = getenv("CALIBRATIONROOT"); m_magField = "sphenix3dtrackingmapxyz.root"; + if (calibrationsroot != nullptr) - { - m_magField = std::string(calibrationsroot) + std::string("/Field/Map/") + m_magField; - } - //m_magField = std::string("/phenix/u/bogui/data/Field/sphenix3dtrackingmapxyz.root"); - //m_magField = std::string("/phenix/u/bogui/data/Field/sphenix3dbigmapxyz.root"); + { + m_magField = std::string(calibrationsroot) + std::string("/Field/Map/") + m_magField; + } + m_magField = CDBInterface::instance()->getUrl("FIELDMAPTRACKING", m_magField); + argstr[7] = "--bf-map-file"; argstr[8] = m_magField; argstr[9]= "--bf-map-tree"; diff --git a/offline/packages/trackreco/MakeActsGeometry.h b/offline/packages/trackreco/MakeActsGeometry.h index 234bb2fa19..4abf59703c 100644 --- a/offline/packages/trackreco/MakeActsGeometry.h +++ b/offline/packages/trackreco/MakeActsGeometry.h @@ -119,16 +119,14 @@ class MakeActsGeometry : public SubsysReco } - void misalignmentFactor(TrkrDefs::TrkrId id, const double misalignment) + void misalignmentFactor(uint8_t layer, const double misalignment) { - auto it = m_misalignmentFactor.find(id); + auto it = m_misalignmentFactor.find(layer); if(it != m_misalignmentFactor.end()) { it->second = misalignment; return; } - - std::cout << "Passed an unknown trkr id, misalignment factor will not be set for " << id << std::endl; } double getSurfStepPhi() {return m_surfStepPhi;} @@ -209,7 +207,7 @@ class MakeActsGeometry : public SubsysReco TGeoManager* m_geoManager = nullptr; bool m_useField = true; - std::map m_misalignmentFactor; + std::map m_misalignmentFactor; /// Several maps that connect Acts world to sPHENIX G4 world std::map m_clusterNodeMap; diff --git a/offline/packages/trackreco/Makefile.am b/offline/packages/trackreco/Makefile.am index b1693c8e28..b339d1b542 100644 --- a/offline/packages/trackreco/Makefile.am +++ b/offline/packages/trackreco/Makefile.am @@ -159,10 +159,10 @@ libtrack_reco_la_LIBADD = \ -lgenfit2 \ -lgenfit2exp \ -lPHGenFit \ - -lg4bbc_io \ -lg4tpc \ -lg4intt \ -lg4mvtx \ + -lbbc_io \ -lmicromegas_io \ -lmvtx_io \ -lintt_io \ diff --git a/offline/packages/trackreco/PHActsGSF.cc b/offline/packages/trackreco/PHActsGSF.cc index 35bf72986b..77754a0cc5 100644 --- a/offline/packages/trackreco/PHActsGSF.cc +++ b/offline/packages/trackreco/PHActsGSF.cc @@ -338,7 +338,7 @@ SourceLinkVec PHActsGSF::getSourceLinks(TrackSeed* track, else if (m_cluster_version == 4) { double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); - auto para_errors = _ClusErrPara.get_cluster_error(track, cluster, clusRadius, cluskey); + auto para_errors = _ClusErrPara.get_cluster_error(cluster, clusRadius, cluskey, track->get_qOverR(), track->get_slope()); cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; @@ -346,10 +346,13 @@ SourceLinkVec PHActsGSF::getSourceLinks(TrackSeed* track, } else if (m_cluster_version == 5) { - cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = pow(cluster->getRPhiError(),2) * Acts::UnitConstants::cm2; + double clusRadius = sqrt(global[0]*global[0] + global[1]*global[1]); + TrkrClusterv5* clusterv5 = dynamic_cast(cluster); + auto para_errors = _ClusErrPara.get_clusterv5_modified_error(clusterv5,clusRadius,cluskey); + cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; - cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = pow(cluster->getZError(),2) * Acts::UnitConstants::cm2; + cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; } ActsSourceLink::Index index = measurements.size(); diff --git a/offline/packages/trackreco/PHActsKDTreeSeeding.h b/offline/packages/trackreco/PHActsKDTreeSeeding.h index 545d97f7ce..630bcc3a99 100644 --- a/offline/packages/trackreco/PHActsKDTreeSeeding.h +++ b/offline/packages/trackreco/PHActsKDTreeSeeding.h @@ -22,6 +22,7 @@ class TrkrClusterContainer; class TrackSeedContainer; class TrkrCluster; class PHG4CylinderGeomContainer; +class TrackSeed; class PHActsKDTreeSeeding : public SubsysReco { diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.cc b/offline/packages/trackreco/PHActsSiliconSeeding.cc index f99f154bb5..6af3745e70 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.cc +++ b/offline/packages/trackreco/PHActsSiliconSeeding.cc @@ -170,10 +170,12 @@ GridSeeds PHActsSiliconSeeding::runSeeder(std::vector& spVec) /// Covariance converter functor needed by seed finder auto covConverter = - [=](const SpacePoint& sp, float, float, float) + [=](const SpacePoint& sp, float zAlign, float rAlign, float sigmaError) -> std::pair { Acts::Vector3 position{sp.x(), sp.y(), sp.z()}; - Acts::Vector2 cov{sp.m_varianceR, sp.m_varianceZ}; + Acts::Vector2 cov; + cov[0] = (sp.m_varianceR + rAlign*rAlign) * sigmaError; + cov[1] = (sp.m_varianceZ + zAlign*zAlign) * sigmaError; return std::make_pair(position, cov); }; @@ -729,6 +731,14 @@ Acts::SeedFinderConfig PHActsSiliconSeeding::configureSeeder() /// Maximum impact parameter must be smaller than rMin config.impactMax = m_impactMax; + /// Configurations for dealing with misalignment + config.zAlign = m_zalign; + config.rAlign = m_ralign; + config.toleranceParam = m_tolerance; + config.maxPtScattering = m_maxPtScattering; + config.sigmaError = m_sigmaError; + config.helixcut = m_helixcut; + return config; } diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.h b/offline/packages/trackreco/PHActsSiliconSeeding.h index 4b0a858351..87bd6c6366 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.h +++ b/offline/packages/trackreco/PHActsSiliconSeeding.h @@ -85,6 +85,20 @@ class PHActsSiliconSeeding : public SubsysReco {m_gridFactor = gridFactor;} void sigmaScattering(const float sigma) { m_sigmaScattering = sigma; } + void maxPtScattering(const float pt) + { m_maxPtScattering = pt; } + void sigmaError(const float sigma) + { m_sigmaError = sigma; } + void zalign(const float z) + { m_zalign = z; } + void ralign(const float r) + { m_ralign = r; } + void tolerance(const float tolerance) + { m_tolerance = tolerance; } + void helixcut(const float cut) + { m_helixcut = cut; } + + /// A function to run the seeder with large (true) /// or small (false) grid spacing void largeGridSpacing(const bool spacing); @@ -154,7 +168,6 @@ class PHActsSiliconSeeding : public SubsysReco /// MVTX can only have the middle layer be the middle hit int m_maxSeedsPerSpM = 1; - float m_sigmaScattering = 5.; /// Limiting location of measurements (e.g. detector constraints) /// We limit to the MVTX float m_rMax = 200. * Acts::UnitConstants::mm; @@ -162,6 +175,15 @@ class PHActsSiliconSeeding : public SubsysReco float m_zMax = 300. * Acts::UnitConstants::mm; float m_zMin = -300. * Acts::UnitConstants::mm; + /// misalignment parameters + float m_helixcut = 1; + float m_tolerance = 1.1 * Acts::UnitConstants::mm; + float m_ralign = 0; + float m_zalign = 0; + float m_maxPtScattering = 10; + float m_sigmaScattering = 5.; + float m_sigmaError = 5; + /// Value tuned to provide as large of phi bins as possible. /// Increases the secondary finding efficiency float m_gridFactor = 2.3809; diff --git a/offline/packages/trackreco/PHActsTrackProjection.cc b/offline/packages/trackreco/PHActsTrackProjection.cc index 3b8f9b566e..e404ed9652 100644 --- a/offline/packages/trackreco/PHActsTrackProjection.cc +++ b/offline/packages/trackreco/PHActsTrackProjection.cc @@ -41,10 +41,16 @@ PHActsTrackProjection::PHActsTrackProjection(const std::string& name) m_caloNames.push_back("CEMC"); m_caloNames.push_back("HCALIN"); m_caloNames.push_back("HCALOUT"); + m_caloNames.push_back("OUTER_CEMC"); + m_caloNames.push_back("OUTER_HCALIN"); + m_caloNames.push_back("OUTER_HCALOUT"); m_caloTypes.push_back(SvtxTrack::CEMC); m_caloTypes.push_back(SvtxTrack::HCALIN); m_caloTypes.push_back(SvtxTrack::HCALOUT); + m_caloTypes.push_back(SvtxTrack::OUTER_CEMC); + m_caloTypes.push_back(SvtxTrack::OUTER_HCALIN); + m_caloTypes.push_back(SvtxTrack::OUTER_HCALOUT); } int PHActsTrackProjection::InitRun(PHCompositeNode* topNode) @@ -98,6 +104,11 @@ int PHActsTrackProjection::process_event(PHCompositeNode* topNode) { return Fun4AllReturnCodes::ABORTEVENT; } + ret = projectTracks(layer+m_nCaloLayers); + if (ret != Fun4AllReturnCodes::EVENT_OK) + { + return Fun4AllReturnCodes::ABORTEVENT; + } } if (Verbosity() > 1) @@ -140,17 +151,15 @@ int PHActsTrackProjection::projectTracks(const int caloLayer) return Fun4AllReturnCodes::EVENT_OK; } - - void PHActsTrackProjection::updateSvtxTrack( const ActsPropagator::BoundTrackParamPair& parameters, SvtxTrack* svtxTrack, const int caloLayer) { - float pathlength = parameters.first; + float pathlength = parameters.first / Acts::UnitConstants::cm; auto params = parameters.second; - - SvtxTrackState_v1 out(pathlength); + float calorad = m_caloRadii.find(m_caloTypes.at(caloLayer))->second; + SvtxTrackState_v1 out(calorad); auto projectionPos = params.position(m_tGeometry->geometry().getGeoContext()); const auto momentum = params.momentum(); @@ -164,7 +173,7 @@ void PHActsTrackProjection::updateSvtxTrack( if (Verbosity() > 1) { std::cout << "Adding track state for caloLayer " << caloLayer - << " with position " << projectionPos.transpose() << std::endl; + << " at pathlength " << pathlength << " with position " << projectionPos.transpose() << std::endl; } ActsTransformations transformer; @@ -308,6 +317,8 @@ int PHActsTrackProjection::makeCaloSurfacePtrs(PHCompositeNode* topNode) /// Default to using calo radius double caloRadius = m_towerGeomContainer->get_radius(); + double caloOuterRadius = m_towerGeomContainer->get_radius() + m_towerGeomContainer->get_thickness(); + if (m_caloRadii.find(m_caloTypes.at(caloLayer)) != m_caloRadii.end()) { caloRadius = m_caloRadii.find(m_caloTypes.at(caloLayer))->second; @@ -319,11 +330,23 @@ int PHActsTrackProjection::makeCaloSurfacePtrs(PHCompositeNode* topNode) caloRadius *= Acts::UnitConstants::cm; + if (m_caloRadii.find(m_caloTypes.at(caloLayer+m_nCaloLayers)) != m_caloRadii.end()) + { + caloOuterRadius = m_caloRadii.find(m_caloTypes.at(caloLayer+m_nCaloLayers))->second; + } + else + { + m_caloRadii.insert(std::make_pair(m_caloTypes.at(caloLayer+m_nCaloLayers), caloOuterRadius)); + } + + caloOuterRadius *= Acts::UnitConstants::cm; + /// Extend farther so that there is at least surface there, for high /// curling tracks. Can always reject later const auto eta = 2.5; const auto theta = 2. * atan(exp(-eta)); const auto halfZ = caloRadius / tan(theta) * Acts::UnitConstants::cm; + const auto halfZOuter = caloOuterRadius / tan(theta) * Acts::UnitConstants::cm; /// Make a cylindrical surface at (0,0,0) aligned along the z axis auto transform = Acts::Transform3::Identity(); @@ -332,12 +355,17 @@ int PHActsTrackProjection::makeCaloSurfacePtrs(PHCompositeNode* topNode) Acts::Surface::makeShared(transform, caloRadius, halfZ); + std::shared_ptr outer_surf = + Acts::Surface::makeShared(transform, + caloOuterRadius, + halfZOuter); if (Verbosity() > 1) { std::cout << "Creating cylindrical surface at " << caloRadius << std::endl; + std::cout << "Creating cylindrical surface at " << caloOuterRadius << std::endl; } - m_caloSurfaces.insert(std::make_pair(m_caloNames.at(caloLayer), - surf)); + m_caloSurfaces.insert(std::make_pair(m_caloNames.at(caloLayer),surf)); + m_caloSurfaces.insert(std::make_pair(m_caloNames.at(caloLayer+m_nCaloLayers), outer_surf)); } if (Verbosity() > 1) diff --git a/offline/packages/trackreco/PHActsTrackPropagator.cc b/offline/packages/trackreco/PHActsTrackPropagator.cc index f45f88e402..00a5b6421e 100644 --- a/offline/packages/trackreco/PHActsTrackPropagator.cc +++ b/offline/packages/trackreco/PHActsTrackPropagator.cc @@ -72,7 +72,7 @@ void PHActsTrackPropagator::addTrackState( BoundTrackParamResult &result, SvtxTrack *svtxTrack) { - float pathlength = result.value().first; + float pathlength = result.value().first / Acts::UnitConstants::cm; auto params = result.value().second; SvtxTrackState_v1 out(pathlength); diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index a0c5f66c23..7271714cd9 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -427,7 +427,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) unsigned int trid = m_directedTrackMap->size(); newTrack.set_id(trid); - if( getTrackFitResult(fitOutput, &newTrack) ) + if( getTrackFitResult(fitOutput, &newTrack, measurements) ) { m_directedTrackMap->insertWithKey(&newTrack, trid); } } else { @@ -435,7 +435,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) unsigned int trid = m_trackMap->size(); newTrack.set_id(trid); - if( getTrackFitResult(fitOutput, &newTrack)) + if( getTrackFitResult(fitOutput, &newTrack, measurements)) { m_trackMap->insertWithKey(&newTrack, trid); } } @@ -627,7 +627,7 @@ SourceLinkVec PHActsTrkFitter::getSourceLinks(TrackSeed* track, TrkrDefs::cluskey cluskey = global_moved[i].first; Acts::Vector3 global = global_moved[i].second; - if(TrkrDefs::getLayer(cluskey) == m_ignoreLayer) + if(m_ignoreLayer.find(TrkrDefs::getLayer(cluskey)) != m_ignoreLayer.end()) { if(Verbosity() > 3) { @@ -699,16 +699,19 @@ SourceLinkVec PHActsTrkFitter::getSourceLinks(TrackSeed* track, cluster->getActsLocalError(1,1) * Acts::UnitConstants::cm2; }else if(m_cluster_version==4){ double clusRadius = sqrt(global[0]*global[0] + global[1]*global[1]); - auto para_errors = _ClusErrPara.get_cluster_error(track,cluster,clusRadius,cluskey); + auto para_errors = _ClusErrPara.get_cluster_error(cluster,clusRadius,cluskey, track->get_qOverR(), track->get_slope()); cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; }else if(m_cluster_version==5){ - cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = pow(cluster->getRPhiError(),2) * Acts::UnitConstants::cm2; + double clusRadius = sqrt(global[0]*global[0] + global[1]*global[1]); + TrkrClusterv5* clusterv5 = dynamic_cast(cluster); + auto para_errors = _ClusErrPara.get_clusterv5_modified_error(clusterv5,clusRadius,cluskey); + cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; - cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = pow(cluster->getZError(),2) * Acts::UnitConstants::cm2; + cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; } ActsSourceLink::Index index = measurements.size(); @@ -747,7 +750,7 @@ SourceLinkVec PHActsTrkFitter::getSourceLinks(TrackSeed* track, return sourcelinks; } -bool PHActsTrkFitter::getTrackFitResult(const FitResult &fitOutput, SvtxTrack* track) +bool PHActsTrkFitter::getTrackFitResult(const FitResult &fitOutput, SvtxTrack* track, const ActsTrackFittingAlgorithm::MeasurementContainer& measurements) { /// Make a trajectory state for storage, which conforms to Acts track fit /// analysis tool @@ -801,7 +804,7 @@ bool PHActsTrkFitter::getTrackFitResult(const FitResult &fitOutput, SvtxTrack* t { if(track->get_silicon_seed() && track->get_tpc_seed()) { - m_alignStates.fillAlignmentStateMap(trajectory, track); + m_alignStates.fillAlignmentStateMap(trajectory, track, measurements); } } diff --git a/offline/packages/trackreco/PHActsTrkFitter.h b/offline/packages/trackreco/PHActsTrkFitter.h index 1521619214..604a58362d 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.h +++ b/offline/packages/trackreco/PHActsTrkFitter.h @@ -109,7 +109,7 @@ class PHActsTrkFitter : public SubsysReco /// Set flag for pp running void set_pp_mode(bool ispp) { m_pp_mode = ispp; } - void ignoreLayer(int layer) { m_ignoreLayer = layer; } + void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } private: @@ -143,7 +143,8 @@ class PHActsTrkFitter : public SubsysReco SurfacePtrVec& surfaces) const; void checkSurfaceVec(SurfacePtrVec& surfaces) const; - bool getTrackFitResult(const FitResult& fitOutput, SvtxTrack* track); + bool getTrackFitResult(const FitResult& fitOutput, SvtxTrack* track, + const ActsTrackFittingAlgorithm::MeasurementContainer& measurements); Acts::BoundSymMatrix setDefaultCovariance() const; void printTrackSeed(const ActsTrackFittingAlgorithm::TrackParameters& seed) const; @@ -202,8 +203,8 @@ class PHActsTrkFitter : public SubsysReco TpcClusterMover _clusterMover; ClusterErrorPara _ClusErrPara; - int m_ignoreLayer = std::numeric_limits::max(); - + std::set m_ignoreLayer; + std::string m_fieldMap = ""; int _n_iteration = 0; diff --git a/offline/packages/trackreco/PHActsVertexPropagator.cc b/offline/packages/trackreco/PHActsVertexPropagator.cc index a1d30e073f..1553bcc185 100644 --- a/offline/packages/trackreco/PHActsVertexPropagator.cc +++ b/offline/packages/trackreco/PHActsVertexPropagator.cc @@ -39,11 +39,6 @@ int PHActsVertexPropagator::InitRun(PHCompositeNode* topNode) } int PHActsVertexPropagator::process_event(PHCompositeNode*) { - if (m_vertexMap->size() == 0) - { - setTrackVertexTo0(); - } - std::vector deletedKeys; for (const auto& [trackKey, trajectory] : *m_trajectories) { @@ -81,13 +76,19 @@ int PHActsVertexPropagator::process_event(PHCompositeNode*) } else { - svtxTrack->identify(); + if (Verbosity() > 1) + { + svtxTrack->identify(); + } } } } setVtxChi2(); - + if (m_vertexMap->size() == 0 && Verbosity() > 2) + { + std::cout << "Propagated tracks to PerigeeSurface at (0,0,0) as no track vertices were found" << std::endl; + } /// Erase the trajectories that were removed from the track cleaner for (auto& key : deletedKeys) { @@ -182,44 +183,22 @@ PHActsVertexPropagator::propagateTrack( ActsPropagator propagator(m_tGeometry); propagator.verbosity(Verbosity()); - - return propagator.propagateTrack(params,perigee); - + + return propagator.propagateTrack(params, perigee); } Acts::Vector3 PHActsVertexPropagator::getVertex(const unsigned int vtxid) { auto svtxVertex = m_vertexMap->get(vtxid); - return Acts::Vector3(svtxVertex->get_x() * Acts::UnitConstants::cm, - svtxVertex->get_y() * Acts::UnitConstants::cm, - svtxVertex->get_z() * Acts::UnitConstants::cm); -} - -void PHActsVertexPropagator::setTrackVertexTo0() -{ - /// If we found no vertices in the event, propagate the tracks to 0,0,0 - auto vertex = std::make_unique(); - vertex->set_chisq(0.); - vertex->set_ndof(0); - vertex->set_t0(0); - vertex->set_id(0); - vertex->set_x(0); - vertex->set_y(0); - vertex->set_z(0); - for (int i = 0; i < 3; i++) + /// check that a vertex exists + if (svtxVertex) { - for (int j = 0; j < 3; j++) - { - vertex->set_error(i, j, 20.); - } + return Acts::Vector3(svtxVertex->get_x() * Acts::UnitConstants::cm, + svtxVertex->get_y() * Acts::UnitConstants::cm, + svtxVertex->get_z() * Acts::UnitConstants::cm); } - m_vertexMap->insert(vertex.release()); - - for (auto& [key, track] : *m_trackMap) - { - track->set_vertex_id(0); - } + return Acts::Vector3::Zero(); } int PHActsVertexPropagator::End(PHCompositeNode*) diff --git a/offline/packages/trackreco/PHActsVertexPropagator.h b/offline/packages/trackreco/PHActsVertexPropagator.h index ed17f5814f..59f0682861 100644 --- a/offline/packages/trackreco/PHActsVertexPropagator.h +++ b/offline/packages/trackreco/PHActsVertexPropagator.h @@ -36,10 +36,9 @@ class PHActsVertexPropagator : public SubsysReco private: int getNodes(PHCompositeNode *topNode); - void setTrackVertexTo0(); - ActsPropagator::BoundTrackParamResult - propagateTrack(const Acts::BoundTrackParameters ¶ms, - const unsigned int vtxid); + ActsPropagator::BoundTrackParamResult + propagateTrack(const Acts::BoundTrackParameters ¶ms, + const unsigned int vtxid); Acts::Vector3 getVertex(const unsigned int vtxid); void updateSvtxTrack(SvtxTrack *track, const Acts::BoundTrackParameters ¶ms); diff --git a/offline/packages/trackreco/PHGenFitTrkFitter.cc b/offline/packages/trackreco/PHGenFitTrkFitter.cc index 8a7a5ec569..c8fc1bc461 100644 --- a/offline/packages/trackreco/PHGenFitTrkFitter.cc +++ b/offline/packages/trackreco/PHGenFitTrkFitter.cc @@ -1186,7 +1186,7 @@ std::shared_ptr PHGenFitTrkFitter::ReFitTrack(PHCompositeNode* case TrkrDefs::mvtxId: case TrkrDefs::inttId: { - const auto errors_square = m_cluster_error_parametrization.get_cluster_error( intrack->get_silicon_seed(), cluster, cluster_r, cluster_key ); + const auto errors_square = m_cluster_error_parametrization.get_cluster_error(cluster, cluster_r, cluster_key, intrack->get_silicon_seed()->get_qOverR(), intrack->get_silicon_seed()->get_slope() ); cluster_rphi_error = std::sqrt( errors_square.first ); cluster_z_error = std::sqrt( errors_square.second ); break; @@ -1195,7 +1195,7 @@ std::shared_ptr PHGenFitTrkFitter::ReFitTrack(PHCompositeNode* case TrkrDefs::micromegasId: case TrkrDefs::tpcId: { - const auto errors_square = m_cluster_error_parametrization.get_cluster_error( intrack->get_tpc_seed(), cluster, cluster_r, cluster_key ); + const auto errors_square = m_cluster_error_parametrization.get_cluster_error(cluster, cluster_r, cluster_key, intrack->get_tpc_seed()->get_qOverR(), intrack->get_tpc_seed()->get_slope() ); cluster_rphi_error = std::sqrt( errors_square.first ); cluster_z_error = std::sqrt( errors_square.second ); break; diff --git a/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc b/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc index dfec97b23b..b6daf183bd 100644 --- a/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc +++ b/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc @@ -305,7 +305,7 @@ void PHSiliconTpcTrackMatching::findEtaPhiMatches( bool eta_match = false; double si_eta = _tracklet_si->get_eta(); if( fabs(tpc_eta - si_eta) < _eta_search_win * mag) eta_match = true; -// if(!eta_match) continue; + if(!eta_match) continue; unsigned int siid = phtrk_iter_si; double si_x = _tracklet_si->get_x(); double si_y = _tracklet_si->get_y(); @@ -329,14 +329,14 @@ void PHSiliconTpcTrackMatching::findEtaPhiMatches( position_match = true; } -// if(!position_match) -// { continue; } + if(!position_match) + { continue; } bool phi_match = false; double si_phi = _tracklet_si->get_phi(_cluster_map,_tGeometry); if( fabs(tpc_phi - si_phi) < _phi_search_win * mag) phi_match = true; if( fabs( fabs(tpc_phi - si_phi) - 2.0 * M_PI) < _phi_search_win * mag ) phi_match = true; -// if(!phi_match) continue; + if(!phi_match) continue; if(Verbosity() > 3) { cout << " testing for a match for TPC track " << tpcid << " with pT " << _tracklet_tpc->get_pt() @@ -347,29 +347,27 @@ void PHSiliconTpcTrackMatching::findEtaPhiMatches( std::cout << " x search " << _x_search_win*mag << " y search " << _y_search_win*mag << " z search " << _z_search_win*mag << std::endl; } - if(eta_match && phi_match && position_match) + // got a match, add to the list + // These stubs are matched in eta, phi, x and y already + matched = true; + tpc_matches.insert(std::make_pair(tpcid, siid)); + tpc_matched_set.insert(tpcid); + + if(Verbosity() > 1) { - // got a match, add to the list - // These stubs are matched in eta, phi, x and y already - matched = true; - tpc_matches.insert(std::make_pair(tpcid, siid)); - tpc_matched_set.insert(tpcid); - - if(Verbosity() > 1) - { - cout << " found a match for TPC track " << tpcid << " with Si track " << siid << endl; - cout << " tpc_phi " << tpc_phi << " si_phi " << si_phi << " phi_match " << phi_match - << " tpc_eta " << tpc_eta << " si_eta " << si_eta << " eta_match " << eta_match << endl; - std::cout << " tpc x " << tpc_x << " si x " << si_x << " tpc y " << tpc_y << " si y " << si_y << " tpc_z " << tpc_z << " si z " << si_z << std::endl; - } - - // temporary! - if(_test_windows) - cout << " Try_silicon: pt " << tpc_pt << " tpc_phi " << tpc_phi << " si_phi " << si_phi << " dphi " << tpc_phi-si_phi - << " tpc_eta " << tpc_eta << " si_eta " << si_eta << " deta " << tpc_eta-si_eta << " tpc_x " << tpc_x << " tpc_y " << tpc_y << " tpc_z " << tpc_z - << " dx " << tpc_x - si_x << " dy " << tpc_y - si_y << " dz " << tpc_z - si_z - << endl; + cout << " found a match for TPC track " << tpcid << " with Si track " << siid << endl; + cout << " tpc_phi " << tpc_phi << " si_phi " << si_phi << " phi_match " << phi_match + << " tpc_eta " << tpc_eta << " si_eta " << si_eta << " eta_match " << eta_match << endl; + std::cout << " tpc x " << tpc_x << " si x " << si_x << " tpc y " << tpc_y << " si y " << si_y << " tpc_z " << tpc_z << " si z " << si_z << std::endl; } + + // temporary! + if(_test_windows) + cout << " Try_silicon: pt " << tpc_pt << " tpc_phi " << tpc_phi << " si_phi " << si_phi << " dphi " << tpc_phi-si_phi + << " tpc_eta " << tpc_eta << " si_eta " << si_eta << " deta " << tpc_eta-si_eta << " tpc_x " << tpc_x << " tpc_y " << tpc_y << " tpc_z " << tpc_z + << " dx " << tpc_x - si_x << " dy " << tpc_y - si_y << " dz " << tpc_z - si_z + << endl; + } // if no match found, keep tpc seed for fitting if(!matched) diff --git a/offline/packages/trackreco/PHSimpleKFProp.cc b/offline/packages/trackreco/PHSimpleKFProp.cc index fd751f6b84..32476b8cfe 100644 --- a/offline/packages/trackreco/PHSimpleKFProp.cc +++ b/offline/packages/trackreco/PHSimpleKFProp.cc @@ -1168,14 +1168,16 @@ std::vector PHSimpleKFProp::RemoveBadClusters(const std::vector& seeds, PositionMap& positions) +void PHSimpleKFProp::publishSeeds(std::vector& seeds, PositionMap& /*positions*/) { for(auto& seed: seeds ) { /// The ALICEKF gives a better charge determination at high pT int q = seed.get_charge(); - seed.circleFitByTaubin(positions,7,55); - seed.lineFit(positions,7,55); + + seed.circleFitByTaubin(_cluster_map, _tgeometry, 7, 55); + seed.lineFit(_cluster_map,_tgeometry, 7, 55); + seed.set_qOverR(fabs(seed.get_qOverR()) * q); _track_map->insert(&seed); diff --git a/offline/packages/trackreco/PHTrackFitting.cc b/offline/packages/trackreco/PHTrackFitting.cc index 4c63959704..b92742f8a0 100644 --- a/offline/packages/trackreco/PHTrackFitting.cc +++ b/offline/packages/trackreco/PHTrackFitting.cc @@ -21,7 +21,6 @@ using namespace std; PHTrackFitting::PHTrackFitting(const std::string& name) : SubsysReco(name) , _cluster_map(nullptr) - , _hitsets(nullptr) , _vertex_map(nullptr) , _track_map(nullptr) , _track_map_name("SvtxTrackMap") @@ -64,13 +63,6 @@ int PHTrackFitting::GetNodes(PHCompositeNode* topNode) cout << PHWHERE << " ERROR: Can't find node TRKR_CLUSTER" << endl; return Fun4AllReturnCodes::ABORTEVENT; } - _hitsets = findNode::getClass(topNode, "TRKR_HITSET"); - if(!_hitsets) - { - std::cout << PHWHERE << "No hitset container on node tree. Bailing." - << std::endl; - return Fun4AllReturnCodes::ABORTEVENT; - } _vertex_map = findNode::getClass(topNode, "SvtxVertexMap"); if (!_vertex_map) diff --git a/offline/packages/trackreco/PHTrackFitting.h b/offline/packages/trackreco/PHTrackFitting.h index 434305c238..2819c4283a 100644 --- a/offline/packages/trackreco/PHTrackFitting.h +++ b/offline/packages/trackreco/PHTrackFitting.h @@ -53,7 +53,6 @@ class PHTrackFitting : public SubsysReco //SvtxClusterMap *_cluster_map; TrkrClusterContainer *_cluster_map; - TrkrHitSetContainer *_hitsets = nullptr; SvtxVertexMap *_vertex_map; SvtxTrackMap *_track_map; diff --git a/offline/packages/trackreco/PHTrackSeeding.cc b/offline/packages/trackreco/PHTrackSeeding.cc index 648547704d..89b79afdee 100644 --- a/offline/packages/trackreco/PHTrackSeeding.cc +++ b/offline/packages/trackreco/PHTrackSeeding.cc @@ -142,13 +142,5 @@ int PHTrackSeeding::GetNodes(PHCompositeNode* topNode) cerr << PHWHERE << " ERROR: Can't find " << _track_map_name << endl; return Fun4AllReturnCodes::ABORTEVENT; } - /* - _hitsets = findNode::getClass(topNode, "TRKR_HITSET"); - if (!_hitsets) - { - cerr << PHWHERE << " ERROR: Can't find TrkrHitSetContainer." << endl; - return Fun4AllReturnCodes::ABORTEVENT; - } - */ return Fun4AllReturnCodes::EVENT_OK; } diff --git a/simulation/g4simulation/eASTPhysicsList/Makefile.am b/simulation/g4simulation/eASTPhysicsList/Makefile.am deleted file mode 100644 index 2df119efa1..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/Makefile.am +++ /dev/null @@ -1,61 +0,0 @@ -AUTOMAKE_OPTIONS = foreign - -AM_CXXFLAGS = `geant4-config --cflags` - -lib_LTLIBRARIES = \ - libeASTPhysicsList.la - -# set in configure.in to check if gcc version >= 4.8 -# leave this here to show how it can be done, -std=c++11 is now -# enabled by default in our config.site -#if GCC_GE_48 -# AM_CXXFLAGS = -std=c++11 -#endif - -AM_CPPFLAGS = \ - -I$(includedir) \ - -I$(OFFLINE_MAIN)/include - -AM_LDFLAGS = \ - -L$(libdir) \ - -L$(OFFLINE_MAIN)/lib \ - `geant4-config --libs` - -libeASTPhysicsList_la_SOURCES = \ - eASTAntiBaryonPhysics.cc \ - eASTGammaLeptoNuclearPhysics.cc \ - eASTHyperonPhysics.cc \ - eASTIonPhysics.cc \ - eASTKaonPhysics.cc \ - eASTNeutronPhysics.cc \ - eASTPhysicsList.cc \ - eASTPhysicsListMessenger.cc \ - eASTPionPhysics.cc \ - eASTProtonPhysics.cc - -pkginclude_HEADERS = \ - eASTPhysicsList.hh - -################################################ -# linking tests - -noinst_PROGRAMS = \ - testexternals - -BUILT_SOURCES = testexternals.cc - -testexternals_SOURCES = \ - testexternals.cc - -testexternals_LDADD = \ - libeASTPhysicsList.la - -testexternals.cc: - echo "//*** this is a generated file. Do not commit, do not edit" > $@ - echo "int main()" >> $@ - echo "{" >> $@ - echo " return 0;" >> $@ - echo "}" >> $@ - -clean-local: - rm -f $(BUILT_SOURCES) diff --git a/simulation/g4simulation/eASTPhysicsList/configure.ac b/simulation/g4simulation/eASTPhysicsList/configure.ac deleted file mode 100644 index bfdbb10498..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/configure.ac +++ /dev/null @@ -1,19 +0,0 @@ -AC_INIT(eastphysicslist, [1.00]) -AC_CONFIG_SRCDIR([configure.ac]) - -AM_INIT_AUTOMAKE - -AC_PROG_CXX(CC g++) -LT_INIT([disable-static]) - -CXXFLAGS="$CXXFLAGS -Wall -Werror -Wextra -Wshadow" - -case $CXX in - clang++) - CXXFLAGS="$CXXFLAGS -Wno-final-dtor-non-final-class" - ;; -esac -dnl AM_CONDITIONAL(GCC_GE_48, test `g++ -dumpversion | awk '{print $1>=4.8?"1":"0"}'` = 1) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/simulation/g4simulation/eASTPhysicsList/eASTAntiBaryonPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTAntiBaryonPhysics.cc deleted file mode 100644 index 23593fcaa6..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTAntiBaryonPhysics.cc +++ /dev/null @@ -1,433 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTAntiBaryonPhysics.cc -// Anti-baryon hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.02.2021 : migration to Geant4 version 10.7 - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTAntiBaryonPhysics.hh" - -#include "G4ProcessManager.hh" - -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4AntiProtonInelasticProcess.hh" -#include "G4AntiNeutronInelasticProcess.hh" -#include "G4AntiLambdaInelasticProcess.hh" -#include "G4AntiSigmaPlusInelasticProcess.hh" -#include "G4AntiSigmaMinusInelasticProcess.hh" -#include "G4AntiXiZeroInelasticProcess.hh" -#include "G4AntiXiMinusInelasticProcess.hh" -#include "G4AntiOmegaMinusInelasticProcess.hh" -#include "G4AntiDeuteronInelasticProcess.hh" -#include "G4AntiTritonInelasticProcess.hh" -#include "G4AntiHe3InelasticProcess.hh" -#include "G4AntiAlphaInelasticProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#endif - -#include "G4HadronElasticProcess.hh" - -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4HadronElastic.hh" -#include "G4AntiNuclElastic.hh" -#include "G4HadronicAbsorptionFritiof.hh" - -#include "G4ChipsAntiBaryonElasticXS.hh" -#include "G4ChipsHyperonInelasticXS.hh" -#include "G4ComponentAntiNuclNuclearXS.hh" -#include "G4ChipsAntiBaryonElasticXS.hh" -#include "G4CrossSectionInelastic.hh" -#include "G4CrossSectionElastic.hh" - -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTAntiBaryonPhysics::eASTAntiBaryonPhysics() -{} - -eASTAntiBaryonPhysics::~eASTAntiBaryonPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; - - delete theAntiNucleonXS; -} -#else -eASTAntiBaryonPhysics::eASTAntiBaryonPhysics() -: G4VPhysicsConstructor("eASTAntiBaryon") -{;} - -eASTAntiBaryonPhysics::~eASTAntiBaryonPhysics() -{;} -#endif - -void eASTAntiBaryonPhysics::ConstructParticle() -{} - - -void eASTAntiBaryonPhysics::ConstructProcess() -{ - G4ProcessManager* procMan = 0; - - // One elastic model for all anti-hyperon and anti-neutron energies - G4HadronElastic* elModel = new G4HadronElastic(); - - // Elastic models for anti-(p, d, t, He3, alpha) - G4HadronElastic* loelModel = new G4HadronElastic(); - loelModel->SetMaxEnergy(100.1*MeV); - - G4AntiNuclElastic* anucEl = new G4AntiNuclElastic(); - anucEl->SetMinEnergy(100.0*MeV); - - // Use FTFP for all energies ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(0.0); - ftfp->SetMaxEnergy(100*TeV); - - // Elastic data sets - G4CrossSectionElastic* anucElxs = - new G4CrossSectionElastic(anucEl->GetComponentCrossSection() ); - G4VCrossSectionDataSet* abaryElXs = new G4ChipsAntiBaryonElasticXS; - - G4VCrossSectionDataSet* anucnucElxs = - new G4CrossSectionElastic(new G4ComponentAntiNuclNuclearXS); - - // Inelastic cross section sets - theAntiNucleonXS = new G4ComponentAntiNuclNuclearXS; - G4VCrossSectionDataSet* antiNucleonData = - new G4CrossSectionInelastic(theAntiNucleonXS); - - G4ChipsHyperonInelasticXS* hchipsInelastic = new G4ChipsHyperonInelasticXS; - - ////////////////////////////////////////////////////////////////////////////// - // Anti-proton // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiProton::AntiProton()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* apProcEl = new G4HadronElasticProcess; - apProcEl->RegisterMe(loelModel); - apProcEl->RegisterMe(anucEl); - apProcEl->AddDataSet(anucElxs); - procMan->AddDiscreteProcess(apProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiProtonInelasticProcess* apProcInel = new G4AntiProtonInelasticProcess; -#else - auto* apProcInel = new G4HadronInelasticProcess("AntiProtonInelasticProcess", - G4AntiProton::AntiProton() ); -#endif - apProcInel->RegisterMe(ftfp); - apProcInel->AddDataSet(antiNucleonData); - procMan->AddDiscreteProcess(apProcInel); - - // stopping - G4HadronicAbsorptionFritiof* apAbsorb = new G4HadronicAbsorptionFritiof(); - procMan->AddRestProcess(apAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-neutron // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiNeutron::AntiNeutron()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* anProcEl = new G4HadronElasticProcess; - anProcEl->RegisterMe(elModel); - anProcEl->AddDataSet(anucnucElxs); - procMan->AddDiscreteProcess(anProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiNeutronInelasticProcess* anProcInel = new G4AntiNeutronInelasticProcess; -#else - auto* anProcInel = new G4HadronInelasticProcess("AntiNeutronInelasticProcess", - G4AntiNeutron::AntiNeutron() ); -#endif - anProcInel->RegisterMe(ftfp); - anProcInel->AddDataSet(antiNucleonData); - procMan->AddDiscreteProcess(anProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-deuteron // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiDeuteron::AntiDeuteron()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* adProcEl = new G4HadronElasticProcess; - adProcEl->RegisterMe(loelModel); - adProcEl->RegisterMe(anucEl); - adProcEl->AddDataSet(anucElxs); - procMan->AddDiscreteProcess(adProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiDeuteronInelasticProcess* adProcInel = new G4AntiDeuteronInelasticProcess; -#else - auto* adProcInel = new G4HadronInelasticProcess("AntiDeuteronInelasticProcess", - G4AntiDeuteron::AntiDeuteron() ); -#endif - adProcInel->RegisterMe(ftfp); - adProcInel->AddDataSet(antiNucleonData); - procMan->AddDiscreteProcess(adProcInel); - - // stopping - G4HadronicAbsorptionFritiof* adAbsorb = new G4HadronicAbsorptionFritiof(); - procMan->AddRestProcess(adAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-triton // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiTriton::AntiTriton()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* atProcEl = new G4HadronElasticProcess; - atProcEl->RegisterMe(loelModel); - atProcEl->RegisterMe(anucEl); - atProcEl->AddDataSet(anucElxs); - procMan->AddDiscreteProcess(atProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiTritonInelasticProcess* atProcInel = new G4AntiTritonInelasticProcess; -#else - auto* atProcInel = new G4HadronInelasticProcess("AntiTritonInelasticProcess", - G4AntiTriton::AntiTriton() ); -#endif - atProcInel->RegisterMe(ftfp); - atProcInel->AddDataSet(antiNucleonData); - procMan->AddDiscreteProcess(atProcInel); - - // stopping - G4HadronicAbsorptionFritiof* atAbsorb = new G4HadronicAbsorptionFritiof(); - procMan->AddRestProcess(atAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-He3 // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiHe3::AntiHe3()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* ahe3ProcEl = new G4HadronElasticProcess; - ahe3ProcEl->RegisterMe(loelModel); - ahe3ProcEl->RegisterMe(anucEl); - ahe3ProcEl->AddDataSet(anucElxs); - procMan->AddDiscreteProcess(ahe3ProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiHe3InelasticProcess* ahe3ProcInel = new G4AntiHe3InelasticProcess; -#else - auto* ahe3ProcInel = new G4HadronInelasticProcess("Anti3HeInelasticProcess", - G4AntiHe3::AntiHe3() ); -#endif - ahe3ProcInel->RegisterMe(ftfp); - ahe3ProcInel->AddDataSet(antiNucleonData); - procMan->AddDiscreteProcess(ahe3ProcInel); - - // stopping - G4HadronicAbsorptionFritiof* ahe3Absorb = new G4HadronicAbsorptionFritiof(); - procMan->AddRestProcess(ahe3Absorb); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-alpha // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiAlpha::AntiAlpha()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* aaProcEl = new G4HadronElasticProcess; - aaProcEl->RegisterMe(loelModel); - aaProcEl->RegisterMe(anucEl); - aaProcEl->AddDataSet(anucElxs); - procMan->AddDiscreteProcess(aaProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiAlphaInelasticProcess* aaProcInel = new G4AntiAlphaInelasticProcess; -#else - auto* aaProcInel = new G4HadronInelasticProcess("AntiAlphaInelasticProcess", - G4AntiAlpha::AntiAlpha() ); -#endif - aaProcInel->RegisterMe(ftfp); - aaProcInel->AddDataSet(antiNucleonData); - procMan->AddDiscreteProcess(aaProcInel); - - // stopping - G4HadronicAbsorptionFritiof* aaAbsorb = new G4HadronicAbsorptionFritiof(); - procMan->AddRestProcess(aaAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-lambda // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiLambda::AntiLambda()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* alamProcEl = new G4HadronElasticProcess; - alamProcEl->RegisterMe(elModel); - alamProcEl->AddDataSet(abaryElXs); - procMan->AddDiscreteProcess(alamProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiLambdaInelasticProcess* alamProcInel = new G4AntiLambdaInelasticProcess; -#else - auto* alamProcInel = new G4HadronInelasticProcess("AntiLambdaInelasticProcess", - G4AntiLambda::AntiLambda() ); -#endif - alamProcInel->RegisterMe(ftfp); - alamProcInel->AddDataSet(hchipsInelastic); - procMan->AddDiscreteProcess(alamProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-sigma+ // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiSigmaPlus::AntiSigmaPlus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* aspProcEl = new G4HadronElasticProcess; - aspProcEl->RegisterMe(elModel); - aspProcEl->AddDataSet(abaryElXs); - procMan->AddDiscreteProcess(aspProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiSigmaPlusInelasticProcess* aspProcInel = new G4AntiSigmaPlusInelasticProcess; -#else - auto* aspProcInel = new G4HadronInelasticProcess("AntiSigmaPInelasticProcess", - G4AntiSigmaPlus::AntiSigmaPlus() ); -#endif - aspProcInel->RegisterMe(ftfp); - aspProcInel->AddDataSet(hchipsInelastic); - procMan->AddDiscreteProcess(aspProcInel); - - // stopping - G4HadronicAbsorptionFritiof* aspAbsorb = new G4HadronicAbsorptionFritiof(); - procMan->AddRestProcess(aspAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-sigma- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiSigmaMinus::AntiSigmaMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* asmProcEl = new G4HadronElasticProcess; - asmProcEl->RegisterMe(elModel); - asmProcEl->AddDataSet(abaryElXs); - procMan->AddDiscreteProcess(asmProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiSigmaMinusInelasticProcess* asmProcInel = new G4AntiSigmaMinusInelasticProcess; -#else - auto* asmProcInel = new G4HadronInelasticProcess("AntiSigmaMInelasticProcess", - G4AntiSigmaMinus::AntiSigmaMinus() ); -#endif - asmProcInel->RegisterMe(ftfp); - asmProcInel->AddDataSet(hchipsInelastic); - procMan->AddDiscreteProcess(asmProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-xi0 // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiXiZero::AntiXiZero()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* axzProcEl = new G4HadronElasticProcess; - axzProcEl->RegisterMe(elModel); - axzProcEl->AddDataSet(abaryElXs); - procMan->AddDiscreteProcess(axzProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiXiZeroInelasticProcess* axzProcInel = new G4AntiXiZeroInelasticProcess; -#else - auto* axzProcInel = new G4HadronInelasticProcess("AntiXi0InelasticProcess", - G4AntiXiZero::AntiXiZero() ); -#endif - axzProcInel->RegisterMe(ftfp); - axzProcInel->AddDataSet(hchipsInelastic); - procMan->AddDiscreteProcess(axzProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-xi- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiXiMinus::AntiXiMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* axmProcEl = new G4HadronElasticProcess; - axmProcEl->RegisterMe(elModel); - axmProcEl->AddDataSet(abaryElXs); - procMan->AddDiscreteProcess(axmProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiXiMinusInelasticProcess* axmProcInel = new G4AntiXiMinusInelasticProcess; -#else - auto* axmProcInel = new G4HadronInelasticProcess("AntiXiMInelasticProcess", - G4AntiXiMinus::AntiXiMinus() ); -#endif - axmProcInel->RegisterMe(ftfp); - axmProcInel->AddDataSet(hchipsInelastic); - procMan->AddDiscreteProcess(axmProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Anti-omega- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4AntiOmegaMinus::AntiOmegaMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* aomProcEl = new G4HadronElasticProcess; - aomProcEl->RegisterMe(elModel); - aomProcEl->AddDataSet(abaryElXs); - procMan->AddDiscreteProcess(aomProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4AntiOmegaMinusInelasticProcess* aomProcInel = new G4AntiOmegaMinusInelasticProcess; -#else - auto* aomProcInel = new G4HadronInelasticProcess("AntiOmegaMInelasticProcess", - G4AntiOmegaMinus::AntiOmegaMinus() ); -#endif - aomProcInel->RegisterMe(ftfp); - aomProcInel->AddDataSet(hchipsInelastic); - procMan->AddDiscreteProcess(aomProcInel); - -} - -void eASTAntiBaryonPhysics::TerminateWorker() -{} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTAntiBaryonPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTAntiBaryonPhysics.hh deleted file mode 100644 index c8957c8336..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTAntiBaryonPhysics.hh +++ /dev/null @@ -1,43 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTAntiBaryonPhysics.hh -// Anti-baryon hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTAntiBaryonPhysics_h -#define eASTAntiBaryonPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; -class G4ComponentAntiNuclNuclearXS; - -class eASTAntiBaryonPhysics: public G4VPhysicsConstructor -{ - public: - eASTAntiBaryonPhysics(); - ~eASTAntiBaryonPhysics(); - - virtual void ConstructParticle() override; - virtual void ConstructProcess() override; - virtual void TerminateWorker() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - - G4ComponentAntiNuclNuclearXS* theAntiNucleonXS = nullptr; -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTGammaLeptoNuclearPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTGammaLeptoNuclearPhysics.cc deleted file mode 100644 index 5722df185f..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTGammaLeptoNuclearPhysics.cc +++ /dev/null @@ -1,134 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTGammaLeptoNuclearPhysics.cc -// Description: Gamma-nuclear, electro-nuclear and muon-nuclear physics -// constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTGammaLeptoNuclearPhysics.hh" - -#include "G4ProcessManager.hh" -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4PhotoNuclearProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#include "G4PhotoNuclearCrossSection.hh" -#include "G4HadronicProcess.hh" -#endif -#include "G4ElectronNuclearProcess.hh" -#include "G4PositronNuclearProcess.hh" -#include "G4MuonNuclearProcess.hh" - -#include "G4CascadeInterface.hh" -#include "G4ElectroVDNuclearModel.hh" -#include "G4MuonVDNuclearModel.hh" - -#include "G4TheoFSGenerator.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4QGSMFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" - -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTGammaLeptoNuclearPhysics::eASTGammaLeptoNuclearPhysics() -{} - -eASTGammaLeptoNuclearPhysics::~eASTGammaLeptoNuclearPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; -} -#else -eASTGammaLeptoNuclearPhysics::eASTGammaLeptoNuclearPhysics() -: G4VPhysicsConstructor("eASTGammaLeptoNuclear") -{;} - -eASTGammaLeptoNuclearPhysics::~eASTGammaLeptoNuclearPhysics() -{;} -#endif - -void eASTGammaLeptoNuclearPhysics::ConstructProcess() -{ - // Use Bertini cascade for low energies - G4CascadeInterface* theGammaReaction = new G4CascadeInterface; - theGammaReaction->SetMinEnergy(0.0); - theGammaReaction->SetMaxEnergy(3.5*GeV); - - // Use QGSP for high energies - qgsp = new G4TheoFSGenerator("QGSP"); - stringModel = new G4QGSModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4QGSMFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - qgsp->SetHighEnergyGenerator(stringModel); - qgsp->SetTransport(preCompoundModel); - qgsp->SetMinEnergy(3*GeV); - qgsp->SetMaxEnergy(100*TeV); - - // Lepto-nuclear models - G4ElectroVDNuclearModel* evdn = new G4ElectroVDNuclearModel; - G4MuonVDNuclearModel* mvdn = new G4MuonVDNuclearModel; - - - G4ProcessManager* procMan = 0; - - // Gamma - procMan = G4Gamma::Gamma()->GetProcessManager(); -#if G4VERSION_NUMBER < 1100 - G4PhotoNuclearProcess* pnProc = new G4PhotoNuclearProcess; -#else - auto* pnProc = new G4HadronInelasticProcess("PhotoNuclearProcess", - G4Gamma::Gamma() ); - pnProc->AddDataSet(new G4PhotoNuclearCrossSection); -#endif - pnProc->RegisterMe(theGammaReaction); - pnProc->RegisterMe(qgsp); - procMan->AddDiscreteProcess(pnProc); - -//#if G4VERSION_NUMBER >= 1100 -// auto* photonCapture = new G4HadronicProcess( "photonNuclear", fCapture ); -// auto* photonFission = new G4HadronicProcess( "photonFission", fFission ); -// procMan->AddDiscreteProcess(photonCapture); -// procMan->AddDiscreteProcess(photonFission); -//#endif - - // Electron - procMan = G4Electron::Electron()->GetProcessManager(); - G4ElectronNuclearProcess* emn = new G4ElectronNuclearProcess; - emn->RegisterMe(evdn); - procMan->AddDiscreteProcess(emn); - - // Positron - procMan = G4Positron::Positron()->GetProcessManager(); - G4PositronNuclearProcess* epn = new G4PositronNuclearProcess; - epn->RegisterMe(evdn); - procMan->AddDiscreteProcess(epn); - - // Muon- - procMan = G4MuonMinus::MuonMinus()->GetProcessManager(); - G4MuonNuclearProcess* mun = new G4MuonNuclearProcess; - mun->RegisterMe(mvdn); - procMan->AddDiscreteProcess(mun); - - // Muon+ - procMan = G4MuonPlus::MuonPlus()->GetProcessManager(); - procMan->AddDiscreteProcess(mun); - -} - - -void eASTGammaLeptoNuclearPhysics::ConstructParticle() -{} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTGammaLeptoNuclearPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTGammaLeptoNuclearPhysics.hh deleted file mode 100644 index 4f01426a58..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTGammaLeptoNuclearPhysics.hh +++ /dev/null @@ -1,43 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTGammaLeptoNuclearPhysics.hh -// Description: Gamma-nuclear, electro-nuclear and muon-nuclear physics -// constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTGammaLeptoNuclearPhysics_h -#define eASTGammaLeptoNuclearPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" -#include "G4GammaParticipants.hh" -#include "G4QGSModel.hh" - -class G4TheoFSGenerator; -class G4ExcitedStringDecay; -class G4QGSMFragmentation; -class G4GeneratorPrecompoundInterface; - - -class eASTGammaLeptoNuclearPhysics: public G4VPhysicsConstructor -{ - public: - eASTGammaLeptoNuclearPhysics(); - ~eASTGammaLeptoNuclearPhysics(); - - virtual void ConstructProcess() override; - virtual void ConstructParticle() override; - - private: - G4TheoFSGenerator* qgsp = nullptr; - G4QGSModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4QGSMFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTHyperonPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTHyperonPhysics.cc deleted file mode 100644 index b658f01aef..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTHyperonPhysics.cc +++ /dev/null @@ -1,257 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTHyperonPhysics.cc -// Hyperon hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.02.2021 : migration to Geant4 version 10.7 - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTHyperonPhysics.hh" - -#include "G4ProcessManager.hh" -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4LambdaInelasticProcess.hh" -#include "G4SigmaPlusInelasticProcess.hh" -#include "G4SigmaMinusInelasticProcess.hh" -#include "G4XiZeroInelasticProcess.hh" -#include "G4XiMinusInelasticProcess.hh" -#include "G4OmegaMinusInelasticProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#endif - -#include "G4HadronElasticProcess.hh" -#include "G4HadronicAbsorptionBertini.hh" - -#include "G4CascadeInterface.hh" -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4HadronElastic.hh" - -#include "G4ChipsHyperonElasticXS.hh" -#include "G4ChipsHyperonInelasticXS.hh" -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTHyperonPhysics::eASTHyperonPhysics() -{} - -eASTHyperonPhysics::~eASTHyperonPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; -} -#else -eASTHyperonPhysics::eASTHyperonPhysics() -: G4VPhysicsConstructor("eASTHyperon") -{;} - -eASTHyperonPhysics::~eASTHyperonPhysics() -{;} -#endif - -void eASTHyperonPhysics::ConstructParticle() -{} - - -void eASTHyperonPhysics::ConstructProcess() -{ - G4ProcessManager* procMan = 0; - - // One elastic model for all hyperon energies - G4HadronElastic* elModel = new G4HadronElastic(); - - // Use Bertini cascade for low energies - G4CascadeInterface* loInelModel = new G4CascadeInterface; - loInelModel->SetMinEnergy(0.0); - loInelModel->SetMaxEnergy(6.0*GeV); - - // Use FTFP for high energies ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(4*GeV); - ftfp->SetMaxEnergy(100*TeV); - - // Elastic and inelastic cross section sets - G4ChipsHyperonElasticXS* chipsElastic = new G4ChipsHyperonElasticXS; - G4ChipsHyperonInelasticXS* chipsInelastic = new G4ChipsHyperonInelasticXS; - - ////////////////////////////////////////////////////////////////////////////// - // Lambda // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4Lambda::Lambda()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* lamProcEl = new G4HadronElasticProcess; - lamProcEl->RegisterMe(elModel); - lamProcEl->AddDataSet(chipsElastic); - procMan->AddDiscreteProcess(lamProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4LambdaInelasticProcess* lamProcInel = new G4LambdaInelasticProcess; -#else - auto* lamProcInel = new G4HadronInelasticProcess("LambdaInelasticProcess", - G4Lambda::Lambda() ); -#endif - lamProcInel->RegisterMe(loInelModel); - lamProcInel->RegisterMe(ftfp); - lamProcInel->AddDataSet(chipsInelastic); - procMan->AddDiscreteProcess(lamProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Sigma+ // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4SigmaPlus::SigmaPlus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* spProcEl = new G4HadronElasticProcess; - spProcEl->RegisterMe(elModel); - spProcEl->AddDataSet(chipsElastic); - procMan->AddDiscreteProcess(spProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4SigmaPlusInelasticProcess* spProcInel = new G4SigmaPlusInelasticProcess; -#else - auto* spProcInel = new G4HadronInelasticProcess("SigmaPlusInelasticProcess", - G4SigmaPlus::SigmaPlus() ); -#endif - spProcInel->RegisterMe(loInelModel); - spProcInel->RegisterMe(ftfp); - spProcInel->AddDataSet(chipsInelastic); - procMan->AddDiscreteProcess(spProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Sigma- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4SigmaMinus::SigmaMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* smProcEl = new G4HadronElasticProcess; - smProcEl->RegisterMe(elModel); - smProcEl->AddDataSet(chipsElastic); - procMan->AddDiscreteProcess(smProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4SigmaMinusInelasticProcess* smProcInel = new G4SigmaMinusInelasticProcess; -#else - auto* smProcInel = new G4HadronInelasticProcess("SigmaMinusInelasticProcess", - G4SigmaMinus::SigmaMinus() ); -#endif - smProcInel->RegisterMe(loInelModel); - smProcInel->RegisterMe(ftfp); - smProcInel->AddDataSet(chipsInelastic); - procMan->AddDiscreteProcess(smProcInel); - - // stopping - G4HadronicAbsorptionBertini* smAbsorb = new G4HadronicAbsorptionBertini; - procMan->AddRestProcess(smAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Xi0 // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4XiZero::XiZero()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* xzProcEl = new G4HadronElasticProcess; - xzProcEl->RegisterMe(elModel); - xzProcEl->AddDataSet(chipsElastic); - procMan->AddDiscreteProcess(xzProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4XiZeroInelasticProcess* xzProcInel = new G4XiZeroInelasticProcess; -#else - auto* xzProcInel = new G4HadronInelasticProcess("XiZeroInelasticProcess", - G4XiZero::XiZero() ); -#endif - xzProcInel->RegisterMe(loInelModel); - xzProcInel->RegisterMe(ftfp); - xzProcInel->AddDataSet(chipsInelastic); - procMan->AddDiscreteProcess(xzProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Xi- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4XiMinus::XiMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* xmProcEl = new G4HadronElasticProcess; - xmProcEl->RegisterMe(elModel); - xmProcEl->AddDataSet(chipsElastic); - procMan->AddDiscreteProcess(xmProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4XiMinusInelasticProcess* xmProcInel = new G4XiMinusInelasticProcess; -#else - auto* xmProcInel = new G4HadronInelasticProcess("XiMinusInelasticProcess", - G4XiMinus::XiMinus() ); -#endif - xmProcInel->RegisterMe(loInelModel); - xmProcInel->RegisterMe(ftfp); - xmProcInel->AddDataSet(chipsInelastic); - procMan->AddDiscreteProcess(xmProcInel); - - // stopping - G4HadronicAbsorptionBertini* xmAbsorb = new G4HadronicAbsorptionBertini; - procMan->AddRestProcess(xmAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // Omega- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4OmegaMinus::OmegaMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* omProcEl = new G4HadronElasticProcess; - omProcEl->RegisterMe(elModel); - omProcEl->AddDataSet(chipsElastic); - procMan->AddDiscreteProcess(omProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4OmegaMinusInelasticProcess* omProcInel = new G4OmegaMinusInelasticProcess; -#else - auto* omProcInel = new G4HadronInelasticProcess("OmegaMinusInelasticProcess", - G4OmegaMinus::OmegaMinus() ); -#endif - omProcInel->RegisterMe(loInelModel); - omProcInel->RegisterMe(ftfp); - omProcInel->AddDataSet(chipsInelastic); - procMan->AddDiscreteProcess(omProcInel); - - // stopping - G4HadronicAbsorptionBertini* omAbsorb = new G4HadronicAbsorptionBertini; - procMan->AddRestProcess(omAbsorb); - -} - -void eASTHyperonPhysics::TerminateWorker() -{} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTHyperonPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTHyperonPhysics.hh deleted file mode 100644 index 9991dbb0cc..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTHyperonPhysics.hh +++ /dev/null @@ -1,42 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTHyperonPhysics.hh -// Hyperon hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTHyperonPhysics_h -#define eASTHyperonPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; - - -class eASTHyperonPhysics: public G4VPhysicsConstructor -{ - public: - eASTHyperonPhysics(); - ~eASTHyperonPhysics(); - - virtual void ConstructParticle() override; - virtual void ConstructProcess() override; - virtual void TerminateWorker() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTIonPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTIonPhysics.cc deleted file mode 100644 index 3ba6c62214..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTIonPhysics.cc +++ /dev/null @@ -1,206 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTIonPhysics.cc -// Ion hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTIonPhysics.hh" - -#include "G4ProcessManager.hh" -#include "G4HadronElasticProcess.hh" -#include "G4HadronInelasticProcess.hh" - -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4QMDReaction.hh" -#include "G4HadronicInteractionRegistry.hh" -#include "G4PreCompoundModel.hh" -#include "G4BinaryLightIonReaction.hh" -#include "G4HadronElastic.hh" -#include "G4NuclNuclDiffuseElastic.hh" - -#include "G4CrossSectionElastic.hh" -#include "G4CrossSectionInelastic.hh" -#include "G4ComponentGGNuclNuclXsc.hh" -#include "G4SystemOfUnits.hh" - -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -eASTIonPhysics::eASTIonPhysics() -{} - -eASTIonPhysics::~eASTIonPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; - - delete theGGNuclNuclXS; - delete ionGGXS; -} -#else -eASTIonPhysics::eASTIonPhysics() -: G4VPhysicsConstructor("eASTIon") -{;} - -eASTIonPhysics::~eASTIonPhysics() -{;} -#endif - -void eASTIonPhysics::ConstructParticle() -{} - - -void eASTIonPhysics::ConstructProcess() -{ - G4ProcessManager* procMan = 0; - - // Elastic model for generic ions (z > 2) - G4NuclNuclDiffuseElastic* ionElastic = new G4NuclNuclDiffuseElastic; - ionElastic->SetMinEnergy(0.0); - - // FTFP ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(10.01*GeV); - ftfp->SetMaxEnergy(1.0*TeV); - - // QMD model - G4QMDReaction* qmd = new G4QMDReaction; - qmd->SetMinEnergy(100.0*MeV); - qmd->SetMaxEnergy(10.0*GeV); - - // BIC ion model - G4HadronicInteraction* p = - G4HadronicInteractionRegistry::Instance()->FindModel("PRECO"); - G4PreCompoundModel* thePreCompound = static_cast(p); - if(!thePreCompound) { thePreCompound = new G4PreCompoundModel; } - - G4BinaryLightIonReaction* ionBC = new G4BinaryLightIonReaction(thePreCompound); - ionBC->SetMinEnergy(0.0*MeV); - ionBC->SetMaxEnergy(110.0*MeV); - - // Elastic cross section set - ionGGXS = new G4ComponentGGNuclNuclXsc; - G4VCrossSectionDataSet* ionElasticXS = new G4CrossSectionElastic(ionGGXS); - ionElasticXS->SetMinKinEnergy(0.0); - - // Inelastic cross section set - theGGNuclNuclXS = new G4ComponentGGNuclNuclXsc(); - G4VCrossSectionDataSet* nuclNuclXS = - new G4CrossSectionInelastic(theGGNuclNuclXS); - - ////////////////////////////////////////////////////////////////////////////// - // Deuteron // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4Deuteron::Deuteron()->GetProcessManager(); - - // elastic - // no model available - - // inelastic - G4HadronInelasticProcess* deutProcInel = - new G4HadronInelasticProcess("DeuteronInelProcess", G4Deuteron::Deuteron() ); - deutProcInel->RegisterMe(ionBC); - deutProcInel->RegisterMe(qmd); - deutProcInel->RegisterMe(ftfp); - deutProcInel->AddDataSet(nuclNuclXS); - procMan->AddDiscreteProcess(deutProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Triton // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4Triton::Triton()->GetProcessManager(); - - // elastic - // no model available - - // inelastic - G4HadronInelasticProcess* tritProcInel = - new G4HadronInelasticProcess("TritonInelProcess", G4Triton::Triton() ); - tritProcInel->RegisterMe(ionBC); - tritProcInel->RegisterMe(qmd); - tritProcInel->RegisterMe(ftfp); - tritProcInel->AddDataSet(nuclNuclXS); - procMan->AddDiscreteProcess(tritProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // He3 // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4He3::He3()->GetProcessManager(); - - // elastic - // no model available - - // inelastic - G4HadronInelasticProcess* he3ProcInel = - new G4HadronInelasticProcess("He3InelProcess", G4He3::He3() ); - he3ProcInel->RegisterMe(ionBC); - he3ProcInel->RegisterMe(qmd); - he3ProcInel->RegisterMe(ftfp); - he3ProcInel->AddDataSet(nuclNuclXS); - procMan->AddDiscreteProcess(he3ProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Alpha // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4Alpha::Alpha()->GetProcessManager(); - - // elastic - // no model available - - // inelastic - G4HadronInelasticProcess* alphProcInel = - new G4HadronInelasticProcess("AlphaInelProcess", G4Alpha::Alpha() ); - alphProcInel->RegisterMe(ionBC); - alphProcInel->RegisterMe(qmd); - alphProcInel->RegisterMe(ftfp); - alphProcInel->AddDataSet(nuclNuclXS); - procMan->AddDiscreteProcess(alphProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // Generic ion // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4GenericIon::GenericIon()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* ionProcEl = new G4HadronElasticProcess; - ionProcEl->RegisterMe(ionElastic); - ionProcEl->AddDataSet(ionElasticXS); - procMan->AddDiscreteProcess(ionProcEl); - - // inelastic - G4HadronInelasticProcess* genIonProcInel = - new G4HadronInelasticProcess("IonInelProcess", G4GenericIon::GenericIon() ); - genIonProcInel->RegisterMe(ionBC); - genIonProcInel->RegisterMe(qmd); - genIonProcInel->RegisterMe(ftfp); - genIonProcInel->AddDataSet(nuclNuclXS); - procMan->AddDiscreteProcess(genIonProcInel); - -} - -void eASTIonPhysics::TerminateWorker() -{} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTIonPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTIonPhysics.hh deleted file mode 100644 index f712cc695c..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTIonPhysics.hh +++ /dev/null @@ -1,46 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTIonPhysics.hh -// Ion hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTIonPhysics_h -#define eASTIonPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; -class G4VComponentCrossSection; -class G4ComponentGGNuclNuclXsc; - - -class eASTIonPhysics: public G4VPhysicsConstructor -{ - public: - eASTIonPhysics(); - ~eASTIonPhysics(); - - virtual void ConstructParticle() override; - virtual void ConstructProcess() override; - virtual void TerminateWorker() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - - G4VComponentCrossSection* theGGNuclNuclXS = nullptr; - G4ComponentGGNuclNuclXsc* ionGGXS = nullptr; -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTKaonPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTKaonPhysics.cc deleted file mode 100644 index 17216cebf4..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTKaonPhysics.cc +++ /dev/null @@ -1,205 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTKaonPhysics.hh -// Kaon hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.02.2021 : migration to Genat4 version 10.7 - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTKaonPhysics.hh" - -#include "G4ProcessManager.hh" -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4KaonPlusInelasticProcess.hh" -#include "G4KaonMinusInelasticProcess.hh" -#include "G4KaonZeroLInelasticProcess.hh" -#include "G4KaonZeroSInelasticProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#endif -#include "G4HadronElasticProcess.hh" -#include "G4HadronicAbsorptionBertini.hh" - -#include "G4CascadeInterface.hh" -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4HadronElastic.hh" - -#include "G4ChipsKaonPlusInelasticXS.hh" -#include "G4ChipsKaonMinusInelasticXS.hh" -#include "G4ChipsKaonZeroInelasticXS.hh" -#include "G4CrossSectionElastic.hh" -#include "G4ComponentGGHadronNucleusXsc.hh" -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTKaonPhysics::eASTKaonPhysics() -{} - -eASTKaonPhysics::~eASTKaonPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; -} -#else -eASTKaonPhysics::eASTKaonPhysics() -: G4VPhysicsConstructor("eASTKaon") -{;} - -eASTKaonPhysics::~eASTKaonPhysics() -{;} -#endif - -void eASTKaonPhysics::ConstructParticle() -{} - - -void eASTKaonPhysics::ConstructProcess() -{ - G4ProcessManager* procMan; - - // One elastic model for all kaon energies - G4HadronElastic* elModel = new G4HadronElastic(); - - // Use Bertini cascade for low energies - G4CascadeInterface* loInelModel = new G4CascadeInterface; - loInelModel->SetMinEnergy(0.0); - loInelModel->SetMaxEnergy(12.0*GeV); - - // Use FTFP for high energies ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(10*GeV); - ftfp->SetMaxEnergy(100*TeV); - - // Inelastic cross section sets - G4VCrossSectionDataSet* kpCS = new G4ChipsKaonPlusInelasticXS; - G4VCrossSectionDataSet* kmCS = new G4ChipsKaonMinusInelasticXS; - G4VCrossSectionDataSet* kzCS = new G4ChipsKaonZeroInelasticXS; - - // Elastic cross section - G4VCrossSectionDataSet* kelCS = - new G4CrossSectionElastic(new G4ComponentGGHadronNucleusXsc); - - ////////////////////////////////////////////////////////////////////////////// - // K+ // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4KaonPlus::KaonPlus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* kpProcEl = new G4HadronElasticProcess; - kpProcEl->RegisterMe(elModel); - kpProcEl->AddDataSet(kelCS); - procMan->AddDiscreteProcess(kpProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4KaonPlusInelasticProcess* kpProcInel = new G4KaonPlusInelasticProcess; -#else - auto* kpProcInel = new G4HadronInelasticProcess("KaonPlusInelasticProcess", - G4KaonPlus::KaonPlus() ); -#endif - kpProcInel->RegisterMe(loInelModel); - kpProcInel->RegisterMe(ftfp); - kpProcInel->AddDataSet(kpCS); - procMan->AddDiscreteProcess(kpProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // K- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4KaonMinus::KaonMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* kmProcEl = new G4HadronElasticProcess; - kmProcEl->RegisterMe(elModel); - kmProcEl->AddDataSet(kelCS); - procMan->AddDiscreteProcess(kmProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4KaonMinusInelasticProcess* kmProcInel = new G4KaonMinusInelasticProcess; -#else - auto* kmProcInel = new G4HadronInelasticProcess("KaonMinusInelasticProcess", - G4KaonMinus::KaonMinus() ); -#endif - kmProcInel->RegisterMe(loInelModel); - kmProcInel->RegisterMe(ftfp); - kmProcInel->AddDataSet(kmCS); - procMan->AddDiscreteProcess(kmProcInel); - - // stopping - G4HadronicAbsorptionBertini* bertAbsorb = new G4HadronicAbsorptionBertini; - procMan->AddRestProcess(bertAbsorb); - - ////////////////////////////////////////////////////////////////////////////// - // K0L // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4KaonZeroLong::KaonZeroLong()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* k0LProcEl = new G4HadronElasticProcess; - k0LProcEl->RegisterMe(elModel); - k0LProcEl->AddDataSet(kelCS); - procMan->AddDiscreteProcess(k0LProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4KaonZeroLInelasticProcess* k0LProcInel = new G4KaonZeroLInelasticProcess; -#else - auto* k0LProcInel = new G4HadronInelasticProcess("Kaon0LongInelasticProcess", - G4KaonZeroLong::KaonZeroLong() ); -#endif - k0LProcInel->RegisterMe(loInelModel); - k0LProcInel->RegisterMe(ftfp); - k0LProcInel->AddDataSet(kzCS); - procMan->AddDiscreteProcess(k0LProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // K0S // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4KaonZeroShort::KaonZeroShort()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* k0SProcEl = new G4HadronElasticProcess; - k0SProcEl->RegisterMe(elModel); - k0SProcEl->AddDataSet(kelCS); - procMan->AddDiscreteProcess(k0SProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4KaonZeroSInelasticProcess* k0SProcInel = new G4KaonZeroSInelasticProcess; -#else - auto* k0SProcInel = new G4HadronInelasticProcess("Kaon0ShortInelasticProcess", - G4KaonZeroShort::KaonZeroShort() ); -#endif - k0SProcInel->RegisterMe(loInelModel); - k0SProcInel->RegisterMe(ftfp); - k0SProcInel->AddDataSet(kzCS); - procMan->AddDiscreteProcess(k0SProcInel); -} - -void eASTKaonPhysics::TerminateWorker() -{} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTKaonPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTKaonPhysics.hh deleted file mode 100644 index 23e103e547..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTKaonPhysics.hh +++ /dev/null @@ -1,42 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTKaonPhysics.hh -// Kaon hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTKaonPhysics_h -#define eASTKaonPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; - - -class eASTKaonPhysics: public G4VPhysicsConstructor -{ - public: - eASTKaonPhysics(); - ~eASTKaonPhysics(); - - virtual void ConstructParticle() override; - virtual void ConstructProcess() override; - virtual void TerminateWorker() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTNeutronPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTNeutronPhysics.cc deleted file mode 100644 index 5d6ec14c96..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTNeutronPhysics.cc +++ /dev/null @@ -1,136 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTNeutronPhysics.cc -// Neutron hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTNeutronPhysics.hh" - -#include "G4ProcessManager.hh" -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4NeutronInelasticProcess.hh" -#include "G4HadronCaptureProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#include "G4NeutronCaptureProcess.hh" -#endif -#include "G4HadronElasticProcess.hh" -#include "G4NeutronKiller.hh" - -#include "G4CascadeInterface.hh" -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4ChipsElasticModel.hh" -#include "G4NeutronRadCapture.hh" - -#include "G4BGGNucleonInelasticXS.hh" -#include "G4NeutronElasticXS.hh" -#include "G4NeutronCaptureXS.hh" - -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTNeutronPhysics::eASTNeutronPhysics() -{ -} - -eASTNeutronPhysics::~eASTNeutronPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; -} -#else -eASTNeutronPhysics::eASTNeutronPhysics() -: G4VPhysicsConstructor("eASTNeutron") -{;} - -eASTNeutronPhysics::~eASTNeutronPhysics() -{;} -#endif - -void eASTNeutronPhysics::ConstructParticle() -{} - - -void eASTNeutronPhysics::ConstructProcess() -{ - // Low energy elastic model - G4ChipsElasticModel* elMod = new G4ChipsElasticModel(); - - // Use Bertini cascade for low energies - G4CascadeInterface* loInelModel = new G4CascadeInterface; - loInelModel->SetMinEnergy(0.0); - loInelModel->SetMaxEnergy(12.0*GeV); - - // Capture model - G4NeutronRadCapture* capModel = new G4NeutronRadCapture(); - - // Use FTFP for high energies ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(5*GeV); - ftfp->SetMaxEnergy(100*TeV); - - // Cross section sets - G4BGGNucleonInelasticXS* inelCS = new G4BGGNucleonInelasticXS(G4Neutron::Neutron() ); - G4NeutronElasticXS* elCS = new G4NeutronElasticXS; - G4NeutronCaptureXS* capCS = new G4NeutronCaptureXS; - - G4ProcessManager* procMan = G4Neutron::Neutron()->GetProcessManager(); - - // Elastic process - G4HadronElasticProcess* nProcEl = new G4HadronElasticProcess; - nProcEl->RegisterMe(elMod); - nProcEl->AddDataSet(elCS); - procMan->AddDiscreteProcess(nProcEl); - - // Inelastic process -#if G4VERSION_NUMBER < 1100 - G4NeutronInelasticProcess* nProcInel = new G4NeutronInelasticProcess; -#else - auto* nProcInel = new G4HadronInelasticProcess("NeutronInelasticProcess", - G4Neutron::Neutron() ); -#endif - nProcInel->RegisterMe(loInelModel); - nProcInel->RegisterMe(ftfp); - nProcInel->AddDataSet(inelCS); - procMan->AddDiscreteProcess(nProcInel); - - // Capture process -#if G4VERSION_NUMBER < 1100 - G4HadronCaptureProcess* nProcCap = new G4HadronCaptureProcess("nCapture"); -#else - auto* nProcCap = new G4NeutronCaptureProcess("nCapture"); -#endif - nProcCap->RegisterMe(capModel); - nProcCap->AddDataSet(capCS); - procMan->AddDiscreteProcess(nProcCap); - - // Neutron cut (kill neutrons that live too long or have too little energy) - G4NeutronKiller* nKiller = new G4NeutronKiller(); - nKiller->SetKinEnergyLimit(0.0*MeV); - nKiller->SetTimeLimit(10.*microsecond); - procMan->AddDiscreteProcess(nKiller); - -} - - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTNeutronPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTNeutronPhysics.hh deleted file mode 100644 index 84edc65ac3..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTNeutronPhysics.hh +++ /dev/null @@ -1,41 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTNeutronPhysics.hh -// Neutron hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTNeutronPhysics_h -#define eASTNeutronPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; - - -class eASTNeutronPhysics: public G4VPhysicsConstructor -{ - public: - eASTNeutronPhysics(); - ~eASTNeutronPhysics(); - - virtual void ConstructParticle() override; - virtual void ConstructProcess() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsList.cc b/simulation/g4simulation/eASTPhysicsList/eASTPhysicsList.cc deleted file mode 100644 index 25cda95f86..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsList.cc +++ /dev/null @@ -1,254 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTPhysicsList.cc -// Geant4 physics list for Electron Ion Collider detector simulation -// -// History -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.05.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - -#include "eASTPhysicsList.hh" -#include "eASTPhysicsListMessenger.hh" - -#include "G4SystemOfUnits.hh" -#include "G4UnitsTable.hh" -#include "G4ProcessTable.hh" -#include "G4RegionStore.hh" - -#include "G4EmStandardPhysics.hh" -#include "G4EmExtraPhysics.hh" -#include "G4EmParameters.hh" -#include "G4HadronicParameters.hh" -#include "G4DecayPhysics.hh" -#include "G4NuclideTable.hh" - -#include "G4RadioactiveDecayPhysics.hh" -#include "G4OpticalPhysics.hh" -#include "G4StepLimiterPhysics.hh" - -#include "eASTProtonPhysics.hh" -#include "eASTNeutronPhysics.hh" -#include "eASTPionPhysics.hh" -#include "eASTKaonPhysics.hh" -#include "eASTHyperonPhysics.hh" -#include "eASTAntiBaryonPhysics.hh" -#include "eASTIonPhysics.hh" -#include "eASTGammaLeptoNuclearPhysics.hh" - -// particles - -#include "G4BosonConstructor.hh" -#include "G4LeptonConstructor.hh" -#include "G4MesonConstructor.hh" -#include "G4BaryonConstructor.hh" -#include "G4IonConstructor.hh" -#include "G4ShortLivedConstructor.hh" - -#include "G4Version.hh" - -eASTPhysicsList::eASTPhysicsList(G4int verb) - :G4VModularPhysicsList() -{ - SetVerboseLevel(verb); - - //add new units for radioActive decays - // - new G4UnitDefinition( "millielectronVolt", "meV", "Energy", 1.e-3*eV); - // -#if G4VERSION_NUMBER < 1100 - const G4double minute = 60*second; - const G4double hour = 60*minute; - const G4double day = 24*hour; - const G4double year = 365*day; - new G4UnitDefinition("minute", "min", "Time", minute); - new G4UnitDefinition("hour", "h", "Time", hour); - new G4UnitDefinition("day", "d", "Time", day); - new G4UnitDefinition("year", "y", "Time", year); -#endif - - // Mandatory for G4NuclideTable - // Half-life threshold must be set small or many short-lived isomers - // will not be assigned life times (default to 0) - G4NuclideTable::GetInstance()->SetThresholdOfHalfLife(0.1*picosecond); - G4NuclideTable::GetInstance()->SetLevelTolerance(1.0*eV); - - globalCuts[2] = 0.7*mm; //gamma - globalCuts[0] = 0.7*mm; //e- - globalCuts[1] = 0.7*mm; //e+ - globalCuts[3] = 0.7*mm; //proton - - pMessenger = new eASTPhysicsListMessenger(this); -} - - -eASTPhysicsList::~eASTPhysicsList() -{ delete pMessenger; } - -void eASTPhysicsList::ConstructParticle() -{ - if(!processesAreRegistered) SetupProcesses(); - - G4BosonConstructor pBosonConstructor; - pBosonConstructor.ConstructParticle(); - - G4LeptonConstructor pLeptonConstructor; - pLeptonConstructor.ConstructParticle(); - - G4MesonConstructor pMesonConstructor; - pMesonConstructor.ConstructParticle(); - - G4BaryonConstructor pBaryonConstructor; - pBaryonConstructor.ConstructParticle(); - - G4IonConstructor pIonConstructor; - pIonConstructor.ConstructParticle(); - - G4ShortLivedConstructor pShortLivedConstructor; - pShortLivedConstructor.ConstructParticle(); -} - -void eASTPhysicsList::SetupProcesses() -{ - // EM physics - RegisterPhysics(new G4EmStandardPhysics()); - G4EmParameters* param = G4EmParameters::Instance(); - param->SetAugerCascade(true); - param->SetStepFunction(1., 1.*CLHEP::mm); - param->SetStepFunctionMuHad(1., 1.*CLHEP::mm); - - // Decay - RegisterPhysics(new G4DecayPhysics()); - - // Radioactive decay - if(addRDM) - { RegisterPhysics(new G4RadioactiveDecayPhysics()); } - - // Hadronic physics - RegisterPhysics(new eASTProtonPhysics() ); - RegisterPhysics(new eASTNeutronPhysics() ); - RegisterPhysics(new eASTPionPhysics() ); - RegisterPhysics(new eASTKaonPhysics() ); - RegisterPhysics(new eASTHyperonPhysics() ); - RegisterPhysics(new eASTAntiBaryonPhysics() ); - RegisterPhysics(new eASTIonPhysics() ); - RegisterPhysics(new eASTGammaLeptoNuclearPhysics() ); - - // Optical physics - if(addOptical) - { RegisterPhysics(new G4OpticalPhysics() ); } - - // Step limiter - if(stepLimit_opt>=0) - { RegisterPhysics(new G4StepLimiterPhysics()); } - - processesAreRegistered = true; -} - -void eASTPhysicsList::ConstructProcess() -{ - auto verbose = G4ProcessTable::GetProcessTable()->GetVerboseLevel(); - SetVerboseLevel(verbose); - G4EmParameters::Instance()->SetVerbose(verbose); - -#if G4VERSION_NUMBER >= 1100 - G4HadronicParameters::Instance()->SetVerboseLevel(verbose); -#endif - G4VModularPhysicsList::ConstructProcess(); -} - -void eASTPhysicsList::SetCuts() -{ - SetCutValue(globalCuts[2],"gamma"); // gamma should be defined first! - SetCutValue(globalCuts[0],"e-"); - SetCutValue(globalCuts[1],"e+"); - SetCutValue(globalCuts[3],"proton"); -} - -G4Region* eASTPhysicsList::FindRegion(const G4String& reg) const -{ - auto store = G4RegionStore::GetInstance(); - return store->GetRegion(reg); -} - -void eASTPhysicsList::SetGlobalCuts(G4double val) -{ - for(G4int i=0; i<4; i++) - { SetGlobalCut(i,val); } - SetCuts(); -} - -void eASTPhysicsList::SetGlobalCut(G4int i, G4double val) -{ - globalCuts[i] = val; - SetCuts(); -} - -G4Region* eASTPhysicsList::SetLocalCut(const G4String& reg,G4int i,G4double val) -{ - auto regPtr = FindRegion(reg); - if(!regPtr) return regPtr; - - auto cuts = regPtr->GetProductionCuts(); - if(!cuts) - { - cuts = new G4ProductionCuts(); - regPtr->SetProductionCuts(cuts); - } - - cuts->SetProductionCut(val,i); - return regPtr; -} - -G4double eASTPhysicsList::GetLocalCut(const G4String& reg,G4int i) const -{ - auto regPtr = FindRegion(reg); - G4double val = -1.0; - if(regPtr) - { - auto cuts = regPtr->GetProductionCuts(); - if(cuts) val = cuts->GetProductionCut(i); - } - return val; -} - -#include "G4UserLimits.hh" - -G4Region* eASTPhysicsList::SetLocalStepLimit(const G4String& reg,G4double val) -{ - auto regPtr = FindRegion(reg); - if(!regPtr) return regPtr; - - auto uLim = regPtr->GetUserLimits(); - if(!uLim) - { - uLim = new G4UserLimits(val); - regPtr->SetUserLimits(uLim); - } - else - { uLim->SetMaxAllowedStep(val); } - return regPtr; -} - -#include "G4Track.hh" -G4double eASTPhysicsList::GetLocalStepLimit(const G4String& reg) const -{ - static G4Track dummyTrack; - auto regPtr = FindRegion(reg); - G4double val = -1.0; - if(regPtr) - { - auto uLim = regPtr->GetUserLimits(); - if(uLim) val = uLim->GetMaxAllowedStep(dummyTrack); - } - return val; -} - -void eASTPhysicsList::SetGlobalStepLimit(G4double val) -{ SetLocalStepLimit("DefaultRegionForTheWorld",val); } - -G4double eASTPhysicsList::GetGlobalStepLimit() const -{ return GetLocalStepLimit("DefaultRegionForTheWorld"); } - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsList.hh b/simulation/g4simulation/eASTPhysicsList/eASTPhysicsList.hh deleted file mode 100644 index 4b40f9c839..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsList.hh +++ /dev/null @@ -1,87 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTPhysicsList.hh -// Geant4 physics list for Electron Ion Collider detector simulation -// -// History -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTPhysicsList_h -#define eASTPhysicsList_h 1 - -#include "G4VModularPhysicsList.hh" -#include "globals.hh" - -class eASTPhysicsListMessenger; -class G4Region; -class G4ProductionCuts; - -#include - -class eASTPhysicsList: public G4VModularPhysicsList -{ - public: - eASTPhysicsList(G4int verb=0); - ~eASTPhysicsList(); - - virtual void ConstructParticle(); - virtual void ConstructProcess(); - virtual void SetCuts(); - - private: - void SetupProcesses(); - - private: - G4bool processesAreRegistered = false; - eASTPhysicsListMessenger* pMessenger; - - //G4bool addHP = false; // add Neutron_HP - G4bool addRDM = false; // add Radioactive Decay Module - G4bool addOptical = false; // add optical physics - - G4int stepLimit_opt = -1; // step limiter option (0:charged, 1:neutral, 2:all, 3:e+/e-) - std::map localStepLimits; // map of region name and limit value - G4double globalCuts[4]; // for e-, e+ gamma, proton - std::map localCuts; // map of region name and cuts - - public: - // Neutron_HP needs further implementation - //void AddHP(G4bool val = true) { addHP = val; } - //G4bool IfHP() const { return addHP; } - void AddRDM(G4bool val = true) { addRDM = val; } - G4bool IfRDM() const { return addRDM; } - void AddOptical(G4bool val = true) { addOptical = val; } - G4bool IfOptical() const { return addOptical; } - - void AddStepLimit(G4int val = 0) { stepLimit_opt = val; } - G4int IfStepLimit() const { return stepLimit_opt; } - void SetGlobalStepLimit(G4double); - G4double GetGlobalStepLimit() const; - G4Region* SetLocalStepLimit(const G4String&,G4double); - G4double GetLocalStepLimit(const G4String&) const; - void SetGlobalCuts(G4double); - G4double GetGlobalCuts() const { return GetGlobalCut(0); } - void SetGlobalCut(G4int, G4double); - G4double GetGlobalCut(G4int i) const { return globalCuts[i]; } - G4Region* SetLocalCuts(const G4String& reg,G4double val) - { - G4Region* regPtr = nullptr; - for(G4int i=0; i<4; i++) - { - regPtr = SetLocalCut(reg,i,val); - if(!regPtr) return regPtr; - } - return regPtr; - } - G4double GetLocalCuts(const G4String& reg) const { return GetLocalCut(reg,0); } - G4Region* SetLocalCut(const G4String&,G4int,G4double); - G4double GetLocalCut(const G4String&,G4int) const; - - private: - G4Region* FindRegion(const G4String&) const; -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsListMessenger.cc b/simulation/g4simulation/eASTPhysicsList/eASTPhysicsListMessenger.cc deleted file mode 100644 index 756542fd79..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsListMessenger.cc +++ /dev/null @@ -1,286 +0,0 @@ -// ******************************************************************** -// -// eASTPhysicsListMessenger.cc -// A messenger class that handles physics list options. -// -// History -// September 8th, 2020 : first implementation -// -// ******************************************************************** - -#include "eASTPhysicsListMessenger.hh" - -#include "eASTPhysicsList.hh" -#include "G4UIcommand.hh" -#include "G4UIparameter.hh" -#include "G4UIdirectory.hh" -#include "G4UIcmdWithAString.hh" -#include "G4UIcmdWithADoubleAndUnit.hh" -#include "G4UIcmdWithoutParameter.hh" - -eASTPhysicsListMessenger::eASTPhysicsListMessenger(eASTPhysicsList* pl) -: pPL(pl) -{ - G4UIparameter* param = nullptr; - - physDir = new G4UIdirectory("/eAST/physics/"); - physDir->SetGuidance("eAST physics selection"); - - //addHPCmd = new G4UIcmdWithoutParameter("/eAST/physics/addHP",this); - //addHPCmd->AvailableForStates(G4State_PreInit); - //addHPCmd->SetToBeBroadcasted(false); - //addHPCmd->SetGuidance("Add High-Precision neutron model."); - //addHPCmd->SetGuidance(" Note: Shielding option has already had HP. This command does not make effect to Shielding option."); - - addRDMCmd = new G4UIcmdWithoutParameter("/eAST/physics/addRDM",this); - addRDMCmd->AvailableForStates(G4State_PreInit); - addRDMCmd->SetToBeBroadcasted(false); - addRDMCmd->SetGuidance("Add Radioactive Decay model."); - addRDMCmd->SetGuidance(" Note: Shielding option has already had RDM. This command does not make effect to Shielding option."); - - addOpticalCmd = new G4UIcmdWithoutParameter("/eAST/physics/addOptical",this); - addOpticalCmd->AvailableForStates(G4State_PreInit); - addOpticalCmd->SetToBeBroadcasted(false); - addOpticalCmd->SetGuidance("Add Optical physics"); - - addStepLimitCmd = new G4UIcmdWithAString("/eAST/physics/addStepLimit",this); - addStepLimitCmd->AvailableForStates(G4State_PreInit); - addStepLimitCmd->SetToBeBroadcasted(false); - addStepLimitCmd->SetGuidance("Add step-limiter process to artificially limit step length."); - addStepLimitCmd->SetGuidance("Specify particle types to be applied."); - addStepLimitCmd->SetGuidance(" charged (default) : applied only to the charged particles"); - addStepLimitCmd->SetGuidance(" neutral : applied only to the neutral particles"); - addStepLimitCmd->SetGuidance(" all : applied to all particle types"); - addStepLimitCmd->SetGuidance(" e+/- : applied only to e+/e-"); - addStepLimitCmd->SetGuidance(" Note: In addition to this command, you need to specify the limitation value by"); - addStepLimitCmd->SetGuidance(" /eAST/physics/limit/stepLimit or /eAST/physics/limit/localStepLimt command."); - addStepLimitCmd->SetParameterName("particle",true); - addStepLimitCmd->SetDefaultValue("charged"); - addStepLimitCmd->SetCandidates("charged neutral all e+/-"); - - physLimitDir = new G4UIdirectory("/eAST/physics/limit/"); - physLimitDir->SetGuidance("Specify step limitation"); - - setStepLimitCmd = new G4UIcmdWithADoubleAndUnit("/eAST/physics/limit/stepLimit",this); - setStepLimitCmd->AvailableForStates(G4State_Idle); - setStepLimitCmd->SetToBeBroadcasted(false); - setStepLimitCmd->SetParameterName("length",false); - setStepLimitCmd->SetDefaultUnit("mm"); - setStepLimitCmd->SetGuidance("Define the limitation of the step length"); - setStepLimitCmd->SetGuidance("This limitation is applied to the entire geometry except regions that has its dedicated limit."); - - setRegionStepLimitCmd = new G4UIcommand("/eAST/physics/limit/regionStepLimit",this); - setRegionStepLimitCmd->AvailableForStates(G4State_Idle); - setRegionStepLimitCmd->SetToBeBroadcasted(false); - setRegionStepLimitCmd->SetGuidance("Define the limitation of the step length for the specified region"); - setRegionStepLimitCmd->SetGuidance(" [usage] /eAST/physics/limit/regionStepLimit region length [unit]"); - setRegionStepLimitCmd->SetGuidance(" region (string) : region name"); - setRegionStepLimitCmd->SetGuidance(" Note: Region has to be defined in advance to this command."); - setRegionStepLimitCmd->SetGuidance(" If new region is necessary, use /eAST/geometry/createRegion to create it."); - param = new G4UIparameter("region",'s',false); - setRegionStepLimitCmd->SetParameter(param); - param = new G4UIparameter("length",'d',false); - setRegionStepLimitCmd->SetParameter(param); - param = new G4UIparameter("unit",'s',true); - param->SetDefaultUnit("mm"); - setRegionStepLimitCmd->SetParameter(param); - - physCutDir = new G4UIdirectory("/eAST/physics/cuts/"); - physCutDir->SetGuidance("Specify production thresholds (a.k.a. cuts)"); - - setCutCmd = new G4UIcmdWithADoubleAndUnit("/eAST/physics/cuts/setCuts",this); - setCutCmd->AvailableForStates(G4State_PreInit, G4State_Idle); - setCutCmd->SetToBeBroadcasted(false); - setCutCmd->SetParameterName("length",false); - setCutCmd->SetDefaultUnit("mm"); - setCutCmd->SetGuidance("Specify production thresholds (a.k.a. cuts) that is applied to the entire geometry"); - setCutCmd->SetGuidance("This threshold is applied to all of e-, e+, gamma and proton."); - setCutCmd->SetGuidance("Threshold of each particle can be overwitted by /eAST/physics/cuts/setParticleCut command"); - - setCutParticleCmd = new G4UIcommand("/eAST/physics/cuts/setParticleCut",this); - setCutParticleCmd->AvailableForStates(G4State_PreInit, G4State_Idle); - setCutParticleCmd->SetToBeBroadcasted(false); - setCutParticleCmd->SetGuidance("Specify production threshold (a.k.a. cut) for the specified particle that is applied to the entire geometry"); - setCutParticleCmd->SetGuidance(" [usage] /eAST/physics/setParticleCut particle cut unit"); - param = new G4UIparameter("particle",'s',false); - param->SetParameterCandidates("e- e+ gamma proton"); - setCutParticleCmd->SetParameter(param); - param = new G4UIparameter("cut",'d',false); - setCutParticleCmd->SetParameter(param); - param = new G4UIparameter("unit",'s',true); - param->SetDefaultUnit("mm"); - setCutParticleCmd->SetParameter(param); - - setCutRegionCmd = new G4UIcommand("/eAST/physics/cuts/setRegionCut",this); - setCutRegionCmd->AvailableForStates(G4State_Idle); - setCutRegionCmd->SetToBeBroadcasted(false); - setCutRegionCmd->SetGuidance("Specify production threshold (a.k.a. cut) that is applied to the specified region"); - setCutRegionCmd->SetGuidance(" [usage] /eAST/physics/setRegionCut region cut unit"); - setCutRegionCmd->SetGuidance("This threshold is applied to all of e-, e+, gamma and proton."); - setCutRegionCmd->SetGuidance("Threshold of each particle can be overwitted by /eAST/physics/cuts/setRegionParticleCut command"); - setCutRegionCmd->SetGuidance(" Note: Region has to be defined in advance to this command."); - setCutRegionCmd->SetGuidance(" If new region is necessary, use /eAST/geometry/createRegion to create it."); - param = new G4UIparameter("region",'s',false); - setCutRegionCmd->SetParameter(param); - param = new G4UIparameter("cut",'d',false); - setCutRegionCmd->SetParameter(param); - param = new G4UIparameter("unit",'s',true); - param->SetDefaultUnit("mm"); - setCutRegionCmd->SetParameter(param); - - setCutRegionParticleCmd = new G4UIcommand("/eAST/physics/cuts/setRegionParticleCut",this); - setCutRegionParticleCmd->AvailableForStates(G4State_Idle); - setCutRegionParticleCmd->SetToBeBroadcasted(false); - setCutRegionParticleCmd->SetGuidance("Specify production threshold (a.k.a. cut) that is applied to the specified region"); - setCutRegionParticleCmd->SetGuidance(" [usage] /eAST/physics/setRegionParticleCut region particle cut unit"); - setCutRegionParticleCmd->SetGuidance(" Note: Region has to be defined in advance to this command."); - setCutRegionParticleCmd->SetGuidance(" If new region is necessary, use /eAST/geometry/createRegion to create it."); - param = new G4UIparameter("region",'s',false); - setCutRegionParticleCmd->SetParameter(param); - param = new G4UIparameter("particle",'s',false); - param->SetParameterCandidates("e- e+ gamma proton"); - setCutRegionParticleCmd->SetParameter(param); - param = new G4UIparameter("cut",'d',false); - setCutRegionParticleCmd->SetParameter(param); - param = new G4UIparameter("unit",'s',true); - param->SetDefaultUnit("mm"); - setCutRegionParticleCmd->SetParameter(param); - -} - -eASTPhysicsListMessenger::~eASTPhysicsListMessenger() -{ - //delete addHPCmd; - delete addRDMCmd; - delete addOpticalCmd; - delete addStepLimitCmd; - delete setStepLimitCmd; - delete setRegionStepLimitCmd; - delete setCutCmd; - delete setCutParticleCmd; - delete setCutRegionCmd; - delete setCutRegionParticleCmd; - - delete physLimitDir; - delete physCutDir; - delete physDir; -} - -#include "G4Tokenizer.hh" - -void eASTPhysicsListMessenger::SetNewValue(G4UIcommand* cmd, G4String val) -{ - //if(cmd==addHPCmd) - //{ pPL->AddHP(); } - //else - if(cmd==addRDMCmd) - { pPL->AddRDM(); } - else if(cmd==addOpticalCmd) - { pPL->AddOptical(); } - else if(cmd==addStepLimitCmd) - { - G4int opt = 0; - if(val=="neutral") opt = 1; - else if(val=="all") opt = 2; - else if(val=="e+/-") opt = 3; - pPL->AddStepLimit(opt); - } - else if(cmd==setStepLimitCmd) - { pPL->SetGlobalStepLimit(setStepLimitCmd->GetNewDoubleValue(val)); } - else if(cmd==setRegionStepLimitCmd) - { - G4Tokenizer next(val); - G4String reg = next(); - G4String newVal = next(); - newVal += " "; - newVal += next(); - auto regPtr = pPL->SetLocalStepLimit(reg,setRegionStepLimitCmd->ConvertToDimensionedDouble(newVal)); - if(!regPtr) - { - G4ExceptionDescription ed; - ed << "Region <" << reg << "> is not defined."; - setRegionStepLimitCmd->CommandFailed(ed); - } - } - else if(cmd==setCutCmd) - { pPL->SetGlobalCuts(setCutCmd->GetNewDoubleValue(val)); } - else if(cmd==setCutParticleCmd) - { - G4Tokenizer next(val); - G4String pat = next(); - G4String newVal = next(); - newVal += " "; - newVal += next(); - G4int i = 0; - if(pat=="e-") i = 0; - else if(pat=="e+") i = 1; - else if(pat=="gamma") i = 2; - else if(pat=="proton") i = 3; - pPL->SetGlobalCut(i,setCutParticleCmd->ConvertToDimensionedDouble(newVal)); - } - else if(cmd==setCutRegionCmd) - { - G4Tokenizer next(val); - G4String reg = next(); - G4String newVal = next(); - newVal += " "; - newVal += next(); - auto regPtr = pPL->SetLocalCuts(reg,setCutRegionCmd->ConvertToDimensionedDouble(newVal)); - if(!regPtr) - { - G4ExceptionDescription ed; - ed << "Region <" << reg << "> is not defined."; - setRegionStepLimitCmd->CommandFailed(ed); - } - } - else if(cmd==setCutRegionParticleCmd) - { - G4Tokenizer next(val); - G4String reg = next(); - G4String pat = next(); - G4int i = 0; - if(pat=="e-") i = 0; - else if(pat=="e+") i = 1; - else if(pat=="gamma") i = 2; - else if(pat=="proton") i = 3; - G4String newVal = next(); - newVal += " "; - newVal += next(); - auto regPtr = pPL->SetLocalCut(reg,i,setCutRegionParticleCmd->ConvertToDimensionedDouble(newVal)); - if(!regPtr) - { - G4ExceptionDescription ed; - ed << "Region <" << reg << "> is not defined."; - setRegionStepLimitCmd->CommandFailed(ed); - } - } - -} - -G4String eASTPhysicsListMessenger::GetCurrentValue(G4UIcommand* cmd) -{ - G4String val(""); - - //if(cmd==addHPCmd) - //{ val = cmd->ConvertToString(pPL->IfHP()); } - //else - if(cmd==addRDMCmd) - { val = cmd->ConvertToString(pPL->IfRDM()); } - else if(cmd==addOpticalCmd) - { val = cmd->ConvertToString(pPL->IfOptical()); } - else if(cmd==addStepLimitCmd) - { - auto opt = pPL->IfStepLimit(); - switch(opt) - { - case 0: val = "charged"; break; - case 1: val = "neutral"; break; - case 2: val = "all"; break; - case 3: val = "e+/-"; break; - default : val = "undefined"; break; - } - } - return val; -} - - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsListMessenger.hh b/simulation/g4simulation/eASTPhysicsList/eASTPhysicsListMessenger.hh deleted file mode 100644 index 6bf16e71ae..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTPhysicsListMessenger.hh +++ /dev/null @@ -1,53 +0,0 @@ -// ******************************************************************** -// -// eASTPhysicsListMessenger.hh -// Header file of a messenger class that handles physics options. -// -// History -// May 8th, 2021 : first implementation -// -// ******************************************************************** - -#ifndef eASTPhysicsListMessenger_H -#define eASTPhysicsListMessenger_H 1 - -#include "G4UImessenger.hh" -#include "globals.hh" - -class eASTPhysicsList; -class G4UIcommand; -class G4UIdirectory; -class G4UIcmdWithAString; -class G4UIcmdWithADoubleAndUnit; -class G4UIcmdWithoutParameter; - -class eASTPhysicsListMessenger: public G4UImessenger -{ - public: - eASTPhysicsListMessenger(eASTPhysicsList*); - virtual ~eASTPhysicsListMessenger(); - virtual void SetNewValue(G4UIcommand*,G4String); - virtual G4String GetCurrentValue(G4UIcommand*); - - private: - eASTPhysicsList* pPL; - G4UIdirectory* physDir; - //G4UIcmdWithoutParameter* addHPCmd; - G4UIcmdWithoutParameter* addRDMCmd; - G4UIcmdWithoutParameter* addOpticalCmd; - G4UIcmdWithAString* addStepLimitCmd; - - G4UIdirectory* physLimitDir; - G4UIcmdWithADoubleAndUnit* setStepLimitCmd; - G4UIcommand* setRegionStepLimitCmd; - - G4UIdirectory* physCutDir; - G4UIcmdWithADoubleAndUnit* setCutCmd; - G4UIcommand* setCutParticleCmd; - G4UIcommand* setCutRegionCmd; - G4UIcommand* setCutRegionParticleCmd; - -}; - -#endif - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTPionPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTPionPhysics.cc deleted file mode 100644 index 6cab5086da..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTPionPhysics.cc +++ /dev/null @@ -1,151 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTPionPhysics.hh -// Pion hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.02.2021 : migration to Geant4 version 10.7 - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTPionPhysics.hh" -#include "G4MesonConstructor.hh" - -#include "G4ProcessManager.hh" -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4PionPlusInelasticProcess.hh" -#include "G4PionMinusInelasticProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#endif -#include "G4HadronElasticProcess.hh" -#include "G4HadronicAbsorptionBertini.hh" - -#include "G4CascadeInterface.hh" -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4HadronElastic.hh" -#include "G4ElasticHadrNucleusHE.hh" - -#include "G4BGGPionElasticXS.hh" -#include "G4BGGPionInelasticXS.hh" - -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTPionPhysics::eASTPionPhysics() -{} - -eASTPionPhysics::~eASTPionPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; -} -#else -eASTPionPhysics::eASTPionPhysics() -: G4VPhysicsConstructor("eASTPion") -{;} - -eASTPionPhysics::~eASTPionPhysics() -{;} -#endif - -void eASTPionPhysics::ConstructParticle() -{} - - -void eASTPionPhysics::ConstructProcess() -{ - G4ProcessManager* procMan; - - // Low energy elastic model - G4HadronElastic* loElModel = new G4HadronElastic(); - loElModel->SetMaxEnergy(1.0001*GeV); - - // High energy elastic model - G4ElasticHadrNucleusHE* hiElModel = new G4ElasticHadrNucleusHE(); - hiElModel->SetMinEnergy(1.0*GeV); - - // Use Bertini cascade for low energies - G4CascadeInterface* loInelModel = new G4CascadeInterface; - loInelModel->SetMinEnergy(0.0); - loInelModel->SetMaxEnergy(12.0*GeV); - - // Use FTFP for high energies ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(10*GeV); - ftfp->SetMaxEnergy(100*TeV); - - ////////////////////////////////////////////////////////////////////////////// - // pi+ // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4PionPlus::PionPlus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* pipProcEl = new G4HadronElasticProcess; - pipProcEl->RegisterMe(loElModel); - pipProcEl->RegisterMe(hiElModel); - pipProcEl->AddDataSet(new G4BGGPionElasticXS(G4PionPlus::PionPlus() ) ); - procMan->AddDiscreteProcess(pipProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4PionPlusInelasticProcess* pipProcInel = new G4PionPlusInelasticProcess; -#else - auto* pipProcInel = new G4HadronInelasticProcess("PionPlusInelasticProcess", - G4PionPlus::PionPlus() ); -#endif - pipProcInel->RegisterMe(loInelModel); - pipProcInel->RegisterMe(ftfp); - pipProcInel->AddDataSet(new G4BGGPionInelasticXS(G4PionPlus::PionPlus() ) ); - procMan->AddDiscreteProcess(pipProcInel); - - ////////////////////////////////////////////////////////////////////////////// - // pi- // - ////////////////////////////////////////////////////////////////////////////// - - procMan = G4PionMinus::PionMinus()->GetProcessManager(); - - // elastic - G4HadronElasticProcess* pimProcEl = new G4HadronElasticProcess; - pimProcEl->RegisterMe(loElModel); - pimProcEl->RegisterMe(hiElModel); - pimProcEl->AddDataSet(new G4BGGPionElasticXS(G4PionMinus::PionMinus() ) ); - procMan->AddDiscreteProcess(pimProcEl); - - // inelastic -#if G4VERSION_NUMBER < 1100 - G4PionMinusInelasticProcess* pimProcInel = new G4PionMinusInelasticProcess; -#else - auto* pimProcInel = new G4HadronInelasticProcess("PionMinusInelasticProcess", - G4PionMinus::PionMinus() ); -#endif - pimProcInel->RegisterMe(loInelModel); - pimProcInel->RegisterMe(ftfp); - pimProcInel->AddDataSet(new G4BGGPionInelasticXS(G4PionMinus::PionMinus() ) ); - procMan->AddDiscreteProcess(pimProcInel); - - // stopping - G4HadronicAbsorptionBertini* bertAbsorb = new G4HadronicAbsorptionBertini; - procMan->AddRestProcess(bertAbsorb); - -} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTPionPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTPionPhysics.hh deleted file mode 100644 index 3fa3b77533..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTPionPhysics.hh +++ /dev/null @@ -1,41 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTPionPhysics.hh -// Pion hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTPionPhysics_h -#define eASTPionPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; - - -class eASTPionPhysics: public G4VPhysicsConstructor -{ - public: - eASTPionPhysics(); - ~eASTPionPhysics(); - - virtual void ConstructParticle() override; - virtual void ConstructProcess() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - -}; - -#endif diff --git a/simulation/g4simulation/eASTPhysicsList/eASTProtonPhysics.cc b/simulation/g4simulation/eASTPhysicsList/eASTProtonPhysics.cc deleted file mode 100644 index d17755cd38..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTProtonPhysics.cc +++ /dev/null @@ -1,109 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTProtonPhysics.cc -// Proton hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// Dec.22.2021 : migration to Geant4 version 11.0 - Makoto Asai (JLab) -// -//////////////////////////////////////////////////////////////////////////////// - - -#include "eASTProtonPhysics.hh" - -#include "G4ProcessManager.hh" -#include "G4Version.hh" -#if G4VERSION_NUMBER < 1100 -#include "G4ProtonInelasticProcess.hh" -#else -#include "G4HadronInelasticProcess.hh" -#endif -#include "G4HadronElasticProcess.hh" - -#include "G4CascadeInterface.hh" -#include "G4TheoFSGenerator.hh" -#include "G4FTFModel.hh" -#include "G4ExcitedStringDecay.hh" -#include "G4LundStringFragmentation.hh" -#include "G4GeneratorPrecompoundInterface.hh" -#include "G4ChipsElasticModel.hh" - -#include "G4BGGNucleonInelasticXS.hh" -#include "G4ChipsProtonElasticXS.hh" - -#include "G4SystemOfUnits.hh" - -#if G4VERSION_NUMBER < 1100 -eASTProtonPhysics::eASTProtonPhysics() -{} - -eASTProtonPhysics::~eASTProtonPhysics() -{ - delete stringDecay; - delete stringModel; - delete fragModel; - delete preCompoundModel; -} -#else -eASTProtonPhysics::eASTProtonPhysics() -: G4VPhysicsConstructor("eASTProton") -{;} - -eASTProtonPhysics::~eASTProtonPhysics() -{;} -#endif - -void eASTProtonPhysics::ConstructProcess() -{ - // Low energy elastic model - G4ChipsElasticModel* elMod = new G4ChipsElasticModel(); - - // Use Bertini cascade for low energies - G4CascadeInterface* loInelModel = new G4CascadeInterface; - loInelModel->SetMinEnergy(0.0); - loInelModel->SetMaxEnergy(12.0*GeV); - - // Use FTFP for high energies ==>> eventually replace this with new class FTFPInterface - ftfp = new G4TheoFSGenerator("FTFP"); - stringModel = new G4FTFModel; - stringDecay = - new G4ExcitedStringDecay(fragModel = new G4LundStringFragmentation); - stringModel->SetFragmentationModel(stringDecay); - preCompoundModel = new G4GeneratorPrecompoundInterface(); - - ftfp->SetHighEnergyGenerator(stringModel); - ftfp->SetTransport(preCompoundModel); - ftfp->SetMinEnergy(5*GeV); - ftfp->SetMaxEnergy(100*TeV); - - // Inelastic cross section - G4BGGNucleonInelasticXS* inelCS = new G4BGGNucleonInelasticXS(G4Proton::Proton() ); - G4ChipsProtonElasticXS* elCS = new G4ChipsProtonElasticXS; - - G4ProcessManager* procMan = G4Proton::Proton()->GetProcessManager(); - - // Elastic process - G4HadronElasticProcess* pProcEl = new G4HadronElasticProcess; - pProcEl->RegisterMe(elMod); - pProcEl->AddDataSet(elCS); - procMan->AddDiscreteProcess(pProcEl); - - // Inelastic process -#if G4VERSION_NUMBER < 1100 - G4ProtonInelasticProcess* pProcInel = new G4ProtonInelasticProcess; -#else - auto* pProcInel = new G4HadronInelasticProcess("ProtonInelasticProcess", - G4Proton::Proton() ); -#endif - pProcInel->RegisterMe(loInelModel); - pProcInel->RegisterMe(ftfp); - pProcInel->AddDataSet(inelCS); - procMan->AddDiscreteProcess(pProcInel); - -} - - -void eASTProtonPhysics::ConstructParticle() -{} - diff --git a/simulation/g4simulation/eASTPhysicsList/eASTProtonPhysics.hh b/simulation/g4simulation/eASTPhysicsList/eASTProtonPhysics.hh deleted file mode 100644 index 5057fb6a39..0000000000 --- a/simulation/g4simulation/eASTPhysicsList/eASTProtonPhysics.hh +++ /dev/null @@ -1,41 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// eASTProtonPhysics.hh -// Proton hadronic physics constructor for eASTPhysicsList -// -// Jun.21.2018 : original implementation - Dennis H. Wright (SLAC) -// May.06.2021 : migration to eAST - Makoto Asai (SLAC) -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef eASTProtonPhysics_h -#define eASTProtonPhysics_h 1 - -#include "G4VPhysicsConstructor.hh" - -class G4TheoFSGenerator; -class G4FTFModel; -class G4ExcitedStringDecay; -class G4LundStringFragmentation; -class G4GeneratorPrecompoundInterface; - - -class eASTProtonPhysics: public G4VPhysicsConstructor -{ - public: - eASTProtonPhysics(); - ~eASTProtonPhysics(); - - virtual void ConstructProcess() override; - virtual void ConstructParticle() override; - - private: - G4TheoFSGenerator* ftfp = nullptr; - G4FTFModel* stringModel = nullptr; - G4ExcitedStringDecay* stringDecay = nullptr; - G4LundStringFragmentation* fragModel = nullptr; - G4GeneratorPrecompoundInterface* preCompoundModel = nullptr; - -}; - -#endif diff --git a/simulation/g4simulation/g4bbc/BbcDigitization.cc b/simulation/g4simulation/g4bbc/BbcDigitization.cc new file mode 100644 index 0000000000..e52ea226fd --- /dev/null +++ b/simulation/g4simulation/g4bbc/BbcDigitization.cc @@ -0,0 +1,277 @@ +#include "BbcDigitization.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +//____________________________________ +BbcDigitization::BbcDigitization(const std::string &name) + : SubsysReco(name) + , _tres(0.05) +{ + std::fill(std::begin(f_pmtq), std::end(f_pmtq), std::numeric_limits::quiet_NaN()); + std::fill(std::begin(f_pmtt0), std::end(f_pmtt0), std::numeric_limits::quiet_NaN()); + std::fill(std::begin(f_pmtt1), std::end(f_pmtt1), std::numeric_limits::quiet_NaN()); + m_RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937); + m_Seed = PHRandomSeed(); // fixed seed is handled in this funtcion + gsl_rng_set(m_RandomGenerator, m_Seed); +} + +BbcDigitization::~BbcDigitization() +{ + gsl_rng_free(m_RandomGenerator); + return; +} + +//___________________________________ +int BbcDigitization::Init(PHCompositeNode *topNode) +{ + // std::cout << PHWHERE << std::endl; + CreateNodes(topNode); + + _pdg = new TDatabasePDG(); // database of PDG info on particles + + gaussian = new TF1("gaussian", "gaus", 0, 20); + gaussian->FixParameter(2, _tres); // set sigma to timing resolution + + return 0; +} + +//___________________________________ +int BbcDigitization::InitRun(PHCompositeNode *topNode) +{ + GetNodes(topNode); + + return 0; +} + +//__________________________________ +// Call user instructions for every event +int BbcDigitization::process_event(PHCompositeNode * /*topNode*/) +{ + //**** Initialize Variables + + // PMT data + float len[128] = {0.}; + float edep[128] = {0.}; + float first_time[128]; // First hit time for each tube + std::fill_n(first_time, 128, 1e12); + std::fill_n(f_pmtt0, 128, 1e12); + std::fill_n(f_pmtt1, 128, 1e12); + std::fill_n(f_pmtq, 128, 0.); + + // Get True Vertex + // NB: Currently PrimaryVertexIndex is always 1, need to figure out how to handle collision pile-up + PHG4VtxPoint *vtxp = _truth_container->GetPrimaryVtx(_truth_container->GetPrimaryVertexIndex()); + if (vtxp != nullptr) + { + f_vx = vtxp->get_x(); + f_vy = vtxp->get_y(); + f_vz = vtxp->get_z(); + f_vt = vtxp->get_t(); + + if (Verbosity()) + { + std::cout << "VTXP " + << "\t" << f_vx << "\t" << f_vy << "\t" << f_vz << "\t" << f_vt << std::endl; + } + } + + // Go through BBC G4 hits + + TLorentzVector v4; + unsigned int nhits = 0; + + PHG4HitContainer::ConstRange bbc_hit_range = _bbchits->getHits(); + for (auto hit_iter = bbc_hit_range.first; hit_iter != bbc_hit_range.second; hit_iter++) + { + PHG4Hit *this_hit = hit_iter->second; + + unsigned int ch = this_hit->get_layer(); // pmt channel + // int arm = ch/64;; // south=0, north=1 + + int trkid = this_hit->get_trkid(); + // if ( trkid>0 && f_evt<20 ) std::cout << "TRKID " << trkid << std::endl; + + PHG4Particle *part = _truth_container->GetParticle(trkid); + v4.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); + + int pid = part->get_pid(); + TParticlePDG *partinfo = _pdg->GetParticle(pid); + Double_t charge = -9999.; + if (partinfo) + { + charge = partinfo->Charge() / 3; // PDG gives charge in 1/3 e + } + else if (part->isIon()) + { + charge = part->get_IonCharge(); + } + + // get the first time + if (this_hit->get_t(1) < first_time[ch]) + { + if (fabs(this_hit->get_t(1)) < 106.5) + { + first_time[ch] = this_hit->get_t(1) - vtxp->get_t(); + Float_t dt = gsl_ran_gaussian(m_RandomGenerator, _tres); // get fluctuation in time + first_time[ch] += dt; + } + else + { + if (Verbosity()) + { + std::cout << "BAD " << ch << "\t" << this_hit->get_t(1) << std::endl; + } + } + } + + edep[ch] += this_hit->get_edep(); + + // get summed path length for particles that can create CKOV light + // n.p.e. is determined from path length + Double_t beta = v4.Beta(); + if (beta > BbcDefs::v_ckov && charge != 0.) + { + len[ch] += this_hit->get_path_length(); + + _pids[pid] += 1; + } + + nhits++; + } + + for (int ich = 0; ich < 128; ich++) + { + // Fill charge and time info + if (len[ich] > 0.) + { + if (Verbosity() > 0) + { + std::cout << "ich " << ich << "\t" << len[ich] << "\t" << edep[ich] << std::endl; + } + + // Get charge in BBC tube + float npe = len[ich] * (120 / 3.0); // we get 120 p.e. per 3 cm + float dnpe = gsl_ran_gaussian(m_RandomGenerator, std::sqrt(npe)); // get fluctuation in npe + + npe += dnpe; // apply the fluctuations in npe + f_pmtq[ich] = npe; + + // Now time + if (first_time[ich] < 9999.) + { + f_pmtt0[ich] = first_time[ich]; + f_pmtt1[ich] = first_time[ich]; + } + else // should never happen + { + if (Verbosity() != 0) + { + std::cout << "ERROR, have hit but no time" << std::endl; + } + } + + _bbcpmts->AddBbcPmt(ich, f_pmtq[ich], f_pmtt0[ich], f_pmtt1[ich]); + if (Verbosity() > 0) + { + std::cout << "Adding " << ich << ", " << f_pmtq[ich] << ", " << f_pmtt0[ich] << " , " << f_pmtt1[ich] << std::endl; + } + } + } + + return 0; +} + +void BbcDigitization::CreateNodes(PHCompositeNode *topNode) +{ + PHNodeIterator iter(topNode); + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing doing nothing" << std::endl; + gSystem->Exit(1); + exit(1); + } + + PHCompositeNode *bbcNode = dynamic_cast(iter.findFirst("PHCompositeNode", "BBC")); + if (!bbcNode) + { + bbcNode = new PHCompositeNode("BBC"); + dstNode->addNode(bbcNode); + } + + //-* contains info for each pmt (nmips, time, etc) + _bbcpmts = findNode::getClass(bbcNode, "BbcPmtContainer"); + if (!_bbcpmts) + { + _bbcpmts = new BbcPmtContainerV1(); + PHIODataNode *BbcPmtNode = new PHIODataNode(_bbcpmts, "BbcPmtContainer", "PHObject"); + bbcNode->addNode(BbcPmtNode); + } +} + +//___________________________________ +void BbcDigitization::GetNodes(PHCompositeNode *topNode) +{ + // Get the DST objects + + // Truth container + _truth_container = findNode::getClass(topNode, "G4TruthInfo"); + if (!_truth_container) + { + std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl; + gSystem->Exit(1); + } + + // BBC hit container + _bbchits = findNode::getClass(topNode, "G4HIT_BBC"); + if (!_bbchits) + { + std::cout << PHWHERE << " G4HIT_BBC node not found on node tree" << std::endl; + gSystem->Exit(1); + } + + /** DST Objects **/ + + // BbcPmtContainer + _bbcpmts = findNode::getClass(topNode, "BbcPmtContainer"); + if (!_bbcpmts) + { + std::cout << PHWHERE << " BbcPmtContainer node not found on node tree" << std::endl; + gSystem->Exit(1); + } +} diff --git a/simulation/g4simulation/g4bbc/BbcSimReco.h b/simulation/g4simulation/g4bbc/BbcDigitization.h similarity index 72% rename from simulation/g4simulation/g4bbc/BbcSimReco.h rename to simulation/g4simulation/g4bbc/BbcDigitization.h index d62a101f24..4d264e4968 100644 --- a/simulation/g4simulation/g4bbc/BbcSimReco.h +++ b/simulation/g4simulation/g4bbc/BbcDigitization.h @@ -1,5 +1,5 @@ -#ifndef G4BBC_BBCSIMRECO_H -#define G4BBC_BBCSIMRECO_H +#ifndef G4BBC_BBCDIGITIZATION_H +#define G4BBC_BBCDIGITIZATION_H #include @@ -16,7 +16,6 @@ class PHCompositeNode; class PHG4HitContainer; class PHG4TruthInfoContainer; class EventHeader; -class BbcOut; class BbcPmtContainer; class TDatabasePDG; class TRandom3; @@ -24,13 +23,13 @@ class TH1; class TH2; class TF1; -class BbcSimReco : public SubsysReco +class BbcDigitization : public SubsysReco { public: // Default constructor - BbcSimReco(const std::string &name = "BbcSimReco"); + BbcDigitization(const std::string &name = "BbcDigitization"); - ~BbcSimReco() override; + ~BbcDigitization() override; //! Initialization, called for at overall initialization int Init(PHCompositeNode *) override; @@ -54,7 +53,6 @@ class BbcSimReco : public SubsysReco void CreateNodes(PHCompositeNode *topNode); // Create all the nodes void GetNodes(PHCompositeNode *); // Get all the needed nodes - Int_t f_evt = 0; Float_t f_vx = NAN; Float_t f_vy = NAN; Float_t f_vz = NAN; @@ -62,14 +60,7 @@ class BbcSimReco : public SubsysReco Float_t f_pmtq[128]{}; // npe in each arm Float_t f_pmtt0[128]{}; // time in each arm Float_t f_pmtt1[128]{}; // time in each arm - Short_t f_bbcn[2]{}; // num hits for each arm (north and south) - Float_t f_bbcq[2]{}; // total charge (currently npe) in each arm - Float_t f_bbct[2]{}; // time in arm - Float_t f_bbcte[2]{}; // earliest hit time in arm - Float_t f_bbcz = NAN; // z-vertex - Float_t f_bbct0 = NAN; // start time - - TH1 *hevt_bbct[2]{}; // time in each bbc, per event + TF1 *gaussian = nullptr; // @@ -83,11 +74,9 @@ class BbcSimReco : public SubsysReco // Input Objects from DST PHG4TruthInfoContainer *_truth_container = nullptr; PHG4HitContainer *_bbchits = nullptr; - EventHeader *_evtheader = nullptr; // Output to DST - BbcOut *_bbcout = nullptr; BbcPmtContainer *_bbcpmts = nullptr; }; -#endif //* __BBCSIMRECO_H__ *// +#endif //* __BBCDIGITIZATION_H__ *// diff --git a/simulation/g4simulation/g4bbc/BbcSimReco.cc b/simulation/g4simulation/g4bbc/BbcSimReco.cc deleted file mode 100644 index 05429f6fa4..0000000000 --- a/simulation/g4simulation/g4bbc/BbcSimReco.cc +++ /dev/null @@ -1,474 +0,0 @@ -#include "BbcSimReco.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -namespace BBCINFO -{ - const Double_t index_refract = 1.4585; - const Double_t v_ckov = 1.0 / index_refract; // velocity threshold for CKOV - const Double_t C = 29.9792458; // cm/ns - - // kludge where we have the hardcoded positions of the tubes - // These are the x,y for the south BBC (in cm). - // The north inverts the x coordinate (x -> -x) - - /* unused causes compiler warning - const float TubeLoc[64][2] = { - { -12.2976, 4.26 }, - { -12.2976, 1.42 }, - { -9.83805, 8.52 }, - { -9.83805, 5.68 }, - { -9.83805, 2.84 }, - { -7.37854, 9.94 }, - { -7.37854, 7.1 }, - { -7.37854, 4.26 }, - { -7.37854, 1.42 }, - { -4.91902, 11.36 }, - { -4.91902, 8.52 }, - { -4.91902, 5.68 }, - { -2.45951, 12.78 }, - { -2.45951, 9.94 }, - { -2.45951, 7.1 }, - { 0, 11.36 }, - { 0, 8.52 }, - { 2.45951, 12.78 }, - { 2.45951, 9.94 }, - { 2.45951, 7.1 }, - { 4.91902, 11.36 }, - { 4.91902, 8.52 }, - { 4.91902, 5.68 }, - { 7.37854, 9.94 }, - { 7.37854, 7.1 }, - { 7.37854, 4.26 }, - { 7.37854, 1.42 }, - { 9.83805, 8.52 }, - { 9.83805, 5.68 }, - { 9.83805, 2.84 }, - { 12.2976, 4.26 }, - { 12.2976, 1.42 }, - { 12.2976, -4.26 }, - { 12.2976, -1.42 }, - { 9.83805, -8.52 }, - { 9.83805, -5.68 }, - { 9.83805, -2.84 }, - { 7.37854, -9.94 }, - { 7.37854, -7.1 }, - { 7.37854, -4.26 }, - { 7.37854, -1.42 }, - { 4.91902, -11.36 }, - { 4.91902, -8.52 }, - { 4.91902, -5.68 }, - { 2.45951, -12.78 }, - { 2.45951, -9.94 }, - { 2.45951, -7.1 }, - { 0, -11.36 }, - { 0, -8.52 }, - { -2.45951, -12.78 }, - { -2.45951, -9.94 }, - { -2.45951, -7.1 }, - { -4.91902, -11.36 }, - { -4.91902, -8.52 }, - { -4.91902, -5.68 }, - { -7.37854, -9.94 }, - { -7.37854, -7.1 }, - { -7.37854, -4.26 }, - { -7.37854, -1.42 }, - { -9.83805, -8.52 }, - { -9.83805, -5.68 }, - { -9.83805, -2.84 }, - { -12.2976, -4.26 }, - { -12.2976, -1.42 } - }; - */ - -} // namespace BBCINFO - -using namespace BBCINFO; - -//____________________________________ -BbcSimReco::BbcSimReco(const std::string &name) - : SubsysReco(name) - , _tres(0.05) -{ - std::fill(std::begin(f_pmtq), std::end(f_pmtq), NAN); - std::fill(std::begin(f_pmtt0), std::end(f_pmtt0), NAN); - std::fill(std::begin(f_pmtt1), std::end(f_pmtt1), NAN); - std::fill(std::begin(f_bbcn), std::end(f_bbcn), 0); - std::fill(std::begin(f_bbcq), std::end(f_bbcq), NAN); - std::fill(std::begin(f_bbct), std::end(f_bbct), NAN); - std::fill(std::begin(f_bbcte), std::end(f_bbcte), NAN); - hevt_bbct[0] = nullptr; - hevt_bbct[1] = nullptr; - m_RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937); - m_Seed = PHRandomSeed(); // fixed seed is handled in this funtcion - gsl_rng_set(m_RandomGenerator, m_Seed); -} - -BbcSimReco::~BbcSimReco() -{ - gsl_rng_free(m_RandomGenerator); - return; -} - -//___________________________________ -int BbcSimReco::Init(PHCompositeNode *topNode) -{ - // std::cout << PHWHERE << std::endl; - CreateNodes(topNode); - - _pdg = new TDatabasePDG(); // database of PDG info on particles - - TString name, title; - for (int iarm = 0; iarm < 2; iarm++) - { - // - name = "hevt_bbct"; - name += iarm; - title = "bbc times, arm "; - title += iarm; - hevt_bbct[iarm] = new TH1F(name, title, 200, 7.5, 11.5); - hevt_bbct[iarm]->SetLineColor(4); - } - - gaussian = new TF1("gaussian", "gaus", 0, 20); - gaussian->FixParameter(2, _tres); // set sigma to timing resolution - - return 0; -} - -//___________________________________ -int BbcSimReco::InitRun(PHCompositeNode *topNode) -{ - GetNodes(topNode); - - return 0; -} - -//__________________________________ -// Call user instructions for every event -int BbcSimReco::process_event(PHCompositeNode * /*topNode*/) -{ - // GetNodes(topNode); - - f_evt = _evtheader->get_EvtSequence(); - // if(f_evt%100==0) std::cout << PHWHERE << "Events processed: " << f_evt << std::endl; - - //**** Initialize Variables - - // Arm Data - f_bbcn[0] = 0; - f_bbcn[1] = 0; - f_bbcq[0] = 0.; - f_bbcq[1] = 0.; - f_bbct[0] = -9999.; - f_bbct[1] = -9999.; - f_bbcte[0] = -9999.; - f_bbcte[1] = -9999.; - f_bbcz = NAN; - f_bbct0 = NAN; - hevt_bbct[0]->Reset(); - hevt_bbct[1]->Reset(); - - // PMT data - float len[128] = {0.}; - float edep[128] = {0.}; - float first_time[128]; // First hit time for each tube - std::fill_n(first_time, 128, 1e12); - std::fill_n(f_pmtt0, 128, 1e12); - std::fill_n(f_pmtt1, 128, 1e12); - std::fill_n(f_pmtq, 128, 0.); - - // Get True Vertex - // NB: Currently PrimaryVertexIndex is always 1, need to figure out how to handle collision pile-up - PHG4VtxPoint *vtxp = _truth_container->GetPrimaryVtx(_truth_container->GetPrimaryVertexIndex()); - if (vtxp != nullptr) - { - f_vx = vtxp->get_x(); - f_vy = vtxp->get_y(); - f_vz = vtxp->get_z(); - f_vt = vtxp->get_t(); - - if (f_evt < 20) - { - std::cout << "VTXP " - << "\t" << f_vx << "\t" << f_vy << "\t" << f_vz << "\t" << f_vt << std::endl; - } - } - - // Go through BBC G4 hits - - TLorentzVector v4; - unsigned int nhits = 0; - - PHG4HitContainer::ConstRange bbc_hit_range = _bbchits->getHits(); - for (auto hit_iter = bbc_hit_range.first; hit_iter != bbc_hit_range.second; hit_iter++) - { - PHG4Hit *this_hit = hit_iter->second; - - unsigned int ch = this_hit->get_layer(); // pmt channel - // int arm = ch/64;; // south=0, north=1 - - int trkid = this_hit->get_trkid(); - // if ( trkid>0 && f_evt<20 ) std::cout << "TRKID " << trkid << std::endl; - - PHG4Particle *part = _truth_container->GetParticle(trkid); - v4.SetPxPyPzE(part->get_px(), part->get_py(), part->get_pz(), part->get_e()); - - int pid = part->get_pid(); - TParticlePDG *partinfo = _pdg->GetParticle(pid); - Double_t charge = -9999.; - if (partinfo) - { - charge = partinfo->Charge() / 3; // PDG gives charge in 1/3 e - } - else if (part->isIon()) - { - charge = part->get_IonCharge(); - } - - // get the first time - if (this_hit->get_t(1) < first_time[ch]) - { - if (fabs(this_hit->get_t(1)) < 106.5) - { - first_time[ch] = this_hit->get_t(1) - vtxp->get_t(); - Float_t dt = gsl_ran_gaussian(m_RandomGenerator, _tres); // get fluctuation in time - first_time[ch] += dt; - } - else - { - if (Verbosity()) - { - std::cout << "BAD " << ch << "\t" << this_hit->get_t(1) << std::endl; - } - } - } - - edep[ch] += this_hit->get_edep(); - - // get summed path length for particles that can create CKOV light - // n.p.e. is determined from path length - Double_t beta = v4.Beta(); - if (beta > v_ckov && charge != 0.) - { - len[ch] += this_hit->get_path_length(); - - _pids[pid] += 1; - } - - nhits++; - } - - // process the data from each channel - for (float &iarm : f_bbct) - { - iarm = 0.; - } - - std::vector hit_times[2]; // times of the hits in each [arm] - - for (int ich = 0; ich < 128; ich++) - { - int arm = ich / 64; // ch 0-63 = south, ch 64-127 = north - - // Fill charge and time info - if (len[ich] > 0.) - { - if (f_evt < 20 && Verbosity() != 0) - { - std::cout << "ich " << ich << "\t" << len[ich] << "\t" << edep[ich] << std::endl; - } - - // Get charge in BBC tube - float npe = len[ich] * (120 / 3.0); // we get 120 p.e. per 3 cm - float dnpe = gsl_ran_gaussian(m_RandomGenerator, std::sqrt(npe)); // get fluctuation in npe - - npe += dnpe; // apply the fluctuations in npe - - f_bbcq[arm] += npe; - f_pmtq[ich] = npe; - - // Now time - if (first_time[ich] < 9999.) - { - // Fill evt histogram - hevt_bbct[arm]->Fill(first_time[ich]); - hit_times[arm].push_back(first_time[ich]); - - f_bbct[arm] += first_time[ich]; - // std::cout << "XXX " << ich << "\t" << f_bbct[arm] << "\t" << first_time[ich] << std::endl; - - f_pmtt0[ich] = first_time[ich]; - f_pmtt1[ich] = first_time[ich]; - } - else // should never happen - { - if (Verbosity() != 0) - { - std::cout << "ERROR, have hit but no time" << std::endl; - } - } - - //int ipmt = f_bbcn[0] + f_bbcn[1]; // number of hit pmt - _bbcpmts->AddBbcPmt(ich, f_pmtq[ich], f_pmtt0[ich], f_pmtt1[ich]); - - // threshold should be > 0. - ++f_bbcn[arm]; - } - - - } - - // Get best t - if (f_bbcn[0] > 0 && f_bbcn[1] > 0) - { - for (int iarm = 0; iarm < 2; iarm++) - { - std::sort(hit_times[iarm].begin(), hit_times[iarm].end()); - float earliest = hit_times[iarm][0]; - - gaussian->SetParameter(0, 5); - gaussian->SetParameter(1, earliest); - gaussian->SetRange(6, earliest + 5 * 0.05); - // gaussian->SetParameter(1,hevt_bbct[iarm]->GetMean()); - // gaussian->SetRange(6,hevt_bbct[iarm]->GetMean()+0.125); - - hevt_bbct[iarm]->Fit(gaussian, "BLR"); - hevt_bbct[iarm]->Draw(); - - if (f_bbcn[iarm] > 0) - { - // f_bbct[iarm] = f_bbct[iarm] / f_bbcn[iarm]; - f_bbct[iarm] = gaussian->GetParameter(1); - f_bbcte[iarm] = earliest; - - _bbcout->AddBbcNS(iarm, f_bbcn[iarm], f_bbcq[iarm], f_bbct[iarm]); - } - } - - // Now calculate zvtx, t0 from best times - f_bbcz = (f_bbct[0] - f_bbct[1]) * C / 2.0; - f_bbct0 = (f_bbct[0] + f_bbct[1]) / 2.0; - - _bbcout->set_Vertex(f_bbcz, 0.6); - _bbcout->set_TimeZero(f_bbct0, 0.05); - } - - return 0; -} - -void BbcSimReco::CreateNodes(PHCompositeNode *topNode) -{ - PHNodeIterator iter(topNode); - PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); - if (!dstNode) - { - std::cout << PHWHERE << "DST Node missing doing nothing" << std::endl; - } - - PHCompositeNode *bbcNode = dynamic_cast(iter.findFirst("PHCompositeNode", "BBC")); - if (!bbcNode) - { - bbcNode = new PHCompositeNode("BBC"); - dstNode->addNode(bbcNode); - } - - //-* contains final physics products (nmips, t0, etc) - _bbcout = findNode::getClass(bbcNode, "BbcOut"); - if (!_bbcout) - { - std::cout << "Creating BBCOUT" << std::endl; - _bbcout = new BbcOutV1(); - PHIODataNode *BbcOutNode = new PHIODataNode(_bbcout, "BbcOut", "PHObject"); - bbcNode->addNode(BbcOutNode); - } - - //-* contains info for each pmt (nmips, time, etc) - _bbcpmts = findNode::getClass(bbcNode, "BbcPmtContainer"); - if (!_bbcpmts) - { - _bbcpmts = new BbcPmtContainerV1(); - PHIODataNode *BbcPmtNode = new PHIODataNode(_bbcpmts, "BbcPmtContainer", "PHObject"); - bbcNode->addNode(BbcPmtNode); - } -} - -//___________________________________ -void BbcSimReco::GetNodes(PHCompositeNode *topNode) -{ - // Get the DST objects - - // Truth container - _truth_container = findNode::getClass(topNode, "G4TruthInfo"); - if (!_truth_container && f_evt < 10) - { - std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl; - } - - // BBC hit container - _bbchits = findNode::getClass(topNode, "G4HIT_BBC"); - if (!_bbchits && f_evt < 10) - { - std::cout << PHWHERE << " G4HIT_BBC node not found on node tree" << std::endl; - } - - // Event Header info - _evtheader = findNode::getClass(topNode, "EventHeader"); - if (!_evtheader && f_evt < 10) - { - std::cout << PHWHERE << " G4HIT_BBC node not found on node tree" << std::endl; - } - - /** DST Objects **/ - - // BbcOut data - _bbcout = findNode::getClass(topNode, "BbcOut"); - if (!_bbcout && f_evt < 10) - { - std::cout << PHWHERE << " BbcOut node not found on node tree" << std::endl; - } - - // BbcPmtContainer - _bbcpmts = findNode::getClass(topNode, "BbcPmtContainer"); - if (!_bbcpmts && f_evt < 10) - { - std::cout << PHWHERE << " BbcPmtContainer node not found on node tree" << std::endl; - } -} diff --git a/simulation/g4simulation/g4bbc/BbcVertexFastSimReco.cc b/simulation/g4simulation/g4bbc/BbcVertexFastSimReco.cc index cc30dacfa9..7bae66fe87 100644 --- a/simulation/g4simulation/g4bbc/BbcVertexFastSimReco.cc +++ b/simulation/g4simulation/g4bbc/BbcVertexFastSimReco.cc @@ -1,10 +1,10 @@ #include "BbcVertexFastSimReco.h" -#include "BbcVertex.h" // for BbcVertex -#include "BbcVertexMap.h" // for BbcVertexMap -#include "BbcVertexMapv1.h" -#include "BbcVertexv1.h" +#include // for BbcVertex +#include // for BbcVertexMap +#include +#include #include #include diff --git a/simulation/g4simulation/g4bbc/Makefile.am b/simulation/g4simulation/g4bbc/Makefile.am index 448abd0730..9a8f221bfc 100644 --- a/simulation/g4simulation/g4bbc/Makefile.am +++ b/simulation/g4simulation/g4bbc/Makefile.am @@ -18,40 +18,20 @@ libg4bbc_io_la_LIBADD = \ libg4bbc_la_LIBADD = \ libg4bbc_io.la \ + -lbbc_io \ -lg4detectors \ - -lfun4all \ - -lSubsysReco \ - -lbbc + -lSubsysReco pkginclude_HEADERS = \ - BbcVertex.h \ - BbcVertexv1.h \ - BbcVertexMap.h \ - BbcVertexMapv1.h \ - BbcSimReco.h \ + BbcDigitization.h \ BbcVertexFastSimReco.h -ROOTDICTS = \ - BbcVertex_Dict.cc \ - BbcVertexv1_Dict.cc \ - BbcVertexMap_Dict.cc \ - BbcVertexMapv1_Dict.cc - -pcmdir = $(libdir) -nobase_dist_pcm_DATA = \ - BbcVertex_Dict_rdict.pcm \ - BbcVertexv1_Dict_rdict.pcm \ - BbcVertexMap_Dict_rdict.pcm \ - BbcVertexMapv1_Dict_rdict.pcm libg4bbc_io_la_SOURCES = \ - $(ROOTDICTS) \ - BbcVertexv1.cc \ - BbcVertexMap.cc \ - BbcVertexMapv1.cc + $(ROOTDICTS) libg4bbc_la_SOURCES = \ - BbcSimReco.cc \ + BbcDigitization.cc \ BbcVertexFastSimReco.cc # Rule for generating table CINT dictionaries. diff --git a/simulation/g4simulation/g4calo/Makefile.am b/simulation/g4simulation/g4calo/Makefile.am index 080ec27a94..ca4d138a0a 100644 --- a/simulation/g4simulation/g4calo/Makefile.am +++ b/simulation/g4simulation/g4calo/Makefile.am @@ -31,17 +31,17 @@ libg4calo_la_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib libg4calo_la_LIBADD = \ - -lphool \ - -lSubsysReco \ + -lcalo_io \ + -lcdbobjects \ -lfun4all \ -lg4detectors_io \ -lg4testbench \ - -lphg4hit \ - -lphparameter \ -lgsl \ -lgslcblas \ - -lcaloCalibDBFile \ - -lcalo_io + -lphool \ + -lphg4hit \ + -lphparameter \ + -lSubsysReco ################################################ # linking tests diff --git a/simulation/g4simulation/g4calo/RawTowerBuilderByHitIndex.cc b/simulation/g4simulation/g4calo/RawTowerBuilderByHitIndex.cc index edc660c119..0e35184566 100644 --- a/simulation/g4simulation/g4calo/RawTowerBuilderByHitIndex.cc +++ b/simulation/g4simulation/g4calo/RawTowerBuilderByHitIndex.cc @@ -113,7 +113,7 @@ int RawTowerBuilderByHitIndex::process_event(PHCompositeNode *topNode) m_Towers->AddTower(tower->get_id(), tower); } - tower->add_ecell((g4hit_i->get_index_j() << 16) + g4hit_i->get_index_k(), g4hit_i->get_light_yield()); + tower->add_ecell((g4hit_i->get_index_j() << 16U) + g4hit_i->get_index_k(), g4hit_i->get_light_yield()); tower->set_energy(tower->get_energy() + g4hit_i->get_light_yield()); tower->add_eshower(g4hit_i->get_shower_id(), g4hit_i->get_edep()); } @@ -228,7 +228,7 @@ bool RawTowerBuilderByHitIndex::ReadGeometryFromTable() while (getline(istream_mapping, line_mapping)) { /* Skip lines starting with / including a '#' */ - if (line_mapping.find("#") != std::string::npos) + if (line_mapping.find('#') != std::string::npos) { if (Verbosity() > 0) { diff --git a/simulation/g4simulation/g4calo/RawTowerDigitizer.cc b/simulation/g4simulation/g4calo/RawTowerDigitizer.cc index c68513b8af..4b00f313dc 100644 --- a/simulation/g4simulation/g4calo/RawTowerDigitizer.cc +++ b/simulation/g4simulation/g4calo/RawTowerDigitizer.cc @@ -13,15 +13,16 @@ #include #include -#include -#include -#include +#include + +#include + +#include #include // for Fun4AllBase::VERBOSITY_MORE #include #include // for SubsysReco -#include #include #include @@ -59,6 +60,7 @@ RawTowerDigitizer::RawTowerDigitizer(const std::string &name) RawTowerDigitizer::~RawTowerDigitizer() { gsl_rng_free(m_RandomGenerator); + delete m_CDBTTree; } void RawTowerDigitizer::set_seed(const unsigned int iseed) @@ -95,11 +97,27 @@ int RawTowerDigitizer::InitRun(PHCompositeNode *topNode) { if (m_Detector.c_str()[0] == 'H') { - m_CalDBFile = new HcalCaloCalibSimpleCorrFilev1(); + std::string url = CDBInterface::instance()->getUrl("HCALGAINSCORR"); + if (url.empty()) + { + std::cout << PHWHERE << " Could not get Hcal Calibration for domain HCALGAINSCORR" << std::endl; + gSystem->Exit(1); + exit(1); + } + + m_CDBTTree = new CDBTTree(url); } else if (m_Detector.c_str()[0] == 'C') { - m_CalDBFile = new CEmcCaloCalibSimpleCorrFilev1(); + std::string url = CDBInterface::instance()->getUrl("CEMCGAINSCORR"); + if (url.empty()) + { + std::cout << PHWHERE << " Could not get Cemc Calibration for domain CEMCGAINSCORR" << std::endl; + gSystem->Exit(1); + exit(1); + } + + m_CDBTTree = new CDBTTree(url); } else { @@ -108,15 +126,6 @@ int RawTowerDigitizer::InitRun(PHCompositeNode *topNode) << std::endl; gSystem->Exit(1); } - - if (!m_DecalFileName.empty()) - { - m_CalDBFile->Open(m_DecalFileName.c_str()); - } - else - { - m_Decal = false; - } //warnings for bad file names handled inside Open } @@ -254,7 +263,9 @@ int RawTowerDigitizer::process_event(PHCompositeNode */**topNode*/) { if (m_DoDecal && m_Decal) { - float decal_fctr = m_CalDBFile->getCorr(eta, phi); + unsigned int etaphikey = phi; + etaphikey = (etaphikey << 16U) + eta; + float decal_fctr = m_CDBTTree->GetFloatValue(etaphikey,"etaphi"); if (m_DecalInverse) { @@ -324,7 +335,9 @@ int RawTowerDigitizer::process_event(PHCompositeNode */**topNode*/) { if (m_DoDecal && m_Decal) { - float decal_fctr = m_CalDBFile->getCorr(eta, phi); + unsigned int etaphikey = phi; + etaphikey = (etaphikey << 16U) + eta; + float decal_fctr = m_CDBTTree->GetFloatValue(etaphikey,"etaphi"); if (m_DecalInverse) { decal_fctr = 1.0 / decal_fctr; diff --git a/simulation/g4simulation/g4calo/RawTowerDigitizer.h b/simulation/g4simulation/g4calo/RawTowerDigitizer.h index 07d3dcd1bd..a261a9c9d2 100644 --- a/simulation/g4simulation/g4calo/RawTowerDigitizer.h +++ b/simulation/g4simulation/g4calo/RawTowerDigitizer.h @@ -11,7 +11,7 @@ #include #include -class CaloCalibSimpleCorrFile; +class CDBTTree; class PHCompositeNode; class RawTower; class TowerInfo; @@ -278,7 +278,7 @@ class RawTowerDigitizer : public SubsysReco bool m_Decal = true; std::string m_DecalFileName; bool m_UseConditionsDB = false; - CaloCalibSimpleCorrFile *m_CalDBFile = nullptr; + CDBTTree *m_CDBTTree = nullptr; RawTowerDigitizer::ProcessTowerType m_UseTowerInfo = RawTowerDigitizer::ProcessTowerType::kBothTowers; // 0 just produce RawTowers, 1 just produce TowerInfo objects, and 2 produce both diff --git a/simulation/g4simulation/g4detectors/LightCollectionModel.cc b/simulation/g4simulation/g4detectors/LightCollectionModel.cc new file mode 100644 index 0000000000..ab5bfe2b15 --- /dev/null +++ b/simulation/g4simulation/g4detectors/LightCollectionModel.cc @@ -0,0 +1,126 @@ +#include "LightCollectionModel.h" + +#include + +#include + +#include + +#include // for TAxis +#include +#include +#include +#include // for TObject +#include + +#include +#include + +LightCollectionModel::LightCollectionModel() +{ + data_grid_light_guide_efficiency_verify = new TH2F("data_grid_light_guide_efficiency_verify", + "light collection efficiency as used in LightCollectionModel;x positio fraction;y position fraction", // + 100, 0., 1., 100, 0., 1.); + + data_grid_fiber_trans_verify = new TH1F("data_grid_fiber_trans", + "SCSF-78 Fiber Transmission as used in LightCollectionModel;position in fiber (cm);Effective transmission", + 100, -15, 15); + + // register histograms + Fun4AllServer *se = Fun4AllServer::instance(); + + se->registerHisto(data_grid_light_guide_efficiency_verify); + se->registerHisto(data_grid_fiber_trans_verify); +} + +LightCollectionModel::~LightCollectionModel() +{ + delete data_grid_light_guide_efficiency; + delete data_grid_fiber_trans; +} + +void LightCollectionModel::load_data_from_CDB( + const std::string &domain, + const std::string &histogram_light_guide_model, + const std::string &histogram_fiber_model) +{ + recoConsts *rc = recoConsts::instance(); + std::string url = CDBInterface::instance()->getUrl(domain); + if (url.empty()) + { + std::cout << "No calibration for domain " << domain << " for timestamp " << rc->get_uint64Flag("TIMESTAMP") << std::endl; + gSystem->Exit(1); + } + TFile *fin = TFile::Open(url.c_str()); + if (!fin) + { + std::cout << "could not open " << url << std::endl; + gSystem->Exit(1); + } + if (data_grid_light_guide_efficiency) delete data_grid_light_guide_efficiency; + data_grid_light_guide_efficiency = dynamic_cast(fin->Get(histogram_light_guide_model.c_str())); + assert(data_grid_light_guide_efficiency); + data_grid_light_guide_efficiency->SetDirectory(nullptr); + if (data_grid_fiber_trans) delete data_grid_fiber_trans; + data_grid_fiber_trans = dynamic_cast(fin->Get(histogram_fiber_model.c_str())); + assert(data_grid_fiber_trans); + data_grid_fiber_trans->SetDirectory(nullptr); + delete fin; +} + +void LightCollectionModel::load_data_file( + const std::string &input_file, + const std::string &histogram_light_guide_model, + const std::string &histogram_fiber_model) +{ + TFile *fin = TFile::Open(input_file.c_str()); + + assert(fin); + assert(fin->IsOpen()); + + if (data_grid_light_guide_efficiency) delete data_grid_light_guide_efficiency; + data_grid_light_guide_efficiency = dynamic_cast(fin->Get(histogram_light_guide_model.c_str())); + assert(data_grid_light_guide_efficiency); + data_grid_light_guide_efficiency->SetDirectory(nullptr); + + if (data_grid_fiber_trans) delete data_grid_fiber_trans; + data_grid_fiber_trans = dynamic_cast(fin->Get(histogram_fiber_model.c_str())); + assert(data_grid_fiber_trans); + data_grid_fiber_trans->SetDirectory(nullptr); + + delete fin; +} + +double LightCollectionModel::get_light_guide_efficiency(const double x_fraction, const double y_fraction) +{ + assert(data_grid_light_guide_efficiency); + assert(x_fraction >= 0); + assert(x_fraction <= 1); + assert(y_fraction >= 0); + assert(y_fraction <= 1); + + const double eff = data_grid_light_guide_efficiency->Interpolate(x_fraction, + y_fraction); + + data_grid_light_guide_efficiency_verify->SetBinContent( // + data_grid_light_guide_efficiency_verify->GetXaxis()->FindBin(x_fraction), // + data_grid_light_guide_efficiency_verify->GetYaxis()->FindBin(y_fraction), // + eff // + ); + + return eff; +} + +double LightCollectionModel::get_fiber_transmission(const double z_distance) +{ + assert(data_grid_fiber_trans); + + const double eff = data_grid_fiber_trans->Interpolate(z_distance); + + data_grid_fiber_trans_verify->SetBinContent( // + data_grid_fiber_trans_verify->GetXaxis()->FindBin(z_distance), // + eff // + ); + + return eff; +} diff --git a/simulation/g4simulation/g4detectors/LightCollectionModel.h b/simulation/g4simulation/g4detectors/LightCollectionModel.h new file mode 100644 index 0000000000..8fe43ce3c8 --- /dev/null +++ b/simulation/g4simulation/g4detectors/LightCollectionModel.h @@ -0,0 +1,54 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef G4DETECTORS_LIGHTCOLLECTIONMODEL_H +#define G4DETECTORS_LIGHTCOLLECTIONMODEL_H +#include + +class TH2; +class TH1; + +class LightCollectionModel +{ + public: + LightCollectionModel(); + + //! delete copy ctor and assignment opertor (cppcheck) + explicit LightCollectionModel(const LightCollectionModel &) = delete; + LightCollectionModel &operator=(const LightCollectionModel &) = delete; + + virtual ~LightCollectionModel(); + + //! input data file + void load_data_file(const std::string &input_file, const std::string &histogram_light_guide_model, const std::string &histogram_fiber_model); + + //! load from CDB + void load_data_from_CDB(const std::string &domain, const std::string &histogram_light_guide_model, const std::string &histogram_fiber_model); + + //! Whether use light collection model + bool use_light_guide_model() const { return data_grid_light_guide_efficiency != nullptr; } + + //! Whether use Light Transmission Efficiency model for the fiber + bool use_fiber_model() const { return data_grid_fiber_trans != nullptr; } + + //! get Light Collection Efficiency for the light guide as function of x,y position in fraction of tower width + double get_light_guide_efficiency(const double x_fraction, const double y_fraction); + + //! get Light Transmission Efficiency for the fiber as function of z position (cm) in the fiber. Z=0 is at the middle of the fiber + double get_fiber_transmission(const double z_distance); + + private: + //! 2-D data grid for Light Collection Efficiency for the light guide as function of x,y position in fraction of tower width + TH2 *data_grid_light_guide_efficiency = nullptr; + + //! 1-D data grid for the light transmission efficiency in the fiber as function of distance to location in the fiber. Z=0 is at the middle of the fiber + TH1 *data_grid_fiber_trans = nullptr; + + // These two histograms are handed off to Fun4All and will be deleted there + // this suppresses the cppcheck warning + // cppcheck-suppress unsafeClassCanLeak + TH2 *data_grid_light_guide_efficiency_verify = nullptr; + // cppcheck-suppress unsafeClassCanLeak + TH1 *data_grid_fiber_trans_verify = nullptr; +}; + +#endif \ No newline at end of file diff --git a/simulation/g4simulation/g4detectors/Makefile.am b/simulation/g4simulation/g4detectors/Makefile.am index 1e65ce5de0..e86cef946d 100644 --- a/simulation/g4simulation/g4detectors/Makefile.am +++ b/simulation/g4simulation/g4detectors/Makefile.am @@ -38,10 +38,12 @@ libg4detectors_la_LIBADD = \ -lgmp \ -lphg4gdml \ -lphool \ + -lcalo_io \ -lSubsysReco pkginclude_HEADERS = \ BeamLineMagnetSubsystem.h \ + LightCollectionModel.h \ PHG4BbcSubsystem.h \ PHG4BlockCellGeom.h \ PHG4BlockCellGeomContainer.h \ @@ -91,6 +93,7 @@ pkginclude_HEADERS = \ PHG4SectorConstructor.h \ PHG4SectorSubsystem.h \ PHG4SpacalSubsystem.h \ + PHG4SpacalSteppingAction.h \ PHG4StepStatusDecode.h \ PHG4TpcCylinderGeom.h \ PHG4TpcCylinderGeomContainer.h \ @@ -201,6 +204,7 @@ libg4detectors_la_SOURCES = \ BeamLineMagnetDisplayAction.cc \ BeamLineMagnetSubsystem.cc \ BeamLineMagnetSteppingAction.cc \ + LightCollectionModel.cc \ PHG4GDMLDetector.cc \ PHG4GDMLSubsystem.cc \ PHG4BbcDetector.cc \ diff --git a/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.cc b/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.cc index d9b6fc7b84..d6ede34bff 100644 --- a/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.cc +++ b/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.cc @@ -1,10 +1,11 @@ #include "PHG4FullProjSpacalCellReco.h" +#include "LightCollectionModel.h" #include "PHG4Cell.h" // for PHG4Cell #include "PHG4CylinderCellGeom.h" #include "PHG4CylinderCellGeomContainer.h" #include "PHG4CylinderCellGeom_Spacalv1.h" -#include "PHG4CylinderGeom.h" // for PHG4CylinderGeom +#include "PHG4CylinderGeom.h" // for PHG4CylinderGeom #include "PHG4CylinderGeomContainer.h" #include "PHG4CylinderGeom_Spacalv1.h" // for PHG4CylinderGeom_Spaca... #include "PHG4CylinderGeom_Spacalv3.h" @@ -25,14 +26,14 @@ #include #include -#include // for PHNode +#include // for PHNode #include #include // for PHObject #include -#include // for PHWHERE +#include // for PHWHERE #include -#include +#include #include // for TAxis #include @@ -181,14 +182,14 @@ int PHG4FullProjSpacalCellReco::InitRun(PHCompositeNode *topNode) if (tower_ID_phi == 0) { - //assign phi min according phi bin 0 + // assign phi min according phi bin 0 phi_min = M_PI_2 - deltaphi * (layergeom->get_max_phi_bin_in_sec() * layergeom->get_n_subtower_phi() / 2) // shift of first tower in sector + sector_map.begin()->second; } if (tower_ID_phi == layergeom->get_max_phi_bin_in_sec() / 2) { - //assign eta min according phi bin 0 + // assign eta min according phi bin 0 map_z_tower_z_ID[tower.centralZ] = tower_ID_z; } // ... @@ -211,7 +212,7 @@ int PHG4FullProjSpacalCellReco::InitRun(PHCompositeNode *topNode) layerseggeo->set_etamin(NAN); layerseggeo->set_etastep(NAN); - //build eta bin maps + // build eta bin maps for (const auto &tower_pair : tower_map) { const int &tower_ID = tower_pair.first; @@ -229,7 +230,8 @@ int PHG4FullProjSpacalCellReco::InitRun(PHCompositeNode *topNode) const double dz = fabs(0.5 * (tower.pDy1 + tower.pDy2) / sin(tower.pRotationAngleX)); const double tower_radial = layergeom->get_tower_radial_position(tower); - auto z_to_eta = [&tower_radial](const double &z) { return -log(tan(0.5 * atan2(tower_radial, z))); }; + auto z_to_eta = [&tower_radial](const double &z) + { return -log(tan(0.5 * atan2(tower_radial, z))); }; const double eta_central = z_to_eta(tower.centralZ); // half eta-range @@ -421,6 +423,7 @@ int PHG4FullProjSpacalCellReco::process_event(PHCompositeNode *topNode) double light_yield = hiter->second->get_light_yield(); // light yield correction from fiber attenuation: + if (light_collection_model.use_fiber_model()) { const double z = 0.5 * (hiter->second->get_local_z(0) + hiter->second->get_local_z(1)); @@ -428,6 +431,7 @@ int PHG4FullProjSpacalCellReco::process_event(PHCompositeNode *topNode) light_yield *= light_collection_model.get_fiber_transmission(z); } + // light yield correction from light guide collection efficiency: if (light_collection_model.use_fiber_model()) @@ -437,7 +441,6 @@ int PHG4FullProjSpacalCellReco::process_event(PHCompositeNode *topNode) light_yield *= light_collection_model.get_light_guide_efficiency(x, y); } - cell->add_edep(hiter->first, hiter->second->get_edep()); cell->add_edep(hiter->second->get_edep()); cell->add_light_yield(light_yield); @@ -514,117 +517,6 @@ int PHG4FullProjSpacalCellReco::CheckEnergy(PHCompositeNode *topNode) return 0; } -PHG4FullProjSpacalCellReco::LightCollectionModel::LightCollectionModel() -{ - data_grid_light_guide_efficiency_verify = new TH2F("data_grid_light_guide_efficiency_verify", - "light collection efficiency as used in PHG4FullProjSpacalCellReco::LightCollectionModel;x positio fraction;y position fraction", // - 100, 0., 1., 100, 0., 1.); - - data_grid_fiber_trans_verify = new TH1F("data_grid_fiber_trans", - "SCSF-78 Fiber Transmission as used in PHG4FullProjSpacalCellReco::LightCollectionModel;position in fiber (cm);Effective transmission", - 100, -15, 15); - - // register histograms - Fun4AllServer *se = Fun4AllServer::instance(); - - se->registerHisto(data_grid_light_guide_efficiency_verify); - se->registerHisto(data_grid_fiber_trans_verify); -} - -PHG4FullProjSpacalCellReco::LightCollectionModel::~LightCollectionModel() -{ - delete data_grid_light_guide_efficiency; - delete data_grid_fiber_trans; -} - -void PHG4FullProjSpacalCellReco::LightCollectionModel::load_data_from_CDB( - const std::string &domain, - const std::string &histogram_light_guide_model, - const std::string &histogram_fiber_model) -{ - recoConsts *rc = recoConsts::instance(); - xpload::Result result = xpload::fetch(rc->get_StringFlag("XPLOAD_TAG"), domain, rc->get_uint64Flag("TIMESTAMP"), xpload::Configurator(rc->get_StringFlag("XPLOAD_CONFIG"))); - if (result.payload.empty()) - { - std::cout << "No calibration for domain " << domain << " for timestamp " << rc->get_uint64Flag("TIMESTAMP") << std::endl; - gSystem->Exit(1); - } - TFile *fin = TFile::Open(result.payload.c_str()); - if (!fin) - { - std::cout << "could not open " << result.payload << std::endl; - gSystem->Exit(1); - } - if (data_grid_light_guide_efficiency) delete data_grid_light_guide_efficiency; - data_grid_light_guide_efficiency = dynamic_cast(fin->Get(histogram_light_guide_model.c_str())); - assert(data_grid_light_guide_efficiency); - data_grid_light_guide_efficiency->SetDirectory(nullptr); - if (data_grid_fiber_trans) delete data_grid_fiber_trans; - data_grid_fiber_trans = dynamic_cast(fin->Get(histogram_fiber_model.c_str())); - assert(data_grid_fiber_trans); - data_grid_fiber_trans->SetDirectory(nullptr); - delete fin; -} - -void PHG4FullProjSpacalCellReco::LightCollectionModel::load_data_file( - const std::string &input_file, - const std::string &histogram_light_guide_model, - const std::string &histogram_fiber_model) -{ - TFile *fin = TFile::Open(input_file.c_str()); - - assert(fin); - assert(fin->IsOpen()); - - if (data_grid_light_guide_efficiency) delete data_grid_light_guide_efficiency; - data_grid_light_guide_efficiency = dynamic_cast(fin->Get(histogram_light_guide_model.c_str())); - assert(data_grid_light_guide_efficiency); - data_grid_light_guide_efficiency->SetDirectory(nullptr); - - if (data_grid_fiber_trans) delete data_grid_fiber_trans; - data_grid_fiber_trans = dynamic_cast(fin->Get(histogram_fiber_model.c_str())); - assert(data_grid_fiber_trans); - data_grid_fiber_trans->SetDirectory(nullptr); - - delete fin; -} - -double -PHG4FullProjSpacalCellReco::LightCollectionModel::get_light_guide_efficiency(const double x_fraction, const double y_fraction) -{ - assert(data_grid_light_guide_efficiency); - assert(x_fraction >= 0); - assert(x_fraction <= 1); - assert(y_fraction >= 0); - assert(y_fraction <= 1); - - const double eff = data_grid_light_guide_efficiency->Interpolate(x_fraction, - y_fraction); - - data_grid_light_guide_efficiency_verify->SetBinContent( // - data_grid_light_guide_efficiency_verify->GetXaxis()->FindBin(x_fraction), // - data_grid_light_guide_efficiency_verify->GetYaxis()->FindBin(y_fraction), // - eff // - ); - - return eff; -} - -double -PHG4FullProjSpacalCellReco::LightCollectionModel::get_fiber_transmission(const double z_distance) -{ - assert(data_grid_fiber_trans); - - const double eff = data_grid_fiber_trans->Interpolate(z_distance); - - data_grid_fiber_trans_verify->SetBinContent( // - data_grid_fiber_trans_verify->GetXaxis()->FindBin(z_distance), // - eff // - ); - - return eff; -} - void PHG4FullProjSpacalCellReco::SetDefaultParameters() { set_default_double_param("tmax", 60.0); diff --git a/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.h b/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.h index 58ee252046..ec98aa0e49 100644 --- a/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.h +++ b/simulation/g4simulation/g4detectors/PHG4FullProjSpacalCellReco.h @@ -3,6 +3,8 @@ #ifndef G4DETECTORS_PHG4FULLPROJSPACALCELLRECO_H #define G4DETECTORS_PHG4FULLPROJSPACALCELLRECO_H +#include "LightCollectionModel.h" + #include #include @@ -11,6 +13,7 @@ #include #include +class LightCollectionModel; class PHCompositeNode; class PHG4Cell; class TH2; @@ -40,49 +43,6 @@ class PHG4FullProjSpacalCellReco : public SubsysReco, public PHParameterInterfac void set_timing_window(const double tmin, const double tmax); - class LightCollectionModel - { - public: - LightCollectionModel(); - - //! delete copy ctor and assignment opertor (cppcheck) - explicit LightCollectionModel(const LightCollectionModel &) = delete; - LightCollectionModel &operator=(const LightCollectionModel &) = delete; - - virtual ~LightCollectionModel(); - - //! input data file - void load_data_file(const std::string &input_file, const std::string &histogram_light_guide_model, const std::string &histogram_fiber_model); - - //! load from CDB - void load_data_from_CDB(const std::string &domain, const std::string &histogram_light_guide_model, const std::string &histogram_fiber_model); - - //! Whether use light collection model - bool use_light_guide_model() const { return data_grid_light_guide_efficiency != nullptr; } - - //! Whether use Light Transmission Efficiency model for the fiber - bool use_fiber_model() const { return data_grid_fiber_trans != nullptr; } - - //! get Light Collection Efficiency for the light guide as function of x,y position in fraction of tower width - double get_light_guide_efficiency(const double x_fraction, const double y_fraction); - - //! get Light Transmission Efficiency for the fiber as function of z position (cm) in the fiber. Z=0 is at the middle of the fiber - double get_fiber_transmission(const double z_distance); - - private: - //! 2-D data grid for Light Collection Efficiency for the light guide as function of x,y position in fraction of tower width - TH2 *data_grid_light_guide_efficiency = nullptr; - - //! 1-D data grid for the light transmission efficiency in the fiber as function of distance to location in the fiber. Z=0 is at the middle of the fiber - TH1 *data_grid_fiber_trans = nullptr; - - // These two histograms are handed off to Fun4All and will be deleted there - // this suppresses the cppcheck warning - // cppcheck-suppress unsafeClassCanLeak - TH2 *data_grid_light_guide_efficiency_verify = nullptr; - // cppcheck-suppress unsafeClassCanLeak - TH1 *data_grid_fiber_trans_verify = nullptr; - }; LightCollectionModel &get_light_collection_model() { return light_collection_model; } diff --git a/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.cc b/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.cc index 9f9b8ffb77..7120e879e3 100644 --- a/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.cc +++ b/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.cc @@ -15,6 +15,8 @@ #include +#include + #include #include #include // for G4Exception @@ -55,6 +57,7 @@ class PHCompositeNode; PHG4FullProjTiltedSpacalDetector::PHG4FullProjTiltedSpacalDetector(PHG4Subsystem* subsys, PHCompositeNode* Node, const std::string& dnam, PHParameters* parameters, const int lyr) : PHG4SpacalDetector(subsys, Node, dnam, parameters, lyr, false) + , m_Params(parameters) { assert(_geom == nullptr); @@ -90,6 +93,22 @@ void PHG4FullProjTiltedSpacalDetector::ConstructMe(G4LogicalVolume* logicWorld) std::cout << "PHG4FullProjTiltedSpacalDetector::Construct::" << GetName() << " - Completed." << std::endl; } + + if (m_Params->get_int_param("saveg4hit")) return; + try + { + AddCellGeometryNode(); + AddTowerGeometryNode(); + + + } + catch (std::exception &e) + { + std::cout << e.what() << std::endl; + //exit(1); + } + + } std::pair diff --git a/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.h b/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.h index d7b590f49b..1aa26dee03 100644 --- a/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.h +++ b/simulation/g4simulation/g4detectors/PHG4FullProjTiltedSpacalDetector.h @@ -69,6 +69,7 @@ class PHG4FullProjTiltedSpacalDetector : public PHG4SpacalDetector } private: + PHParameters* m_Params = nullptr; // SpacalGeom_t* _geom; //! get the v3 cast of the geometry object SpacalGeom_t* diff --git a/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.cc b/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.cc index 9b480e4a50..7bcc849c56 100644 --- a/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.cc +++ b/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.cc @@ -11,9 +11,21 @@ #include #include +#include +#include +#include // for PHNode +#include +#include // for PHObject +#include #include #include +#include // for convert_name_... +#include // for RawTowerGeom +#include // for RawTowerGeomC... +#include +#include + #include #include @@ -488,6 +500,7 @@ void PHG4InnerHcalDetector::ConstructMe(G4LogicalVolume *logicWorld) } ++it; } + if (!m_Params->get_int_param("saveg4hit")) AddGeometryNode(); return; } @@ -934,3 +947,120 @@ std::pair PHG4InnerHcalDetector::GetLayerTowerId(G4VPhysicalVolume *vo // terminates, so using the standard exit() makes them happy exit(1); } + +// This is dulplicated code, we can get rid of it when we have the code to make towergeom for real data reco. +void PHG4InnerHcalDetector::AddGeometryNode() +{ + PHNodeIterator iter(topNode()); + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) + { + std::cout << PHWHERE << "Run Node missing, exiting." << std::endl; + gSystem->Exit(1); + exit(1); + } + PHNodeIterator runIter(runNode); + PHCompositeNode *RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", m_SuperDetector)); + if (!RunDetNode) + { + RunDetNode = new PHCompositeNode(m_SuperDetector); + runNode->addNode(RunDetNode); + } + m_TowerGeomNodeName = "TOWERGEOM_" + m_SuperDetector; + m_RawTowerGeom = findNode::getClass(topNode(), m_TowerGeomNodeName); + if (!m_RawTowerGeom) + { + m_RawTowerGeom = new RawTowerGeomContainer_Cylinderv1(RawTowerDefs::convert_name_to_caloid(m_SuperDetector)); + PHIODataNode *newNode = new PHIODataNode(m_RawTowerGeom, m_TowerGeomNodeName, "PHObject"); + RunDetNode->addNode(newNode); + } + double innerrad = m_Params->get_double_param(PHG4HcalDefs::innerrad); + double thickness = m_Params->get_double_param(PHG4HcalDefs::outerrad) - innerrad; + m_RawTowerGeom->set_radius(innerrad); + m_RawTowerGeom->set_thickness(thickness); + m_RawTowerGeom->set_phibins(m_Params->get_int_param(PHG4HcalDefs::n_towers)); + m_RawTowerGeom->set_etabins(m_Params->get_int_param("etabins")); + double geom_ref_radius = innerrad + thickness / 2.; + double phistart = m_Params->get_double_param("phistart"); + if (!std::isfinite(phistart)) + { + std::cout << PHWHERE << " phistart is not finite: " << phistart + << ", exiting now (this will crash anyway)" << std::endl; + gSystem->Exit(1); + } + for (int i = 0; i < m_Params->get_int_param(PHG4HcalDefs::n_towers); i++) + { + double phiend = phistart + 2. * M_PI / m_Params->get_int_param(PHG4HcalDefs::n_towers); + std::pair range = std::make_pair(phiend, phistart); + phistart = phiend; + m_RawTowerGeom->set_phibounds(i, range); + } + double etalowbound = -m_Params->get_double_param("scinti_eta_coverage_neg"); + for (int i = 0; i < m_Params->get_int_param("etabins"); i++) + { + // double etahibound = etalowbound + 2.2 / get_int_param("etabins"); + double etahibound = etalowbound + + (m_Params->get_double_param("scinti_eta_coverage_neg") + m_Params->get_double_param("scinti_eta_coverage_pos")) / m_Params->get_int_param("etabins"); + std::pair range = std::make_pair(etalowbound, etahibound); + m_RawTowerGeom->set_etabounds(i, range); + etalowbound = etahibound; + } + for (int iphi = 0; iphi < m_RawTowerGeom->get_phibins(); iphi++) + { + for (int ieta = 0; ieta < m_RawTowerGeom->get_etabins(); ieta++) + { + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::convert_name_to_caloid(m_SuperDetector), ieta, iphi); + + const double x(geom_ref_radius * cos(m_RawTowerGeom->get_phicenter(iphi))); + const double y(geom_ref_radius * sin(m_RawTowerGeom->get_phicenter(iphi))); + const double z(geom_ref_radius / tan(PHG4Utils::get_theta(m_RawTowerGeom->get_etacenter(ieta)))); + + RawTowerGeom *tg = m_RawTowerGeom->get_tower_geometry(key); + if (tg) + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - Tower geometry " << key << " already exists" << std::endl; + } + + if (fabs(tg->get_center_x() - x) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x + << std::endl; + + return; + } + if (fabs(tg->get_center_y() - y) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y + << std::endl; + return; + } + if (fabs(tg->get_center_z() - z) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z + << std::endl; + return; + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - building tower geometry " << key << "" << std::endl; + } + + tg = new RawTowerGeomv1(key); + + tg->set_center_x(x); + tg->set_center_y(y); + tg->set_center_z(z); + m_RawTowerGeom->add_tower_geometry(tg); + } + } + } + if (Verbosity() > 0) + { + m_RawTowerGeom->identify(); + } +} \ No newline at end of file diff --git a/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.h b/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.h index 1802d44893..b5fb54037f 100644 --- a/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.h +++ b/simulation/g4simulation/g4detectors/PHG4InnerHcalDetector.h @@ -11,7 +11,7 @@ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include // for Cartesian_base_ref_count::... #include -#include // for Point_2 +#include // for Point_2 #pragma GCC diagnostic pop #include @@ -28,6 +28,7 @@ class PHCompositeNode; class PHG4InnerHcalDisplayAction; class PHParameters; class PHG4Subsystem; +class RawTowerGeomContainer; class PHG4InnerHcalDetector : public PHG4Detector { @@ -66,6 +67,7 @@ class PHG4InnerHcalDetector : public PHG4Detector std::pair GetLayerTowerId(G4VPhysicalVolume *volume) const; protected: + void AddGeometryNode(); int ConstructInnerHcal(G4LogicalVolume *sandwich); double x_at_y(Point_2 &p0, Point_2 &p1, double yin); PHG4InnerHcalDisplayAction *m_DisplayAction = nullptr; @@ -103,6 +105,8 @@ class PHG4InnerHcalDetector : public PHG4Detector std::map> m_ScintiTilePhysVolMap; std::vector m_ScintiTilesVec; std::string m_ScintiLogicNamePrefix; + RawTowerGeomContainer *m_RawTowerGeom = nullptr; + std::string m_TowerGeomNodeName; }; #endif // G4DETECTORS_PHG4INNERHCALDETECTOR_H diff --git a/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.cc b/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.cc index 94d7bb23b0..8a7af50a0f 100644 --- a/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.cc +++ b/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.cc @@ -12,8 +12,20 @@ #include // for PHG4SteppingAction #include -#include +#include +#include + +#include +#include +#include +#include + +#include +#include // for PHIODataNode +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject #include #include @@ -26,21 +38,21 @@ #include // for G4ParticleDefinition #include // for G4ReferenceCountedHandle #include -#include // for G4StepPoint -#include // for fGeomBoundary, fAtRest... -#include // for G4String +#include // for G4StepPoint +#include // for fGeomBoundary, fAtRest... +#include // for G4String #include -#include // for G4ThreeVector -#include // for G4TouchableHandle -#include // for G4Track -#include // for fStopAndKill +#include // for G4ThreeVector +#include // for G4TouchableHandle +#include // for G4Track +#include // for fStopAndKill #include -#include // for G4double -#include // for G4VPhysicalVolume -#include // for G4VTouchable -#include // for G4VUserTrackInformation +#include // for G4double +#include // for G4VPhysicalVolume +#include // for G4VTouchable +#include // for G4VUserTrackInformation -#include // for isfinite +#include // for isfinite #include #include #include @@ -57,6 +69,10 @@ PHG4InnerHcalSteppingAction::PHG4InnerHcalSteppingAction(PHG4InnerHcalDetector* , m_IsActive(m_Params->get_int_param("active")) , m_IsBlackHole(m_Params->get_int_param("blackhole")) , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model")) + , m_doG4Hit(m_Params->get_int_param("saveg4hit")) + , m_tmin(m_Params->get_double_param("tmin")) + , m_tmax(m_Params->get_double_param("tmax")) + , m_dt(m_Params->get_double_param("dt")) { SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm, m_Params->get_double_param("light_balance_inner_corr"), @@ -76,7 +92,7 @@ PHG4InnerHcalSteppingAction::~PHG4InnerHcalSteppingAction() } //____________________________________________________________________________.. -int PHG4InnerHcalSteppingAction::Init() +int PHG4InnerHcalSteppingAction::InitWithNode(PHCompositeNode* topNode) { if (m_LightScintModelFlag) { @@ -85,7 +101,7 @@ int PHG4InnerHcalSteppingAction::Init() { return 0; } - std::string url = XploadInterface::instance()->getUrl("OLD_INNER_HCAL_TILEMAP", ihcalmapname); + std::string url = CDBInterface::instance()->getUrl("OLD_INNER_HCAL_TILEMAP", ihcalmapname); if (!std::filesystem::exists(url)) { std::cout << PHWHERE << " Could not locate " << url << std::endl; @@ -98,18 +114,137 @@ int PHG4InnerHcalSteppingAction::Init() { std::cout << "ERROR: could not find Histogram " << m_Params->get_string_param("MapHistoName") << " in " << m_Params->get_string_param("MapFileName") << std::endl; gSystem->Exit(1); - exit(1); // make code checkers which do not know gSystem->Exit() happy + exit(1); // make code checkers which do not know gSystem->Exit() happy } m_MapCorrHist->SetDirectory(nullptr); // rootism: this needs to be set otherwise histo vanished when closing the file file->Close(); delete file; } + if (!m_doG4Hit) + { + try + { + CreateNodeTree(topNode); + } + catch (std::exception& e) + { + std::cout << e.what() << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + if (Verbosity() > 1) topNode->print(); + } + return 0; } +//____________________________________________________________________________.. +bool PHG4InnerHcalSteppingAction::NoHitSteppingAction(const G4Step* aStep) +{ + G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); + G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); + // get volume of the current step + G4VPhysicalVolume* volume = touch->GetVolume(); + + // m_Detector->IsInIHCal(volume) + // returns + // 0 is outside of IHCal + // 1 is inside scintillator + // -1 is steel absorber + + int whichactive = m_Detector->IsInInnerHcal(volume); + + if (!whichactive) + { + return false; + } + int layer_id = -1; + int tower_id = -1; + if (whichactive > 0) // scintillator + { + std::pair layer_tower = m_Detector->GetLayerTowerId(volume); + layer_id = layer_tower.first; + tower_id = layer_tower.second; + + // std::cout<<"******** Inner HCal\t"<GetName()<<"\t"<GetPreStepPoint(); + G4StepPoint* postPoint = aStep->GetPostStepPoint(); + // time window cut + double pretime = prePoint->GetGlobalTime() / nanosecond; + double posttime = postPoint->GetGlobalTime() / nanosecond; + if (posttime < m_tmin || pretime > m_tmax) return false; + if ((posttime - pretime) > m_dt) return false; + G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV; + const G4Track* aTrack = aStep->GetTrack(); + // we only need visible energy here + double light_yield = eion; + + // correct evis using light map + if (m_LightScintModelFlag) + { + light_yield = GetVisibleEnergyDeposition(aStep); // for scintillator only, calculate light yields + if (m_MapCorrHist) + { + const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle(); + const G4ThreeVector& worldPosition = postPoint->GetPosition(); + G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition); + float lx = (localPosition.x() / cm); + float lz = fabs(localPosition.z() / cm); + // adjust to tilemap coordinates + int lcz = (int) (5.0 * lz) + 1; + int lcx = (int) (5.0 * (lx + 12.1)) + 1; + + if ((lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsY()) && + (lcz >= 1) && (lcz <= m_MapCorrHist->GetNbinsX())) + { + light_yield *= (double) (m_MapCorrHist->GetBinContent(lcz, lcx)); + } + else + { + light_yield = 0.0; + } + } + else + { + // old correction (linear ligh yield dependence along r), never tested + light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y()); + } + } + // find the tower index for this step, tower_id is ieta, layer_id/4 is iphi + unsigned int ieta = tower_id; + unsigned int iphi = (unsigned int) layer_id / 4; + unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi); + m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield); + // set keep for the track + if (light_yield > 0) + { + if (G4VUserTrackInformation* p = aTrack->GetUserInformation()) + { + if (PHG4TrackUserInfoV1* pp = dynamic_cast(p)) + { + pp->SetKeep(1); // we want to keep the track + } + } + } + + return true; +} + //____________________________________________________________________________.. bool PHG4InnerHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { + if ((!m_doG4Hit) && (!m_IsBlackHole)) + { + return NoHitSteppingAction(aStep); + } G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); // get volume of the current step @@ -203,18 +338,18 @@ bool PHG4InnerHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { m_Hit = new PHG4Hitv1(); } - //here we set the entrance values in cm + // here we set the entrance values in cm m_Hit->set_x(0, prePoint->GetPosition().x() / cm); m_Hit->set_y(0, prePoint->GetPosition().y() / cm); m_Hit->set_z(0, prePoint->GetPosition().z() / cm); // time in ns m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond); - //set and save the track ID + // set and save the track ID m_Hit->set_trkid(aTrack->GetTrackID()); m_SaveTrackId = aTrack->GetTrackID(); - //set the initial energy deposit + // set the initial energy deposit m_Hit->set_edep(0); - if (whichactive > 0) // return of IsInInnerHcalDetector, > 0 hit in scintillator, < 0 hit in absorber + if (whichactive > 0) // return of IsInInnerHcalDetector, > 0 hit in scintillator, < 0 hit in absorber { m_Hit->set_scint_id(tower_id); // the slat id m_Hit->set_eion(0); // only implemented for v5 otherwise empty @@ -282,7 +417,7 @@ bool PHG4InnerHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond); - //sum up the energy to get total deposited + // sum up the energy to get total deposited m_Hit->set_edep(m_Hit->get_edep() + edep); if (whichactive > 0) // return of IsInInnerHcalDetector, > 0 hit in scintillator, < 0 hit in absorber { @@ -299,7 +434,7 @@ bool PHG4InnerHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition); float lx = (localPosition.x() / cm); float lz = fabs(localPosition.z() / cm); - //adjust to tilemap coordinates + // adjust to tilemap coordinates int lcz = (int) (5.0 * lz) + 1; int lcx = (int) (5.0 * (lx + 12.1)) + 1; @@ -396,7 +531,7 @@ void PHG4InnerHcalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode) absorbernodename = "G4HIT_ABSORBER_" + m_Detector->GetName(); } - //now look for the map and grab a pointer to it. + // now look for the map and grab a pointer to it. m_Hits = findNode::getClass(topNode, hitnodename); m_AbsorberHits = findNode::getClass(topNode, absorbernodename); @@ -413,3 +548,26 @@ void PHG4InnerHcalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode) } } } + +void PHG4InnerHcalSteppingAction::CreateNodeTree(PHCompositeNode* topNode) +{ + PHNodeIterator nodeItr(topNode); + PHCompositeNode* dst_node = dynamic_cast( + nodeItr.findFirst("PHCompositeNode", "DST")); + if (!dst_node) + { + std::cout << "PHComposite node created: DST" << std::endl; + dst_node = new PHCompositeNode("DST"); + topNode->addNode(dst_node); + } + PHNodeIterator dstiter(dst_node); + PHCompositeNode* DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector())); + if (!DetNode) + { + DetNode = new PHCompositeNode(m_Detector->SuperDetector()); + dst_node->addNode(DetNode); + } + m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL); + PHIODataNode* towerNode = new PHIODataNode(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject"); + DetNode->addNode(towerNode); +} \ No newline at end of file diff --git a/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.h b/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.h index 4c6349feb8..1e0e61f43f 100644 --- a/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.h +++ b/simulation/g4simulation/g4detectors/PHG4InnerHcalSteppingAction.h @@ -8,6 +8,7 @@ class G4Step; class G4VPhysicalVolume; class PHCompositeNode; +class TowerInfoContainer; class PHG4InnerHcalDetector; class PHParameters; class PHG4Hit; @@ -27,12 +28,15 @@ class PHG4InnerHcalSteppingAction : public PHG4SteppingAction //! stepping action bool UserSteppingAction(const G4Step *, bool) override; - int Init() override; + int InitWithNode(PHCompositeNode *topNode) override; //! reimplemented from base class void SetInterfacePointers(PHCompositeNode *) override; + void CreateNodeTree(PHCompositeNode *topNode); + private: + bool NoHitSteppingAction(const G4Step *aStep); //! pointer to the detector PHG4InnerHcalDetector *m_Detector = nullptr; @@ -57,6 +61,11 @@ class PHG4InnerHcalSteppingAction : public PHG4SteppingAction int m_IsActive = -1; int m_IsBlackHole = -1; int m_LightScintModelFlag = -1; + bool m_doG4Hit = true; + double m_tmin = -20.; + double m_tmax = 60.; + double m_dt = 100.; + TowerInfoContainer *m_CaloInfoContainer = nullptr; }; #endif // G4DETECTORS_PHG4INNERHCALSTEPPINGACTION_H diff --git a/simulation/g4simulation/g4detectors/PHG4InnerHcalSubsystem.cc b/simulation/g4simulation/g4detectors/PHG4InnerHcalSubsystem.cc index aaf6f261a3..8a9e749da0 100644 --- a/simulation/g4simulation/g4detectors/PHG4InnerHcalSubsystem.cc +++ b/simulation/g4simulation/g4detectors/PHG4InnerHcalSubsystem.cc @@ -7,7 +7,7 @@ #include -#include // for PHG4DisplayAction +#include // for PHG4DisplayAction #include #include // for PHG4SteppingAction @@ -100,7 +100,7 @@ int PHG4InnerHcalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) // create stepping action m_SteppingAction = new PHG4InnerHcalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); } else { @@ -108,7 +108,7 @@ int PHG4InnerHcalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) if (GetParams()->get_int_param("blackhole")) { m_SteppingAction = new PHG4InnerHcalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); } } return 0; @@ -155,6 +155,7 @@ void PHG4InnerHcalSubsystem::SetDefaultParameters() set_default_double_param("light_balance_inner_radius", NAN); set_default_double_param("light_balance_outer_corr", NAN); set_default_double_param("light_balance_outer_radius", NAN); + set_default_double_param("phistart", NAN); set_default_double_param(PHG4HcalDefs::outerrad, 134.42); set_default_double_param("place_x", 0.); set_default_double_param("place_y", 0.); @@ -168,6 +169,9 @@ void PHG4InnerHcalSubsystem::SetDefaultParameters() set_default_double_param("scinti_gap_neighbor", 0.1); set_default_double_param("scinti_inner_gap", 0.85); set_default_double_param("scinti_outer_gap", 1.22 * (5.0 / 4.0)); + set_default_double_param("tmin", -20.); + set_default_double_param("tmax", 60.); + set_default_double_param("dt", 100.); // some math issue in the code subtracts 0.4mm so the scintillator // does not end at 133.09 as per drawing but at 133.05 // adding 0.4mm compensates for this (so 133.13 gives the desired 133.09 @@ -187,6 +191,8 @@ void PHG4InnerHcalSubsystem::SetDefaultParameters() set_default_int_param(PHG4HcalDefs::n_scinti_tiles, 12); set_default_int_param(PHG4HcalDefs::n_scinti_tiles_pos, 12); set_default_int_param(PHG4HcalDefs::n_scinti_tiles_neg, 12); + set_default_int_param("etabins", 24); + set_default_int_param("saveg4hit", 1); set_default_string_param("material", "G4_Al"); std::string defaultmapfilename; diff --git a/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.cc b/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.cc index 06964e03d1..97a2358f13 100644 --- a/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.cc +++ b/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.cc @@ -13,6 +13,18 @@ #include #include +#include +#include +#include // for PHNode +#include +#include // for PHObject +#include + +#include // for convert_name_... +#include // for RawTowerGeom +#include // for RawTowerGeomC... +#include +#include #include @@ -479,6 +491,7 @@ void PHG4OuterHcalDetector::ConstructMe(G4LogicalVolume *logicWorld) } ++it; } + if(!m_Params->get_int_param("saveg4hit")) AddGeometryNode(); return; } @@ -978,3 +991,120 @@ std::pair PHG4OuterHcalDetector::GetLayerTowerId(G4VPhysicalVolume *vo // terminates, so using the standard exit() makes them happy exit(1); } + +// This is dulplicated code, we can get rid of it when we have the code to make towergeom for real data reco. +void PHG4OuterHcalDetector::AddGeometryNode() +{ + PHNodeIterator iter(topNode()); + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) + { + std::cout << PHWHERE << "Run Node missing, exiting." << std::endl; + gSystem->Exit(1); + exit(1); + } + PHNodeIterator runIter(runNode); + PHCompositeNode *RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", m_SuperDetector)); + if (!RunDetNode) + { + RunDetNode = new PHCompositeNode(m_SuperDetector); + runNode->addNode(RunDetNode); + } + m_TowerGeomNodeName = "TOWERGEOM_" + m_SuperDetector; + m_RawTowerGeom = findNode::getClass(topNode(), m_TowerGeomNodeName); + if (!m_RawTowerGeom) + { + m_RawTowerGeom = new RawTowerGeomContainer_Cylinderv1(RawTowerDefs::convert_name_to_caloid(m_SuperDetector)); + PHIODataNode *newNode = new PHIODataNode(m_RawTowerGeom, m_TowerGeomNodeName, "PHObject"); + RunDetNode->addNode(newNode); + } + double innerrad = m_Params->get_double_param(PHG4HcalDefs::innerrad); + double thickness = m_Params->get_double_param(PHG4HcalDefs::outerrad) - innerrad; + m_RawTowerGeom->set_radius(innerrad); + m_RawTowerGeom->set_thickness(thickness); + m_RawTowerGeom->set_phibins(m_Params->get_int_param(PHG4HcalDefs::n_towers)); + m_RawTowerGeom->set_etabins(m_Params->get_int_param("etabins")); + double geom_ref_radius = innerrad + thickness / 2.; + double phistart = m_Params->get_double_param("phistart"); + if (!std::isfinite(phistart)) + { + std::cout << PHWHERE << " phistart is not finite: " << phistart + << ", exiting now (this will crash anyway)" << std::endl; + gSystem->Exit(1); + } + for (int i = 0; i < m_Params->get_int_param(PHG4HcalDefs::n_towers); i++) + { + double phiend = phistart + 2. * M_PI / m_Params->get_int_param(PHG4HcalDefs::n_towers); + std::pair range = std::make_pair(phiend, phistart); + phistart = phiend; + m_RawTowerGeom->set_phibounds(i, range); + } + double etalowbound = -m_Params->get_double_param("scinti_eta_coverage_neg"); + for (int i = 0; i < m_Params->get_int_param("etabins"); i++) + { + // double etahibound = etalowbound + 2.2 / get_int_param("etabins"); + double etahibound = etalowbound + + (m_Params->get_double_param("scinti_eta_coverage_neg") + m_Params->get_double_param("scinti_eta_coverage_pos")) / m_Params->get_int_param("etabins"); + std::pair range = std::make_pair(etalowbound, etahibound); + m_RawTowerGeom->set_etabounds(i, range); + etalowbound = etahibound; + } + for (int iphi = 0; iphi < m_RawTowerGeom->get_phibins(); iphi++) + { + for (int ieta = 0; ieta < m_RawTowerGeom->get_etabins(); ieta++) + { + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::convert_name_to_caloid(m_SuperDetector), ieta, iphi); + + const double x(geom_ref_radius * cos(m_RawTowerGeom->get_phicenter(iphi))); + const double y(geom_ref_radius * sin(m_RawTowerGeom->get_phicenter(iphi))); + const double z(geom_ref_radius / tan(PHG4Utils::get_theta(m_RawTowerGeom->get_etacenter(ieta)))); + + RawTowerGeom *tg = m_RawTowerGeom->get_tower_geometry(key); + if (tg) + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - Tower geometry " << key << " already exists" << std::endl; + } + + if (fabs(tg->get_center_x() - x) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x + << std::endl; + + return; + } + if (fabs(tg->get_center_y() - y) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y + << std::endl; + return; + } + if (fabs(tg->get_center_z() - z) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z + << std::endl; + return; + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - building tower geometry " << key << "" << std::endl; + } + + tg = new RawTowerGeomv1(key); + + tg->set_center_x(x); + tg->set_center_y(y); + tg->set_center_z(z); + m_RawTowerGeom->add_tower_geometry(tg); + } + } + } + if (Verbosity() > 0) + { + m_RawTowerGeom->identify(); + } +} diff --git a/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.h b/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.h index 0027343d7a..f4b9be894a 100644 --- a/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.h +++ b/simulation/g4simulation/g4detectors/PHG4OuterHcalDetector.h @@ -30,6 +30,7 @@ class PHG4OuterHcalDisplayAction; class PHG4OuterHcalFieldSetup; class PHParameters; class PHG4Subsystem; +class RawTowerGeomContainer; class PHG4OuterHcalDetector : public PHG4Detector { @@ -64,6 +65,7 @@ class PHG4OuterHcalDetector : public PHG4Detector std::pair GetLayerTowerId(G4VPhysicalVolume *volume) const; protected: + void AddGeometryNode(); int ConstructOuterHcal(G4LogicalVolume *hcalenvelope); G4VSolid *ConstructSteelPlate(G4LogicalVolume *hcalenvelope); G4AssemblyVolume *ConstructHcalScintillatorAssembly(G4LogicalVolume *hcalenvelope); @@ -104,6 +106,8 @@ class PHG4OuterHcalDetector : public PHG4Detector std::vector m_ScintiTilesVec; std::set m_SteelAbsorberVec; std::map> m_ScintiTilePhysVolMap; + RawTowerGeomContainer *m_RawTowerGeom = nullptr; + std::string m_TowerGeomNodeName; }; #endif diff --git a/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.cc b/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.cc index 159d84d329..6fc45716ef 100644 --- a/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.cc +++ b/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.cc @@ -9,8 +9,9 @@ #include -#include +#include +#include #include #include @@ -20,8 +21,18 @@ #include // for PHG4SteppingAction #include +#include +#include // for PHIODataNode +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject #include +#include +#include +#include +#include + // Root headers #include // for TAxis #include @@ -33,23 +44,23 @@ #include #include -#include // for G4ParticleDefinition +#include // for G4ParticleDefinition #include #include // for G4ReferenceCountedHandle #include -#include // for G4StepPoint -#include // for fGeomBoundary, fAtRest... -#include // for G4String +#include // for G4StepPoint +#include // for fGeomBoundary, fAtRest... +#include // for G4String #include -#include // for G4ThreeVector -#include // for G4TouchableHandle -#include // for G4Track -#include // for fStopAndKill +#include // for G4ThreeVector +#include // for G4TouchableHandle +#include // for G4Track +#include // for fStopAndKill #include -#include // for G4double -#include // for G4VPhysicalVolume -#include // for G4VTouchable -#include // for G4VUserTrackInformation +#include // for G4double +#include // for G4VPhysicalVolume +#include // for G4VTouchable +#include // for G4VUserTrackInformation // finally system headers #include @@ -72,6 +83,10 @@ PHG4OuterHcalSteppingAction::PHG4OuterHcalSteppingAction(PHG4OuterHcalDetector* , m_IsBlackHoleFlag(m_Params->get_int_param("blackhole")) , m_NScintiPlates(m_Params->get_int_param(PHG4HcalDefs::scipertwr) * m_Params->get_int_param("n_towers")) , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model")) + , m_doG4Hit(m_Params->get_int_param("saveg4hit")) + , m_tmin(m_Params->get_double_param("tmin")) + , m_tmax(m_Params->get_double_param("tmax")) + , m_dt(m_Params->get_double_param("dt")) { SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm, m_Params->get_double_param("light_balance_inner_corr"), @@ -90,7 +105,7 @@ PHG4OuterHcalSteppingAction::~PHG4OuterHcalSteppingAction() delete m_MapCorrHist; } -int PHG4OuterHcalSteppingAction::Init() +int PHG4OuterHcalSteppingAction::InitWithNode(PHCompositeNode* topNode) { m_EnableFieldCheckerFlag = m_Params->get_int_param("field_check"); if (m_LightScintModelFlag) @@ -100,7 +115,7 @@ int PHG4OuterHcalSteppingAction::Init() { return 0; } - std::string url = XploadInterface::instance()->getUrl("OLD_OUTER_HCAL_TILEMAP", mappingfilename); + std::string url = CDBInterface::instance()->getUrl("OLD_OUTER_HCAL_TILEMAP", mappingfilename); if (!std::filesystem::exists(url)) { std::cout << PHWHERE << " Could not locate " << url << std::endl; @@ -113,18 +128,142 @@ int PHG4OuterHcalSteppingAction::Init() { std::cout << "ERROR: could not find Histogram " << m_Params->get_string_param("MapHistoName") << " in " << m_Params->get_string_param("MapFileName") << std::endl; gSystem->Exit(1); - exit(1); // make code checkers which do not know gSystem->Exit() happy + exit(1); // make code checkers which do not know gSystem->Exit() happy } m_MapCorrHist->SetDirectory(nullptr); // rootism: this needs to be set otherwise histo vanished when closing the file file->Close(); delete file; } + if (!m_doG4Hit) + { + try + { + CreateNodeTree(topNode); + } + catch (std::exception& e) + { + std::cout << e.what() << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + if (Verbosity() > 1) topNode->print(); + } return 0; } +//____________________________________________________________________________.. +bool PHG4OuterHcalSteppingAction::NoHitSteppingAction(const G4Step* aStep) +{ + G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); + G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); + // get volume of the current step + G4VPhysicalVolume* volume = touch->GetVolume(); + + // m_Detector->IsInIHCal(volume) + // returns + // 0 is outside of IHCal + // 1 is inside scintillator + // -1 is steel absorber + + int whichactive = m_Detector->IsInOuterHcal(volume); + + if (!whichactive) + { + return false; + } + if (m_EnableFieldCheckerFlag) + { + FieldChecker(aStep); + } + int layer_id = -1; + int tower_id = -1; + if (whichactive > 0) // scintillator + { + std::pair layer_tower = m_Detector->GetLayerTowerId(volume); + layer_id = layer_tower.first; + tower_id = layer_tower.second; + + // std::cout<<"******** Outer HCal\t"<GetName()<<"\t"<GetPreStepPoint(); + G4StepPoint* postPoint = aStep->GetPostStepPoint(); + // time window cut + double pretime = prePoint->GetGlobalTime() / nanosecond; + double posttime = postPoint->GetGlobalTime() / nanosecond; + if (posttime < m_tmin || pretime > m_tmax) return false; + if ((posttime - pretime) > m_dt) return false; + G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV; + const G4Track* aTrack = aStep->GetTrack(); + // we only need visible energy here + double light_yield = eion; + + // correct evis using light map + if (m_LightScintModelFlag) + { + light_yield = GetVisibleEnergyDeposition(aStep); + if (m_MapCorrHist) + { + const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle(); + const G4ThreeVector& worldPosition = postPoint->GetPosition(); + G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition); + float lx = localPosition.x() / cm; + float lz = fabs(localPosition.z() / cm); // reverse the sense for towerid<12 + + // convert to the map bin coordinates: + // map is in 0.5 cm bins + int lcz = (int) (2.0 * lz) + 1; + int lcx = (int) (2.0 * (lx + 42.75)) + 1; + + if ((lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsY()) && + (lcz >= 1) && (lcz <= m_MapCorrHist->GetNbinsX())) + { + light_yield *= m_MapCorrHist->GetBinContent(lcz, lcx); + } + else + { + light_yield = 0.0; + } + } + else + { + // old correction (linear ligh yield dependence along r), never tested + light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y()); + } + } + // find the tower index for this step, tower_id is ieta, layer_id/5 is iphi + unsigned int ieta = tower_id; + unsigned int iphi = (unsigned int) layer_id / 5; + unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi); + m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield); + // set keep for the track + if (light_yield > 0) + { + if (G4VUserTrackInformation* p = aTrack->GetUserInformation()) + { + if (PHG4TrackUserInfoV1* pp = dynamic_cast(p)) + { + pp->SetKeep(1); // we want to keep the track + } + } + } + + return true; +} + //____________________________________________________________________________.. bool PHG4OuterHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { + if ((!m_doG4Hit) && (!m_IsBlackHoleFlag)) + { + return NoHitSteppingAction(aStep); + } G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); // get volume of the current step @@ -222,7 +361,7 @@ bool PHG4OuterHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { m_Hit = new PHG4Hitv1(); } - //here we set the entrance values in cm + // here we set the entrance values in cm m_Hit->set_x(0, prePoint->GetPosition().x() / cm); m_Hit->set_y(0, prePoint->GetPosition().y() / cm); m_Hit->set_z(0, prePoint->GetPosition().z() / cm); @@ -245,12 +384,12 @@ bool PHG4OuterHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) // time in ns m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond); - //set the track ID + // set the track ID m_Hit->set_trkid(aTrack->GetTrackID()); m_SaveTrackId = aTrack->GetTrackID(); - //set the initial energy deposit + // set the initial energy deposit m_Hit->set_edep(0); - if (whichactive > 0) // return of IsInOuterHcalDetector, > 0 hit in scintillator, < 0 hit in absorber + if (whichactive > 0) // return of IsInOuterHcalDetector, > 0 hit in scintillator, < 0 hit in absorber { m_Hit->set_scint_id(tower_id); // the slat id m_Hit->set_eion(0); @@ -316,7 +455,7 @@ bool PHG4OuterHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond); - //sum up the energy to get total deposited + // sum up the energy to get total deposited m_Hit->set_edep(m_Hit->get_edep() + edep); if (whichactive > 0) @@ -432,7 +571,7 @@ void PHG4OuterHcalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode) absorbernodename = "G4HIT_ABSORBER_" + m_Detector->GetName(); } - //now look for the map and grab a pointer to it. + // now look for the map and grab a pointer to it. m_Hits = findNode::getClass(topNode, hitnodename); m_AbsorberHits = findNode::getClass(topNode, absorbernodename); @@ -523,3 +662,26 @@ void PHG4OuterHcalSteppingAction::FieldChecker(const G4Step* aStep) << "," << globPosVec[1] / cm << " cm" << std::endl; } } + +void PHG4OuterHcalSteppingAction::CreateNodeTree(PHCompositeNode* topNode) +{ + PHNodeIterator nodeItr(topNode); + PHCompositeNode* dst_node = dynamic_cast( + nodeItr.findFirst("PHCompositeNode", "DST")); + if (!dst_node) + { + std::cout << "PHComposite node created: DST" << std::endl; + dst_node = new PHCompositeNode("DST"); + topNode->addNode(dst_node); + } + PHNodeIterator dstiter(dst_node); + PHCompositeNode* DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector())); + if (!DetNode) + { + DetNode = new PHCompositeNode(m_Detector->SuperDetector()); + dst_node->addNode(DetNode); + } + m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL); + PHIODataNode* towerNode = new PHIODataNode(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject"); + DetNode->addNode(towerNode); +} diff --git a/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.h b/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.h index 0c08cc7ba3..e93cd8b333 100644 --- a/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.h +++ b/simulation/g4simulation/g4detectors/PHG4OuterHcalSteppingAction.h @@ -8,6 +8,7 @@ class G4Step; class G4VPhysicalVolume; class PHCompositeNode; +class TowerInfoContainer; class PHG4OuterHcalDetector; class PHParameters; class PHG4Hit; @@ -27,15 +28,17 @@ class PHG4OuterHcalSteppingAction : public PHG4SteppingAction //! stepping action bool UserSteppingAction(const G4Step *, bool) override; - int Init() override; + int InitWithNode(PHCompositeNode *topNode) override; //! reimplemented from base class void SetInterfacePointers(PHCompositeNode *) override; void FieldChecker(const G4Step *); void EnableFieldChecker(const int i = 1) { m_EnableFieldCheckerFlag = i; } + void CreateNodeTree(PHCompositeNode *topNode); private: + bool NoHitSteppingAction(const G4Step *aStep); //! pointer to the detector PHG4OuterHcalDetector *m_Detector = nullptr; @@ -63,6 +66,11 @@ class PHG4OuterHcalSteppingAction : public PHG4SteppingAction int m_IsBlackHoleFlag = -1; int m_NScintiPlates = -1; int m_LightScintModelFlag = 0; + bool m_doG4Hit = true; + double m_tmin = -20.; + double m_tmax = 60.; + double m_dt = 100.; + TowerInfoContainer *m_CaloInfoContainer = nullptr; }; #endif // G4DETECTORS_PHG4OUTERHCALSTEPPINGACTION_H diff --git a/simulation/g4simulation/g4detectors/PHG4OuterHcalSubsystem.cc b/simulation/g4simulation/g4detectors/PHG4OuterHcalSubsystem.cc index fc905acbc3..43f472a040 100644 --- a/simulation/g4simulation/g4detectors/PHG4OuterHcalSubsystem.cc +++ b/simulation/g4simulation/g4detectors/PHG4OuterHcalSubsystem.cc @@ -7,7 +7,7 @@ #include -#include // for PHG4DisplayAction +#include // for PHG4DisplayAction #include #include // for PHG4SteppingAction @@ -98,14 +98,14 @@ int PHG4OuterHcalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) } // create stepping action m_SteppingAction = new PHG4OuterHcalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); } else { if (GetParams()->get_int_param("blackhole")) { m_SteppingAction = new PHG4OuterHcalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); } } @@ -157,6 +157,9 @@ void PHG4OuterHcalSubsystem::SetDefaultParameters() set_default_double_param("light_balance_inner_radius", NAN); set_default_double_param("light_balance_outer_corr", NAN); set_default_double_param("light_balance_outer_radius", NAN); + set_default_double_param("phistart", NAN); + set_default_double_param("scinti_eta_coverage_neg", 1.1); + set_default_double_param("scinti_eta_coverage_pos", 1.1); // some math issue in the code does not subtract the magnet cutout correctly // (maybe some factor of 2 in a G4 volume creation) // The engineering drawing values are: @@ -173,6 +176,9 @@ void PHG4OuterHcalSubsystem::SetDefaultParameters() set_default_double_param("rot_x", 0.); set_default_double_param("rot_y", 0.); set_default_double_param("rot_z", 0.); + set_default_double_param("tmin", -20.); + set_default_double_param("tmax", 60.); + set_default_double_param("dt", 100.); set_default_double_param("scinti_eta_coverage", 1.1); set_default_double_param("scinti_gap", 0.85); set_default_double_param("scinti_gap_neighbor", 0.1); @@ -190,6 +196,8 @@ void PHG4OuterHcalSubsystem::SetDefaultParameters() set_default_int_param("field_check", 0); set_default_int_param("light_scint_model", 1); set_default_int_param("magnet_cutout_first_scinti", 8); // tile start at 0, drawing tile starts at 1 + set_default_int_param("etabins", 24); + set_default_int_param("saveg4hit", 1); // if ncross is set (and tilt_angle is NAN) tilt_angle is calculated // from number of crossings diff --git a/simulation/g4simulation/g4detectors/PHG4SpacalDetector.cc b/simulation/g4simulation/g4detectors/PHG4SpacalDetector.cc index 51e744d0ee..054943fb46 100644 --- a/simulation/g4simulation/g4detectors/PHG4SpacalDetector.cc +++ b/simulation/g4simulation/g4detectors/PHG4SpacalDetector.cc @@ -6,13 +6,21 @@ * \date $$Date: 2015/02/10 15:39:26 $$ */ #include "PHG4SpacalDetector.h" +#include "PHG4CylinderGeom_Spacalv3.h" +#include "PHG4CylinderCellGeom_Spacalv1.h" +#include "PHG4CylinderGeom_Spacalv1.h" // for PHG4CylinderGeom_Spaca... + +#include "PHG4CellDefs.h" +#include "PHG4CylinderCellGeom.h" +#include "PHG4CylinderCellGeomContainer.h" #include "PHG4CylinderGeomContainer.h" #include "PHG4SpacalDisplayAction.h" #include // for PHG4Detector #include // for PHG4DisplayAction #include +#include #include #include @@ -25,18 +33,24 @@ #include #include +#include // for convert_name_... +#include // for RawTowerGeom +#include // for RawTowerGeomC... +#include +#include + #include #include #include #include #include -#include // for G4String +#include // for G4String #include #include // for G4ThreeVector #include // for G4Transform3D, G4RotateZ3D #include -#include // for G4double +#include // for G4double #include #include @@ -47,7 +61,7 @@ class PHG4CylinderGeom; //_______________________________________________________________ -//note this inactive thickness is ~1.5% of a radiation length +// note this inactive thickness is ~1.5% of a radiation length PHG4SpacalDetector::PHG4SpacalDetector(PHG4Subsystem *subsys, PHCompositeNode *Node, const std::string &dnam, @@ -118,7 +132,6 @@ int PHG4SpacalDetector::IsInCylinderActive(const G4VPhysicalVolume *volume) void PHG4SpacalDetector::ConstructMe(G4LogicalVolume *logicWorld) { assert(_geom); - fiber_core_step_limits = new G4UserLimits(_geom->get_fiber_core_step_size() * cm); Verbosity(_geom->get_construction_verbose()); @@ -320,13 +333,7 @@ PHG4SpacalDetector::Construct_AzimuthalSeg() << "_geom->get_fiber_distance() = " << _geom->get_fiber_distance() << std::endl; std::cout << "\t" - << "fiber_length = " << fiber_length / cm << std::endl; - std::cout << "\t" - << "z_step = " << z_step << std::endl; - std::cout << "\t" - << "_geom->get_azimuthal_bin() = " << _geom->get_azimuthal_n_sec() - << std::endl; - std::cout << "\t" + << "fiber_length = " << fiber_length << "_geom->get_azimuthal_distance() = " << _geom->get_azimuthal_distance() << std::endl; std::cout << "\t" @@ -385,3 +392,543 @@ void PHG4SpacalDetector::Print(const std::string & /*what*/) const return; } +// This is dulplicated code, we can get rid of it when we have the code to make towergeom for real data reco. +void PHG4SpacalDetector::AddTowerGeometryNode() +{ + PHNodeIterator iter(topNode()); + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) + { + std::cout << PHWHERE << "Run Node missing, doing nothing." << std::endl; + throw std::runtime_error("Failed to find Run node in PHG4SpacalDetector::AddGeometryNode"); + } + + PHNodeIterator runIter(runNode); + PHCompositeNode *RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", superdetector)); + if (!RunDetNode) + { + RunDetNode = new PHCompositeNode(superdetector); + runNode->addNode(RunDetNode); + } + + const RawTowerDefs::CalorimeterId caloid = RawTowerDefs::convert_name_to_caloid(superdetector); + + // get the cell geometry and build up the tower geometry object + std::string geonodename = "CYLINDERCELLGEOM_" + superdetector; + PHG4CylinderCellGeomContainer *cellgeos = findNode::getClass(topNode(), geonodename); + if (!cellgeos) + { + std::cout << PHWHERE << " " << geonodename + << " Node missing, doing nothing." << std::endl; + throw std::runtime_error( + "Failed to find " + geonodename + " node in PHG4SpacalDetector::AddGeometryNode"); + } + m_TowerGeomNodeName = "TOWERGEOM_" + superdetector; + m_RawTowerGeomContainer = findNode::getClass(topNode(), m_TowerGeomNodeName); + if (!m_RawTowerGeomContainer) + { + m_RawTowerGeomContainer = new RawTowerGeomContainer_Cylinderv1(caloid); + PHIODataNode *newNode = new PHIODataNode(m_RawTowerGeomContainer, m_TowerGeomNodeName, "PHObject"); + RunDetNode->addNode(newNode); + } + // fill the number of layers in the calorimeter + m_NumLayers = cellgeos->get_NLayers(); + + // Create the tower nodes on the tree + PHG4CylinderCellGeomContainer::ConstIterator miter; + PHG4CylinderCellGeomContainer::ConstRange begin_end = + cellgeos->get_begin_end(); + int ifirst = 1; + int first_layer = -1; + PHG4CylinderCellGeom *first_cellgeo = nullptr; + double inner_radius = 0; + double thickness = 0; + for (miter = begin_end.first; miter != begin_end.second; ++miter) + { + PHG4CylinderCellGeom *cellgeo = miter->second; + + if (Verbosity()) + { + cellgeo->identify(); + } + thickness += cellgeo->get_thickness(); + if (ifirst) + { + first_cellgeo = miter->second; + m_CellBinning = cellgeo->get_binning(); + m_NumPhiBins = cellgeo->get_phibins(); + m_PhiMin = cellgeo->get_phimin(); + m_PhiStep = cellgeo->get_phistep(); + if (m_CellBinning == PHG4CellDefs::etaphibinning || m_CellBinning == PHG4CellDefs::etaslatbinning) + { + m_NumEtaBins = cellgeo->get_etabins(); + m_EtaMin = cellgeo->get_etamin(); + m_EtaStep = cellgeo->get_etastep(); + } + else if (m_CellBinning == PHG4CellDefs::sizebinning) + { + m_NumEtaBins = cellgeo->get_zbins(); // bin eta in the same number of z bins + } + else if (m_CellBinning == PHG4CellDefs::spacalbinning) + { + // use eta definiton for each row of towers + m_NumEtaBins = cellgeo->get_etabins(); + } + else + { + std::cout << "PHG4SpacalDetector::AddGeometryNode::" << GetName() + << " - Fatal Error - unsupported cell binning method " + << m_CellBinning << std::endl; + } + inner_radius = cellgeo->get_radius(); + first_layer = cellgeo->get_layer(); + ifirst = 0; + } + else + { + if (m_CellBinning != cellgeo->get_binning()) + { + std::cout << "inconsistent binning method from " << m_CellBinning + << " layer " << cellgeo->get_layer() << ": " + << cellgeo->get_binning() << std::endl; + exit(1); + } + if (inner_radius > cellgeo->get_radius()) + { + std::cout << "radius of layer " << cellgeo->get_layer() << " is " + << cellgeo->get_radius() << " which smaller than radius " + << inner_radius << " of first layer in list " << first_layer + << std::endl; + } + if (m_NumPhiBins != cellgeo->get_phibins()) + { + std::cout << "mixing number of phibins, fisrt layer: " << m_NumPhiBins + << " layer " << cellgeo->get_layer() << ": " + << cellgeo->get_phibins() << std::endl; + exit(1); + } + if (m_PhiMin != cellgeo->get_phimin()) + { + std::cout << "mixing number of phimin, fisrt layer: " << m_PhiMin + << " layer " << cellgeo->get_layer() << ": " + << cellgeo->get_phimin() << std::endl; + exit(1); + } + if (m_PhiStep != cellgeo->get_phistep()) + { + std::cout << "mixing phisteps first layer: " << m_PhiStep << " layer " + << cellgeo->get_layer() << ": " << cellgeo->get_phistep() + << " diff: " << m_PhiStep - cellgeo->get_phistep() << std::endl; + exit(1); + } + if (m_CellBinning == PHG4CellDefs::etaphibinning || m_CellBinning == PHG4CellDefs::etaslatbinning) + { + if (m_NumEtaBins != cellgeo->get_etabins()) + { + std::cout << "mixing number of EtaBins , first layer: " + << m_NumEtaBins << " layer " << cellgeo->get_layer() << ": " + << cellgeo->get_etabins() << std::endl; + exit(1); + } + if (fabs(m_EtaMin - cellgeo->get_etamin()) > 1e-9) + { + std::cout << "mixing etamin, fisrt layer: " << m_EtaMin << " layer " + << cellgeo->get_layer() << ": " << cellgeo->get_etamin() + << " diff: " << m_EtaMin - cellgeo->get_etamin() << std::endl; + exit(1); + } + if (fabs(m_EtaStep - cellgeo->get_etastep()) > 1e-9) + { + std::cout << "mixing eta steps first layer: " << m_EtaStep + << " layer " << cellgeo->get_layer() << ": " + << cellgeo->get_etastep() << " diff: " + << m_EtaStep - cellgeo->get_etastep() << std::endl; + exit(1); + } + } + + else if (m_CellBinning == PHG4CellDefs::sizebinning) + { + if (m_NumEtaBins != cellgeo->get_zbins()) + { + std::cout << "mixing number of z bins , first layer: " << m_NumEtaBins + << " layer " << cellgeo->get_layer() << ": " + << cellgeo->get_zbins() << std::endl; + exit(1); + } + } + } + } + m_RawTowerGeomContainer->set_radius(inner_radius); + m_RawTowerGeomContainer->set_thickness(thickness); + m_RawTowerGeomContainer->set_phibins(m_NumPhiBins); + // m_RawTowerGeomContainer->set_phistep(m_PhiStep); + // m_RawTowerGeomContainer->set_phimin(m_PhiMin); + m_RawTowerGeomContainer->set_etabins(m_NumEtaBins); + + if (!first_cellgeo) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - ERROR - can not find first layer of cells " + << std::endl; + + exit(1); + } + + for (int ibin = 0; ibin < first_cellgeo->get_phibins(); ibin++) + { + const std::pair range = first_cellgeo->get_phibounds(ibin); + + m_RawTowerGeomContainer->set_phibounds(ibin, range); + } + + if (m_CellBinning == PHG4CellDefs::etaphibinning || m_CellBinning == PHG4CellDefs::etaslatbinning || m_CellBinning == PHG4CellDefs::spacalbinning) + { + const double r = inner_radius; + + for (int ibin = 0; ibin < first_cellgeo->get_etabins(); ibin++) + { + const std::pair range = first_cellgeo->get_etabounds(ibin); + + m_RawTowerGeomContainer->set_etabounds(ibin, range); + } + + // setup location of all towers + for (int iphi = 0; iphi < m_RawTowerGeomContainer->get_phibins(); iphi++) + { + for (int ieta = 0; ieta < m_RawTowerGeomContainer->get_etabins(); ieta++) + { + const RawTowerDefs::keytype key = + RawTowerDefs::encode_towerid(caloid, ieta, iphi); + + const double x(r * cos(m_RawTowerGeomContainer->get_phicenter(iphi))); + const double y(r * sin(m_RawTowerGeomContainer->get_phicenter(iphi))); + const double z(r / tan(PHG4Utils::get_theta(m_RawTowerGeomContainer->get_etacenter(ieta)))); + + RawTowerGeom *tg = m_RawTowerGeomContainer->get_tower_geometry(key); + if (tg) + { + if (Verbosity() > 0) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Tower geometry " << key << " already exists" << std::endl; + } + + if (fabs(tg->get_center_x() - x) > 1e-4) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x + << std::endl; + + exit(1); + } + if (fabs(tg->get_center_y() - y) > 1e-4) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y + << std::endl; + exit(1); + } + if (fabs(tg->get_center_z() - z) > 1e-4) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z + << std::endl; + exit(1); + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - building tower geometry " << key << "" << std::endl; + } + + tg = new RawTowerGeomv1(key); + + tg->set_center_x(x); + tg->set_center_y(y); + tg->set_center_z(z); + m_RawTowerGeomContainer->add_tower_geometry(tg); + } + } + } + } + else if (m_CellBinning == PHG4CellDefs::sizebinning) + { + const double r = inner_radius; + + for (int ibin = 0; ibin < first_cellgeo->get_zbins(); ibin++) + { + const std::pair z_range = first_cellgeo->get_zbounds(ibin); + // const double r = first_cellgeo->get_radius(); + const double eta1 = -log(tan(atan2(r, z_range.first) / 2.)); + const double eta2 = -log(tan(atan2(r, z_range.second) / 2.)); + m_RawTowerGeomContainer->set_etabounds(ibin, std::make_pair(eta1, eta2)); + } + + // setup location of all towers + for (int iphi = 0; iphi < m_RawTowerGeomContainer->get_phibins(); iphi++) + { + for (int ibin = 0; ibin < first_cellgeo->get_zbins(); ibin++) + { + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(caloid, ibin, iphi); + + const double x(r * cos(m_RawTowerGeomContainer->get_phicenter(iphi))); + const double y(r * sin(m_RawTowerGeomContainer->get_phicenter(iphi))); + const double z(first_cellgeo->get_zcenter(ibin)); + + RawTowerGeom *tg = m_RawTowerGeomContainer->get_tower_geometry(key); + if (tg) + { + if (Verbosity() > 0) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Tower geometry " << key << " already exists" << std::endl; + } + + if (fabs(tg->get_center_x() - x) > 1e-4) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x + << std::endl; + + exit(1); + } + if (fabs(tg->get_center_y() - y) > 1e-4) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y + << std::endl; + exit(1); + } + if (fabs(tg->get_center_z() - z) > 1e-4) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z + << std::endl; + exit(1); + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - building tower geometry " << key << "" << std::endl; + } + + tg = new RawTowerGeomv1(key); + + tg->set_center_x(x); + tg->set_center_y(y); + tg->set_center_z(z); + m_RawTowerGeomContainer->add_tower_geometry(tg); + } + } + } + } + else + { + std::cout << "PHG4SpacalDetector::AddGeometryNode - ERROR - unsupported cell geometry " + << m_CellBinning << std::endl; + exit(1); + } + + if (Verbosity() >= 1) + { + m_RawTowerGeomContainer->identify(); + } + + return; +} + +void PHG4SpacalDetector::AddCellGeometryNode() +{ + PHNodeIterator iter(topNode()); + std::string detector = superdetector; + // Looking for the DST node + PHCompositeNode *dstNode; + dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; + exit(1); + } + + std::string geonodename = "CYLINDERGEOM_" + detector; + PHG4CylinderGeomContainer *geo = findNode::getClass(topNode(), geonodename); + if (!geo) + { + std::cout << "PHG4SpacalDetector::AddCellGeometryNode - Could not locate geometry node " + << geonodename << std::endl; + topNode()->print(); + exit(1); + } + if (Verbosity() > 0) + { + std::cout << "PHG4SpacalDetector::AddCellGeometryNode- incoming geometry:" + << std::endl; + geo->identify(); + } + std::string seggeonodename = "CYLINDERCELLGEOM_" + detector; + PHG4CylinderCellGeomContainer *seggeo = findNode::getClass(topNode(), seggeonodename); + if (!seggeo) + { + seggeo = new PHG4CylinderCellGeomContainer(); + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + PHIODataNode *newNode = new PHIODataNode(seggeo, seggeonodename, "PHObject"); + runNode->addNode(newNode); + } + + const PHG4CylinderGeom *layergeom_raw = geo->GetFirstLayerGeom(); + assert(layergeom_raw); + + // a special implimentation of PHG4CylinderGeom is required here. + const PHG4CylinderGeom_Spacalv3 *layergeom = + dynamic_cast(layergeom_raw); + + if (!layergeom) + { + std::cout << "PHG4SpacalDetector::AddCellGeometryNode- Fatal Error -" + << " require to work with a version of SPACAL geometry of PHG4CylinderGeom_Spacalv3 or higher. " + << "However the incoming geometry has version " + << layergeom_raw->ClassName() << std::endl; + exit(1); + } + if (Verbosity() > 1) + { + layergeom->identify(); + } + + layergeom->subtower_consistency_check(); + + // int layer = layergeom->get_layer(); + + // create geo object and fill with variables common to all binning methods + PHG4CylinderCellGeom_Spacalv1 *layerseggeo = new PHG4CylinderCellGeom_Spacalv1(); + layerseggeo->set_layer(layergeom->get_layer()); + layerseggeo->set_radius(layergeom->get_radius()); + layerseggeo->set_thickness(layergeom->get_thickness()); + layerseggeo->set_binning(PHG4CellDefs::spacalbinning); + + // construct a map to convert tower_ID into the older eta bins. + + const PHG4CylinderGeom_Spacalv3::tower_map_t &tower_map = layergeom->get_sector_tower_map(); + const PHG4CylinderGeom_Spacalv3::sector_map_t §or_map = layergeom->get_sector_map(); + const int nphibin = layergeom->get_azimuthal_n_sec() // sector + * layergeom->get_max_phi_bin_in_sec() // blocks per sector + * layergeom->get_n_subtower_phi(); // subtower per block + const double deltaphi = 2. * M_PI / nphibin; + + using map_z_tower_z_ID_t = std::map; + map_z_tower_z_ID_t map_z_tower_z_ID; + double phi_min = NAN; + + for (const auto &tower_pair : tower_map) + { + const int &tower_ID = tower_pair.first; + const PHG4CylinderGeom_Spacalv3::geom_tower &tower = tower_pair.second; + + // inspect index in sector 0 + std::pair tower_z_phi_ID = layergeom->get_tower_z_phi_ID(tower_ID, 0); + + const int &tower_ID_z = tower_z_phi_ID.first; + const int &tower_ID_phi = tower_z_phi_ID.second; + + if (tower_ID_phi == 0) + { + // assign phi min according phi bin 0 + phi_min = M_PI_2 - deltaphi * (layergeom->get_max_phi_bin_in_sec() * layergeom->get_n_subtower_phi() / 2) // shift of first tower in sector + + sector_map.begin()->second; + } + + if (tower_ID_phi == layergeom->get_max_phi_bin_in_sec() / 2) + { + // assign eta min according phi bin 0 + map_z_tower_z_ID[tower.centralZ] = tower_ID_z; + } + // ... + } // const auto &tower_pair: tower_map + + assert(!std::isnan(phi_min)); + layerseggeo->set_phimin(phi_min); + layerseggeo->set_phistep(deltaphi); + layerseggeo->set_phibins(nphibin); + + PHG4CylinderCellGeom_Spacalv1::tower_z_ID_eta_bin_map_t tower_z_ID_eta_bin_map; + int eta_bin = 0; + for (auto &z_tower_z_ID : map_z_tower_z_ID) + { + tower_z_ID_eta_bin_map[z_tower_z_ID.second] = eta_bin; + eta_bin++; + } + layerseggeo->set_tower_z_ID_eta_bin_map(tower_z_ID_eta_bin_map); + layerseggeo->set_etabins(eta_bin * layergeom->get_n_subtower_eta()); + layerseggeo->set_etamin(NAN); + layerseggeo->set_etastep(NAN); + + // build eta bin maps + for (const auto &tower_pair : tower_map) + { + const int &tower_ID = tower_pair.first; + const PHG4CylinderGeom_Spacalv3::geom_tower &tower = tower_pair.second; + + // inspect index in sector 0 + std::pair tower_z_phi_ID = layergeom->get_tower_z_phi_ID(tower_ID, 0); + const int &tower_ID_z = tower_z_phi_ID.first; + const int &tower_ID_phi = tower_z_phi_ID.second; + const int &etabin = tower_z_ID_eta_bin_map[tower_ID_z]; + + if (tower_ID_phi == layergeom->get_max_phi_bin_in_sec() / 2) + { + // half z-range + const double dz = fabs(0.5 * (tower.pDy1 + tower.pDy2) / sin(tower.pRotationAngleX)); + const double tower_radial = layergeom->get_tower_radial_position(tower); + + auto z_to_eta = [&tower_radial](const double &z) + { return -log(tan(0.5 * atan2(tower_radial, z))); }; + + const double eta_central = z_to_eta(tower.centralZ); + // half eta-range + const double deta = (z_to_eta(tower.centralZ + dz) - z_to_eta(tower.centralZ - dz)) / 2; + assert(deta > 0); + + for (int sub_tower_ID_y = 0; sub_tower_ID_y < tower.NSubtowerY; + ++sub_tower_ID_y) + { + assert(tower.NSubtowerY <= layergeom->get_n_subtower_eta()); + // do not overlap to the next bin. + const int sub_tower_etabin = etabin * layergeom->get_n_subtower_eta() + sub_tower_ID_y; + + const std::pair etabounds(eta_central - deta + sub_tower_ID_y * 2 * deta / tower.NSubtowerY, + eta_central - deta + (sub_tower_ID_y + 1) * 2 * deta / tower.NSubtowerY); + + const std::pair zbounds(tower.centralZ - dz + sub_tower_ID_y * 2 * dz / tower.NSubtowerY, + tower.centralZ - dz + (sub_tower_ID_y + 1) * 2 * dz / tower.NSubtowerY); + + layerseggeo->set_etabounds(sub_tower_etabin, etabounds); + layerseggeo->set_zbounds(sub_tower_etabin, zbounds); + } + } + // ... + } // const auto &tower_pair: tower_map + + // add geo object filled by different binning methods + seggeo->AddLayerCellGeom(layerseggeo); + // save this to the run wise tree to store on DST + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + //PHCompositeNode *parNode = dynamic_cast(iter.findFirst("PHCompositeNode", "PAR")); + PHNodeIterator runIter(runNode); + PHCompositeNode *RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", detector)); + if (!RunDetNode) + { + RunDetNode = new PHCompositeNode(detector); + runNode->addNode(RunDetNode); + } + /* + std::string paramnodename = "G4CELLPARAM_" + detector; + SaveToNodeTree(RunDetNode, paramnodename); + save this to the parNode for use + PHNodeIterator parIter(parNode); + PHCompositeNode *ParDetNode = dynamic_cast(parIter.findFirst("PHCompositeNode", detector)); + if (!ParDetNode) + { + ParDetNode = new PHCompositeNode(detector); + parNode->addNode(ParDetNode); + } + std::string cellgeonodename = "G4CELLGEO_" + detector; + PutOnParNode(ParDetNode, cellgeonodename); + */ + return; +} \ No newline at end of file diff --git a/simulation/g4simulation/g4detectors/PHG4SpacalDetector.h b/simulation/g4simulation/g4detectors/PHG4SpacalDetector.h index 4857fcf8ba..bc8e742f86 100644 --- a/simulation/g4simulation/g4detectors/PHG4SpacalDetector.h +++ b/simulation/g4simulation/g4detectors/PHG4SpacalDetector.h @@ -12,6 +12,7 @@ #ifndef G4DETECTORS_PHG4SPACALDETECTOR_H #define G4DETECTORS_PHG4SPACALDETECTOR_H +#include "PHG4CellDefs.h" #include "PHG4CylinderGeom_Spacalv1.h" #include @@ -32,6 +33,7 @@ class PHG4GDMLConfig; class PHG4SpacalDisplayAction; class PHParameters; class PHG4Subsystem; +class RawTowerGeomContainer; class PHG4SpacalDetector : public PHG4Detector { @@ -121,6 +123,8 @@ class PHG4SpacalDetector : public PHG4Detector PHG4SpacalDisplayAction* m_DisplayAction = nullptr; protected: + void AddTowerGeometryNode(); + void AddCellGeometryNode(); std::map fiber_core_vol; //! map for G4VPhysicalVolume -> fiber ID @@ -136,6 +140,15 @@ class PHG4SpacalDetector : public PHG4Detector int absorberactive = 0; int layer = -9999; int m_CosmicSetupFlag = 0; + int m_CellBinning = PHG4CellDefs::undefined; + int m_NumLayers = -1; + int m_NumPhiBins = -1; + int m_NumEtaBins = -1; + double m_Emin = 1e-6; + double m_EtaMin = NAN; + double m_PhiMin = NAN; + double m_EtaStep = NAN; + double m_PhiStep = NAN; std::string detector_type; std::string superdetector; @@ -145,9 +158,12 @@ class PHG4SpacalDetector : public PHG4Detector //! registry for volumes that should not be exported, i.e. fibers PHG4GDMLConfig* gdml_config = nullptr; - //private: + // private: SpacalGeom_t* _geom = nullptr; + + RawTowerGeomContainer* m_RawTowerGeomContainer = nullptr; + std::string m_TowerGeomNodeName; }; #endif diff --git a/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.cc b/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.cc index 66de630953..06a0fe99db 100644 --- a/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.cc +++ b/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.cc @@ -10,6 +10,19 @@ #include "PHG4CylinderGeom_Spacalv3.h" #include "PHG4SpacalDetector.h" +#include "PHG4CellDefs.h" +#include "PHG4CylinderCellGeom.h" +#include "PHG4CylinderCellGeomContainer.h" +#include "PHG4CylinderCellGeom_Spacalv1.h" +#include "PHG4CylinderGeom.h" // for PHG4CylinderGeom +#include "PHG4CylinderGeomContainer.h" +#include "PHG4CylinderGeom_Spacalv1.h" // for PHG4CylinderGeom_Spaca... + +#include +#include +#include +#include + #include // for PHG4Hit #include #include @@ -17,39 +30,55 @@ #include // for PHG4SteppingAction #include +#include +#include +#include // for PHNode +#include +#include // for PHObject #include +#include // for PHWHERE +#include + +#include -#include // for G4IonisParamMat -#include // for G4Material +#include // for G4IonisParamMat +#include // for G4Material #include -#include // for G4ParticleDefinition +#include // for G4ParticleDefinition +#include // for G4ReferenceCountedHandle #include -#include // for G4StepPoint -#include // for fGeomBoundary, fAtRestD... -#include // for G4String +#include // for G4StepPoint +#include // for fGeomBoundary, fAtRestD... +#include // for G4String #include -#include // for G4ThreeVector -#include // for G4TouchableHandle -#include // for G4Track -#include // for fStopAndKill -#include // for G4double -#include // for G4VTouchable -#include // for G4VUserTrackInformation +#include // for G4ThreeVector +#include // for G4TouchableHandle +#include // for G4Track +#include // for fStopAndKill +#include +#include // for G4double +#include // for G4VTouchable +#include // for G4VUserTrackInformation #include #include // for isfinite #include // for exit #include -#include // for operator<<, char_traits +#include // for operator<<, char_traits class G4VPhysicalVolume; class PHCompositeNode; //____________________________________________________________________________.. -PHG4SpacalSteppingAction::PHG4SpacalSteppingAction(PHG4SpacalDetector* detector) - : PHG4SteppingAction(detector->GetName()) - , m_Detector(detector) +PHG4SpacalSteppingAction::PHG4SpacalSteppingAction(PHG4SpacalDetector *indetector, const PHParameters *parameters) + : PHG4SteppingAction(indetector->GetName()) + , m_Detector(indetector) + , m_Params(parameters) + , m_doG4Hit(m_Params->get_int_param("saveg4hit")) + , m_tmin(m_Params->get_double_param("tmin")) + , m_tmax(m_Params->get_double_param("tmax")) + , m_dt(m_Params->get_double_param("dt")) { } @@ -62,17 +91,231 @@ PHG4SpacalSteppingAction::~PHG4SpacalSteppingAction() delete m_Hit; } +int PHG4SpacalSteppingAction::InitWithNode(PHCompositeNode *topNode) +{ + if (m_doG4Hit) return 0; + PHNodeIterator iter(topNode); + detector = m_Detector->SuperDetector(); + // Looking for the DST node + PHCompositeNode *dstNode; + dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; + exit(1); + } + + // add towerinfo here + PHNodeIterator dstiter(dstNode); + PHCompositeNode *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", detector)); + if (!DetNode) + { + DetNode = new PHCompositeNode(detector); + dstNode->addNode(DetNode); + } + m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::EMCAL); + PHIODataNode *towerNode = new PHIODataNode(m_CaloInfoContainer, "TOWERINFO_SIM_" + detector, "PHObject"); + DetNode->addNode(towerNode); + + return 0; +} + +int PHG4SpacalSteppingAction::SetUpGeomNode(PHCompositeNode *topNode) +{ + if (m_geomsetup) return 0; + + if (m_doG4Hit) return 0; + PHNodeIterator iter(topNode); + detector = m_Detector->SuperDetector(); + + geonodename = "CYLINDERGEOM_" + detector; + seggeonodename = "CYLINDERCELLGEOM_" + detector; + // get the private layergeo + _layergeo = findNode::getClass(topNode, geonodename); + if (!_layergeo) + { + std::cout << "PHG4SpacalSteppingAction::InitWithNode - Fatal Error - Could not locate sim geometry node " + << geonodename << std::endl; + exit(1); + } + + _seggeo = findNode::getClass(topNode, seggeonodename); + if (!_seggeo) + { + std::cout << "PHG4FullProjSpacalCellReco::process_event - Fatal Error - could not locate cell geometry node " + << seggeonodename << std::endl; + exit(1); + } + PHG4CylinderCellGeom *_geo_raw = _seggeo->GetFirstLayerCellGeom(); + _geo = dynamic_cast(_geo_raw); + assert(_geo); + const PHG4CylinderGeom *_layergeom_raw = _layergeo->GetFirstLayerGeom(); + assert(_layergeom_raw); + // a special implimentation of PHG4CylinderGeom is required here. + _layergeom = dynamic_cast(_layergeom_raw); + assert(_layergeom); + m_geomsetup = true; + return 0; +} + +bool PHG4SpacalSteppingAction::NoHitSteppingAction(const G4Step *aStep) +{ + // get volume of the current step + G4VPhysicalVolume *volume = aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume(); + int isactive = m_Detector->IsInCylinderActive(volume); + if (isactive > PHG4SpacalDetector::INACTIVE) + { + G4StepPoint *prePoint = aStep->GetPreStepPoint(); + G4StepPoint *postPoint = aStep->GetPostStepPoint(); + // time window cut + double pretime = prePoint->GetGlobalTime() / nanosecond; + double posttime = postPoint->GetGlobalTime() / nanosecond; + if (posttime < m_tmin || pretime > m_tmax) return false; + if ((posttime - pretime) > m_dt) return false; + + int scint_id = -1; + + if ( // + m_Detector->get_geom()->get_config() == PHG4SpacalDetector::SpacalGeom_t::kFullProjective_2DTaper || + m_Detector->get_geom()->get_config() == PHG4SpacalDetector::SpacalGeom_t::kFullProjective_2DTaper_SameLengthFiberPerTower || + m_Detector->get_geom()->get_config() == PHG4SpacalDetector::SpacalGeom_t::kFullProjective_2DTaper_Tilted || + m_Detector->get_geom()->get_config() == PHG4SpacalDetector::SpacalGeom_t::kFullProjective_2DTaper_Tilted_SameLengthFiberPerTower // + ) + { + // SPACAL ID that is associated with towers + int sector_ID = 0; + int tower_ID = 0; + int fiber_ID = 0; + + if (isactive == PHG4SpacalDetector::FIBER_CORE) + { + fiber_ID = prePoint->GetTouchable()->GetReplicaNumber(1); + tower_ID = prePoint->GetTouchable()->GetReplicaNumber(2); + sector_ID = prePoint->GetTouchable()->GetReplicaNumber(3); + } + + else + { + return false; + } + + // compact the tower/sector/fiber ID into 32 bit scint_id, so we could save some space for SPACAL hits + scint_id = PHG4CylinderGeom_Spacalv3::scint_id_coder(sector_ID, tower_ID, fiber_ID).scint_ID; + } + else + { + // other configuraitons + if (isactive == PHG4SpacalDetector::FIBER_CORE) + { + scint_id = prePoint->GetTouchable()->GetReplicaNumber(2); + } + else + { + return false; + } + } + // decode scint_id + PHG4CylinderGeom_Spacalv3::scint_id_coder decoder(scint_id); + + // convert to z_ID, phi_ID + std::pair tower_z_phi_ID = _layergeom->get_tower_z_phi_ID(decoder.tower_ID, decoder.sector_ID); + const int &tower_ID_z = tower_z_phi_ID.first; + const int &tower_ID_phi = tower_z_phi_ID.second; + + PHG4CylinderGeom_Spacalv3::tower_map_t::const_iterator it_tower = + _layergeom->get_sector_tower_map().find(decoder.tower_ID); + assert(it_tower != _layergeom->get_sector_tower_map().end()); + + // convert tower_ID_z to to eta bin number + int etabin = -1; + try + { + etabin = _geo->get_etabin_block(tower_ID_z); // block eta bin + } + catch (std::exception &e) + { + std::cout << "Print cell geometry:" << std::endl; + _geo->identify(); + std::cout << "Print scint_id_coder:" << std::endl; + decoder.identify(); + std::cout << "PHG4SpacalSteppingAction::UserSteppingAction::" + << " - Fatal Error - " << e.what() << std::endl; + exit(1); + } + + const int sub_tower_ID_x = it_tower->second.get_sub_tower_ID_x(decoder.fiber_ID); + const int sub_tower_ID_y = it_tower->second.get_sub_tower_ID_y(decoder.fiber_ID); + unsigned short etabinshort = etabin * _layergeom->get_n_subtower_eta() + sub_tower_ID_y; + unsigned short phibin = tower_ID_phi * _layergeom->get_n_subtower_phi() + sub_tower_ID_x; + + // get light yield + double light_yield = GetVisibleEnergyDeposition(aStep); + + if (light_collection_model.use_fiber_model()) + { + const G4TouchableHandle &theTouchable0 = prePoint->GetTouchableHandle(); + const G4ThreeVector &worldPosition0 = prePoint->GetPosition(); + G4ThreeVector localPosition = theTouchable0->GetHistory()->GetTopTransform().TransformPoint(worldPosition0); + const double localz0 = localPosition.z(); + // post point + const G4TouchableHandle &theTouchable1 = postPoint->GetTouchableHandle(); + const G4ThreeVector &worldPosition1 = postPoint->GetPosition(); + localPosition = theTouchable1->GetHistory()->GetTopTransform().TransformPoint(worldPosition1); + const double localz1 = localPosition.z(); + + const double z = 0.5 * (localz0 + localz1); + assert(not std::isnan(z)); + + light_yield *= light_collection_model.get_fiber_transmission(z); + } + + // light yield correction from light guide collection efficiency: + if (light_collection_model.use_fiber_model()) + { + const double x = it_tower->second.get_position_fraction_x_in_sub_tower(decoder.fiber_ID); + const double y = it_tower->second.get_position_fraction_y_in_sub_tower(decoder.fiber_ID); + + light_yield *= light_collection_model.get_light_guide_efficiency(x, y); + } + unsigned int tower_key = TowerInfoDefs::encode_emcal(etabinshort, phibin); + m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield); + + // set keep for the track + const G4Track *aTrack = aStep->GetTrack(); + if (light_yield > 0) + { + if (G4VUserTrackInformation *p = aTrack->GetUserInformation()) + { + if (PHG4TrackUserInfoV1 *pp = dynamic_cast(p)) + { + pp->SetKeep(1); // we want to keep the track + } + } + } + return true; + } + else + { + return false; + } +} + //____________________________________________________________________________.. -bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) +bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step *aStep, bool) { + if (!m_doG4Hit) + { + return NoHitSteppingAction(aStep); + } + // get volume of the current step - G4VPhysicalVolume* volume = aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume(); + G4VPhysicalVolume *volume = aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume(); // collect energy and track length step by step G4double edep = aStep->GetTotalEnergyDeposit() / GeV; G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV; - const G4Track* aTrack = aStep->GetTrack(); + const G4Track *aTrack = aStep->GetTrack(); int layer_id = m_Detector->get_Layer(); // make sure we are in a volume @@ -89,8 +332,8 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { geantino = true; } - G4StepPoint* prePoint = aStep->GetPreStepPoint(); - G4StepPoint* postPoint = aStep->GetPostStepPoint(); + G4StepPoint *prePoint = aStep->GetPreStepPoint(); + G4StepPoint *postPoint = aStep->GetPostStepPoint(); int scint_id = -1; if ( // @@ -100,7 +343,7 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) m_Detector->get_geom()->get_config() == PHG4SpacalDetector::SpacalGeom_t::kFullProjective_2DTaper_Tilted_SameLengthFiberPerTower // ) { - //SPACAL ID that is associated with towers + // SPACAL ID that is associated with towers int sector_ID = 0; int tower_ID = 0; int fiber_ID = 0; @@ -169,17 +412,17 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) } m_Hit->set_layer((unsigned int) layer_id); m_Hit->set_scint_id(scint_id); // isactive contains the scintillator slat id - //here we set the entrance values in cm + // here we set the entrance values in cm m_Hit->set_x(0, prePoint->GetPosition().x() / cm); m_Hit->set_y(0, prePoint->GetPosition().y() / cm); m_Hit->set_z(0, prePoint->GetPosition().z() / cm); // time in ns m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond); - //set the track ID + // set the track ID m_Hit->set_trkid(aTrack->GetTrackID()); m_SaveTrackid = aTrack->GetTrackID(); - //set the initial energy deposit + // set the initial energy deposit m_Hit->set_edep(0); // Now add the hit if (isactive == PHG4SpacalDetector::FIBER_CORE) // the slat ids start with zero @@ -194,9 +437,9 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { m_CurrentHitContainer = m_AbsorberHitContainer; } - if (G4VUserTrackInformation* p = aTrack->GetUserInformation()) + if (G4VUserTrackInformation *p = aTrack->GetUserInformation()) { - if (PHG4TrackUserInfoV1* pp = dynamic_cast(p)) + if (PHG4TrackUserInfoV1 *pp = dynamic_cast(p)) { m_Hit->set_trkid(pp->GetUserTrackId()); m_Hit->set_shower_id(pp->GetShower()->get_id()); @@ -241,7 +484,7 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) m_Hit->set_z(1, postPoint->GetPosition().z() / cm); m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond); - //sum up the energy to get total deposited + // sum up the energy to get total deposited m_Hit->set_edep(m_Hit->get_edep() + edep); if (isactive == PHG4SpacalDetector::FIBER_CORE) // only for active areas @@ -295,9 +538,9 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) } if (edep > 0) { - if (G4VUserTrackInformation* p = aTrack->GetUserInformation()) + if (G4VUserTrackInformation *p = aTrack->GetUserInformation()) { - if (PHG4TrackUserInfoV1* pp = dynamic_cast(p)) + if (PHG4TrackUserInfoV1 *pp = dynamic_cast(p)) { pp->SetKeep(1); // we want to keep the track } @@ -344,14 +587,19 @@ bool PHG4SpacalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) } //____________________________________________________________________________.. -void PHG4SpacalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode) +void PHG4SpacalSteppingAction::SetInterfacePointers(PHCompositeNode *topNode) { + // we can only play with the geometry node after ConstructMe is called + if ((!m_geomsetup) && (!m_doG4Hit)) + { + SetUpGeomNode(topNode); + } m_HitContainer = findNode::getClass(topNode, m_HitNodeName); m_AbsorberHitContainer = findNode::getClass(topNode, m_AbsorberNodeName); // if we do not find the node it's messed up. if (!m_HitContainer) { - std::cout << "PHG4ZDCSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl; + std::cout << "PHG4SpacalSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl; gSystem->Exit(1); } // this is perfectly fine if absorber hits are disabled @@ -359,7 +607,7 @@ void PHG4SpacalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode) { if (Verbosity() > 0) { - std::cout << "PHG4ZDCSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl; + std::cout << "PHG4SpacalSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl; } } } @@ -390,7 +638,7 @@ PHG4SpacalSteppingAction::get_zmax() const } } -void PHG4SpacalSteppingAction::SetHitNodeName(const std::string& type, const std::string& name) +void PHG4SpacalSteppingAction::SetHitNodeName(const std::string &type, const std::string &name) { if (type == "G4HIT") { @@ -406,3 +654,4 @@ void PHG4SpacalSteppingAction::SetHitNodeName(const std::string& type, const std gSystem->Exit(1); return; } + diff --git a/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.h b/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.h index 5111c81734..31e2fb5147 100644 --- a/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.h +++ b/simulation/g4simulation/g4detectors/PHG4SpacalSteppingAction.h @@ -11,20 +11,29 @@ #ifndef G4DETECTORS_PHG4SPACALSTEPPINGACTION_H #define G4DETECTORS_PHG4SPACALSTEPPINGACTION_H +#include "LightCollectionModel.h" + #include class G4Step; +class LightCollectionModel; class PHCompositeNode; +class PHG4CylinderCellGeomContainer; +class PHG4CylinderCellGeom_Spacalv1; +class PHG4CylinderGeomContainer; +class PHG4CylinderGeom_Spacalv3; class PHG4SpacalDetector; class PHG4Hit; class PHG4HitContainer; class PHG4Shower; +class PHParameters; +class TowerInfoContainer; class PHG4SpacalSteppingAction : public PHG4SteppingAction { public: //! ctor - explicit PHG4SpacalSteppingAction(PHG4SpacalDetector *); + explicit PHG4SpacalSteppingAction(PHG4SpacalDetector *, const PHParameters *parameters); //! dtor ~PHG4SpacalSteppingAction() override; @@ -32,6 +41,8 @@ class PHG4SpacalSteppingAction : public PHG4SteppingAction //! stepping action bool UserSteppingAction(const G4Step *, bool) override; + int InitWithNode(PHCompositeNode *topNode) override; + //! reimplemented from base class void SetInterfacePointers(PHCompositeNode *) override; @@ -41,7 +52,12 @@ class PHG4SpacalSteppingAction : public PHG4SteppingAction void SetHitNodeName(const std::string &type, const std::string &name) override; + int SetUpGeomNode(PHCompositeNode *topNode); + + LightCollectionModel &get_light_collection_model() { return light_collection_model; } + private: + bool NoHitSteppingAction(const G4Step *aStep); //! pointer to the detector PHG4SpacalDetector *m_Detector = nullptr; @@ -51,11 +67,32 @@ class PHG4SpacalSteppingAction : public PHG4SteppingAction PHG4Hit *m_Hit = nullptr; PHG4HitContainer *m_CurrentHitContainer = nullptr; PHG4Shower *m_CurrentShower = nullptr; + const PHParameters *m_Params = nullptr; int m_SaveTrackid = -1; int m_SavePostStepStatus = -1; + bool m_doG4Hit = true; + bool m_geomsetup = false; + double m_tmin = -20.; + double m_tmax = 60.; + double m_dt = 100.; std::string m_AbsorberNodeName; std::string m_HitNodeName; + std::string detector; + std::string geonodename; + std::string seggeonodename; + + TowerInfoContainer *m_CaloInfoContainer = nullptr; + + PHG4CylinderCellGeomContainer *_seggeo = nullptr; + + PHG4CylinderGeomContainer *_layergeo = nullptr; + + PHG4CylinderCellGeom_Spacalv1 *_geo = nullptr; + + const PHG4CylinderGeom_Spacalv3 *_layergeom = nullptr; + + LightCollectionModel light_collection_model; }; #endif // PHG4VHcalSteppingAction_h diff --git a/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.cc b/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.cc index f83b784a66..679e736c39 100644 --- a/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.cc +++ b/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.cc @@ -16,7 +16,7 @@ #include -#include // for PHG4DisplayAction +#include // for PHG4DisplayAction #include #include // for PHG4SteppingAction @@ -29,8 +29,10 @@ #include +#include #include // for operator<<, basic_ostream #include +#include class PHG4Detector; @@ -137,7 +139,13 @@ int PHG4SpacalSubsystem::InitRunSubsystem(PHCompositeNode* topNode) g4_hits->AddLayer(GetLayer()); } - steppingAction_ = new PHG4SpacalSteppingAction(detector_); + steppingAction_ = new PHG4SpacalSteppingAction(detector_, GetParams()); + steppingAction_->InitWithNode(topNode); + const char* calibrationRoot = getenv("CALIBRATIONROOT"); + assert(calibrationRoot != nullptr && "Environment variable CALIBRATIONROOT is not set"); + std::string filePath = std::string(calibrationRoot) + "/CEMC/LightCollection/Prototype3Module.xml"; + steppingAction_->get_light_collection_model().load_data_file( + filePath, "data_grid_light_guide_efficiency", "data_grid_fiber_trans"); steppingAction_->SetHitNodeName("G4HIT", m_HitNodeName); steppingAction_->SetHitNodeName("G4HIT_ABSORBER", m_AbsorberNodeName); } @@ -151,6 +159,7 @@ int PHG4SpacalSubsystem::process_event(PHCompositeNode* topNode) // relevant nodes needed internally if (steppingAction_) { + steppingAction_->SetInterfacePointers(topNode); } return 0; @@ -179,12 +188,16 @@ void PHG4SpacalSubsystem::SetDefaultParameters() set_default_double_param("radius", 90.); set_default_double_param("zmin", -149.470000); set_default_double_param("zmax", 149.470000); + set_default_double_param("tmin", -20.); + set_default_double_param("tmax", 60.); + set_default_double_param("dt", 100.); set_default_int_param("azimuthal_n_sec", 256); set_default_int_param("construction_verbose", 0.); set_default_int_param("azimuthal_seg_visible", 0.); set_default_int_param("virualize_fiber", 0.); set_default_int_param("config", static_cast(PHG4CylinderGeom_Spacalv1::kNonProjective)); + set_default_int_param("saveg4hit", 1); set_default_double_param("divider_width", 0); // radial size of the divider between blocks. <=0 means no dividers set_default_string_param("divider_mat", "G4_AIR"); // materials of the divider. G4_AIR is equivalent to not installing one in the term of material distribution diff --git a/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.h b/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.h index 87a1fe7ffb..dfef357d3f 100644 --- a/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.h +++ b/simulation/g4simulation/g4detectors/PHG4SpacalSubsystem.h @@ -12,6 +12,7 @@ #define G4DETECTORS_PHG4SPACALSUBSYSTEM_H #include "PHG4DetectorSubsystem.h" +#include "PHG4SpacalSteppingAction.h" #include // for string @@ -19,7 +20,7 @@ class PHCompositeNode; class PHG4Detector; class PHG4DisplayAction; class PHG4SpacalDetector; -class PHG4SteppingAction; +class PHG4SpacalSteppingAction; class PHG4SpacalSubsystem : public PHG4DetectorSubsystem { @@ -69,7 +70,7 @@ class PHG4SpacalSubsystem : public PHG4DetectorSubsystem //! particle tracking "stepping" action /*! derives from PHG4SteppingActions */ - PHG4SteppingAction *steppingAction_ = nullptr; + PHG4SpacalSteppingAction *steppingAction_ = nullptr; //! display attribute setting /*! derives from PHG4DisplayAction */ diff --git a/simulation/g4simulation/g4dst/Makefile.am b/simulation/g4simulation/g4dst/Makefile.am index f888ee6dce..c8e9be23e5 100644 --- a/simulation/g4simulation/g4dst/Makefile.am +++ b/simulation/g4simulation/g4dst/Makefile.am @@ -11,6 +11,7 @@ lib_LTLIBRARIES = \ libg4dst_la_LDFLAGS = \ -L$(libdir) \ -L$(OFFLINE_MAIN)/lib \ + -lbbc_io \ -lcalo_io \ -lcalotrigger_io \ -lcentrality_io \ @@ -23,7 +24,7 @@ libg4dst_la_LDFLAGS = \ -lg4intt_io \ -lg4jets_io \ -lg4tracking_io \ - -lg4vertex_io \ + -lglobalvertex_io \ -lintt_io \ -ljetbackground_io \ -lkfparticle_sphenix_io \ diff --git a/simulation/g4simulation/g4epd/PHG4EPDModuleReco.cc b/simulation/g4simulation/g4epd/PHG4EPDModuleReco.cc index 2fd9ab5a3f..95d0691c2c 100644 --- a/simulation/g4simulation/g4epd/PHG4EPDModuleReco.cc +++ b/simulation/g4simulation/g4epd/PHG4EPDModuleReco.cc @@ -1,9 +1,9 @@ - #include "PHG4EPDModuleReco.h" #include #include #include +#include #include #include @@ -51,17 +51,46 @@ int PHG4EPDModuleReco::InitRun(PHCompositeNode *topNode) CreateNodes(topNode); PHNodeIterator node_itr(topNode); PHCompositeNode *runNode = dynamic_cast(node_itr.findFirst("PHCompositeNode", "RUN")); - if (!runNode) { + if (!runNode) + { std::cout << PHWHERE << "RUN Node not found - that is fatal" << std::endl; gSystem->Exit(1); exit(1); } - EpdGeom *epdGeom = findNode::getClass(topNode,"TOWERGEOM_EPD"); - if (!epdGeom) { + + PHNodeIterator runiter(runNode); + PHCompositeNode *DetNode = dynamic_cast(runiter.findFirst("PHCompositeNode", m_Detector)); + if (!DetNode) + { + DetNode = new PHCompositeNode(m_Detector); + runNode->addNode(DetNode); + } + + EpdGeom *epdGeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); + if (!epdGeom) + { epdGeom = new EpdGeomV1(); PHIODataNode *newNode = new PHIODataNode(epdGeom, "TOWERGEOM_EPD", "PHObject"); - runNode->addNode(newNode); + DetNode->addNode(newNode); } + + // fill epd geometry + unsigned int epdchannels = 744; + for (unsigned int ch = 0; ch < epdchannels; ch++) + { + unsigned int thiskey = TowerInfoDefs::encode_epd(ch); + epdGeom->set_z(thiskey, GetTileZ(TowerInfoDefs::get_epd_arm(thiskey))); + epdGeom->set_r(thiskey, GetTileR(TowerInfoDefs::get_epd_rbin(thiskey))); + if (TowerInfoDefs::get_epd_rbin(thiskey) == 0) + { + epdGeom->set_phi0(thiskey, GetTilePhi0(TowerInfoDefs::get_epd_phibin(thiskey))); + } + else + { + epdGeom->set_phi(thiskey, GetTilePhi(TowerInfoDefs::get_epd_phibin(thiskey))); + } + } + return Fun4AllReturnCodes::EVENT_OK; } @@ -123,13 +152,15 @@ int PHG4EPDModuleReco::process_event(PHCompositeNode *topNode) { unsigned int globalphi = Getphimap(j) + 2 * i; unsigned int r = Getrmap(j); - - unsigned int key = globalphi + (r << 10U) + (k << 20U); - + + if (r == 0) + { + globalphi = i; + } + + unsigned int key = TowerInfoDefs::encode_epd(k, r, globalphi); unsigned int ch = m_TowerInfoContainer->decode_key(key); - m_TowerInfoContainer->get_tower_at_channel(ch)->set_energy(m_EpdTile_e[k][i][j]); - m_TowerInfoContainer_calib->get_tower_at_channel(ch)->set_energy(m_EpdTile_Calib_e[k][i][j]); } } @@ -155,18 +186,42 @@ void PHG4EPDModuleReco::set_timing_window(const double tmi, const double tma) int PHG4EPDModuleReco::Getrmap(int rindex) { - int rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + static const int rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; return rmap[rindex]; } int PHG4EPDModuleReco::Getphimap(int phiindex) { - int phimap[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + static const int phimap[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; return phimap[phiindex]; } +float PHG4EPDModuleReco::GetTilePhi(int thisphi) +{ + static const float tilephi[24] = {0.13089969, 0.39269908, 0.65449847, 0.91629786, 1.17809725, 1.43989663, 1.70169602, 1.96349541, 2.2252948, 2.48709418, 2.74889357, 3.01069296, 3.27249235, 3.53429174, 3.79609112, 4.05789051, 4.3196899, 4.58148929, 4.84328867, 5.10508806, 5.36688745, 5.62868684, 5.89048623, 6.15228561}; + return tilephi[thisphi]; +} + +float PHG4EPDModuleReco::GetTilePhi0(int thisphi0) +{ + static const float tilephi0[12] = {0.26179939, 0.78539816, 1.30899694, 1.83259571, 2.35619449, 2.87979327, 3.40339204, 3.92699082, 4.45058959, 4.97418837, 5.49778714, 6.02138592}; + return tilephi0[thisphi0]; +} + +float PHG4EPDModuleReco::GetTileR(int thisr) +{ + static const float tileR[16] = {6.8, 11.2, 15.6, 20.565, 26.095, 31.625, 37.155, 42.685, 48.215, 53.745, 59.275, 64.805, 70.335, 75.865, 81.395, 86.925}; + return tileR[thisr]; +} + +float PHG4EPDModuleReco::GetTileZ(int thisz) +{ + static const float tileZ[2] = {-316.0, 316.0}; + return tileZ[thisz]; +} + void PHG4EPDModuleReco::CreateNodes(PHCompositeNode *topNode) { PHNodeIterator iter(topNode); @@ -186,7 +241,7 @@ void PHG4EPDModuleReco::CreateNodes(PHCompositeNode *topNode) dstNode->addNode(DetNode); } - m_TowerInfoNodeName = "TOWERINFO_" + m_EPDSimTowerNodePrefix + "_" + m_Detector; // detector name and prefix are set by now + m_TowerInfoNodeName = "TOWERINFO_" + m_EPDSimTowerNodePrefix + "_" + m_Detector; // detector name and prefix are set by now TowerInfoContainer *m_TowerInfoContainer = findNode::getClass(DetNode, m_TowerInfoNodeName); if (m_TowerInfoContainer == nullptr) { @@ -195,7 +250,7 @@ void PHG4EPDModuleReco::CreateNodes(PHCompositeNode *topNode) DetNode->addNode(TowerInfoNode); } - m_TowerInfoNodeName_calib = "TOWERINFO_" + m_EPDCalibTowerNodePrefix + "_" + m_Detector; // detector name and prefix are set by now + m_TowerInfoNodeName_calib = "TOWERINFO_" + m_EPDCalibTowerNodePrefix + "_" + m_Detector; // detector name and prefix are set by now TowerInfoContainer *m_TowerInfoContainer_calib = findNode::getClass(DetNode, m_TowerInfoNodeName_calib); if (m_TowerInfoContainer_calib == nullptr) { diff --git a/simulation/g4simulation/g4epd/PHG4EPDModuleReco.h b/simulation/g4simulation/g4epd/PHG4EPDModuleReco.h index aa0fd6f2aa..ac3f9cc4b0 100644 --- a/simulation/g4simulation/g4epd/PHG4EPDModuleReco.h +++ b/simulation/g4simulation/g4epd/PHG4EPDModuleReco.h @@ -62,6 +62,10 @@ class PHG4EPDModuleReco : public SubsysReco, public PHParameterInterface private: int Getrmap(int rindex); int Getphimap(int phiindex); + float GetTilePhi(int thisphi); + float GetTilePhi0(int thisphi0); + float GetTileR(int thisr); + float GetTileZ(int thisz); void CreateNodes(PHCompositeNode *topNode); std::string m_Detector; diff --git a/simulation/g4simulation/g4eval/CaloEvaluator.cc b/simulation/g4simulation/g4eval/CaloEvaluator.cc index e68fb1aa6c..a3b60139cb 100644 --- a/simulation/g4simulation/g4eval/CaloEvaluator.cc +++ b/simulation/g4simulation/g4eval/CaloEvaluator.cc @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/simulation/g4simulation/g4eval/CaloEvaluator.h b/simulation/g4simulation/g4eval/CaloEvaluator.h index 9425681e44..a239a71a26 100644 --- a/simulation/g4simulation/g4eval/CaloEvaluator.h +++ b/simulation/g4simulation/g4eval/CaloEvaluator.h @@ -38,6 +38,13 @@ class CaloEvaluator : public SubsysReco int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; + // allow user to set the value of the event number + // useful for condor simulation submissions + // must be called after Init() + void set_event(int ievent) { + _ievent = ievent; + } + void set_strict(bool b) { _strict = b; } // funtions to limit the tracing to only part of the event --------- // and speed up the evaluation diff --git a/simulation/g4simulation/g4eval/DSTEmulator.cc b/simulation/g4simulation/g4eval/DSTEmulator.cc index 7e8a3b1ab2..be05cac475 100644 --- a/simulation/g4simulation/g4eval/DSTEmulator.cc +++ b/simulation/g4simulation/g4eval/DSTEmulator.cc @@ -570,9 +570,6 @@ int DSTEmulator::load_nodes( PHCompositeNode* topNode ) // local container m_container = findNode::getClass(topNode, "TrackEvaluationContainer"); - // hitset container - m_hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); - // g4hits m_g4hits_tpc = findNode::getClass(topNode, "G4HIT_TPC"); m_g4hits_intt = findNode::getClass(topNode, "G4HIT_INTT"); diff --git a/simulation/g4simulation/g4eval/DSTEmulator.h b/simulation/g4simulation/g4eval/DSTEmulator.h index 26929b0e8a..2a8d0f353e 100644 --- a/simulation/g4simulation/g4eval/DSTEmulator.h +++ b/simulation/g4simulation/g4eval/DSTEmulator.h @@ -80,9 +80,6 @@ class DSTEmulator : public SubsysReco //! evaluation node TrackEvaluationContainerv1* m_container = nullptr; - //! hits - TrkrHitSetContainer* m_hitsetcontainer = nullptr; - //! clusters TrkrClusterContainer* m_cluster_map = nullptr; diff --git a/simulation/g4simulation/g4eval/EventEvaluator.cc b/simulation/g4simulation/g4eval/EventEvaluator.cc index 0ffdc93ee3..99dd1e3fb7 100644 --- a/simulation/g4simulation/g4eval/EventEvaluator.cc +++ b/simulation/g4simulation/g4eval/EventEvaluator.cc @@ -12,8 +12,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/simulation/g4simulation/g4eval/FillTruthRecoMatchTree.cc b/simulation/g4simulation/g4eval/FillTruthRecoMatchTree.cc new file mode 100644 index 0000000000..47623a7eb9 --- /dev/null +++ b/simulation/g4simulation/g4eval/FillTruthRecoMatchTree.cc @@ -0,0 +1,544 @@ +#include "FillTruthRecoMatchTree.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for PHObject +#include +#include // for PHWHERE +#include +#include +#include +#include +#include +#include + +using std::cout; +using std::endl; +//____________________________________________________________________________.. +FillTruthRecoMatchTree::FillTruthRecoMatchTree( + bool _fill_clusters + , bool _fill_SvUnMatched + , float _cluster_nzwidths + , float _cluster_nphiwidths + , const std::string& _outfile_name + ) + : + m_cluster_comp { _cluster_nphiwidths, _cluster_nzwidths } + , m_fill_clusters { _fill_clusters } + , m_fill_SvU { _fill_SvUnMatched } + , m_outfile_name { _outfile_name } +{ + m_cluscntr.set_comparer(&m_cluster_comp); + PHTFileServer::get().open(m_outfile_name, "RECREATE"); + + h2_G4_nPixelsPhi = new TH2D("G4_nPixelsPhi", "PHG4 Emb Tracks; cluster pixel width Phi; layer", + 100, -0.5, 99.5, 56, -0.5, 55.5); + h2_G4_nPixelsZ = new TH2D("G4_nPixelsZ", "PHG4 Emb Tracks; cluster pixel width Z; layer", + 100, -0.5, 99.5, 56, -0.5, 55.5); + h2_Sv_nPixelsPhi = new TH2D("Sv_nPixelsPhi", "Svtx Reco Tracks; cluster pixel width Phi; layer", + 100, -0.5, 99.5, 56, -0.5, 55.5); + h2_Sv_nPixelsZ = new TH2D("Sv_nPixelsZ", "Svtx Reco Tracks; cluster pixel width Z; layer", + 100, -0.5, 99.5, 56, -0.5, 55.5); + + m_ttree = new TTree("T", "Tracks (and sometimes clusters)"); + + m_ttree->Branch("event", &nevent); + m_ttree->Branch("nphg4_part", &nphg4_part); + m_ttree->Branch("centrality", ¢rality); + m_ttree->Branch("ntrackmatches", &ntrackmatches); + m_ttree->Branch("nphg4", &nphg4); + m_ttree->Branch("nsvtx", &nsvtx); + + m_ttree ->Branch("trackid" , &b_trackid ); + m_ttree ->Branch("is_G4track" , &b_is_g4track ); + m_ttree ->Branch("is_Svtrack" , &b_is_Svtrack ); + m_ttree ->Branch("is_matched" , &b_is_matched ); + + m_ttree ->Branch("trkpt" , &b_trkpt ); + m_ttree ->Branch("trketa" , &b_trketa ); + m_ttree ->Branch("trkphi" , &b_trkphi ); + + m_ttree ->Branch("nclus" , &b_nclus ); + m_ttree ->Branch("nclustpc" , &b_nclustpc ); + m_ttree ->Branch("nclusmvtx" , &b_nclusmvtx ); + m_ttree ->Branch("nclusintt" , &b_nclusintt ); + m_ttree ->Branch("matchrat" , &b_matchrat ); + m_ttree ->Branch("matchrat_intt" , &b_matchrat_intt ); + m_ttree ->Branch("matchrat_mvtx" , &b_matchrat_mvtx ); + m_ttree ->Branch("matchrat_tpc" , &b_matchrat_tpc ); + + if (m_fill_clusters) { + m_ttree ->Branch("clus_match" , &b_clusmatch ); + m_ttree ->Branch("clus_x" , &b_clus_x ); + m_ttree ->Branch("clus_y" , &b_clus_y ); + m_ttree ->Branch("clus_z" , &b_clus_z ); + m_ttree ->Branch("clus_r" , &b_clus_r ); + m_ttree ->Branch("clus_layer" , &b_clus_layer ); + m_ttree ->Branch("nphibins" , &b_clus_nphibins ); + m_ttree ->Branch("nzbins" , &b_clus_ntbins ); + } +} + +//____________________________________________________________________________.. +FillTruthRecoMatchTree::~FillTruthRecoMatchTree() +{ +} + +//____________________________________________________________________________.. +int FillTruthRecoMatchTree::Init(PHCompositeNode *topNode) +{ + if (Verbosity()>1) { + std::cout << " Beginning FillTruthRecoMatchTree " << std::endl; + topNode->print(); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int FillTruthRecoMatchTree::InitRun(PHCompositeNode *topNode) +{ + auto init_status = m_cluster_comp.init(topNode); + if (init_status == Fun4AllReturnCodes::ABORTRUN) return init_status; + + if (createNodes(topNode) != Fun4AllReturnCodes::EVENT_OK) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +int FillTruthRecoMatchTree::createNodes(PHCompositeNode *topNode) +{ + PHNodeIterator iter(topNode); + + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + + if (!dstNode) + { + std::cout << PHWHERE << " DST node is missing, quitting" << std::endl; + std::cerr << PHWHERE << " DST node is missing, quitting" << std::endl; + throw std::runtime_error("Failed to find DST node in FillTruthRecoMatchTree::createNodes"); + } + + m_EmbRecoMatchContainer = findNode::getClass(topNode,"TRKR_EMBRECOMATCHCONTAINER"); + if (!m_EmbRecoMatchContainer) { + std::cout << PHWHERE << " Cannot find node TRKR_EMBRECOMATCHCONTAINER on node tree; quitting " << std::endl; + std::cerr << PHWHERE << " Cannot find node TRKR_EMBRECOMATCHCONTAINER on node tree; quitting " << std::endl; + throw std::runtime_error(" Cannot find node TRKR_EMBRECOMATCHCONTAINER on node tree; quitting"); + } + + PHCompositeNode *svtxNode = dynamic_cast(iter.findFirst("PHCompositeNode", "SVTX")); + if (!svtxNode) + { + svtxNode = new PHCompositeNode("SVTX"); + dstNode->addNode(svtxNode); + } + + m_PHG4TruthInfoContainer = findNode::getClass(topNode, "G4TruthInfo"); + if (!m_PHG4TruthInfoContainer) + { + std::cout << "Could not locate G4TruthInfo node when running " + << "\"TruthRecoTrackMatching\" module." << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + m_SvtxTrackMap = findNode::getClass(topNode, "SvtxTrackMap"); + if (!m_SvtxTrackMap) + { + std::cout << "Could not locate SvtxTrackMap node when running " + <<"\"TruthRecoTrackMatching\" module." << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + + /* m_TruthClusterContainer = findNode::getClass(topNode, */ + /* "TRKR_TRUTHCLUSTERCONTAINER"); */ + /* if (!m_TruthClusterContainer) */ + /* { */ + /* std::cout << "Could not locate TRKR_TRUTHCLUSTERCONTAINER node when running " */ + /* << "\"TruthRecoTrackMatching\" module." << std::endl; */ + /* return Fun4AllReturnCodes::ABORTEVENT; */ + /* } */ + + /* m_RecoClusterContainer = findNode::getClass(topNode, "TRKR_CLUSTER"); */ + /* if (!m_RecoClusterContainer) */ + /* { */ + /* std::cout << "Could not locate TRKR_CLUSTER node when running " */ + /* << "\"TruthRecoTrackMatching\" module." << std::endl; */ + /* return Fun4AllReturnCodes::ABORTEVENT; */ + /* } */ + + m_TrkrTruthTrackContainer = findNode::getClass(topNode, + "TRKR_TRUTHTRACKCONTAINER"); + if (!m_TrkrTruthTrackContainer) + { + std::cout << "Could not locate TRKR_TRUTHTRACKCONTAINER node when running " + << "\"TruthRecoTrackMatching\" module." << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +int FillTruthRecoMatchTree::process_event(PHCompositeNode * /*topNode*/) +{ + + if (Verbosity()>5) cout << " FillTruthRecoMatchTree::process_event() " << endl; + + // fill in the event data + ++nevent; + nphg4 = m_TrkrTruthTrackContainer ->getMap().size(); + nsvtx = m_SvtxTrackMap ->size(); + ntrackmatches = m_EmbRecoMatchContainer->getMatches().size(); + // get centrality later... + + // fill in pixel widths on truth tracks + for (auto hitsetkey : m_cluscntr.get_PHG4_clusters()->getHitSetKeys()) { + float layer = (float) TrkrDefs::getLayer(hitsetkey); + auto range = m_cluscntr.get_PHG4_clusters()->getClusters(hitsetkey); + for (auto iter = range.first; iter != range.second; ++iter) { + auto& cluster = iter->second; + h2_G4_nPixelsPhi ->Fill( (float)cluster->getPhiSize(), layer ); + h2_G4_nPixelsZ ->Fill( (float)cluster->getZSize(), layer ); + } + } + // fill in pixel widths on reco tracks + for (auto hitsetkey : m_cluscntr.get_SVTX_clusters()->getHitSetKeys()) { + float layer = (float) TrkrDefs::getLayer(hitsetkey); + auto range = m_cluscntr.get_SVTX_clusters()->getClusters(hitsetkey); + for (auto iter = range.first; iter != range.second; ++iter) { + auto& cluster = iter->second; + h2_Sv_nPixelsPhi ->Fill( (float)cluster->getPhiSize(), layer ); + h2_Sv_nPixelsZ ->Fill( (float)cluster->getZSize(), layer ); + } + } + + nphg4_part = 0; + const auto range = m_PHG4TruthInfoContainer->GetPrimaryParticleRange(); + for (PHG4TruthInfoContainer::ConstIterator iter = range.first; + iter != range.second; ++iter) + { nphg4_part++; } + + + + // unmatched tracks are only entered once + // matches can repeat a given svtx or phg4 track, depending on the + // parameters in teh matching in filltruthrecomatchtree + // + // (1) fill unmatched phg4 + // (2) fill unmatched svtx + // (3) fill matched phg4 and svtx + clear_clusvecs(" nothing "); + + if (Verbosity() > 2) std::cout << " getting" << (int) m_EmbRecoMatchContainer->getMatches().size() << std::endl; + for (auto& match : m_EmbRecoMatchContainer->getMatches()) { + unsigned int g4_trkid = match->idTruthTrack(); + int sv_trkid = match->idRecoTrack(); + + auto g4trk = m_TrkrTruthTrackContainer->getTruthTrack(g4_trkid); + auto svtrk = m_SvtxTrackMap->get(sv_trkid); + + m_cluscntr.addClusKeys( g4trk ); + m_cluscntr.addClusKeys( svtrk ); + m_cluscntr.find_matches(); + + // <- <- <- <- G4 Matched Tracks + b_is_matched = true; + b_is_g4track = true; + b_is_Svtrack = false; + + b_trackid = g4_trkid; + b_trkpt = g4trk->getPt(); + b_trketa = g4trk->getPseudoRapidity(); + b_trkphi = g4trk->getPhi(); + + auto cnt = m_cluscntr.phg4_cntclus(); + auto cnt_match = m_cluscntr.phg4_cnt_matchedclus(); + + b_nclus = cnt[4] ; + b_nclusmvtx = cnt[0] ; + b_nclusintt = cnt[1] ; + b_nclustpc = cnt[2] ; + + b_matchrat = (float)cnt_match[4] / cnt[4] ; + b_matchrat_mvtx = (float)cnt_match[0] / cnt[0] ; + b_matchrat_intt = (float)cnt_match[1] / cnt[1] ; + b_matchrat_tpc = (float)cnt_match[2] / cnt[2] ; + + if (m_fill_clusters) { + auto clusters = m_cluscntr.phg4_clusloc_unmatched(); + for (auto& loc : clusters) { + b_clusmatch .push_back(false); + b_clus_layer .push_back(std::get<0>(loc)); + auto x = std::get<1>(loc)[0]; + auto y = std::get<1>(loc)[1]; + b_clus_x .push_back(x); + b_clus_y .push_back(y); + b_clus_z .push_back(std::get<1>(loc)[2]); + b_clus_r .push_back(pow(x*x+y*y,0.5)); + b_clus_nphibins .push_back(std::get<2>(loc)); + b_clus_ntbins .push_back(std::get<3>(loc)); + } + + clusters = m_cluscntr.clusloc_matched(); + for (auto& loc : clusters) { + b_clusmatch .push_back(true); + b_clus_layer .push_back(std::get<0>(loc)); + auto x = std::get<1>(loc)[0]; + auto y = std::get<1>(loc)[1]; + b_clus_x .push_back(x); + b_clus_y .push_back(y); + b_clus_z .push_back(std::get<1>(loc)[2]); + b_clus_r .push_back(pow(x*x+y*y,0.5)); + b_clus_nphibins .push_back(std::get<2>(loc)); + b_clus_ntbins .push_back(std::get<3>(loc)); + } + } + m_ttree->Fill(); + clear_clusvecs(); + /* clear_clusvecs("apple0 g4_matched"); */ + + // <- <- <- <- Svtx Matched Tracks + b_is_g4track = false; + b_is_Svtrack = true; + b_trackid = sv_trkid; + b_trkpt = svtrk->get_pt(); + b_trketa = svtrk->get_eta(); + b_trkphi = svtrk->get_phi(); + + cnt = m_cluscntr.svtx_cntclus(); + /* cout << " FIXME 0000 matched Svtx: " << sv_trkid << " " << svtrk->get_pt()<<" " << svtrk->get_eta()<<" "<< svtrk->get_phi() << " " << cnt[4] << endl; */ + b_nclus = cnt[4] ; + b_nclusmvtx = cnt[0] ; + b_nclusintt = cnt[1] ; + b_nclustpc = cnt[2] ; + + b_matchrat = (float)cnt_match[4] / cnt[4] ; + b_matchrat_mvtx = (float)cnt_match[0] / cnt[0] ; + b_matchrat_intt = (float)cnt_match[1] / cnt[1] ; + b_matchrat_tpc = (float)cnt_match[2] / cnt[2] ; + + /* int _ = 0; */ + if (m_fill_clusters) { + auto clusters = m_cluscntr.svtx_clusloc_unmatched(); + for (auto& loc : clusters) { + b_clusmatch .push_back(false); + b_clus_layer .push_back(std::get<0>(loc)); + auto x = std::get<1>(loc)[0]; + auto y = std::get<1>(loc)[1]; + /* if (_==0) cout << " apple x: " << x << " y: " << y << endl; */ + /* _ += 1; */ + b_clus_x .push_back(x); + b_clus_y .push_back(y); + b_clus_z .push_back(std::get<1>(loc)[2]); + b_clus_r .push_back(pow(x*x+y*y,0.5)); + b_clus_nphibins .push_back(std::get<2>(loc)); + b_clus_ntbins .push_back(std::get<3>(loc)); + } + + clusters = m_cluscntr.clusloc_matched(); + for (auto& loc : clusters) { + b_clusmatch .push_back(true); + b_clus_layer .push_back(std::get<0>(loc)); + auto x = std::get<1>(loc)[0]; + auto y = std::get<1>(loc)[1]; + b_clus_x .push_back(x); + b_clus_y .push_back(y); + b_clus_z .push_back(std::get<1>(loc)[2]); + b_clus_r .push_back(pow(x*x+y*y,0.5)); + b_clus_nphibins .push_back(std::get<2>(loc)); + b_clus_ntbins .push_back(std::get<3>(loc)); + } + } + m_ttree->Fill(); + clear_clusvecs(); + /* clear_clusvecs("apple1 s4_matched"); */ + } + + // <- <- <- <- G4 un-matched Tracks + b_is_matched = false; + b_is_g4track = true; + b_is_Svtrack = false; + for (auto& g4_trkid : m_EmbRecoMatchContainer->ids_TruthUnmatched()) { + auto g4trk = m_TrkrTruthTrackContainer->getTruthTrack(g4_trkid); + m_cluscntr.addClusKeys( g4trk ); + + b_trackid = g4_trkid; + b_trkpt = g4trk->getPt(); + b_trketa = g4trk->getPseudoRapidity(); + b_trkphi = g4trk->getPhi(); + + auto cnt = m_cluscntr.phg4_cntclus(); + b_nclus = cnt[4]; + b_nclusmvtx = cnt[0]; + b_nclusintt = cnt[1]; + b_nclustpc = cnt[2]; + + if (m_fill_clusters) { + auto clusters = m_cluscntr.phg4_clusloc_all(); + for (auto& loc : clusters) { + b_clusmatch .push_back(false); + b_clus_layer .push_back(std::get<0>(loc)); + auto x = std::get<1>(loc)[0]; + auto y = std::get<1>(loc)[1]; + b_clus_x .push_back(x); + b_clus_y .push_back(y); + b_clus_z .push_back(std::get<1>(loc)[2]); + b_clus_r .push_back(pow(x*x+y*y,0.5)); + b_clus_nphibins .push_back(std::get<2>(loc)); + b_clus_ntbins .push_back(std::get<3>(loc)); + } + //this is an unmatched track, so there are no matched clusters + } + m_ttree->Fill(); + clear_clusvecs(); + /* clear_clusvecs("apple2 g4_unmatched"); */ + } + + // <- <- <- <- Svtx un-matched Tracks + b_is_matched = false; + b_is_matched = false; + b_is_g4track = false; + b_is_Svtrack = true; + + // just put in all svtx tracks, period... + if (m_fill_SvU) { + for (auto sv_trkid : G4Eval::unmatchedSvtxTrkIds(m_EmbRecoMatchContainer, m_SvtxTrackMap)) { + auto svtrk = m_SvtxTrackMap->get(sv_trkid); + m_cluscntr.addClusKeys( svtrk ); + b_trackid = sv_trkid; + b_trkpt = svtrk->get_pt(); + b_trketa = svtrk->get_eta(); + b_trkphi = svtrk->get_phi(); + + auto cnt = m_cluscntr.svtx_cntclus(); + b_nclus = cnt[4] ; + b_nclusmvtx = cnt[0] ; + b_nclusintt = cnt[1] ; + b_nclustpc = cnt[2] ; + + if (m_fill_clusters) { + auto clusters = m_cluscntr.svtx_clusloc_all(); + for (auto& loc : clusters) { + b_clusmatch .push_back(false); + b_clus_layer .push_back(std::get<0>(loc)); + auto x = std::get<1>(loc)[0]; + auto y = std::get<1>(loc)[1]; + b_clus_x .push_back(x); + b_clus_y .push_back(y); + b_clus_z .push_back(std::get<1>(loc)[2]); + b_clus_r .push_back(pow(x*x+y*y,0.5)); + b_clus_nphibins .push_back(std::get<2>(loc)); + b_clus_ntbins .push_back(std::get<3>(loc)); + } + } + m_ttree->Fill(); + clear_clusvecs(); + } + } + + if (Verbosity()>100) print_mvtx_diagnostics(); + return Fun4AllReturnCodes::EVENT_OK; +} + +void FillTruthRecoMatchTree::print_mvtx_diagnostics() { + std::cout << "To do: " + << " (1) number of truth tracks and total number of mvtx and ratio " << std::endl + << " (2) ditto for reco tracks " << std::endl; + + double n_PHG4_tracks = m_TrkrTruthTrackContainer->getMap().size(); + // count how many mvtx clusters in the phg4 tracks + double n_in_PHG4_tracks {0.}; + for (auto& pair : m_TrkrTruthTrackContainer->getMap()) { + m_cluscntr.addClusKeys( pair.second ); + n_in_PHG4_tracks += m_cluscntr.phg4_cntclus()[0]; + } + // count how mant mvtx clusters in truth container (should be the same) + double n_in_PHG4_clusters {0.}; + for (auto hitsetkey : m_cluscntr.get_PHG4_clusters()->getHitSetKeys()) { + if (TrkrDefs::getLayer(hitsetkey) > 2) continue; + auto range = m_cluscntr.get_PHG4_clusters()->getClusters(hitsetkey); + for (auto r = range.first; r != range.second; ++r) { + n_in_PHG4_clusters += 1.; + } + } + + // count how many svtx tracks + double n_SVTX_tracks = m_SvtxTrackMap->size(); + // count how many mvtx clusters in svtx tracks + double n_in_SVTX_tracks {0.}; + for (auto entry = m_SvtxTrackMap->begin(); entry != m_SvtxTrackMap->end(); ++entry) { + m_cluscntr.addClusKeys(entry->second); + n_in_SVTX_tracks += m_cluscntr.svtx_cntclus()[0]; + } + // count how many mvtx are total in the container + double n_in_SVTX_clusters {0.}; + for (auto hitsetkey : m_cluscntr.get_SVTX_clusters()->getHitSetKeys()) { + if (TrkrDefs::getLayer(hitsetkey) > 2) continue; + auto range = m_cluscntr.get_SVTX_clusters()->getClusters(hitsetkey); + for (auto r = range.first; r != range.second; ++r) { + n_in_SVTX_clusters += 1.; + } + } + + std::cout << Form("MVTX" + "\nPHG4: Tracks(%.0f) Clusters In tracks(%.0f) Total (%.0f)" + "\n ave. per track: %6.3f ratio in all tracks: %6.2f" + , n_PHG4_tracks, n_in_PHG4_tracks, n_in_PHG4_clusters + , (n_in_PHG4_tracks/n_PHG4_tracks), (n_in_PHG4_tracks/n_in_PHG4_clusters)) + << std::endl; + std::cout << Form( + "\nSVTX: Tracks(%.0f) Clusters In tracks(%.0f) Total (%.0f)" + "\n ave. per track: %6.3f ratio in all tracks: %6.2f" + , n_SVTX_tracks, n_in_SVTX_tracks, n_in_SVTX_clusters + , (n_in_SVTX_tracks/n_SVTX_tracks), (n_in_SVTX_tracks/n_in_SVTX_clusters)) + << std::endl; + +} + + int FillTruthRecoMatchTree::End(PHCompositeNode *) + { + if (Verbosity()>2) std::cout << PHWHERE << ": ending FillTruthRecoMatchTree" << std::endl; + PHTFileServer::get().cd(m_outfile_name); + + h2_G4_nPixelsPhi ->Write(); + h2_G4_nPixelsZ ->Write(); + h2_Sv_nPixelsPhi ->Write(); + h2_Sv_nPixelsZ ->Write(); + + m_ttree->Write(); + return Fun4AllReturnCodes::EVENT_OK; + } + + void FillTruthRecoMatchTree::clear_clusvecs(std::string tag) { + /* cout << " banana |" << tag << "|"< +#include +#include + +class EmbRecoMatchContainer; +class PHCompositeNode; +class PHG4ParticleSvtxMap; +class SvtxPHG4ParticleMap; +class EmbRecoMatchContainer; +class PHCompositeNode; +class PHG4TpcCylinderGeom; +class PHG4TpcCylinderGeomContainer; +class PHG4TruthInfoContainer; +class SvtxTrack; +class SvtxTrackMap; +class TrackSeedContainer; +class TrkrCluster; +/* class TrkrClusterContainer; */ +class TrkrTruthTrack; +class TrkrTruthTrackContainer; +class TTree; +class TH2D; + +class FillTruthRecoMatchTree : public SubsysReco +{ + public: + FillTruthRecoMatchTree( + bool _fill_clusters = true + , bool _fill_svtxnomatch = false + , float _cluster_nzwidths = 0.5 + , float _cluster_nphiwidths = 0.5 + , const std::string& tfile_name="trackclusmatch.root" + ); + + virtual ~FillTruthRecoMatchTree(); + + int Init(PHCompositeNode *) override; + int InitRun(PHCompositeNode *topNode) override; + int process_event(PHCompositeNode * /*topNode*/) override; + int End(PHCompositeNode *topNode) override; + + void clear_clusvecs(std::string tag=""); + + void print_mvtx_diagnostics(); + + private: + + int createNodes(PHCompositeNode *topNode); + + G4Eval::TrkrClusterComparer m_cluster_comp { 1., 1.}; + G4Eval::ClusCntr m_cluscntr; + + // contianer used to fill the other track matches + EmbRecoMatchContainer *m_EmbRecoMatchContainer {nullptr}; + PHG4TruthInfoContainer *m_PHG4TruthInfoContainer {nullptr}; + SvtxTrackMap *m_SvtxTrackMap {nullptr}; + /* TrkrClusterContainer *m_TruthClusterContainer {nullptr}; */ + /* TrkrClusterContainer *m_RecoClusterContainer {nullptr}; */ + TrkrTruthTrackContainer *m_TrkrTruthTrackContainer {nullptr}; + /* PHG4TpcCylinderGeomContainer *m_PHG4TpcCylinderGeomContainer {nullptr}; */ + + + TTree* m_ttree; + bool m_fill_clusters; + bool m_fill_SvU; // unmatched Svtx tracks + std::string m_outfile_name; + + // Tree Branch members: + int nevent {-1}; + int nphg4 {0}; + int nsvtx {0}; + int ntrackmatches {0}; + int nphg4_part {0}; + float centrality {0.}; + + // Tracks and clustes + // + // lables: + // tracks: + // g4 : phg4track matched + // sv : svtx_track matched + // gU : phg4track not-matched + // sU : svtx_track not-matched + // clusters: + // M : matched + // U : unmatched + TH2D* h2_G4_nPixelsPhi; + TH2D* h2_G4_nPixelsZ; + TH2D* h2_Sv_nPixelsPhi; + TH2D* h2_Sv_nPixelsZ; + + // Track tree + int b_trackid; + bool b_is_g4track; + bool b_is_Svtrack; + bool b_is_matched; + + float b_trkpt; + float b_trkphi; + float b_trketa; + + + int b_nclus {}; + int b_nclustpc {}; + int b_nclusmvtx {}; + int b_nclusintt {}; + + float b_matchrat {}; + float b_matchrat_intt {}; + float b_matchrat_mvtx {}; + float b_matchrat_tpc {}; + + std::vector b_clusmatch {}; + std::vector b_clus_x {}; + std::vector b_clus_y {}; + std::vector b_clus_z {}; + std::vector b_clus_r {}; + std::vector b_clus_layer {}; + std::vector b_clus_nphibins {}; + std::vector b_clus_ntbins {}; + + /* std::vector b_G4M_trackid {}; // g4-track-matched */ + /* std::vector b_G4M_nclus {}; */ + /* std::vector b_G4M_nclusmvtx {}; */ + /* std::vector b_G4M_nclusintt {}; */ + /* std::vector b_G4M_nclustpc {}; */ + /* std::vector b_G4M_nclus_matchrat {}; */ + /* std::vector b_G4M_nclusmvtx_matchrat {}; */ + /* std::vector b_G4M_nclusintt_matchrat {}; */ + /* std::vector b_G4M_nclustpc_matchrat {}; */ + /* std::vector b_G4M_pt {}; */ + /* std::vector b_G4M_phi {}; */ + /* std::vector b_G4M_eta {}; */ + /* std::vector b_SvM_trackid {}; // Svtx-track-matched */ + /* std::vector b_SvM_nclus {}; */ + /* std::vector b_SvM_nclusmvtx {}; */ + /* std::vector b_SvM_nclusintt {}; */ + /* std::vector b_SvM_nclustpc {}; */ + /* std::vector b_SvM_nclus_matchrat {}; */ + /* std::vector b_SvM_nclusmvtx_matchrat {}; */ + /* std::vector b_SvM_nclusintt_matchrat {}; */ + /* std::vector b_SvM_nclustpc_matchrat {}; */ + /* std::vector b_SvM_pt {}; */ + /* std::vector b_SvM_phi {}; */ + /* std::vector b_SvM_eta {}; */ + /* std::vector b_clusM_i0 {}; // if storing clusters -- matched clusters */ + /* std::vector b_clusM_i1 {}; */ + /* std::vector b_clusM_layer {}; */ + /* std::vector b_clusM_x {}; */ + /* std::vector b_clusM_y {}; */ + /* std::vector b_clusM_z {}; */ + /* std::vector b_clusM_r {}; */ + /* std::vector b_G4M_clusU_i0 {}; // matched phg4 unmatched clusters */ + /* std::vector b_G4M_clusU_i1 {}; */ + /* std::vector b_G4M_clusU_layer {}; */ + /* std::vector b_G4M_clusU_x {}; */ + /* std::vector b_G4M_clusU_y {}; */ + /* std::vector b_G4M_clusU_z {}; */ + /* std::vector b_G4M_clusU_r {}; */ + /* std::vector b_SvM_clusU_i0 {}; // matched phg4 unmatched clusters */ + /* std::vector b_SvM_clusU_i1 {}; */ + /* std::vector b_SvM_clusU_layer {}; */ + /* std::vector b_SvM_clusU_x {}; */ + /* std::vector b_SvM_clusU_y {}; */ + /* std::vector b_SvM_clusU_z {}; */ + /* std::vector b_SvM_clusU_r {}; */ + /* std::vector b_G4U_trackid {}; // unmatched tracks */ + /* std::vector b_G4U_nclus {}; */ + /* std::vector b_G4U_nclusmvtx {}; */ + /* std::vector b_G4U_nclusintt {}; */ + /* std::vector b_G4U_nclustpc {}; */ + /* std::vector b_G4U_pt {}; */ + /* std::vector b_G4U_phi {}; */ + /* std::vector b_G4U_eta {}; */ + /* std::vector b_SvU_trackid {}; // Svtx-track-matched */ + /* std::vector b_SvU_nclus {}; */ + /* std::vector b_SvU_nclusmvtx {}; */ + /* std::vector b_SvU_nclusintt {}; */ + /* std::vector b_SvU_nclustpc {}; */ + /* std::vector b_SvU_pt {}; */ + /* std::vector b_SvU_phi {}; */ + /* std::vector b_SvU_eta {}; */ + /* std::vector b_G4U_clusU_i0 {}; // unmatched phg4 unmatched clusters */ + /* std::vector b_G4U_clusU_i1 {}; */ + /* std::vector b_G4U_clusU_layer {}; */ + /* std::vector b_G4U_clusU_x {}; */ + /* std::vector b_G4U_clusU_y {}; */ + /* std::vector b_G4U_clusU_z {}; */ + /* std::vector b_G4U_clusU_r {}; */ + /* std::vector b_SvU_clusU_i0 {}; // unmatched phg4 unmatched clusters */ + /* std::vector b_SvU_clusU_i1 {}; */ + /* std::vector b_SvU_clusU_layer {}; */ + /* std::vector b_SvU_clusU_x {}; */ + /* std::vector b_SvU_clusU_y {}; */ + /* std::vector b_SvU_clusU_z {}; */ + /* std::vector b_SvU_clusU_r {}; */ + + + +}; + +#endif // FILLTRUTHRECOMATCHTREE_H diff --git a/simulation/g4simulation/g4eval/Makefile.am b/simulation/g4simulation/g4eval/Makefile.am index a13431069a..0e6a4f6222 100644 --- a/simulation/g4simulation/g4eval/Makefile.am +++ b/simulation/g4simulation/g4eval/Makefile.am @@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = \ -I$(includedir) \ -I$(OFFLINE_MAIN)/include \ - -isystem`root-config --incdir` + -isystem`root-config --incdir` AM_LDFLAGS = \ -L$(libdir) \ @@ -26,7 +26,7 @@ libg4eval_la_LIBADD = \ -lfun4all \ -lg4detectors_io \ -lg4jets_io \ - -lg4vertex_io \ + -lglobalvertex_io \ -lg4tracking_io \ -ltrackbase_historic_io \ -ltrack_io \ @@ -47,7 +47,8 @@ pkginclude_HEADERS = \ DSTCompressor.h \ DSTEmulator.h \ EventEvaluator.h \ - FillTruthRecoMatchMap.h \ + FillTruthRecoMatchMap.h \ + FillTruthRecoMatchTree.h \ JetEvalStack.h \ JetEvaluator.h \ JetRecoEval.h \ @@ -63,6 +64,7 @@ pkginclude_HEADERS = \ SvtxTruthEval.h \ SvtxTruthRecoTableEval.h \ SvtxVertexEval.h \ + g4evaltools.h \ TrackEvaluation.h \ TrackEvaluationContainer.h \ TrackEvaluationContainerv1.h \ @@ -94,6 +96,7 @@ libg4eval_la_SOURCES = \ DSTEmulator.cc \ EventEvaluator.cc \ FillTruthRecoMatchMap.cc \ + FillTruthRecoMatchTree.cc \ JetEvalStack.cc \ JetEvaluator.cc \ JetRecoEval.cc \ @@ -109,6 +112,7 @@ libg4eval_la_SOURCES = \ SvtxTruthEval.cc \ SvtxTruthRecoTableEval.cc \ SvtxVertexEval.cc \ + g4evaltools.cc \ TrackEvaluation.cc \ TrackSeedTrackMapConverter.cc \ TruthRecoTrackMatching.cc diff --git a/simulation/g4simulation/g4eval/SvtxEvaluator.cc b/simulation/g4simulation/g4eval/SvtxEvaluator.cc index a28ffa879f..5a14b5139d 100644 --- a/simulation/g4simulation/g4eval/SvtxEvaluator.cc +++ b/simulation/g4simulation/g4eval/SvtxEvaluator.cc @@ -22,16 +22,20 @@ #include #include +#include #include #include #include #include -#include #include +#include #include #include +#include +#include + #include #include #include @@ -64,6 +68,74 @@ using namespace std; +namespace sumClusterEnergyFromHits +{ + void calc( + TrkrClusterHitAssoc* clusterhitmap, + TrkrDefs::cluskey cluster_key, + const std::map& hitsetsmap, + float& sumadc, + float& maxadc, + float& size) + { + TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluster_key); + sumadc = 0; + + auto hitsetsmap_iter = hitsetsmap.find(TrkrDefs::getTrkrId(hitsetkey)); + if (hitsetsmap_iter != hitsetsmap.end()) + { + TrkrHitSetContainer* hitsets = hitsetsmap_iter->second; + assert(hitsets); + + if (dynamic_cast(hitsets->findHitSet(hitsetkey))) + { + // specialized hit container for TPCs + + TrkrHitSetTpc* hitset = dynamic_cast(hitsets->findHitSet(hitsetkey)); + + std::pair::const_iterator, std::multimap::const_iterator> + hitrange = clusterhitmap->getHits(cluster_key); + for (std::multimap::const_iterator + clushititer = hitrange.first; + clushititer != hitrange.second; ++clushititer) + { + auto adc = hitset->getTpcADC(clushititer->second); + if (adc <= 0) continue; + + ++size; + sumadc += (adc - 70); + if ((adc - 70) > maxadc) + maxadc = (adc - 70); + } + + } // if (dynamic_cast(hitsets->findHitSet(hitsetkey))) + else + { + TrkrHitSet* hitset = hitsets->findHitSet(hitsetkey); + + std::pair::const_iterator, std::multimap::const_iterator> + hitrange = clusterhitmap->getHits(cluster_key); + for (std::multimap::const_iterator + clushititer = hitrange.first; + clushititer != hitrange.second; ++clushititer) + { + TrkrHit* hit = hitset->getHit(clushititer->second); + if (!hit) continue; + + ++size; + sumadc += (hit->getAdc() ); + if ((hit->getAdc() ) > maxadc) + maxadc = (hit->getAdc()); + } + + } // else -> if (dynamic_cast(hitsets->findHitSet(hitsetkey))) + + } // if (hitsetsmap_iter != hitsetsmap.end()) + + } // void calc( + +} // namespace sumClusterEnergyFromHits + SvtxEvaluator::SvtxEvaluator(const string& /*name*/, const string& filename, const string& trackmapname, unsigned int nlayers_maps, unsigned int nlayers_intt, @@ -815,34 +887,58 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) float occ216 = 0; float occ31 = 0; float occ316 = 0; - - TrkrHitSetContainer* hitmap_in = findNode::getClass(topNode, "TRKR_HITSET"); + + TrkrHitSetContainer* hitmap_in = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (hitmap_in) + { + TrkrHitSetContainer::ConstRange all_hitsets = hitmap_in->getHitSets(); + for (TrkrHitSetContainer::ConstIterator hitsetiter = all_hitsets.first; + hitsetiter != all_hitsets.second; + ++hitsetiter) { - TrkrHitSetContainer::ConstRange all_hitsets = hitmap_in->getHitSets(); - for (TrkrHitSetContainer::ConstIterator hitsetiter = all_hitsets.first; - hitsetiter != all_hitsets.second; - ++hitsetiter) - { - // we have a single hitset, get the layer - unsigned int layer = TrkrDefs::getLayer(hitsetiter->first); - if(layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) - { - // count all hits in this hitset - TrkrHitSet::ConstRange hitrangei = hitsetiter->second->getHits(); - for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr) - { - nhit[layer]++; - nhit_tpc_all++; - if ((float) layer == _nlayers_maps + _nlayers_intt) nhit_tpc_in++; - if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc - 1) nhit_tpc_out++; - if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc / 2 - 1) nhit_tpc_mid++; - } - } - } + // we have a single hitset, get the layer + unsigned int layer = TrkrDefs::getLayer(hitsetiter->first); + if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) + { + if (dynamic_cast(hitsetiter->second)) + { + const TrkrHitSetTpc::TimeFrameADCDataType& dataframe = dynamic_cast(hitsetiter->second)->getTimeFrameAdcData(); + + for (const auto& pad_data : dataframe) + { + for (const auto& adc : pad_data) + { + if (adc > 0) + { + nhit[layer]++; + nhit_tpc_all++; + if ((float) layer == _nlayers_maps + _nlayers_intt) nhit_tpc_in++; + if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc - 1) nhit_tpc_out++; + if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc / 2 - 1) nhit_tpc_mid++; + } + } + } + } // if (dynamic_cast(hitsetiter->second)) + else + { + // count all hits in this hitset + TrkrHitSet::ConstRange hitrangei = hitsetiter->second->getHits(); + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) + { + nhit[layer]++; + nhit_tpc_all++; + if ((float) layer == _nlayers_maps + _nlayers_intt) nhit_tpc_in++; + if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc - 1) nhit_tpc_out++; + if ((float) layer == _nlayers_maps + _nlayers_intt + _nlayers_tpc / 2 - 1) nhit_tpc_mid++; + } + } + }// if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) + } + } + /**********/ PHG4TpcCylinderGeomContainer* geom_container = findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); @@ -976,6 +1072,7 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) _timer->restart(); } + GlobalVertexMap* gvertexmap = findNode::getClass(topNode, "GlobalVertexMap"); SvtxVertexMap* vertexmap = nullptr; if(_use_initial_vertex) vertexmap = findNode::getClass(topNode, "SvtxVertexMap"); @@ -986,7 +1083,7 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) PHG4TruthInfoContainer* truthinfo = findNode::getClass(topNode, "G4TruthInfo"); - if (vertexmap && truthinfo) + if (gvertexmap && vertexmap && truthinfo) { const auto prange = truthinfo->GetPrimaryParticleRange(); map embedvtxid_particle_count; @@ -1088,11 +1185,19 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) ++ngembed; } - for (SvtxVertexMap::Iter iter = vertexmap->begin(); - iter != vertexmap->end(); + for (auto iter = gvertexmap->begin(); + iter != gvertexmap->end(); ++iter) { - SvtxVertex* vertex = iter->second; + GlobalVertex* gvertex = iter->second; + auto svtxv = gvertex->find_vtxids(GlobalVertex::SVTX); + // check that it contains a track vertex + if(svtxv == gvertex->end_vtxids()) + { continue; } + + auto svtxvertexid = svtxv->second; + auto vertex = vertexmap->find(svtxvertexid)->second; + PHG4VtxPoint* point = vertexeval->max_truth_point_by_ntracks(vertex); int vertexID = vertex->get_id(); float vx = vertex->get_x(); @@ -1540,187 +1645,370 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) _timer->restart(); } // need things off of the DST... - TrkrHitSetContainer *hitmap = findNode::getClass(topNode, "TRKR_HITSET"); - PHG4TpcCylinderGeomContainer* geom_container = - findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); - if (!geom_container) + for ([[maybe_unused]] const auto& [trkrID, trkrName] : TrkrDefs::TrkrNames) { - std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; - return; - } + TrkrHitSetContainer* hitmap = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + PHG4TpcCylinderGeomContainer* geom_container = + findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); + if (!geom_container) + { + std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; + return; + } - if (hitmap) - { - TrkrHitSetContainer::ConstRange all_hitsets = hitmap->getHitSets(); - for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; - iter != all_hitsets.second; - ++iter) + if (hitmap) { - TrkrDefs::hitsetkey hitset_key = iter->first; - TrkrHitSet *hitset = iter->second; - - // get all hits for this hitset - TrkrHitSet::ConstRange hitrangei = hitset->getHits(); - for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr) - { - TrkrDefs::hitkey hit_key = hitr->first; - TrkrHit *hit = hitr->second; - PHG4Hit* g4hit = hiteval->max_truth_hit_by_energy(hit_key); - PHG4Particle* g4particle = trutheval->get_particle(g4hit); - float event = _ievent; - float hitID = hit_key; - float e = hit->getEnergy(); - float adc = hit->getAdc(); - float layer = TrkrDefs::getLayer(hitset_key); - float sector = TpcDefs::getSectorId(hitset_key); - float side = TpcDefs::getSide(hitset_key); - float cellID = 0; - float ecell = hit->getAdc(); - - float phibin = NAN; - float zbin = NAN; - float phi = NAN; - float z = NAN; - - if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc ) - { - PHG4TpcCylinderGeom* GeoLayer = geom_container->GetLayerCellGeom(layer); - phibin = (float) TpcDefs::getPad(hit_key); - zbin = (float) TpcDefs::getTBin(hit_key); - phi = GeoLayer->get_phicenter(phibin); - z = GeoLayer->get_zcenter(zbin); - } + TrkrHitSetContainer::ConstRange all_hitsets = hitmap->getHitSets(); + for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; + iter != all_hitsets.second; + ++iter) + { + TrkrDefs::hitsetkey hitset_key = iter->first; - float g4hitID = NAN; - float gedep = NAN; - float gx = NAN; - float gy = NAN; - float gz = NAN; - float gt = NAN; - float gtrackID = NAN; - float gflavor = NAN; - float gpx = NAN; - float gpy = NAN; - float gpz = NAN; - float gvx = NAN; - float gvy = NAN; - float gvz = NAN; - float gvt = NAN; - float gfpx = NAN; - float gfpy = NAN; - float gfpz = NAN; - float gfx = NAN; - float gfy = NAN; - float gfz = NAN; - float gembed = NAN; - float gprimary = NAN; - - float efromtruth = NAN; + if (dynamic_cast(iter->second)) + { + TrkrHitSetTpc* hitset = dynamic_cast(iter->second); - if (g4hit) - { - g4hitID = g4hit->get_hit_id(); - gedep = g4hit->get_edep(); - gx = g4hit->get_avg_x(); - gy = g4hit->get_avg_y(); - gz = g4hit->get_avg_z(); - gt = g4hit->get_avg_t(); - - if (g4particle) - { - if (_scan_for_embedded) - { - if (trutheval->get_embed(g4particle) <= 0) continue; - } - - gtrackID = g4particle->get_track_id(); - gflavor = g4particle->get_pid(); - gpx = g4particle->get_px(); - gpy = g4particle->get_py(); - gpz = g4particle->get_pz(); - - PHG4VtxPoint* vtx = trutheval->get_vertex(g4particle); - - if (vtx) - { - gvx = vtx->get_x(); - gvy = vtx->get_y(); - gvz = vtx->get_z(); - gvt = vtx->get_t(); - } - - PHG4Hit* outerhit = nullptr; - if (_do_eval_light == false) - outerhit = trutheval->get_outermost_truth_hit(g4particle); - if (outerhit) - { - gfpx = outerhit->get_px(1); - gfpy = outerhit->get_py(1); - gfpz = outerhit->get_pz(1); - gfx = outerhit->get_x(1); - gfy = outerhit->get_y(1); - gfz = outerhit->get_z(1); - } - gembed = trutheval->get_embed(g4particle); - gprimary = trutheval->is_primary(g4particle); - } // if (g4particle){ - } - - if (g4particle) - { - efromtruth = hiteval->get_energy_contribution(hit_key, g4particle); - } + const TrkrHitSetTpc::TimeFrameADCDataType& dataframe = hitset->getTimeFrameAdcData(); - float hit_data[] = { - event, - (float) _iseed, - hitID, - e, - adc, - layer, - sector, - side, - cellID, - ecell, - (float) phibin, - (float) zbin, - phi, - z, - g4hitID, - gedep, - gx, - gy, - gz, - gt, - gtrackID, - gflavor, - gpx, - gpy, - gpz, - gvx, - gvy, - gvz, - gvt, - gfpx, - gfpy, - gfpz, - gfx, - gfy, - gfz, - gembed, - gprimary, - efromtruth, - nhit_tpc_all, - nhit_tpc_in, - nhit_tpc_mid, - nhit_tpc_out, nclus_all, nclus_tpc, nclus_intt, nclus_maps, nclus_mms}; - - _ntp_hit->Fill(hit_data); - } + for (unsigned int local_pad = 0; local_pad < dataframe.size(); ++local_pad) + { + const std::vector& pad_data = dataframe[local_pad]; + + for (unsigned int local_tbin = 0; local_tbin < pad_data.size(); ++local_tbin) + { + const TpcDefs::ADCDataType& rawadc = pad_data[local_tbin]; + if (rawadc <= 0) continue; + + TrkrDefs::hitkey hit_key = hitset->getHitKeyfromLocalBin(local_pad, local_tbin); + + PHG4Hit* g4hit = hiteval->max_truth_hit_by_energy(hitset_key, hit_key); + PHG4Particle* g4particle = trutheval->get_particle(g4hit); + float event = _ievent; + float hitID = hit_key; + float e = rawadc; + float adc = rawadc; + float layer = TrkrDefs::getLayer(hitset_key); + float sector = TpcDefs::getSectorId(hitset_key); + float side = TpcDefs::getSide(hitset_key); + float cellID = 0; + float ecell = rawadc; + + float phibin = NAN; + float zbin = NAN; + float phi = NAN; + float z = NAN; + + if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) + { + PHG4TpcCylinderGeom* GeoLayer = geom_container->GetLayerCellGeom(layer); + phibin = (float) TpcDefs::getPad(hit_key); + zbin = (float) TpcDefs::getTBin(hit_key); + phi = GeoLayer->get_phicenter(phibin); + z = GeoLayer->get_zcenter(zbin); + } + + float g4hitID = NAN; + float gedep = NAN; + float gx = NAN; + float gy = NAN; + float gz = NAN; + float gt = NAN; + float gtrackID = NAN; + float gflavor = NAN; + float gpx = NAN; + float gpy = NAN; + float gpz = NAN; + float gvx = NAN; + float gvy = NAN; + float gvz = NAN; + float gvt = NAN; + float gfpx = NAN; + float gfpy = NAN; + float gfpz = NAN; + float gfx = NAN; + float gfy = NAN; + float gfz = NAN; + float gembed = NAN; + float gprimary = NAN; + + float efromtruth = NAN; + + if (g4hit) + { + g4hitID = g4hit->get_hit_id(); + gedep = g4hit->get_edep(); + gx = g4hit->get_avg_x(); + gy = g4hit->get_avg_y(); + gz = g4hit->get_avg_z(); + gt = g4hit->get_avg_t(); + + if (g4particle) + { + if (_scan_for_embedded) + { + if (trutheval->get_embed(g4particle) <= 0) continue; + } + + gtrackID = g4particle->get_track_id(); + gflavor = g4particle->get_pid(); + gpx = g4particle->get_px(); + gpy = g4particle->get_py(); + gpz = g4particle->get_pz(); + + PHG4VtxPoint* vtx = trutheval->get_vertex(g4particle); + + if (vtx) + { + gvx = vtx->get_x(); + gvy = vtx->get_y(); + gvz = vtx->get_z(); + gvt = vtx->get_t(); + } + + PHG4Hit* outerhit = nullptr; + if (_do_eval_light == false) + outerhit = trutheval->get_outermost_truth_hit(g4particle); + if (outerhit) + { + gfpx = outerhit->get_px(1); + gfpy = outerhit->get_py(1); + gfpz = outerhit->get_pz(1); + gfx = outerhit->get_x(1); + gfy = outerhit->get_y(1); + gfz = outerhit->get_z(1); + } + gembed = trutheval->get_embed(g4particle); + gprimary = trutheval->is_primary(g4particle); + } // if (g4particle){ + } + + if (g4particle) + { + efromtruth = hiteval->get_energy_contribution(hitset_key, hit_key, g4particle); + } + + float hit_data[] = { + event, + (float) _iseed, + hitID, + e, + adc, + layer, + sector, + side, + cellID, + ecell, + (float) phibin, + (float) zbin, + phi, + z, + g4hitID, + gedep, + gx, + gy, + gz, + gt, + gtrackID, + gflavor, + gpx, + gpy, + gpz, + gvx, + gvy, + gvz, + gvt, + gfpx, + gfpy, + gfpz, + gfx, + gfy, + gfz, + gembed, + gprimary, + efromtruth, + nhit_tpc_all, + nhit_tpc_in, + nhit_tpc_mid, + nhit_tpc_out, nclus_all, nclus_tpc, nclus_intt, nclus_maps, nclus_mms}; + + _ntp_hit->Fill(hit_data); + + } // for (unsigned int local_tbin = 0; local_tbin < pad_data.size(); ++local_tbin) + + } // for (unsigned int local_pad = 0; local_pad < dataframe.size(); ++local_pad) + + } // if (TrkrHitSetTpc *hitset = dynamic_cast(my_data->hitset);) + else + { + TrkrHitSet* hitset = iter->second; + + // get all hits for this hitset + TrkrHitSet::ConstRange hitrangei = hitset->getHits(); + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) + { + TrkrDefs::hitkey hit_key = hitr->first; + TrkrHit* hit = hitr->second; + PHG4Hit* g4hit = hiteval->max_truth_hit_by_energy(hitset_key, hit_key); + PHG4Particle* g4particle = trutheval->get_particle(g4hit); + float event = _ievent; + float hitID = hit_key; + float e = hit->getEnergy(); + float adc = hit->getAdc(); + float layer = TrkrDefs::getLayer(hitset_key); + float sector = TpcDefs::getSectorId(hitset_key); + float side = TpcDefs::getSide(hitset_key); + float cellID = 0; + float ecell = hit->getAdc(); + + float phibin = NAN; + float zbin = NAN; + float phi = NAN; + float z = NAN; + + if (layer >= _nlayers_maps + _nlayers_intt && layer < _nlayers_maps + _nlayers_intt + _nlayers_tpc) + { + PHG4TpcCylinderGeom* GeoLayer = geom_container->GetLayerCellGeom(layer); + phibin = (float) TpcDefs::getPad(hit_key); + zbin = (float) TpcDefs::getTBin(hit_key); + phi = GeoLayer->get_phicenter(phibin); + z = GeoLayer->get_zcenter(zbin); + } + + float g4hitID = NAN; + float gedep = NAN; + float gx = NAN; + float gy = NAN; + float gz = NAN; + float gt = NAN; + float gtrackID = NAN; + float gflavor = NAN; + float gpx = NAN; + float gpy = NAN; + float gpz = NAN; + float gvx = NAN; + float gvy = NAN; + float gvz = NAN; + float gvt = NAN; + float gfpx = NAN; + float gfpy = NAN; + float gfpz = NAN; + float gfx = NAN; + float gfy = NAN; + float gfz = NAN; + float gembed = NAN; + float gprimary = NAN; + + float efromtruth = NAN; + + if (g4hit) + { + g4hitID = g4hit->get_hit_id(); + gedep = g4hit->get_edep(); + gx = g4hit->get_avg_x(); + gy = g4hit->get_avg_y(); + gz = g4hit->get_avg_z(); + gt = g4hit->get_avg_t(); + + if (g4particle) + { + if (_scan_for_embedded) + { + if (trutheval->get_embed(g4particle) <= 0) continue; + } + + gtrackID = g4particle->get_track_id(); + gflavor = g4particle->get_pid(); + gpx = g4particle->get_px(); + gpy = g4particle->get_py(); + gpz = g4particle->get_pz(); + + PHG4VtxPoint* vtx = trutheval->get_vertex(g4particle); + + if (vtx) + { + gvx = vtx->get_x(); + gvy = vtx->get_y(); + gvz = vtx->get_z(); + gvt = vtx->get_t(); + } + + PHG4Hit* outerhit = nullptr; + if (_do_eval_light == false) + outerhit = trutheval->get_outermost_truth_hit(g4particle); + if (outerhit) + { + gfpx = outerhit->get_px(1); + gfpy = outerhit->get_py(1); + gfpz = outerhit->get_pz(1); + gfx = outerhit->get_x(1); + gfy = outerhit->get_y(1); + gfz = outerhit->get_z(1); + } + gembed = trutheval->get_embed(g4particle); + gprimary = trutheval->is_primary(g4particle); + } // if (g4particle){ + } + + if (g4particle) + { + efromtruth = hiteval->get_energy_contribution(hitset_key, hit_key, g4particle); + } + + float hit_data[] = { + event, + (float) _iseed, + hitID, + e, + adc, + layer, + sector, + side, + cellID, + ecell, + (float) phibin, + (float) zbin, + phi, + z, + g4hitID, + gedep, + gx, + gy, + gz, + gt, + gtrackID, + gflavor, + gpx, + gpy, + gpz, + gvx, + gvy, + gvz, + gvt, + gfpx, + gfpy, + gfpz, + gfx, + gfy, + gfz, + gembed, + gprimary, + efromtruth, + nhit_tpc_all, + nhit_tpc_in, + nhit_tpc_mid, + nhit_tpc_out, nclus_all, nclus_tpc, nclus_intt, nclus_maps, nclus_mms}; + + _ntp_hit->Fill(hit_data); + } + + } // else -> if (TrkrHitSetTpc *hitset = dynamic_cast(my_data->hitset);) + } } - } + } // for ([[maybe_unused]] const auto& [trkrID, trkrName] : TrkrDefs::TrkrNames) + if (Verbosity() >= 1) { _timer->stop(); @@ -1738,6 +2026,14 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) _timer->restart(); } + std::map hitsetsmap; + for (const auto & [trkrID, trkrName] : TrkrDefs::TrkrNames) + { + TrkrHitSetContainer * hitsets = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + if (hitsets) + hitsetsmap[trkrID] = hitsets; + } + if (_ntp_cluster && !_scan_for_embedded) { if (Verbosity() > 1) cout << "Filling ntp_cluster (all of them) " << endl; @@ -1747,8 +2043,8 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); TrkrClusterHitAssoc* clusterhitmap = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); - TrkrHitSetContainer* hitsets = findNode::getClass(topNode, "TRKR_HITSET"); TrkrClusterIterationMapv1* _iteration_map = findNode::getClass(topNode, "CLUSTER_ITERATION_MAP"); + ClusterErrorPara ClusErrPara; if (Verbosity() > 1){ if (clustermap != nullptr) @@ -1759,14 +2055,14 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) cout << "got clusterhitmap" << endl; else cout << "no clusterhitmap" << endl; - if (hitsets != nullptr) + if (hitsetsmap.size() != 0) cout << "got hitsets" << endl; else cout << "no hitsets" << endl; } - if (clustermap && clusterhitmap && hitsets ){ + if (clustermap && clusterhitmap && hitsetsmap.size()>0 ){ for(const auto& hitsetkey:clustermap->getHitSetKeys()) { int hitsetlayer = TrkrDefs::getLayer(hitsetkey); @@ -1811,8 +2107,6 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) }else if(m_cluster_version==4){ phisize = cluster->getPhiSize(); zsize = cluster->getZSize(); - double clusRadius = r; - ClusterErrorPara ClusErrPara; TrackSeed *seed = nullptr; if(track!=NULL){ if(layer < 7){ @@ -1821,18 +2115,19 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) seed = track->get_tpc_seed(); } if(seed != nullptr){ - auto para_errors = ClusErrPara.get_cluster_error(seed,cluster,clusRadius,cluster_key); + auto para_errors = ClusErrPara.get_cluster_error(cluster,r,cluster_key, seed->get_qOverR(), seed->get_slope()); pephi = sqrt(para_errors.first* Acts::UnitConstants::cm2); pez =sqrt( para_errors.second* Acts::UnitConstants::cm2); } } }else if(m_cluster_version==5){ TrkrClusterv5 *clusterv5 = dynamic_cast(cluster); + auto para_errors = ClusErrPara.get_clusterv5_modified_error(clusterv5,r,cluster_key); phisize = clusterv5->getPhiSize(); zsize = clusterv5->getZSize(); //double clusRadius = r; - ez = clusterv5->getZError(); - ephi = clusterv5->getRPhiError(); + ez = sqrt(para_errors.second); + ephi = sqrt(para_errors.first); maxadc = clusterv5->getMaxAdc(); } @@ -1852,24 +2147,17 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) cout << "Good hitset layer " << hitsetlayer << "| " << hitsetlayer2 << " layer " << layer << endl; } */ - float sumadc = 0; - TrkrHitSetContainer::Iterator hitset = hitsets->findOrAddHitSet(hitsetkey); - std::pair::const_iterator, std::multimap::const_iterator> - hitrange = clusterhitmap->getHits(cluster_key); - for(std::multimap::const_iterator - clushititer = hitrange.first; clushititer != hitrange.second; ++clushititer) - { - TrkrHit* hit = hitset->second->getHit(clushititer->second); - if(!hit) continue; - ++size; - sumadc += (hit->getAdc() - 70); - if((hit->getAdc()-70)>maxadc) - maxadc = (hit->getAdc()-70); - } - e = sumadc; - - float trackID = NAN; + sumClusterEnergyFromHits::calc( + clusterhitmap, + cluster_key, + hitsetsmap, + e, + maxadc, + size + ); + + float trackID = NAN; if (track!=NULL) trackID = track->get_id(); float g4hitID = NAN; @@ -2036,8 +2324,10 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) _ntp_cluster->Fill(cluster_data); } } - } - } + } // if (clustermap && clusterhitmap && hitsets ){ + + } // if (_ntp_cluster && !_scan_for_embedded) + else if (_ntp_cluster && _scan_for_embedded) { if (Verbosity() > 1) @@ -2055,10 +2345,10 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); TrkrClusterHitAssoc* clusterhitmap = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); - TrkrHitSetContainer* hitsets = findNode::getClass(topNode, "TRKR_HITSET"); + TrkrClusterIterationMapv1* _iteration_map = findNode::getClass(topNode, "CLUSTER_ITERATION_MAP"); - if (trackmap != nullptr && clustermap != nullptr && clusterhitmap != nullptr && hitsets != nullptr){ + if (trackmap != nullptr && clustermap != nullptr && clusterhitmap != nullptr && hitsetsmap.size() != 0){ for (SvtxTrackMap::Iter iter = trackmap->begin(); iter != trackmap->end(); ++iter) @@ -2145,7 +2435,7 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) seed = track->get_tpc_seed(); } if(seed != nullptr){ - auto para_errors = _ClusErrPara.get_cluster_error(seed,cluster,clusRadius,cluster_key); + auto para_errors = _ClusErrPara.get_cluster_error(cluster,clusRadius,cluster_key,seed->get_qOverR(), seed->get_slope()); pephi = sqrt(para_errors.first* Acts::UnitConstants::cm2); pez =sqrt( para_errors.second* Acts::UnitConstants::cm2); } @@ -2159,21 +2449,19 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) // count all hits for this cluster float maxadc = -999; - // count all hits for this cluster - TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluster_key); - TrkrHitSetContainer::Iterator hitset = hitsets->findOrAddHitSet(hitsetkey); - std::pair::const_iterator, std::multimap::const_iterator> - hitrange = clusterhitmap->getHits(cluster_key); - for(std::multimap::const_iterator - clushititer = hitrange.first; clushititer != hitrange.second; ++clushititer) - { - TrkrHit* hit = hitset->second->getHit(clushititer->second); - ++size; - if(hit->getAdc()>maxadc) - maxadc = hit->getAdc(); - } - - float trackID = NAN; + float sumadc = 0; + sumClusterEnergyFromHits::calc( + clusterhitmap, + cluster_key, + hitsetsmap, + sumadc, + maxadc, + size + ); + + + + float trackID = NAN; trackID = track->get_id(); float g4hitID = NAN; @@ -2323,8 +2611,10 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) _ntp_cluster->Fill(cluster_data); } } - } - } + } // if (trackmap != nullptr && clustermap != nullptr && clusterhitmap != nullptr && hitsets != nullptr){ + + } // else if (_ntp_cluster && _scan_for_embedded) + if (Verbosity() >= 1){ _timer->stop(); cout << "cluster time: " << _timer->get_accumulated_time() / 1000. << " sec" << endl; @@ -2343,8 +2633,8 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) { if (Verbosity() >= 1) cout << "Filling ntp_g4cluster " << endl; - - PHG4TruthInfoContainer* truthinfo = findNode::getClass(topNode, "G4TruthInfo"); + ClusterErrorPara ClusErrPara; + PHG4TruthInfoContainer* truthinfo = findNode::getClass(topNode, "G4TruthInfo"); PHG4TruthInfoContainer::ConstRange range = truthinfo->GetParticleRange(); for (PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; @@ -2439,11 +2729,13 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) phisize = reco_cluster->getPhiSize(); zsize = reco_cluster->getZSize(); }else if(m_cluster_version==5){ + TrkrClusterv5 *clusterv5 = dynamic_cast(reco_cluster); + auto para_errors = ClusErrPara.get_clusterv5_modified_error(clusterv5,r,ckey); //cout << " ver v4 " << endl; phisize = reco_cluster->getPhiSize(); zsize = reco_cluster->getZSize(); - ez = reco_cluster->getZError(); - ephi = reco_cluster->getRPhiError(); + ez = sqrt(para_errors.second); + ephi = sqrt(para_errors.first); } adc = reco_cluster->getAdc(); @@ -2514,7 +2806,8 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) } PHG4TruthInfoContainer* truthinfo = findNode::getClass(topNode, "G4TruthInfo"); - SvtxVertexMap *vertexmap = findNode::getClass(topNode, "SvtxVertexMap"); + GlobalVertexMap *gvertexmap = findNode::getClass(topNode, "GlobalVertexMap"); + if (truthinfo) { @@ -2912,14 +3205,16 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) << endl; */ + // this is the global vertex id vertexID = track->get_vertex_id(); - SvtxVertex* vertex = vertexmap->get(vertexID); + + GlobalVertex* vertex = gvertexmap->get(vertexID); if(vertex) { vx = vertex->get_x(); vy = vertex->get_y(); vz = vertex->get_z(); - get_dca(track, vertexmap, dca3dxy, dca3dz, dca3dxysigma, dca3dzsigma); + get_dca(track, gvertexmap, dca3dxy, dca3dz, dca3dxysigma, dca3dzsigma); } px = track->get_px(); @@ -3109,7 +3404,8 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) // need things off of the DST... SvtxTrackMap* trackmap = findNode::getClass(topNode, _trackmapname.c_str()); - SvtxVertexMap *vertexmap = findNode::getClass(topNode, "SvtxVertexMap"); + + GlobalVertexMap *gvertexmap = findNode::getClass(topNode, "GlobalVertexMap"); if (trackmap) { @@ -3277,8 +3573,9 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) dca3dxysigma = NAN, dca3dzsigma = NAN; float dca2d = NAN, dca2dsigma = NAN; + /// this is the global vertex int vertexID = track->get_vertex_id(); - SvtxVertex* vertex = vertexmap->get(vertexID); + GlobalVertex* vertex = gvertexmap->get(vertexID); float vx = NAN; float vy = NAN; float vz = NAN; @@ -3287,7 +3584,7 @@ void SvtxEvaluator::fillOutputNtuples(PHCompositeNode* topNode) vy = vertex->get_y(); vz = vertex->get_z(); - get_dca(track, vertexmap, dca3dxy, dca3dz, + get_dca(track, gvertexmap, dca3dxy, dca3dz, dca3dxysigma, dca3dzsigma); } float px = track->get_px(); @@ -3776,7 +4073,7 @@ TMatrixF SvtxEvaluator::calculateClusterError(TrkrCluster* c, float& clusphi) } -void SvtxEvaluator::get_dca(SvtxTrack* track, SvtxVertexMap* vertexmap, +void SvtxEvaluator::get_dca(SvtxTrack* track, GlobalVertexMap* vertexmap, float& dca3dxy, float& dca3dz, float& dca3dxysigma, float& dca3dzsigma) { diff --git a/simulation/g4simulation/g4eval/SvtxEvaluator.h b/simulation/g4simulation/g4eval/SvtxEvaluator.h index ca3b58189a..365516cfd4 100644 --- a/simulation/g4simulation/g4eval/SvtxEvaluator.h +++ b/simulation/g4simulation/g4eval/SvtxEvaluator.h @@ -22,6 +22,7 @@ class TFile; class TNtuple; class SvtxTrack; class SvtxVertexMap; +class GlobalVertexMap; //class TrkrClusterContainer; @@ -80,7 +81,7 @@ class SvtxEvaluator : public SubsysReco SvtxEvalStack *_svtxevalstack; TMatrixF calculateClusterError(TrkrCluster* c, float& clusphi); - void get_dca(SvtxTrack* track, SvtxVertexMap* vertexmap, + void get_dca(SvtxTrack* track, GlobalVertexMap* vertexmap, float& dca3dxy, float& dca3dz, float& dca3dxysigma, float& dca3dzsigma); //TrkrClusterContainer *cluster_map{nullptr}; @@ -139,6 +140,7 @@ class SvtxEvaluator : public SubsysReco void printInputInfo(PHCompositeNode *topNode); ///< print out the input object information (debugging upstream components) void printOutputInfo(PHCompositeNode *topNode); ///< print out the ancestry information for detailed diagnosis int m_cluster_version = 4; + }; #endif // G4EVAL_SVTXEVALUATOR_H diff --git a/simulation/g4simulation/g4eval/SvtxHitEval.cc b/simulation/g4simulation/g4eval/SvtxHitEval.cc index 793bde92a8..afd82b4e6b 100644 --- a/simulation/g4simulation/g4eval/SvtxHitEval.cc +++ b/simulation/g4simulation/g4eval/SvtxHitEval.cc @@ -1,9 +1,9 @@ #include "SvtxHitEval.h" +#include #include #include #include -#include #include #include @@ -18,7 +18,7 @@ #include #include #include -#include // for operator<<, endl, basic_... +#include // for operator<<, endl, basic_... #include #include @@ -28,10 +28,9 @@ using namespace std; SvtxHitEval::SvtxHitEval(PHCompositeNode* topNode) : _trutheval(topNode) - , _hitmap(nullptr) - // , _g4cells_svtx(nullptr) - // , _g4cells_tracker(nullptr) - //, _g4cells_maps(nullptr) + // , _g4cells_svtx(nullptr) + // , _g4cells_tracker(nullptr) + //, _g4cells_maps(nullptr) , _g4hits_tpc(nullptr) , _g4hits_intt(nullptr) , _g4hits_mvtx(nullptr) @@ -82,54 +81,12 @@ void SvtxHitEval::next_event(PHCompositeNode* topNode) get_node_pointers(topNode); } -/* -PHG4Cell* SvtxHitEval::get_cell(SvtxHit* hit) +std::set SvtxHitEval::all_truth_hits(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key) { if (!has_node_pointers()) { ++_errors; - cout << PHWHERE << " nerr: " << _errors << endl; - return nullptr; - } - - if (_strict) - { - assert(hit); - } - else if (!hit) - { - ++_errors; - cout << PHWHERE << " nerr: " << _errors << endl; - return nullptr; - } - - // hop from reco hit to g4cell - PHG4Cell* cell = nullptr; - if (_g4cells_svtx) cell = _g4cells_svtx->findCell(hit->get_cellid()); - if (!cell && _g4cells_tracker) cell = _g4cells_tracker->findCell(hit->get_cellid()); - if (!cell && _g4cells_maps) cell = _g4cells_maps->findCell(hit->get_cellid()); - - // only noise hits (cellid left at default value) should not trace - if ((_strict) && (hit->get_cellid() != 0xFFFFFFFF)) - { - assert(cell); - } - else if (!cell) - { - ++_errors; - cout << PHWHERE << " nerr: " << _errors << endl; - } - - return cell; -} -*/ - -std::set SvtxHitEval::all_truth_hits(TrkrDefs::hitkey hit_key) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return std::set(); } @@ -140,184 +97,69 @@ std::set SvtxHitEval::all_truth_hits(TrkrDefs::hitkey hit_key) else if (!hit_key) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return std::set(); } + const std::pair key(hitset_key, hit_key); + if (_do_cache) { - std::map >::iterator iter = - _cache_all_truth_hits.find(hit_key); + const auto & iter = + _cache_all_truth_hits.find(key); if (iter != _cache_all_truth_hits.end()) { return iter->second; } } - std::set truth_hits; + const uint8_t trkrid = TrkrDefs::getTrkrId(hitset_key); - /* - // hop from reco hit to g4cell - PHG4Cell* cell = nullptr; - if (_g4cells_svtx) cell = _g4cells_svtx->findCell(hit->get_cellid()); - if (!cell && _g4cells_tracker) cell = _g4cells_tracker->findCell(hit->get_cellid()); - if (!cell && _g4cells_maps) cell = _g4cells_maps->findCell(hit->get_cellid()); + std::set truth_hits; - // only noise hits (cellid left at default value) should not trace - if ((_strict) && (hit->get_cellid() != 0xFFFFFFFF)) - assert(cell); - else if (!cell) - { - ++_errors; - cout << PHWHERE << " nerr: " << _errors << endl; - return truth_hits; - } + assert(_hit_truth_map); - //cout << "Eval: hitid " << hit->get_id() << " cellid " << cell->get_cellid() << endl; - // loop over all the g4hits in this cell - for (PHG4Cell::EdepConstIterator g4iter = cell->get_g4hits().first; - g4iter != cell->get_g4hits().second; - ++g4iter) + std::multimap > temp_map; + _hit_truth_map->getG4Hits(hitset_key, hit_key, temp_map); // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only + for (std::multimap >::iterator htiter = temp_map.begin(); + htiter != temp_map.end(); ++htiter) { - //cout << " Looking for hit " << g4iter->first << " in layer " << cell->get_layer() << " with edep " << g4iter->second << endl; + // extract the g4 hit key here and add the g4hit to the set + PHG4HitDefs::keytype g4hitkey = htiter->second.second; + // cout << " hitkey " << hitkey << " g4hitkey " << g4hitkey << endl; PHG4Hit* g4hit = nullptr; - if (_g4hits_svtx) g4hit = _g4hits_svtx->findHit(g4iter->first); - if (!g4hit && _g4hits_tracker) g4hit = _g4hits_tracker->findHit(g4iter->first); - if (!g4hit && _g4hits_maps) g4hit = _g4hits_maps->findHit(g4iter->first); - if (!g4hit) cout << " Failed to find g4hit " << g4iter->first << " with edep " << g4iter->second << endl; - if (_strict) - assert(g4hit); - else if (!g4hit) + switch (trkrid) { - ++_errors; - cout << PHWHERE << " nerr: " << _errors << endl; - continue; - } - */ - - // get all of the g4hits for this hit_key - // have to start with all hitsets, unfortunately - TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(); - for(TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; iter != all_hitsets.second; ++iter) - { - TrkrDefs::hitsetkey hitset_key = iter->first; - unsigned int trkrid = TrkrDefs::getTrkrId(hitset_key); - TrkrHitSet *hitset = iter->second; - - // does this hitset contain our hitkey? - TrkrHit *hit = nullptr; - hit = hitset->getHit(hit_key); - if(hit) - { - // get g4hits for this hit - - std::multimap< TrkrDefs::hitsetkey, std::pair > temp_map; - _hit_truth_map->getG4Hits(hitset_key, hit_key, temp_map); // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only - for(std::multimap< TrkrDefs::hitsetkey, std::pair >::iterator htiter = temp_map.begin(); - htiter != temp_map.end(); ++htiter) - { - // extract the g4 hit key here and add the g4hit to the set - PHG4HitDefs::keytype g4hitkey = htiter->second.second; - //cout << " hitkey " << hitkey << " g4hitkey " << g4hitkey << endl; - PHG4Hit * g4hit = nullptr; - switch( trkrid ) - { - case TrkrDefs::tpcId: g4hit = _g4hits_tpc->findHit(g4hitkey); break; - case TrkrDefs::inttId: g4hit = _g4hits_intt->findHit(g4hitkey); break; - case TrkrDefs::mvtxId: g4hit = _g4hits_mvtx->findHit(g4hitkey); break; - case TrkrDefs::micromegasId: g4hit = _g4hits_mms->findHit(g4hitkey); break; - default: break; - } - // fill output set - if( g4hit ) truth_hits.insert(g4hit); - } - } - } - - if (_do_cache) _cache_all_truth_hits.insert(make_pair(hit_key, truth_hits)); - - return truth_hits; -} - -std::set SvtxHitEval::all_truth_hits(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_strict) - { - assert(hit_key); - } - else if (!hit_key) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_do_cache) - { - std::map >::iterator iter = - _cache_all_truth_hits.find(hit_key); - if (iter != _cache_all_truth_hits.end()) - { - return iter->second; + case TrkrDefs::tpcId: + g4hit = _g4hits_tpc->findHit(g4hitkey); + break; + case TrkrDefs::inttId: + g4hit = _g4hits_intt->findHit(g4hitkey); + break; + case TrkrDefs::mvtxId: + g4hit = _g4hits_mvtx->findHit(g4hitkey); + break; + case TrkrDefs::micromegasId: + g4hit = _g4hits_mms->findHit(g4hitkey); + break; + default: + break; } + // fill output set + if (g4hit) truth_hits.insert(g4hit); } - std::set truth_hits; - TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(trkrid); - - for(TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; iter != all_hitsets.second; ++iter) - { - TrkrDefs::hitsetkey hitset_key = iter->first; - TrkrHitSet *hitset = iter->second; - - // does this hitset contain our hitkey? - TrkrHit *hit = nullptr; - hit = hitset->getHit(hit_key); - if(hit) - { - // get g4hits for this hit - - std::multimap< TrkrDefs::hitsetkey, std::pair > temp_map; - _hit_truth_map->getG4Hits(hitset_key, hit_key, temp_map); // returns pairs (hitsetkey, std::pair(hitkey, g4hitkey)) for this hitkey only - for(std::multimap< TrkrDefs::hitsetkey, std::pair >::iterator htiter = temp_map.begin(); - htiter != temp_map.end(); ++htiter) - { - // extract the g4 hit key here and add the g4hit to the set - PHG4HitDefs::keytype g4hitkey = htiter->second.second; - //cout << " hitkey " << hitkey << " g4hitkey " << g4hitkey << endl; - PHG4Hit * g4hit = nullptr; - switch( trkrid ) - { - case TrkrDefs::tpcId: g4hit = _g4hits_tpc->findHit(g4hitkey); break; - case TrkrDefs::inttId: g4hit = _g4hits_intt->findHit(g4hitkey); break; - case TrkrDefs::mvtxId: g4hit = _g4hits_mvtx->findHit(g4hitkey); break; - case TrkrDefs::micromegasId: g4hit = _g4hits_mms->findHit(g4hitkey); break; - default: break; - } - // fill output set - if( g4hit ) truth_hits.insert(g4hit); - } - } - } - - if (_do_cache) _cache_all_truth_hits.insert(make_pair(hit_key, truth_hits)); + if (_do_cache) _cache_all_truth_hits.insert(make_pair(key, truth_hits)); return truth_hits; } -PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(TrkrDefs::hitkey hit_key) +PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key) { if (!has_node_pointers()) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return nullptr; } @@ -328,71 +170,23 @@ PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(TrkrDefs::hitkey hit_key) else if (!hit_key) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return nullptr; } - if (_do_cache) - { - std::map::iterator iter = - _cache_max_truth_hit_by_energy.find(hit_key); - if (iter != _cache_max_truth_hit_by_energy.end()) - { - return iter->second; - } - } - - std::set hits = all_truth_hits(hit_key); - PHG4Hit* max_hit = nullptr; - float max_e = FLT_MAX * -1.0; - for (std::set::iterator iter = hits.begin(); - iter != hits.end(); - ++iter) - { - PHG4Hit* hit = *iter; - if (hit->get_edep() > max_e) - { - max_e = hit->get_edep(); - max_hit = hit; - } - } - - if (_do_cache) _cache_max_truth_hit_by_energy.insert(make_pair(hit_key, max_hit)); - - return max_hit; -} - -PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return nullptr; - } - - if (_strict) - { - assert(hit_key); - } - else if (!hit_key) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return nullptr; - } + const std::pair key(hitset_key, hit_key); if (_do_cache) { - std::map::iterator iter = - _cache_max_truth_hit_by_energy.find(hit_key); + const auto & iter = + _cache_max_truth_hit_by_energy.find(key); if (iter != _cache_max_truth_hit_by_energy.end()) { return iter->second; } } - std::set hits = all_truth_hits(hit_key, trkrid); + std::set hits = all_truth_hits(hitset_key, hit_key); PHG4Hit* max_hit = nullptr; float max_e = FLT_MAX * -1.0; for (std::set::iterator iter = hits.begin(); @@ -407,17 +201,17 @@ PHG4Hit* SvtxHitEval::max_truth_hit_by_energy(TrkrDefs::hitkey hit_key, const Tr } } - if (_do_cache) _cache_max_truth_hit_by_energy.insert(make_pair(hit_key, max_hit)); + if (_do_cache) _cache_max_truth_hit_by_energy.insert(make_pair(key, max_hit)); return max_hit; } -std::set SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_key) +std::set SvtxHitEval::all_truth_particles(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key) { if (!has_node_pointers()) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return std::set(); } @@ -428,72 +222,16 @@ std::set SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_ke else if (!hit_key) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return std::set(); } - if (_do_cache) - { - std::map >::iterator iter = - _cache_all_truth_particles.find(hit_key); - if (iter != _cache_all_truth_particles.end()) - { - return iter->second; - } - } - - std::set truth_particles; - - std::set g4hits = all_truth_hits(hit_key); - - for (std::set::iterator iter = g4hits.begin(); - iter != g4hits.end(); - ++iter) - { - PHG4Hit* g4hit = *iter; - PHG4Particle* particle = get_truth_eval()->get_particle(g4hit); - - if (_strict) - assert(particle); - else if (!particle) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - continue; - } - - truth_particles.insert(particle); - } - - if (_do_cache) _cache_all_truth_particles.insert(make_pair(hit_key, truth_particles)); - - return truth_particles; -} - -std::set SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_strict) - { - assert(hit_key); - } - else if (!hit_key) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } + const std::pair key(hitset_key, hit_key); if (_do_cache) { - std::map >::iterator iter = - _cache_all_truth_particles.find(hit_key); + const auto & iter = + _cache_all_truth_particles.find(key); if (iter != _cache_all_truth_particles.end()) { return iter->second; @@ -502,7 +240,7 @@ std::set SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_ke std::set truth_particles; - std::set g4hits = all_truth_hits(hit_key, trkrid); + std::set g4hits = all_truth_hits(hitset_key, hit_key); for (std::set::iterator iter = g4hits.begin(); iter != g4hits.end(); @@ -516,77 +254,24 @@ std::set SvtxHitEval::all_truth_particles(TrkrDefs::hitkey hit_ke else if (!particle) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; continue; } truth_particles.insert(particle); } - if (_do_cache) _cache_all_truth_particles.insert(make_pair(hit_key, truth_particles)); + if (_do_cache) _cache_all_truth_particles.insert(make_pair(key, truth_particles)); return truth_particles; } -PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return nullptr; - } - - if (_strict) - { - assert(hit_key); - } - else if (!hit_key) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return nullptr; - } - - if (_do_cache) - { - std::map::iterator iter = - _cache_max_truth_particle_by_energy.find(hit_key); - if (iter != _cache_max_truth_particle_by_energy.end()) - { - return iter->second; - } - } - - // loop over all particles associated with this hit and - // get the energy contribution for each one, record the max - PHG4Particle* max_particle = nullptr; - float max_e = FLT_MAX * -1.0; - std::set particles = all_truth_particles(hit_key); - for (std::set::iterator iter = particles.begin(); - iter != particles.end(); - ++iter) - { - PHG4Particle* particle = *iter; - float e = get_energy_contribution(hit_key, particle); - if (e > max_e) - { - max_e = e; - max_particle = particle; - } - } - - if (_do_cache) _cache_max_truth_particle_by_energy.insert(make_pair(hit_key, max_particle)); - - return max_particle; -} - -PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid) +PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key) { if (!has_node_pointers()) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return nullptr; } @@ -597,14 +282,15 @@ PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key else if (!hit_key) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return nullptr; } + const std::pair key(hitset_key, hit_key); if (_do_cache) { - std::map::iterator iter = - _cache_max_truth_particle_by_energy.find(hit_key); + const auto & iter = + _cache_max_truth_particle_by_energy.find(key); if (iter != _cache_max_truth_particle_by_energy.end()) { return iter->second; @@ -615,13 +301,13 @@ PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key // get the energy contribution for each one, record the max PHG4Particle* max_particle = nullptr; float max_e = FLT_MAX * -1.0; - std::set particles = all_truth_particles(hit_key, trkrid); + std::set particles = all_truth_particles(hitset_key, hit_key); for (std::set::iterator iter = particles.begin(); iter != particles.end(); ++iter) { PHG4Particle* particle = *iter; - float e = get_energy_contribution(hit_key, particle); + float e = get_energy_contribution(hitset_key, hit_key, particle); if (e > max_e) { max_e = e; @@ -629,200 +315,157 @@ PHG4Particle* SvtxHitEval::max_truth_particle_by_energy(TrkrDefs::hitkey hit_key } } - if (_do_cache) _cache_max_truth_particle_by_energy.insert(make_pair(hit_key, max_particle)); + if (_do_cache) _cache_max_truth_particle_by_energy.insert(make_pair(key, max_particle)); return max_particle; } -std::set SvtxHitEval::all_hits_from(PHG4Particle* g4particle) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_strict) - { - assert(g4particle); - } - else if (!g4particle) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_do_cache) - { - std::map >::iterator iter = - _cache_all_hits_from_particle.find(g4particle); - if (iter != _cache_all_hits_from_particle.end()) - { - return iter->second; - } - } - - std::set hits; - - // loop over all the hits - TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(); - for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; - iter != all_hitsets.second; - ++iter) - { - TrkrHitSet::ConstRange range = iter->second->getHits(); - for(TrkrHitSet::ConstIterator hitr = range.first; hitr != range.second; ++hitr) - { - TrkrDefs::hitkey hit_key = hitr->first; - - // loop over all truth hits connected to this hit - std::set g4hits = all_truth_hits(hit_key); - for (std::set::iterator jter = g4hits.begin(); - jter != g4hits.end(); - ++jter) - { - PHG4Hit* candidate = *jter; - PHG4Particle *particle = _truthinfo->GetParticle(candidate->get_trkid()); - if (g4particle->get_track_id() == particle->get_track_id()) - { - hits.insert(hit_key); - } - } - } - } - - if (_do_cache) _cache_all_hits_from_particle.insert(make_pair(g4particle, hits)); - - return hits; -} - -std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_strict) - { - assert(g4hit); - } - else if (!g4hit) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return std::set(); - } - - if (_do_cache) - { - std::map >::iterator iter = - _cache_all_hits_from_g4hit.find(g4hit); - if (iter != _cache_all_hits_from_g4hit.end()) - { - return iter->second; - } - } - - std::set hits; - - unsigned int hit_layer = g4hit->get_layer(); - - // loop over all the hits - TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(); - for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; - iter != all_hitsets.second; - ++iter) - { - TrkrHitSet::ConstRange range = iter->second->getHits(); - for(TrkrHitSet::ConstIterator hitr = range.first; hitr != range.second; ++hitr) - { - TrkrDefs::hitkey hit_key = hitr->first; - - if (TrkrDefs::getLayer(hit_key) != hit_layer) continue; - - // loop over all truth hits connected to this hit - std::set g4hits = all_truth_hits(hit_key); - for (std::set::iterator jter = g4hits.begin(); - jter != g4hits.end(); - ++jter) - { - PHG4Hit* candidate = *jter; - if (candidate->get_hit_id() == g4hit->get_hit_id()) - { - hits.insert(hit_key); - } - } - } - } - - if (_do_cache) _cache_all_hits_from_g4hit.insert(make_pair(g4hit, hits)); - - return hits; -} - - TrkrDefs::hitkey SvtxHitEval::best_hit_from(PHG4Hit* g4hit) -{ - if (!has_node_pointers()) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return 0; - } - - if (_strict) - { - assert(g4hit); - } - else if (!g4hit) - { - ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; - return 0; - } - - if (_do_cache) - { - std::map::iterator iter = - _cache_best_hit_from_g4hit.find(g4hit); - if (iter != _cache_best_hit_from_g4hit.end()) - { - return iter->second; - } - } - - TrkrDefs::hitkey best_hit = 0; - float best_energy = 0.0; - std::set hits = all_hits_from(g4hit); - for (std::set::iterator iter = hits.begin(); - iter != hits.end(); - ++iter) - { - TrkrDefs::hitkey hit_key = *iter; - float energy = get_energy_contribution(hit_key, g4hit); - if (energy > best_energy) - { - best_hit = hit_key; - best_energy = energy; - } - } - - if (_do_cache) _cache_best_hit_from_g4hit.insert(make_pair(g4hit, best_hit)); - - return best_hit; -} +//std::set > SvtxHitEval::all_hits_from(PHG4Particle* g4particle) +//{ +// if (!has_node_pointers()) +// { +// ++_errors; +// if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; +// return std::set >(); +// } +// +// if (_strict) +// { +// assert(g4particle); +// } +// else if (!g4particle) +// { +// ++_errors; +// if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; +// return std::set >(); +// } +// +// if (_do_cache) +// { +// const auto & iter = +// _cache_all_hits_from_particle.find(g4particle); +// if (iter != _cache_all_hits_from_particle.end()) +// { +// return iter->second; +// } +// } +// +// std::set > hits; +// +// assert(_hit_truth_map); +// +// for (const auto& [trkrID, _hitmap] : _hitmaps) +// { +// // loop over all the hits +// TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(); +// for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; +// iter != all_hitsets.second; +// ++iter) +// { +// TrkrHitSet::ConstRange range = iter->second->getHits(); +// for (TrkrHitSet::ConstIterator hitr = range.first; hitr != range.second; ++hitr) +// { +// TrkrDefs::hitkey hit_key = hitr->first; +// +// // loop over all truth hits connected to this hit +// std::set g4hits = all_truth_hits(hit_key, trkrID); +// for (std::set::iterator jter = g4hits.begin(); +// jter != g4hits.end(); +// ++jter) +// { +// PHG4Hit* candidate = *jter; +// PHG4Particle* particle = _truthinfo->GetParticle(candidate->get_trkid()); +// if (g4particle->get_track_id() == particle->get_track_id()) +// { +// hits.insert(make_pair(iter->first, hit_key)); +// } +// } +// } +// } +// } +// +// if (_do_cache) _cache_all_hits_from_particle.insert(make_pair(g4particle, hits)); +// +// return hits; +//} + +//std::set > SvtxHitEval::all_hits_from(PHG4Hit* g4hit) +//{ +// if (!has_node_pointers()) +// { +// ++_errors; +// if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; +// return std::set >(); +// } +// +// if (_strict) +// { +// assert(g4hit); +// } +// else if (!g4hit) +// { +// ++_errors; +// if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; +// return std::set >(); +// } +// +// if (_do_cache) +// { +// const auto & iter = +// _cache_all_hits_from_g4hit.find(g4hit); +// if (iter != _cache_all_hits_from_g4hit.end()) +// { +// return iter->second; +// } +// } +// +// std::set hits; +// +// unsigned int hit_layer = g4hit->get_layer(); +// +// // loop over all the hits +// for (const auto& [trkrID, _hitmap] : _hitmaps) +// { +// TrkrHitSetContainer::ConstRange all_hitsets = _hitmap->getHitSets(); +// for (TrkrHitSetContainer::ConstIterator iter = all_hitsets.first; +// iter != all_hitsets.second; +// ++iter) +// { +// TrkrHitSet::ConstRange range = iter->second->getHits(); +// for (TrkrHitSet::ConstIterator hitr = range.first; hitr != range.second; ++hitr) +// { +// TrkrDefs::hitkey hit_key = hitr->first; +// +// if (TrkrDefs::getLayer(hit_key) != hit_layer) continue; +// +// // loop over all truth hits connected to this hit +// std::set g4hits = all_truth_hits(iter->first, hit_key); +// for (std::set::iterator jter = g4hits.begin(); +// jter != g4hits.end(); +// ++jter) +// { +// PHG4Hit* candidate = *jter; +// if (candidate->get_hit_id() == g4hit->get_hit_id()) +// { +// hits.insert(make_pair(iter->first, hit_key)); +// } +// } +// } +// } +// } +// +// if (_do_cache) _cache_all_hits_from_g4hit.insert(make_pair(g4hit, hits)); +// +// return hits; +//} // overlap calculations - float SvtxHitEval::get_energy_contribution(TrkrDefs::hitkey hit_key, PHG4Particle* particle) +float SvtxHitEval::get_energy_contribution(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key, PHG4Particle* particle) { if (!has_node_pointers()) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return NAN; } @@ -834,14 +477,16 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) else if (!hit_key || !particle) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return NAN; } + const std::pair key(hitset_key, hit_key); + if (_do_cache) { - std::map, float>::iterator iter = - _cache_get_energy_contribution_g4particle.find(make_pair(hit_key, particle)); + const auto & iter = + _cache_get_energy_contribution_g4particle.find(make_pair(key, particle)); if (iter != _cache_get_energy_contribution_g4particle.end()) { return iter->second; @@ -849,7 +494,7 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) } float energy = 0.0; - std::set g4hits = all_truth_hits(hit_key); + std::set g4hits = all_truth_hits(hitset_key, hit_key); for (std::set::iterator iter = g4hits.begin(); iter != g4hits.end(); ++iter) @@ -861,17 +506,22 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) } } - if (_do_cache) _cache_get_energy_contribution_g4particle.insert(make_pair(make_pair(hit_key, particle), energy)); + if (_do_cache) _cache_get_energy_contribution_g4particle.insert( + make_pair( + make_pair( + key, + particle), + energy)); return energy; } - float SvtxHitEval::get_energy_contribution(TrkrDefs::hitkey hit_key, PHG4Hit* g4hit) +float SvtxHitEval::get_energy_contribution(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key, PHG4Hit* g4hit) { if (!has_node_pointers()) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return NAN; } @@ -883,14 +533,15 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) else if (!hit_key || !g4hit) { ++_errors; - if(_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; + if (_verbosity > 0) cout << PHWHERE << " nerr: " << _errors << endl; return NAN; } + const std::pair key(hitset_key, hit_key); if (_do_cache) { - std::map, float>::iterator iter = - _cache_get_energy_contribution_g4hit.find(make_pair(hit_key, g4hit)); + const auto & iter = + _cache_get_energy_contribution_g4hit.find(make_pair(key, g4hit)); if (iter != _cache_get_energy_contribution_g4hit.end()) { return iter->second; @@ -901,7 +552,7 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) // complex in the future, so this is here mostly as future-proofing. float energy = 0.0; - std::set g4hits = all_truth_hits(hit_key); + std::set g4hits = all_truth_hits(hitset_key, hit_key); for (std::set::iterator iter = g4hits.begin(); iter != g4hits.end(); ++iter) @@ -911,7 +562,7 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) energy += candidate->get_edep(); } - if (_do_cache) _cache_get_energy_contribution_g4hit.insert(make_pair(make_pair(hit_key, g4hit), energy)); + if (_do_cache) _cache_get_energy_contribution_g4hit.insert(make_pair(make_pair(key, g4hit), energy)); return energy; } @@ -919,13 +570,18 @@ std::set SvtxHitEval::all_hits_from(PHG4Hit* g4hit) void SvtxHitEval::get_node_pointers(PHCompositeNode* topNode) { // need things off of the DST... - _hitmap = findNode::getClass(topNode, "TRKR_HITSET"); - + for (const auto& [trkrID, trkrName] : TrkrDefs::TrkrNames) + { + TrkrHitSetContainer* _hitmap = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + if (_hitmap) + _hitmaps[trkrID] = _hitmap; + } + _clustermap = findNode::getClass(topNode, "CORRECTED_TRKR_CLUSTER"); - if(!_clustermap) + if (!_clustermap) _clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); - - _hit_truth_map = findNode::getClass(topNode,"TRKR_HITTRUTHASSOC"); + + _hit_truth_map = findNode::getClass(topNode, "TRKR_HITTRUTHASSOC"); // need things off of the DST... _g4hits_tpc = findNode::getClass(topNode, "G4HIT_TPC"); @@ -941,8 +597,8 @@ void SvtxHitEval::get_node_pointers(PHCompositeNode* topNode) bool SvtxHitEval::has_node_pointers() { if (_strict) - assert(_hitmap); - else if (!_hitmap) + assert(_hitmaps.size()); + else if (!_hitmaps.size()) { return false; } diff --git a/simulation/g4simulation/g4eval/SvtxHitEval.h b/simulation/g4simulation/g4eval/SvtxHitEval.h index eefb1d0d54..3b9b7d2036 100644 --- a/simulation/g4simulation/g4eval/SvtxHitEval.h +++ b/simulation/g4simulation/g4eval/SvtxHitEval.h @@ -46,41 +46,34 @@ class SvtxHitEval // access the clustereval (and its cached values) SvtxTruthEval* get_truth_eval() { return &_trutheval; } - //PHG4Cell* get_cell(SvtxHit* hit); + // PHG4Cell* get_cell(SvtxHit* hit); // backtrace through to PHG4Hits - std::set all_truth_hits(TrkrDefs::hitkey hit_key); - PHG4Hit* max_truth_hit_by_energy(TrkrDefs::hitkey hit_key); - - // backtrace through to PHG4Hits for a specific tracker - std::set all_truth_hits(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid); - PHG4Hit* max_truth_hit_by_energy(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid); + std::set all_truth_hits(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key); + PHG4Hit* max_truth_hit_by_energy(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key); // backtrace through to PHG4Particles - std::set all_truth_particles(TrkrDefs::hitkey hit_key); - PHG4Particle* max_truth_particle_by_energy(TrkrDefs::hitkey hit_key); - - // backtrace through to PHG4Particles for a specific tracker - std::set all_truth_particles(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid); - PHG4Particle* max_truth_particle_by_energy(TrkrDefs::hitkey hit_key, const TrkrDefs::TrkrId trkrid); + std::set all_truth_particles(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key); + PHG4Particle* max_truth_particle_by_energy(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey hit_key); - // forwardtrace through to SvtxHits - std::set all_hits_from(PHG4Particle* truthparticle); - std::set all_hits_from(PHG4Hit* truthhit); - TrkrDefs::hitkey best_hit_from(PHG4Hit* truthhit); + // retire unused functions. Nonetheless, kept in comment at the moment in case some non-daily built class still uses them +// // forwardtrace through to SvtxHits +// std::set > all_hits_from(PHG4Particle* truthparticle); +// std::set > all_hits_from(PHG4Hit* truthhit); // overlap calculations - float get_energy_contribution(TrkrDefs::hitkey, PHG4Particle* truthparticle); - float get_energy_contribution(TrkrDefs::hitkey, PHG4Hit* truthhit); + float get_energy_contribution(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey, PHG4Particle* truthparticle); + float get_energy_contribution(const TrkrDefs::hitsetkey hitset_key, TrkrDefs::hitkey, PHG4Hit* truthhit); unsigned int get_errors() { return _errors + _trutheval.get_errors(); } private: + void get_node_pointers(PHCompositeNode* topNode); bool has_node_pointers(); SvtxTruthEval _trutheval; - TrkrHitSetContainer* _hitmap; + std::map _hitmaps; TrkrClusterContainer* _clustermap; TrkrHitTruthAssoc* _hit_truth_map; @@ -96,15 +89,15 @@ class SvtxHitEval unsigned int _errors; bool _do_cache; - std::map > _cache_all_truth_hits; - std::map _cache_max_truth_hit_by_energy; - std::map > _cache_all_truth_particles; - std::map _cache_max_truth_particle_by_energy; - std::map > _cache_all_hits_from_particle; - std::map > _cache_all_hits_from_g4hit; - std::map _cache_best_hit_from_g4hit; - std::map, float> _cache_get_energy_contribution_g4particle; - std::map, float> _cache_get_energy_contribution_g4hit; + std::map, std::set > _cache_all_truth_hits; + std::map, PHG4Hit*> _cache_max_truth_hit_by_energy; + std::map, std::set > _cache_all_truth_particles; + std::map, PHG4Particle*> _cache_max_truth_particle_by_energy; + std::map> > _cache_all_hits_from_particle; + std::map> > _cache_all_hits_from_g4hit; + std::map> _cache_best_hit_from_g4hit; + std::map, PHG4Particle*>, float> _cache_get_energy_contribution_g4particle; + std::map, PHG4Hit*>, float> _cache_get_energy_contribution_g4hit; }; #endif // G4EVAL_SVTXHITEVAL_H diff --git a/simulation/g4simulation/g4eval/TrackEvaluation.cc b/simulation/g4simulation/g4eval/TrackEvaluation.cc index 1dd23a104c..591805b7de 100644 --- a/simulation/g4simulation/g4eval/TrackEvaluation.cc +++ b/simulation/g4simulation/g4eval/TrackEvaluation.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -205,37 +206,46 @@ namespace } //! hit energy for a given cluster - void add_cluster_energy( TrackEvaluationContainerv1::ClusterStruct& cluster, TrkrDefs::cluskey clus_key, - TrkrClusterHitAssoc* cluster_hit_map, - TrkrHitSetContainer* hitsetcontainer ) + void add_cluster_energy(TrackEvaluationContainerv1::ClusterStruct& cluster, TrkrDefs::cluskey clus_key, + TrkrClusterHitAssoc* cluster_hit_map, + TrkrHitSetContainer* hitsetcontainer) { - // check container - if(!(cluster_hit_map && hitsetcontainer)) return; + if (!(cluster_hit_map && hitsetcontainer)) return; // for now this is only filled for micromegas const auto detId = TrkrDefs::getTrkrId(clus_key); - if(detId != TrkrDefs::micromegasId) return; + if (detId != TrkrDefs::micromegasId) return; const auto hitset_key = TrkrDefs::getHitSetKeyFromClusKey(clus_key); - const auto hitset = hitsetcontainer->findHitSet( hitset_key ); - if( !hitset ) return; + const auto hitset = hitsetcontainer->findHitSet(hitset_key); + if (!hitset) return; const auto range = cluster_hit_map->getHits(clus_key); cluster.energy_max = 0; cluster.energy_sum = 0; - for( const auto& pair:range_adaptor(range)) + for (const auto& pair : range_adaptor(range)) { - const auto hit = hitset->getHit( pair.second ); - if( hit ) + if (dynamic_cast(hitset)) { - const auto energy = hit->getEnergy(); + // specialized hit container for TPCs + + const auto energy = dynamic_cast(hitset)->getTpcADC(pair.second); cluster.energy_sum += energy; - if( energy > cluster.energy_max ) cluster.energy_max = energy; + if (energy > cluster.energy_max) cluster.energy_max = energy; + } + else + { + const auto hit = hitset->getHit(pair.second); + if (hit) + { + const auto energy = hit->getEnergy(); + cluster.energy_sum += energy; + if (energy > cluster.energy_max) cluster.energy_max = energy; + } } } - } // ad}d truth information @@ -386,7 +396,12 @@ int TrackEvaluation::load_nodes( PHCompositeNode* topNode ) m_container = findNode::getClass(topNode, "TrackEvaluationContainer"); // hitset container - m_hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + for (const auto & [trkrID, trkrName] : TrkrDefs::TrkrNames) + { + TrkrHitSetContainer * hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_" + trkrName); + if (hitsetcontainer) + m_hitsetcontainermap[trkrID] = hitsetcontainer; + } // g4hits m_g4hits_tpc = findNode::getClass(topNode, "G4HIT_TPC"); @@ -447,7 +462,7 @@ void TrackEvaluation::evaluate_event() void TrackEvaluation::evaluate_clusters() { - if(!(m_cluster_map&&m_hitsetcontainer&&m_container)) return; + if(!(m_cluster_map&&m_hitsetcontainermap.size()>0&&m_container)) return; // clear array m_container->clearClusters(); @@ -460,7 +475,15 @@ void TrackEvaluation::evaluate_clusters() // create cluster structure auto cluster_struct = create_cluster( key, cluster, track ); add_cluster_size( cluster_struct, cluster); - add_cluster_energy( cluster_struct, key, m_cluster_hit_map, m_hitsetcontainer ); + + + auto hitsetsmap_iter = m_hitsetcontainermap.find(TrkrDefs::getTrkrId(hitsetkey)); + if (hitsetsmap_iter != m_hitsetcontainermap.end()) + { + TrkrHitSetContainer* hitsetcontainer = hitsetsmap_iter->second; + assert(hitsetcontainer); + add_cluster_energy( cluster_struct, key, m_cluster_hit_map, hitsetcontainer ); + } // truth information const auto g4hits = find_g4hits( key ); @@ -516,7 +539,15 @@ void TrackEvaluation::evaluate_tracks() // create new cluster struct auto cluster_struct = create_cluster( cluster_key, cluster, track ); add_cluster_size( cluster_struct, cluster); - add_cluster_energy( cluster_struct, cluster_key, m_cluster_hit_map, m_hitsetcontainer ); + + auto hitsetsmap_iter = m_hitsetcontainermap.find(TrkrDefs::getTrkrId(cluster_key)); + if (hitsetsmap_iter != m_hitsetcontainermap.end()) + { + TrkrHitSetContainer* hitsetcontainer = hitsetsmap_iter->second; + assert(hitsetcontainer); + add_cluster_energy( cluster_struct, cluster_key, m_cluster_hit_map, hitsetcontainer ); + } + // truth information const auto g4hits = find_g4hits( cluster_key ); const bool is_micromegas( TrkrDefs::getTrkrId(cluster_key) == TrkrDefs::micromegasId ); @@ -686,7 +717,7 @@ TrackEvaluationContainerv1::ClusterStruct TrackEvaluation::create_cluster( TrkrD if(cluster_struct.layer>=7){ TrkrClusterv5 *clusterv5 = dynamic_cast(cluster); - auto para_errors_mm = ClusErrPara.get_clusterv5_error(tpc_seed,clusterv5,r,key); + auto para_errors_mm = ClusErrPara.get_clusterv5_modified_error(clusterv5,r,key); cluster_struct.phi_error = clusterv5->getRPhiError()/cluster_struct.r; cluster_struct.z_error = clusterv5->getZError(); @@ -697,7 +728,7 @@ TrackEvaluationContainerv1::ClusterStruct TrackEvaluation::create_cluster( TrkrD cluster_struct.trk_alpha = (r*r) /(2*r*TMath::Abs(1.0/tpc_seed->get_qOverR())); cluster_struct.trk_beta = atan(tpc_seed->get_slope()); }else{ - auto para_errors_mvtx = ClusErrPara.get_cluster_error(si_seed,cluster,r,key); + auto para_errors_mvtx = ClusErrPara.get_cluster_error(cluster,r,key,si_seed->get_qOverR(), si_seed->get_slope()); cluster_struct.phi_error = sqrt(para_errors_mvtx.first)/cluster_struct.r; cluster_struct.z_error = sqrt(para_errors_mvtx.second); // float R = TMath::Abs(1.0/si_seed->get_qOverR()); diff --git a/simulation/g4simulation/g4eval/TrackEvaluation.h b/simulation/g4simulation/g4eval/TrackEvaluation.h index 9b612eb2c3..cb221d122f 100644 --- a/simulation/g4simulation/g4eval/TrackEvaluation.h +++ b/simulation/g4simulation/g4eval/TrackEvaluation.h @@ -121,7 +121,7 @@ class TrackEvaluation : public SubsysReco ActsGeometry *m_tGeometry = nullptr; //! hits - TrkrHitSetContainer* m_hitsetcontainer = nullptr; + std::map m_hitsetcontainermap; //! clusters TrkrClusterContainer* m_cluster_map = nullptr; diff --git a/simulation/g4simulation/g4eval/TruthRecoTrackMatching.cc b/simulation/g4simulation/g4eval/TruthRecoTrackMatching.cc index 4a0d6f0c60..dfa98496bd 100644 --- a/simulation/g4simulation/g4eval/TruthRecoTrackMatching.cc +++ b/simulation/g4simulation/g4eval/TruthRecoTrackMatching.cc @@ -1,4 +1,5 @@ #include "TruthRecoTrackMatching.h" +#include "g4evaltools.h" #include #include @@ -52,15 +53,16 @@ using std::cout; TruthRecoTrackMatching::TruthRecoTrackMatching ( const unsigned short _nmincluster_match , const float _nmincluster_ratio - , const double _cutoff_dphi - , const double _same_dphi - , const double _cutoff_deta - , const double _same_deta - , const double _cluster_nzwidths - , const double _cluster_nphiwidths + , const float _cutoff_dphi + , const float _same_dphi + , const float _cutoff_deta + , const float _same_deta + , const float _cluster_nzwidths + , const float _cluster_nphiwidths , const unsigned short _max_nreco_per_truth , const unsigned short _max_ntruth_per_reco - ) : m_nmincluster_match { _nmincluster_match } // minimum number of clusters to match, default=4 + ) : m_cluster_comp { _cluster_nphiwidths, _cluster_nzwidths } + , m_nmincluster_match { _nmincluster_match } // minimum number of clusters to match, default=4 , m_nmincluster_ratio { _nmincluster_ratio } // minimum ratio to match a track, default=0. // -- Track Kinematic Cuts to match -- , m_cutoff_dphi { _cutoff_dphi } // maximum |dphi|=|phi_reco-phi_truth| to search for match @@ -68,8 +70,6 @@ TruthRecoTrackMatching::TruthRecoTrackMatching , m_cutoff_deta { _cutoff_deta } // same as m_cutoff_dphi for deta , m_same_deta { _same_deta } // same as m_same_dphi for deta // cluster matching widths (how close the truth center must be reco center) - , m_cluster_nzwidths { _cluster_nzwidths } - , m_cluster_nphiwidths { _cluster_nphiwidths } // number of truth tracks allowed matched per reco track, and v. versa , m_max_nreco_per_truth { _max_nreco_per_truth } , m_max_ntruth_per_reco { _max_ntruth_per_reco } @@ -77,11 +77,16 @@ TruthRecoTrackMatching::TruthRecoTrackMatching , m_nmatched_id_reco {nullptr} , m_nmatched_id_true {nullptr} { + m_cluscntr.set_comparer(&m_cluster_comp); if (Verbosity() > 50) cout << " Starting TruthRecoTrackMatching.cc " << endl; } int TruthRecoTrackMatching::InitRun(PHCompositeNode *topNode) //` { + if (Verbosity() > 10) topNode->print(); + auto init_status = m_cluster_comp.init(topNode); + if (init_status == Fun4AllReturnCodes::ABORTRUN) return init_status; + if (createNodes(topNode) != Fun4AllReturnCodes::EVENT_OK) { return Fun4AllReturnCodes::ABORTRUN; @@ -89,12 +94,10 @@ int TruthRecoTrackMatching::InitRun(PHCompositeNode *topNode) //` m_nmatched_id_reco = &(m_EmbRecoMatchContainer->map_nTruthPerReco()); m_nmatched_id_true = &(m_EmbRecoMatchContainer->map_nRecoPerTruth()); return Fun4AllReturnCodes::EVENT_OK; - if (Verbosity()>50) topNode->print(); - return 0; } -int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode) //` +int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode) { if (topnode == nullptr) { return Fun4AllReturnCodes::ABORTRUN; @@ -143,7 +146,8 @@ int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode) //` // phi-0 eta-0 pT-0 index-0 // <- values wrapped from the lowest phi values // phi-1 eta-1 pT-1 index-1 // <- RECOvec wraps{}; - auto wrap_from_start = std::upper_bound(recoData.begin(), recoData.end(), (-M_PI+m_cutoff_dphi), CompRECOtoPhi()); + auto wrap_from_start = std::upper_bound(recoData.begin(), + recoData.end(), (-M_PI+m_cutoff_dphi), CompRECOtoPhi()); for (auto iter = recoData.begin(); iter != wrap_from_start; ++iter) { auto entry = *iter; // make a new copy to wrap to the other side of recoData get(entry) = get(entry) + 2*M_PI; // put the new copy on the other end @@ -178,12 +182,17 @@ int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode) //` std::vector> outerbox_pairs {}; std::vector> innerbox_pairs {}; + if (topnode == nullptr) { + return Fun4AllReturnCodes::ABORTRUN; + } if (Verbosity()>70) { - std::cout << "Number of truth tracks: " << m_TrkrTruthTrackContainer->getMap().size() << std::endl; + std::cout << "Number of truth tracks: " << + m_TrkrTruthTrackContainer->getMap().size() << std::endl; for (auto& _pair : m_TrkrTruthTrackContainer->getMap()) { auto& track = _pair.second; cout << Form(" id:%2i (phi:eta:pt) (%5.2f:%5.2f:%5.2f nclus: %i)", track->getTrackid(), - track->getPhi(), track->getPseudoRapidity(), track->getPt(), (int)track->getClusters().size()) << endl; + track->getPhi(), track->getPseudoRapidity(), track->getPt(), + (int)track->getClusters().size()) << endl; } cout << " ----end-listing-truth-tracks---------- " << endl; } @@ -192,7 +201,8 @@ int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode) //` auto id_true = _pair.first; auto track = _pair.second; - auto match_indices = find_box_matches(track->getPhi(), track->getPseudoRapidity(), track->getPt()); + auto match_indices = find_box_matches(track->getPhi(), + track->getPseudoRapidity(), track->getPt()); // keep track of all truth tracks (by track-id) which has been matched @@ -201,7 +211,8 @@ int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode) //` if (Verbosity() > 80) { cout << Form(" T(%i) find box(%5.2f:%5.2f:%5.2f)", - (int)track->getTrackid(), track->getPhi(), track->getPseudoRapidity(), track->getPt()); + (int)track->getTrackid(), track->getPhi(), + track->getPseudoRapidity(), track->getPt()); for (auto& id_reco : match_indices.first) cout <<"->IB("<OB("<GetFile(); if (m_write_diag) { - TFile *s_current = gDirectory->GetFile(); m_diag_file->cd(); + G4Eval::write_StringToTFile( + "trk_match_sel", + Form(" Matching criteria:\n" + " min. clusters to match: %i\n" + " min. clust. match ratio: %4.2f" + " dphi small window: %4.2f" + " dphi large windows: %4.2f" + " deta small window: %4.2f" + " deta large window: %4.2f" + " nmax phg4 matches per svtx: %i" + " nmax svtx matches per phg4: %i" + , m_nmincluster_match + , m_nmincluster_ratio + , m_same_dphi + , m_cutoff_dphi + , m_same_deta + , m_cutoff_deta + , m_max_ntruth_per_reco + , m_max_nreco_per_truth + )); m_diag_tree ->Write(); m_diag_file ->Save(); m_diag_file ->Close(); @@ -256,40 +287,57 @@ int TruthRecoTrackMatching::End(PHCompositeNode * /*topNode*/) int TruthRecoTrackMatching::createNodes(PHCompositeNode* topNode) { + + PHNodeIterator iter(topNode); + PHCompositeNode *dstNode = dynamic_cast + (iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; + exit(1); + } + // Initiailize the modules m_PHG4TruthInfoContainer = findNode::getClass(topNode, "G4TruthInfo"); if (!m_PHG4TruthInfoContainer) { - std::cout << "Could not locate G4TruthInfo node when running \"TruthRecoTrackMatching\" module." << std::endl; + std::cout << "Could not locate G4TruthInfo node when running " + << "\"TruthRecoTrackMatching\" module." << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } m_SvtxTrackMap = findNode::getClass(topNode, "SvtxTrackMap"); if (!m_SvtxTrackMap) { - std::cout << "Could not locate SvtxTrackMap node when running \"TruthRecoTrackMatching\" module." << std::endl; + std::cout << "Could not locate SvtxTrackMap node when running " + << "\"TruthRecoTrackMatching\" module." << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - m_TruthClusterContainer = findNode::getClass(topNode, "TRKR_TRUTHCLUSTERCONTAINER"); + m_TruthClusterContainer = findNode::getClass(topNode, + "TRKR_TRUTHCLUSTERCONTAINER"); if (!m_TruthClusterContainer) { - std::cout << "Could not locate TRKR_TRUTHCLUSTERCONTAINER node when running \"TruthRecoTrackMatching\" module." << std::endl; + std::cout << "Could not locate TRKR_TRUTHCLUSTERCONTAINER node when " + << "running \"TruthRecoTrackMatching\" module." << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } m_RecoClusterContainer = findNode::getClass(topNode, "TRKR_CLUSTER"); if (!m_RecoClusterContainer) { - std::cout << "Could not locate TRKR_CLUSTER node when running \"TruthRecoTrackMatching\" module." << std::endl; + std::cout << "Could not locate TRKR_CLUSTER node when running " + <<"\"TruthRecoTrackMatching\" module." << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - m_TrkrTruthTrackContainer = findNode::getClass(topNode, "TRKR_TRUTHTRACKCONTAINER"); + m_TrkrTruthTrackContainer = findNode::getClass(topNode, + "TRKR_TRUTHTRACKCONTAINER"); if (!m_TrkrTruthTrackContainer) { - std::cout << "Could not locate TRKR_TRUTHTRACKCONTAINER node when running \"TruthRecoTrackMatching\" module." << std::endl; + std::cout << "Could not locate TRKR_TRUTHTRACKCONTAINER node when " + << "running \"TruthRecoTrackMatching\" module." << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -297,30 +345,25 @@ int TruthRecoTrackMatching::createNodes(PHCompositeNode* topNode) findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); if (!m_PHG4TpcCylinderGeomContainer) { - std::cout << "Could not locate CYLINDERCELLGEOM_SVTX node when running \"TruthRecoTrackMatching\" module." << std::endl; + std::cout << "Could not locate CYLINDERCELLGEOM_SVTX node when " + << "running \"TruthRecoTrackMatching\" module." << std::endl; /* std::cout << PHWHERE << "ERROR: Can't find node CYLINDERCELLGEOM_SVTX" << std::endl; */ return Fun4AllReturnCodes::ABORTEVENT; } // note that layers 0-6, and > 55, don't work - for (int layer=7; layer<55; ++layer) { - PHG4TpcCylinderGeom *layergeom = m_PHG4TpcCylinderGeomContainer->GetLayerCellGeom(layer); - if (layer==7) m_zstep = layergeom->get_zstep(); - m_phistep[layer] = layergeom->get_phistep(); - } - - PHNodeIterator iter(topNode); - PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); - if (!dstNode) - { - std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; - exit(1); - } - m_EmbRecoMatchContainer = findNode::getClass(topNode,"TRKR_EMBRECOMATCHCONTAINER"); + /* for (int layer=7; layer<55; ++layer) { */ + /* PHG4TpcCylinderGeom *layergeom = m_PHG4TpcCylinderGeomContainer->GetLayerCellGeom(layer); */ + /* if (layer==7) m_zstep = layergeom->get_zstep(); */ + /* m_phistep[layer] = layergeom->get_phistep(); */ + /* } */ + m_EmbRecoMatchContainer = findNode::getClass(topNode, + "TRKR_EMBRECOMATCHCONTAINER"); if (!m_EmbRecoMatchContainer) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto DetNode = dynamic_cast + (dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); @@ -328,7 +371,8 @@ int TruthRecoTrackMatching::createNodes(PHCompositeNode* topNode) } m_EmbRecoMatchContainer = new EmbRecoMatchContainerv1; - auto newNode = new PHIODataNode(m_EmbRecoMatchContainer, "TRKR_EMBRECOMATCHCONTAINER", "PHObject"); + auto newNode = new PHIODataNode(m_EmbRecoMatchContainer, + "TRKR_EMBRECOMATCHCONTAINER", "PHObject"); DetNode->addNode(newNode); } @@ -396,8 +440,10 @@ TruthRecoTrackMatching::find_box_matches(float truth_phi, float truth_eta, float inner_box = outer_box; if (_delta_inner_pt > 0) { // start the inner pair -- the outerbox is already sorted by pT - inner_box.first = std::lower_bound(inner_box.first, inner_box.second, truth_pt-_delta_inner_pt, CompRECOtoPt()); - inner_box.second = std::upper_bound(inner_box.first, inner_box.second, truth_pt+_delta_inner_pt, CompRECOtoPt()); + inner_box.first = std::lower_bound(inner_box.first, + inner_box.second, truth_pt-_delta_inner_pt, CompRECOtoPt()); + inner_box.second = std::upper_bound(inner_box.first, + inner_box.second, truth_pt+_delta_inner_pt, CompRECOtoPt()); } // go back to sorted by eta @@ -473,12 +519,14 @@ void TruthRecoTrackMatching::match_tracks_in_box( } // make all possible reco matches matched for this track - std::map truth_keys; - auto truth_track = m_TrkrTruthTrackContainer->getTruthTrack(id_true); - for (auto& key : truth_track->getClusters()) { - truth_keys[TrkrDefs::getHitSetKeyFromClusKey(key)] = key; - } - unsigned short nclus_true = truth_keys.size(); + /* std::map truth_keys; */ + m_cluscntr.addClusKeys(m_TrkrTruthTrackContainer->getTruthTrack(id_true)); + // add the truth keys into the track counter + /* auto truth_track = m_TrkrTruthTrackContainer->getTruthTrack(id_true); */ + /* for (auto& key : truth_track->getClusters()) { */ + /* truth_keys[TrkrDefs::getHitSetKeyFromClusKey(key)] = key; */ + /* } */ + /* unsigned short nclus_true = truth_keys.size(); */ while (ipair != box_pairs.end()) { // Loop over all possible matches only for this index_true //(subsequent true tracks will be caught on following loops) @@ -488,25 +536,32 @@ void TruthRecoTrackMatching::match_tracks_in_box( continue; }// make sure the reco-track isn't alread matched // ok, make a possible match: compare the clusters in the truth track and the reco track - unsigned short nclus_match = 0; // fill in the comparison loop - unsigned short nclus_nomatch = 0; // number of reco and truth cluster that share a hitsetkey, but still fair matching criteria - unsigned short nclus_reco = 0; // count in the comparison loop SvtxTrack* reco_track = m_SvtxTrackMap->get(ipair->second); - - - for (auto reco_ckey : ClusKeyIter(reco_track)) { - ++nclus_reco; - auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(reco_ckey); - if (truth_keys.count(hitsetkey) != 0) { - // reco and truth cluster are in same hitsetkey-indexed subsurface. - // See if they match (++nclus_match) or not (++nclus_nomatch) - if (compare_cluster_pair(truth_keys[hitsetkey], reco_ckey, hitsetkey).first) { - ++nclus_match; - } else { - ++nclus_nomatch; - } - } - } + m_cluscntr.addClusKeys(reco_track); + m_cluscntr.find_matches(); + + /* unsigned short nclus_match = 0; // fill in the comparison loop */ + /* unsigned short nclus_nomatch = 0; // number of reco and truth cluster + * // that share a hitsetkey, but still fair matching criteria */ + /* unsigned short nclus_reco = 0; // count in the comparison loop */ + //do the comparison of the tracks + /* for (auto reco_ckey : G4Eval::ClusKeyIter(reco_track)) { */ + /* ++nclus_reco; */ + /* auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(reco_ckey); */ + /* if (truth_keys.count(hitsetkey) != 0) { */ + /* // reco and truth cluster are in same hitsetkey-indexed subsurface. */ + /* // See if they match (++nclus_match) or not (++nclus_nomatch) */ + /* if (m_cluster_comp(truth_keys[hitsetkey], reco_ckey).first) { */ + /* ++nclus_match; */ + /* } else { */ + /* ++nclus_nomatch; */ + /* } */ + /* } */ + /* } */ + unsigned short nclus_match = m_cluscntr.phg4_n_matched(); + unsigned short nclus_true = m_cluscntr.phg4_nclus(); + unsigned short nclus_reco = m_cluscntr.svtx_nclus(); + unsigned short nclus_nomatch = (int) (m_cluscntr.svtx_keys.size()-nclus_match); if (Verbosity()>100) { auto truth_track = m_TrkrTruthTrackContainer->getTruthTrack(id_true); @@ -521,7 +576,9 @@ void TruthRecoTrackMatching::match_tracks_in_box( if ( nclus_match >= m_nmincluster_match && ( static_cast(nclus_match)/nclus_true >= m_nmincluster_ratio) ) { - poss_matches.push_back( {nclus_match, nclus_true, nclus_reco, ipair->first, ipair->second} ); + poss_matches.push_back( + {nclus_match, nclus_true, nclus_reco, + ipair->first, ipair->second} ); } ++ipair; } @@ -598,88 +655,51 @@ void TruthRecoTrackMatching::match_tracks_in_box( // ---------------------------------------- inline float TruthRecoTrackMatching::abs_dphi (float phi0, float phi1) { float dphi = fabs(phi0-phi1); - while (dphi > M_PI) dphi -= fabs(2*M_PI); + while (dphi > M_PI) dphi = fabs(dphi-2*M_PI); return dphi; } -/* - input: TrkrCluster* truth, TrkrCluster *reco, TrkrDefs::hitsetkey, bool calc_sigma=false - pair - out: Does it match? - - */ -std::pair TruthRecoTrackMatching::compare_cluster_pair ( - TrkrDefs::cluskey key_T - , TrkrDefs::cluskey key_R - , TrkrDefs::hitsetkey hitsetkey - , bool calc_sigma -) { - auto layer = TrkrDefs::getLayer(hitsetkey); - if (layer > 55) { - cout << " Error! Trying to compar cluster in layer > 55, which is not programmed yet!" << endl; - return {false, 0.}; - } - - auto clus_T = m_TruthClusterContainer ->findCluster(key_T); - auto clus_R = m_RecoClusterContainer ->findCluster(key_R); - - const auto phi_step = m_phistep[layer]; - - const auto phi_T = clus_T->getPosition(0); - // const auto phisize_T = clus_T->getPhiSize(); // not currently used for matching - const auto phi_R = clus_R->getPosition(0); - const auto phisize_R = clus_R->getPhiSize(); - - const auto z_T = clus_T->getPosition(1); - // const auto zsize_T = clus_T->getZSize(); // not currently used for matching - const auto z_R = clus_R->getPosition(1); - const auto zsize_R = clus_R->getZSize(); - - const double phi_delta = abs_dphi (phi_T,phi_R); - const double z_delta = fabs (z_T-z_R); - - const double phi_stat = (m_cluster_nphiwidths * phi_step * phisize_R ); - const double z_stat = (m_cluster_nzwidths * m_zstep * zsize_R ); - - if ( phi_delta > phi_stat || z_delta > z_stat ) return { false, 0. }; - else if (!calc_sigma) { - return { true, 0. }; - } else { - return { true, phi_delta/phi_stat +z_delta/z_stat }; - } -} - float TruthRecoTrackMatching::sigma_CompMatchClusters(PossibleMatch& match) { auto id_true = match[PM_idtrue]; auto id_reco = match[PM_idreco]; - auto truth_track = m_TrkrTruthTrackContainer->getTruthTrack(id_true); - if (!truth_track) return std::numeric_limits::max(); - std::map truth_keys; // truth cluster keys - for (auto& key : truth_track->getClusters()) truth_keys[TrkrDefs::getHitSetKeyFromClusKey(key)] = key; - - - SvtxTrack* reco_track = m_SvtxTrackMap->get(id_reco); - if (!reco_track) return std::numeric_limits::max(); - - auto tpcseed = reco_track->get_tpc_seed(); - if (!tpcseed) return std::numeric_limits::max(); + m_cluscntr.addClusKeys( m_TrkrTruthTrackContainer->getTruthTrack(id_true) ); + m_cluscntr.addClusKeys( m_SvtxTrackMap->get(id_reco)); - double n_matches = 0.; // get the mean match values - double sum_diff = 0.; + m_cluscntr.find_matches(); - for (auto reco_ckey : ClusKeyIter(reco_track)) { - auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(reco_ckey); - if (truth_keys.count(hitsetkey) == 0) continue; - auto comp_val = compare_cluster_pair(truth_keys[hitsetkey], reco_ckey, hitsetkey, true); + int n_matched = m_cluscntr.phg4_n_matched(); - if (comp_val.first) { - n_matches += 1.; - sum_diff += comp_val.second; - } - } - return sum_diff/n_matches; + if (n_matched) return std::numeric_limits::max(); + else return m_cluscntr.match_stat / n_matched; } + /* auto truth_track = m_TrkrTruthTrackContainer->getTruthTrack(id_true); */ + /* if (!truth_track) return std::numeric_limits::max(); */ + /* std::map truth_keys; // truth cluster keys */ + /* for (auto& key : truth_track->getClusters()) */ + /* truth_keys[TrkrDefs::getHitSetKeyFromClusKey(key)] = key; */ + + /* SvtxTrack* reco_track = m_SvtxTrackMap->get(id_reco); */ + /* if (!reco_track) return std::numeric_limits::max(); */ + + /* auto tpcseed = reco_track->get_tpc_seed(); */ + /* if (!tpcseed) return std::numeric_limits::max(); */ + + /* double n_matches = 0.; // get the mean match values */ + /* double sum_diff = 0.; */ + + /* for (auto reco_ckey : G4Eval::ClusKeyIter(reco_track)) { */ + /* auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(reco_ckey); */ + /* if (truth_keys.count(hitsetkey) == 0) continue; */ + /* auto comp_val = m_cluster_comp(truth_keys[hitsetkey], reco_ckey); */ + + /* if (comp_val.first) { */ + /* n_matches += 1.; */ + /* sum_diff += comp_val.second; */ + /* } */ + /* } */ + /* return sum_diff/n_matches; */ +/* } */ inline bool TruthRecoTrackMatching::skip_match( PossibleMatch& match ) { @@ -720,6 +740,7 @@ void TruthRecoTrackMatching::set_diagnostic_file(std::string file_name) { m_write_diag = true; TFile *s_current = gDirectory->GetFile(); m_diag_file = new TFile(file_name.c_str(),"recreate"); + // write out the cuts on this set of data m_diag_file->cd(); m_diag_tree = new TTree("T", "Tree of Reco and True Clusters"); @@ -810,7 +831,7 @@ void TruthRecoTrackMatching::fill_tree() { for (auto& ckey : track->getClusters()) { auto cluster = m_TruthClusterContainer->findCluster(ckey); m_cnt_true_notmatched.push_back(itrk); - Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(ckey, cluster); + Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(ckey, cluster); m_layer_true_notmatched .push_back(TrkrDefs::getLayer(ckey)); m_x_true_notmatched .push_back(gloc[0]); m_y_true_notmatched .push_back(gloc[1]); @@ -841,6 +862,7 @@ void TruthRecoTrackMatching::fill_tree() { m_i1_true_matched.push_back(cnt); ++itrk; } + // fill clusters of matched reco tracks std::set set_reco_matched; @@ -852,7 +874,7 @@ void TruthRecoTrackMatching::fill_tree() { SvtxTrack* reco_track = m_SvtxTrackMap->get(trkid); m_i0_reco_matched.push_back(cnt); - for (auto reco_ckey : ClusKeyIter(reco_track)) { + for (auto reco_ckey : G4Eval::ClusKeyIter(reco_track)) { auto cluster = m_RecoClusterContainer->findCluster(reco_ckey); Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(reco_ckey, cluster); m_layer_reco_matched .push_back(TrkrDefs::getLayer(reco_ckey)); @@ -875,7 +897,7 @@ void TruthRecoTrackMatching::fill_tree() { m_trkid_reco_notmatched.push_back(trkid); SvtxTrack* reco_track = m_SvtxTrackMap->get(trkid); m_i0_reco_notmatched.push_back(cnt); - for (auto reco_ckey : ClusKeyIter(reco_track)) { + for (auto reco_ckey : G4Eval::ClusKeyIter(reco_track)) { auto cluster = m_RecoClusterContainer->findCluster(reco_ckey); Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(reco_ckey, cluster); m_layer_reco_notmatched .push_back(TrkrDefs::getLayer(reco_ckey)); @@ -891,59 +913,7 @@ void TruthRecoTrackMatching::fill_tree() { ++m_event; m_diag_tree->Fill(); clear_branch_vectors(); + return; } -// Implementation of the iterable struct to get cluster keys from -// a SvtxTrack. It is used like: -// for (auto& cluskey : ClusKeyIter(svtx_track)) { -// ... // do things with cluster keys -// } -TruthRecoTrackMatching::ClusKeyIter::ClusKeyIter(SvtxTrack* _track) : - track {_track} - , in_silicon { _track->get_silicon_seed()!=nullptr } - , has_tpc { _track->get_tpc_seed()!=nullptr } - , no_data { !in_silicon && !has_tpc } -{ -} - -TruthRecoTrackMatching::ClusKeyIter TruthRecoTrackMatching::ClusKeyIter::begin() { - ClusKeyIter iter0 { track }; - if (iter0.no_data) return iter0; - if (iter0.in_silicon) { - iter0.iter = track->get_silicon_seed()->begin_cluster_keys(); - iter0.iter_end_silicon = track->get_silicon_seed()->end_cluster_keys(); - } else if (has_tpc) { - iter0.iter = track->get_tpc_seed()->begin_cluster_keys(); - } - return iter0; -} - -TruthRecoTrackMatching::ClusKeyIter TruthRecoTrackMatching::ClusKeyIter::end() { - ClusKeyIter iter0 { track }; - if (iter0.no_data) return iter0; - if (has_tpc) { - iter0.iter = track->get_tpc_seed()->end_cluster_keys(); - } else if (in_silicon) { - iter0.iter = track->get_silicon_seed()->end_cluster_keys(); - } - return iter0; -} - -void TruthRecoTrackMatching::ClusKeyIter::operator++() { - if (no_data) return; - ++iter; - if (in_silicon && has_tpc && iter == iter_end_silicon) { - in_silicon = false; - iter = track->get_tpc_seed()->begin_cluster_keys(); - } -} - -bool TruthRecoTrackMatching::ClusKeyIter::operator!=(const ClusKeyIter& rhs) { - if (no_data) return false; - return iter != rhs.iter; -} - -TrkrDefs::cluskey TruthRecoTrackMatching::ClusKeyIter::operator*() { - return *iter; -} diff --git a/simulation/g4simulation/g4eval/TruthRecoTrackMatching.h b/simulation/g4simulation/g4eval/TruthRecoTrackMatching.h index 6a8f822457..e3110b6b74 100644 --- a/simulation/g4simulation/g4eval/TruthRecoTrackMatching.h +++ b/simulation/g4simulation/g4eval/TruthRecoTrackMatching.h @@ -1,6 +1,8 @@ #ifndef TRUTHTRKMATCHER__H #define TRUTHTRKMATCHER__H +#include "g4evaltools.h" // has some G4Eval tools (TrkrClusterComparer) + #include #include #include @@ -55,12 +57,12 @@ class TruthRecoTrackMatching : public SubsysReco *--------------------------------------------------------*/ const unsigned short _nmin_match = 4 , const float _nmin_ratio = 0. - , const double _cutoff_dphi = 0.3 - , const double _same_dphi = 0.05 - , const double _cutoff_deta = 0.3 - , const double _same_deta = 0.05 - , const double _cluster_nzwidths = 0.5 - , const double _cluster_nphiwidths = 0.5 + , const float _cutoff_dphi = 0.3 + , const float _same_dphi = 0.05 + , const float _cutoff_deta = 0.3 + , const float _same_deta = 0.05 + , const float _cluster_nzwidths = 0.5 + , const float _cluster_nphiwidths = 0.5 , const unsigned short _max_nreco_per_truth = 4 , const unsigned short _max_ntruth_per_reco = 4 ); // for some output kinematis @@ -71,11 +73,13 @@ class TruthRecoTrackMatching : public SubsysReco int process_event(PHCompositeNode *) override; //` int End(PHCompositeNode *) override; + G4Eval::TrkrClusterComparer m_cluster_comp; + G4Eval::ClusCntr m_cluscntr; int createNodes(PHCompositeNode* topNode); - void set_cluster_nphiwidths (float val) { m_cluster_nphiwidths = val; }; - void set_cluster_nzwidths (float val) { m_cluster_nzwidths = val; }; + void set_cluster_nphiwidths (float val) { m_cluster_comp.set_nphi_widths(val);}; + void set_cluster_nzwidths (float val) { m_cluster_comp.set_nz_widths(val);}; void set_cutoff_deta (float val) { m_cutoff_deta = val; }; void set_cutoff_dphi (float val) { m_cutoff_dphi = val; }; void set_nmin_truth_cluster_ratio (float val) { m_nmincluster_ratio = val; }; @@ -89,10 +93,12 @@ class TruthRecoTrackMatching : public SubsysReco //-------------------------------------------------- // Internal functions //-------------------------------------------------- + //-------------------------------------------------- // Constant parameters for track matching //-------------------------------------------------- + unsigned short m_nmincluster_match; // minimum of matched clustered to keep a truth to emb match float m_nmincluster_ratio; // minimum ratio of truth clustered that must be matched in reconstructed track @@ -101,15 +107,15 @@ class TruthRecoTrackMatching : public SubsysReco double m_cutoff_deta; // how far in |eta_truth-eta_reco| to match double m_same_deta; // |eta_truth-eta_reco| to auto-evaluate (is < m_cutoff_deta) - double m_cluster_nzwidths; // cutoff in *getPhiSize() in cluster for |cluster_phi_truth-cluster_phi_reco| to match - double m_cluster_nphiwidths; // same for eta + /* double m_cluster_nzwidths; // cutoff in *getPhiSize() in cluster for |cluster_phi_truth-cluster_phi_reco| to match */ + /* double m_cluster_nphiwidths; // same for eta */ unsigned short m_max_nreco_per_truth; unsigned short m_max_ntruth_per_reco; - std::array m_phistep {0.}; // the phistep squared - double m_zstep {0.}; + /* std::array m_phistep {0.}; // the phistep squared */ + /* double m_zstep {0.}; */ std::map m_nmatched_index_true {}; @@ -267,29 +273,6 @@ class TruthRecoTrackMatching : public SubsysReco void clear_branch_vectors(); void fill_tree(); - // The following is a struct to iterate over the cluster keys for a given - // StvxTrack* tracks, starting with the silicone seed and then returning - // values for the tpc seed. It is used like: - // - // for (auto& cluskey : ClusKeyIter(svtx_track)) { - // ... // do things with cluster keys - // } - struct ClusKeyIter { - ClusKeyIter(SvtxTrack* _track); - // data - SvtxTrack* track; - bool in_silicon; - bool has_tpc; - bool no_data; // neither a tpc nor a silicon seed - TrackSeed::ClusterKeyIter iter { }; - TrackSeed::ClusterKeyIter iter_end_silicon { }; - - ClusKeyIter begin(); - ClusKeyIter end(); - void operator++(); - TrkrDefs::cluskey operator*(); - bool operator!=(const ClusKeyIter& rhs); - }; }; #endif diff --git a/simulation/g4simulation/g4eval/g4evaltools.cc b/simulation/g4simulation/g4eval/g4evaltools.cc new file mode 100644 index 0000000000..13ee1a7741 --- /dev/null +++ b/simulation/g4simulation/g4eval/g4evaltools.cc @@ -0,0 +1,474 @@ +#include "g4evaltools.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // for PHWHERE +#include +#include // for PHNode +#include +#include +#include // for PHObject +#include +#include +#include +#include +#include +#include + +using std::cout; +using std::endl; + +namespace G4Eval { + std::vector unmatchedSvtxTrkIds(EmbRecoMatchContainer* matches, SvtxTrackMap* m_SvtxTrackMap) { + std::set ids_matched{}; + for (auto trkid : matches->ids_RecoMatched()) { + ids_matched.insert(trkid); + } + + std::set ids_unmatched; + for (auto reco = m_SvtxTrackMap->begin(); reco != m_SvtxTrackMap->end(); ++reco) { + auto trkid = reco->first; + if (ids_matched.count(trkid)==0) ids_unmatched.insert(trkid); + } + std::vector ids_vec; + for (auto id : ids_unmatched) ids_vec.push_back((int)id); + std::sort(ids_vec.begin(), ids_vec.end()); + return ids_vec; + } + + +// function implementation mostly from +// https://root-forum.cern.ch/t/is-it-possible-to-save-plain-text-in-a-root-file/27674/4 +// Note that there is also the code there to read it back from a TFile + void write_StringToTFile(const std::string& msg_name, const std::string& msg) + { + //the string is either written to the current file, or to a new file + //that is named f_outname + TFile* s_current = gDirectory->GetFile(); + if (s_current == nullptr) { + std::cout << PHWHERE << " Error no TFile open to which to wrote the " + << std::endl << " TObjString mesaged." << std::endl; + return; + } + TObjString obj( msg.c_str() ); + s_current->WriteObject( &obj, msg_name.c_str() ); + return; + } + + // return the layer of the hit: 0:Mvtx 1:Intt 2:Tpc 3:Tpot + int trklayer_0123(TrkrDefs::hitsetkey key) { + auto layer = TrkrDefs::getLayer(key); + if (layer < 3) return 0; + if (layer < 7) return 1; + if (layer < 55) return 2; + return 3; + } + + //Implementation of Cluster comparator + TrkrClusterComparer::TrkrClusterComparer (float _nphi_widths, float _nz_widths ) + : m_nphi_widths { _nphi_widths }, + m_nz_widths { _nz_widths } + {}; + int TrkrClusterComparer::init(PHCompositeNode* topNode, + const std::string& name_phg4_clusters, + const std::string& name_reco_clusters) + { + // fill bin/pixel sizes + // ------ MVTX data ------ + PHG4CylinderGeomContainer* geom_container_mvtx + = findNode::getClass(topNode, "CYLINDERGEOM_MVTX"); + if (!geom_container_mvtx) { + std::cout << PHWHERE << " Could not locate CYLINDERGEOM_MVTX " << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + for (int layer=0; layer<3; ++layer) { + auto layergeom = dynamic_cast + (geom_container_mvtx->GetLayerGeom(layer)); + const double pitch = layergeom->get_pixel_x(); + const double length = layergeom->get_pixel_z(); + m_phistep [layer] = pitch; + if (layer == 0) m_zstep_mvtx = length; + } + + // ------ INTT data ------ + PHG4CylinderGeomContainer* geom_container_intt + = findNode::getClass(topNode, "CYLINDERGEOM_INTT"); + if (!geom_container_intt) { + std::cout << PHWHERE << " Could not locate CYLINDERGEOM_INTT " << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + // get phi and Z steps for intt + for (int layer=3; layer<7; ++layer) { + CylinderGeomIntt* geom = + dynamic_cast(geom_container_intt->GetLayerGeom(layer)); + float pitch = geom->get_strip_y_spacing(); + m_phistep [layer] = pitch; + } + + // ------ TPC data ------ + auto geom_tpc = + findNode::getClass(topNode, "CYLINDERCELLGEOM_SVTX"); + if (!geom_tpc) + { + std::cout << PHWHERE << " Could not locate CYLINDERCELLGEOM_SVTX node " << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + for (int layer=7; layer<55; ++layer) { + PHG4TpcCylinderGeom *layergeom = geom_tpc->GetLayerCellGeom(layer); + if (layer==7) m_zstep_tpc = layergeom->get_zstep(); + m_phistep[layer] = layergeom->get_phistep(); + } + + m_TruthClusters = + findNode::getClass(topNode, name_phg4_clusters.c_str()); + if (!m_TruthClusters) + { + std::cout << PHWHERE << " Could not locate " << name_phg4_clusters << " node" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_RecoClusters = + findNode::getClass(topNode, name_reco_clusters.c_str()); + if (!m_TruthClusters) + { + std::cout << PHWHERE << " Could not locate " << name_reco_clusters << " node" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_ActsGeometry = findNode::getClass(topNode, "ActsGeometry"); + if (!m_ActsGeometry) { + std::cout << PHWHERE << " Could not locate ActsGeometry node" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + return Fun4AllReturnCodes::EVENT_OK; + } + + // ok return tuple TrkrClusterComparer::operator() + (TrkrDefs::cluskey key_T, TrkrDefs::cluskey key_R) + { + // note: can use returned values, or just pull from these values + layer = TrkrDefs::getLayer(key_T); + if (layer > 55) { + std::cout << " Error! Trying to compar cluster in layer > 55, " + << "which is not programmed yet!" << std::endl; + return {false, 0.}; + } + + in_mvtx = ( layer <3 ); + in_intt = (layer >2 && layer <7); + in_tpc = (layer >6 && layer <55); + + float phi_step = m_phistep[layer]; + float z_step = in_mvtx ? m_zstep_mvtx : m_zstep_tpc; + + clus_T = m_TruthClusters ->findCluster(key_T); + clus_R = m_RecoClusters ->findCluster(key_R); + + phi_T = clus_T->getPosition(0); + phi_R = clus_R->getPosition(0); + phisize_R = clus_R->getPhiSize()*m_nphi_widths;// * phi_step; + phisize_T = clus_T->getPhiSize()*m_nphi_widths;// * phi_step; // only for user to get, if they want + + z_T = clus_T->getPosition(1); + z_R = clus_R->getPosition(1); + + if (!in_intt) { + zsize_R = clus_R->getZSize()*m_nz_widths;// * z_step; + zsize_T = clus_R->getZSize()*m_nz_widths;// * z_step; + } + + phi_delta = fabs(phi_T-phi_R); + while (phi_delta > M_PI) phi_delta = fabs(phi_delta-2*M_PI); + phi_delta /= phi_step; + + z_delta = fabs (z_T-z_R) / z_step; + + /* float phi_stat = (m_nphi_widths * phisize_R ); */ + + float phi_stat = std::max(phisize_T, phisize_R); + float fit_statistic = (phi_delta / phi_stat); + is_match = (fit_statistic <= 1.); + + float z_stat = 0; + if (!in_intt) { + z_stat = std::max(zsize_T, zsize_R); + + is_match = is_match && (z_delta < z_stat); + fit_statistic += z_delta / z_stat; + } + return { is_match, fit_statistic }; + } + + ClusLoc TrkrClusterComparer::clusloc_PHG4( + std::pair input) { + auto cluster = m_TruthClusters->findCluster(input.second); + Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(input.second, cluster); + return {TrkrDefs::getLayer(input.first),gloc, + (int)cluster->getPhiSize(),(int)cluster->getZSize()}; + } + + ClusLoc TrkrClusterComparer::clusloc_SVTX( + std::pair input) { + auto cluster = m_RecoClusters->findCluster(input.second); + Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(input.second, cluster); + return {TrkrDefs::getLayer(input.first),gloc, + (int)cluster->getPhiSize(),(int)cluster->getZSize()}; + } + + // Implementation of the iterable struct to get cluster keys from + // a SvtxTrack. It is used like: + // for (auto& cluskey : ClusKeyIter(svtx_track)) { + // ... // do things with cluster keys + // } + ClusKeyIter::ClusKeyIter(SvtxTrack* _track) : + track {_track} + , in_silicon { _track->get_silicon_seed()!=nullptr } + , has_tpc { _track->get_tpc_seed()!=nullptr } + , no_data { !in_silicon && !has_tpc } + { + } + + ClusKeyIter ClusKeyIter::begin() { + ClusKeyIter iter0 { track }; + if (iter0.no_data) return iter0; + if (iter0.in_silicon) { + iter0.iter = track->get_silicon_seed()->begin_cluster_keys(); + iter0.iter_end_silicon = track->get_silicon_seed()->end_cluster_keys(); + } else if (has_tpc) { + iter0.iter = track->get_tpc_seed()->begin_cluster_keys(); + } + return iter0; + } + + ClusKeyIter ClusKeyIter::end() { + ClusKeyIter iter0 { track }; + if (iter0.no_data) return iter0; + if (has_tpc) { + iter0.iter = track->get_tpc_seed()->end_cluster_keys(); + } else if (in_silicon) { + iter0.iter = track->get_silicon_seed()->end_cluster_keys(); + } + return iter0; + } + + void ClusKeyIter::operator++() { + if (no_data) return; + ++iter; + if (in_silicon && has_tpc && iter == iter_end_silicon) { + in_silicon = false; + iter = track->get_tpc_seed()->begin_cluster_keys(); + } + } + + bool ClusKeyIter::operator!=(const ClusKeyIter& rhs) { + if (no_data) return false; + return iter != rhs.iter; + } + + TrkrDefs::cluskey ClusKeyIter::operator*() { + return *iter; + } + + TrkrClusterContainer* ClusCntr::get_PHG4_clusters() { + if (comp == nullptr) return nullptr; + else return comp->m_TruthClusters; + } + + TrkrClusterContainer* ClusCntr::get_SVTX_clusters() { + if (comp == nullptr) return nullptr; + else return comp->m_RecoClusters; + } + + std::array ClusCntr::cntclus(Vector& keys) { + std::array cnt { 0, 0, 0, 0, 0 }; + for (auto& it : keys) { + cnt[trklayer_0123(it.first)] += 1; + } + for (int i=0;i<4;++i) cnt[4] += cnt[i]; + return cnt; + } + + std::array ClusCntr::cnt_matchedclus + (Vector& keys, std::vector& matches) + { + std::array cnt { 0, 0, 0, 0, 0 }; + if (keys.size() != matches.size()) { + std::cout << PHWHERE << " matching and key vector not the same size. " + << std::endl << " run find_matches() first." << std::endl; + return cnt; + } + for (unsigned int i=0; igetClusters()) { + phg4_keys.push_back( {TrkrDefs::getHitSetKeyFromClusKey(ckey), ckey} ); + } + std::sort(phg4_keys.begin(), phg4_keys.end()); + return phg4_keys.size(); + } + + void ClusCntr::reset() { + phg4_keys.clear(); + phg4_matches.clear(); + svtx_keys.clear(); + svtx_matches.clear(); + } + + std::array ClusCntr::find_matches() { + if (comp == nullptr) { + std::cout << PHWHERE + << " Won't compare tracks because of missing TrkrClusterComparer" << std::endl; + return {0,0,0}; + } + // find the matches between the svtx_keys and phg4_keys + // also keep track of the sum of the comparison between then + + // --------------------------------- + // set aliases for notation cleaness + // use A for PHG4 and B for SVTX + auto& vA = phg4_keys; + auto& vB = svtx_keys; + + auto& matchesA = phg4_matches; + auto& matchesB = svtx_matches; + + match_stat = 0.; + + // matches will say, cluster by cluster, which clusters are matched + matchesA = std::vector(vA.size(),false); + matchesB = std::vector(vB.size(),false); + + // user iterators to access the vectors + auto iA0 = vA.begin(); + auto iA1 = vA.end(); + + auto iB0 = vB.begin(); + auto iB1 = vB.end(); + + auto iA = iA0; + auto iB = iB0; + + int n_match {0}; + + while (iA != iA1 && iB != iB1) { + if (iA->first == iB->first) { + auto hitset = iA->first; + + // must compare ALL sets of iA and iB with this same hitset + auto sAend = iA+1; // search A end + while (sAend != iA1 && sAend->first == hitset) ++sAend; + + auto sBend = iB+1; // search B end + while (sBend != iB1 && sBend->first == hitset) ++sBend; + + for (auto _A = iA; _A!=sAend; ++_A) { + for (auto _B = iB; _B!=sBend; ++_B) { + auto comp_val = comp->operator()(_A->second,_B->second); + if (comp_val.first) { + matchesA[_A-iA0] = true; + matchesB[_B-iB0] = true; + match_stat += comp_val.second; + ++n_match; + } + }} + iA = sAend; + iB = sBend; + } else if (iA->first < iB->first) { + ++iA; + } else { + ++iB; + } + } + return { n_match, (int)phg4_keys.size(), (int)svtx_keys.size() }; + } + + std::array ClusCntr::find_matches(TrkrTruthTrack* g4_track, SvtxTrack* sv_track) { + addClusKeys(sv_track); + addClusKeys(g4_track); + return find_matches(); + } + + int ClusCntr::phg4_n_matched() { + return std::accumulate(phg4_matches.begin(), phg4_matches.end(), 0); } + + int ClusCntr::svtx_n_matched() { + return std::accumulate(svtx_matches.begin(), svtx_matches.end(), 0); } + + std::vector ClusCntr::phg4_clusloc_all() { + std::vector vec{}; + for (auto& cluspair : phg4_keys) vec.push_back(comp->clusloc_PHG4(cluspair)); + return vec; + } + + std::vector ClusCntr::phg4_clusloc_unmatched() { + std::vector vec{}; + auto cnt = phg4_keys.size(); + for (unsigned int i = 0; iclusloc_PHG4(phg4_keys[i])); + } + return vec; + } + + std::vector ClusCntr::svtx_clusloc_all() { + std::vector vec{}; + for (auto& cluspair : svtx_keys) vec.push_back(comp->clusloc_SVTX(cluspair)); + return vec; + } + + std::vector ClusCntr::svtx_clusloc_unmatched() { + std::vector vec{}; + auto cnt = svtx_keys.size(); + for (unsigned int i = 0; iclusloc_SVTX(svtx_keys[i])); + } + return vec; + } + + std::vector ClusCntr::clusloc_matched() { + std::vector vec{}; + auto cnt = phg4_keys.size(); + for (unsigned int i = 0; iclusloc_PHG4(phg4_keys[i])); + } + return vec; + } + + /* ClusCntr::layer_xyzLoc ClusCntr::xyzLoc(std::pairgetGlobalPosition(reco_ckey, cluster); */ + /* } */ + +} diff --git a/simulation/g4simulation/g4eval/g4evaltools.h b/simulation/g4simulation/g4eval/g4evaltools.h new file mode 100644 index 0000000000..5e2dd2ea1f --- /dev/null +++ b/simulation/g4simulation/g4eval/g4evaltools.h @@ -0,0 +1,173 @@ +#ifndef CLUSTERMATCHTOOLS__H +#define CLUSTERMATCHTOOLS__H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* #include */ + +class ActsGeometry; +class EmbRecoMatchContainer; +class PHCompositeNode; +class SvtxTrack; +class SvtxTrackMap; +class TrkrCluster; +class TrkrClusterContainer; +class TrkrTruthTrack; + +namespace G4Eval { + // ClusLoc holds layer, location, phi size and z size + using ClusLoc = std::tuple; + + // Following function writes msg to the currently active TFile + // if f_outname is provided, then it will write the message to a new + // TFiles of that name and close it again. + void write_StringToTFile(const std::string& msg_name, const std::string& msg); + + std::vector unmatchedSvtxTrkIds(EmbRecoMatchContainer*, SvtxTrackMap*); + + class TrkrClusterComparer { + // most members are public for easy access after the node has been used + public: + TrkrClusterComparer (float _nphi_widths=0.5, float _nz_widths=0.5 ); + int init(PHCompositeNode* topNode, + const std::string& name_truth_clusters="TRKR_TRUTHCLUSTERCONTAINER", + const std::string&name_reco_clusters="TRKR_CLUSTER"); + + TrkrCluster* clus_T { nullptr }; + TrkrCluster* clus_R { nullptr }; + + /* std::pair is_match_b */ + std::pair operator() (TrkrDefs::cluskey key_T, TrkrDefs::cluskey key_R); + + // Members that are set with each set of cluster keys that + // are passed to it. + // z and phi locations of phg4 hit (T) and Svtx hit (R) + bool is_match { false }; + int layer { INT_MAX }; + + float z_T { FLT_MAX }, z_R { FLT_MAX }; + float phi_T { FLT_MAX }, phi_R { FLT_MAX }; + float phisize_R { FLT_MAX }, phisize_T { FLT_MAX }; // phisize is in nbins * nwidhts + float zsize_R { FLT_MAX }, zsize_T { FLT_MAX }; // zsize is in nbins * nwdiths + float phi_delta { FLT_MAX }, z_delta { FLT_MAX }; // deltas are also in nbins + + bool in_tpc {false}; + bool in_mvtx {false}; + bool in_intt {false}; + bool in_tpot {false}; + + //z pixel sizes. n.b.: there is no z clustering in the INTT + float m_zstep_tpc {0.}; // from tpc geometry + float m_zstep_mvtx {0.}; + // TPOT not implemented yet... + + void set_nz_widths(float val) { m_nz_widths = val; }; + void set_nphi_widths(float val) { m_nphi_widths = val; }; + + ClusLoc clusloc_PHG4(std::pair); + ClusLoc clusloc_SVTX(std::pair); + + TrkrClusterContainer* m_TruthClusters {nullptr}; + TrkrClusterContainer* m_RecoClusters {nullptr}; + private: + //phi pixel sizes, got for the geometries from the topNode + std::array m_phistep {0.}; // the phistep squared + float m_nphi_widths; + float m_nz_widths; + + ActsGeometry* m_ActsGeometry {nullptr}; + + }; + + // The following is a struct to iterate over the cluster keys for a given + // StvxTrack* tracks, starting with the silicone seed and then returning + // values for the tpc seed. It is used like: + // + // for (auto& cluskey : ClusKeyIter(svtx_track)) { + // ... // do things with cluster keys + // } + struct ClusKeyIter { + typedef std::set ClusterKeySet; + typedef ClusterKeySet::iterator ClusterKeyIter; + + ClusKeyIter(SvtxTrack* _track); + // data + SvtxTrack* track; + bool in_silicon; + bool has_tpc; + bool no_data; // neither a tpc nor a silicon seed + ClusterKeyIter iter { }; + ClusterKeyIter iter_end_silicon { }; + + ClusKeyIter begin(); + ClusKeyIter end(); + + void operator++(); + TrkrDefs::cluskey operator*(); + bool operator!=(const ClusKeyIter& rhs); + }; + + int trklayer_0123(TrkrDefs::hitsetkey); // 0:Mvtx 1:Intt 2:Tpc 3:Tpot + + class ClusCntr { + private: + using Vector = std::vector>; + using Iter = Vector::iterator; + + TrkrClusterComparer* comp; + std::array cntclus(Vector& keys); + std::array cnt_matchedclus(Vector& keys, std::vector& matches); + + public: + ClusCntr(TrkrClusterComparer*_=nullptr) : comp{_} {}; + TrkrClusterContainer* get_PHG4_clusters(); + TrkrClusterContainer* get_SVTX_clusters(); + + Vector svtx_keys {}; + Vector phg4_keys {}; + + double match_stat {0}; + + void reset(); + std::array find_matches();// populated matches_{svtx,phg4}; + // return's {n-matched, n-phg4, n-svtx} + std::array find_matches(TrkrTruthTrack* g4_track, SvtxTrack* sv_track); + + int phg4_n_matched(); // also same as phg4_cnt_matchedclus()[4] + int svtx_n_matched(); // should be almost always the same + // which is ALMOST guaranteed to be same as svtx_cnt_matchedclus()[4] + int phg4_nclus() { return (int) phg4_keys.size(); } + int svtx_nclus() { return (int) svtx_keys.size(); } + + std::vector svtx_matches; + std::vector phg4_matches; + + int addClusKeys(SvtxTrack*); // return number of clusters + int addClusKeys(TrkrTruthTrack*); // return number of clusters + + std::array svtx_cntclus() { return cntclus(svtx_keys); }; // Mvtx Intt Tpc TPOT Sum + std::array phg4_cntclus() { return cntclus(phg4_keys); }; + + std::array svtx_cnt_matchedclus() {return cnt_matchedclus(svtx_keys, svtx_matches); }; + std::array phg4_cnt_matchedclus() {return cnt_matchedclus(phg4_keys, phg4_matches); }; + + //I need the cluster widths for diagnostics, too + std::vector phg4_clusloc_all (); + std::vector phg4_clusloc_unmatched(); + std::vector svtx_clusloc_all (); + std::vector svtx_clusloc_unmatched (); + std::vector clusloc_matched (); + + void set_comparer(TrkrClusterComparer* _comp) { comp = _comp; }; + + }; +} + +#endif diff --git a/simulation/g4simulation/g4histos/G4RawTowerTTree.cc b/simulation/g4simulation/g4histos/G4RawTowerTTree.cc index fef84a923b..f2aa714cb4 100644 --- a/simulation/g4simulation/g4histos/G4RawTowerTTree.cc +++ b/simulation/g4simulation/g4histos/G4RawTowerTTree.cc @@ -5,7 +5,7 @@ #include #include -#include +#include #include @@ -21,10 +21,6 @@ #include #include // for operator<<, endl, basic_... -#include // for _Rb_tree_const_iterator -#include // for pair - -using namespace std; G4RawTowerTTree::G4RawTowerTTree(const std::string &name) : SubsysReco(name) @@ -39,9 +35,9 @@ int G4RawTowerTTree::Init(PHCompositeNode *topNode) { if (_detector.empty()) { - cout << "Detector not set via Detector() method" << endl; - cout << "(it is the name appended to the G4TOWER_ nodename)" << endl; - cout << "you do not want to run like this, exiting now" << endl; + std::cout << "Detector not set via Detector() method" << std::endl; + std::cout << "(it is the name appended to the G4TOWER_ nodename)" << std::endl; + std::cout << "you do not want to run like this, exiting now" << std::endl; gSystem->Exit(1); } hm = new Fun4AllHistoManager("TOWERHIST"); @@ -63,10 +59,10 @@ int G4RawTowerTTree::process_event(PHCompositeNode *topNode) RawTowerGeomContainer *rawtowergeom = findNode::getClass(topNode, _towergeomnodename); // RawTowerContainer *g4towers = findNode::getClass(topNode, _towernodename); - TowerInfoContainer *g4towers = findNode::getClass(topNode, _towernodename); + TowerInfoContainer *g4towers = findNode::getClass(topNode, _towernodename); if (!g4towers) { - cout << "could not find " << _towernodename << endl; + std::cout << "could not find " << _towernodename << std::endl; gSystem->Exit(1); } diff --git a/simulation/g4simulation/g4ihcal/Makefile.am b/simulation/g4simulation/g4ihcal/Makefile.am index dc362413e5..9745693c9e 100644 --- a/simulation/g4simulation/g4ihcal/Makefile.am +++ b/simulation/g4simulation/g4ihcal/Makefile.am @@ -17,6 +17,7 @@ AM_LDFLAGS = \ -L$(ROOTSYS)/lib libg4ihcal_la_LIBADD = \ + -lcalo_io \ -lfun4all \ -lphg4hit \ -lg4detectors diff --git a/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.cc b/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.cc index f1af9f4b2c..444f6fb0d4 100644 --- a/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.cc +++ b/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.cc @@ -9,12 +9,26 @@ #include #include #include +#include -#include +#include +#include +#include // for PHNode +#include +#include // for PHObject +#include +#include #include + #include #include +#include // for convert_name_... +#include // for RawTowerGeom +#include // for RawTowerGeomC... +#include +#include + #include #include @@ -129,7 +143,7 @@ void PHG4IHCalDetector::ConstructMe(G4LogicalVolume *logicWorld) } } } - + if(!m_Params->get_int_param("saveg4hit")) AddGeometryNode(); return; } @@ -141,7 +155,7 @@ int PHG4IHCalDetector::ConstructIHCal(G4LogicalVolume *hcalenvelope) gdmlParser.SetOverlapCheck(OverlapCheck()); gdmlParser.Read(m_GDMPath, false); - G4AssemblyVolume *abs_asym = reader->GetAssembly("InnerSector"); //absorber + G4AssemblyVolume *abs_asym = reader->GetAssembly("InnerSector"); // absorber m_ScintiMotherAssembly = reader->GetAssembly("InnerTileAssembly90"); // scintillator std::vector::iterator it = abs_asym->GetVolumesIterator(); static const unsigned int tilepersec = 24 * 4 * 2; @@ -421,3 +435,121 @@ int PHG4IHCalDetector::map_layerid(const int layer_id) } return rowid; } + +//This is dulplicated code, we can get rid of it when we have the code to make towergeom for real data reco. +void PHG4IHCalDetector::AddGeometryNode() +{ + PHNodeIterator iter(topNode()); + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) + { + std::cout << PHWHERE << "Run Node missing, exiting." << std::endl; + gSystem->Exit(1); + exit(1); + } + PHNodeIterator runIter(runNode); + PHCompositeNode *RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", m_SuperDetector)); + if (!RunDetNode) + { + RunDetNode = new PHCompositeNode(m_SuperDetector); + runNode->addNode(RunDetNode); + } + m_TowerGeomNodeName = "TOWERGEOM_" + m_SuperDetector; + m_RawTowerGeom = findNode::getClass(topNode(), m_TowerGeomNodeName); + if (!m_RawTowerGeom) + { + m_RawTowerGeom = new RawTowerGeomContainer_Cylinderv1(RawTowerDefs::convert_name_to_caloid(m_SuperDetector)); + PHIODataNode *newNode = new PHIODataNode(m_RawTowerGeom, m_TowerGeomNodeName, "PHObject"); + RunDetNode->addNode(newNode); + } + double innerrad = m_Params->get_double_param(PHG4HcalDefs::innerrad); + double thickness = m_Params->get_double_param(PHG4HcalDefs::outerrad) - innerrad; + m_RawTowerGeom->set_radius(innerrad); + m_RawTowerGeom->set_thickness(thickness); + m_RawTowerGeom->set_phibins(m_Params->get_int_param(PHG4HcalDefs::n_towers)); + m_RawTowerGeom->set_etabins(m_Params->get_int_param("etabins")); + double geom_ref_radius = innerrad + thickness / 2.; + double phistart = m_Params->get_double_param("phistart"); + if (!std::isfinite(phistart)) + { + std::cout << PHWHERE << " phistart is not finite: " << phistart + << ", exiting now (this will crash anyway)" << std::endl; + gSystem->Exit(1); + } + for (int i = 0; i < m_Params->get_int_param(PHG4HcalDefs::n_towers); i++) + { + double phiend = phistart + 2. * M_PI / m_Params->get_int_param(PHG4HcalDefs::n_towers); + std::pair range = std::make_pair(phiend, phistart); + phistart = phiend; + m_RawTowerGeom->set_phibounds(i, range); + } + double etalowbound = - m_Params->get_double_param("scinti_eta_coverage_neg"); + for (int i = 0; i < m_Params->get_int_param("etabins"); i++) + { + //double etahibound = etalowbound + 2.2 / get_int_param("etabins"); + double etahibound = etalowbound + + (m_Params->get_double_param("scinti_eta_coverage_neg") + m_Params->get_double_param("scinti_eta_coverage_pos")) / m_Params->get_int_param("etabins"); + std::pair range = std::make_pair(etalowbound, etahibound); + m_RawTowerGeom->set_etabounds(i, range); + etalowbound = etahibound; + } + for (int iphi = 0; iphi < m_RawTowerGeom->get_phibins(); iphi++) + { + for (int ieta = 0; ieta < m_RawTowerGeom->get_etabins(); ieta++) + { + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::convert_name_to_caloid(m_SuperDetector), ieta, iphi); + + const double x(geom_ref_radius * cos(m_RawTowerGeom->get_phicenter(iphi))); + const double y(geom_ref_radius * sin(m_RawTowerGeom->get_phicenter(iphi))); + const double z(geom_ref_radius / tan(PHG4Utils::get_theta(m_RawTowerGeom->get_etacenter(ieta)))); + + RawTowerGeom *tg = m_RawTowerGeom->get_tower_geometry(key); + if (tg) + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - Tower geometry " << key << " already exists" << std::endl; + } + + if (fabs(tg->get_center_x() - x) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x + << std::endl; + + return; + } + if (fabs(tg->get_center_y() - y) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y + << std::endl; + return; + } + if (fabs(tg->get_center_z() - z) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z + << std::endl; + return; + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - building tower geometry " << key << "" << std::endl; + } + + tg = new RawTowerGeomv1(key); + + tg->set_center_x(x); + tg->set_center_y(y); + tg->set_center_z(z); + m_RawTowerGeom->add_tower_geometry(tg); + } + } + } + if (Verbosity() > 0) + { + m_RawTowerGeom->identify(); + } + +} diff --git a/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.h b/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.h index 7d5c162b17..770a6463ec 100644 --- a/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.h +++ b/simulation/g4simulation/g4ihcal/PHG4IHCalDetector.h @@ -20,6 +20,7 @@ class PHG4IHCalDisplayAction; class PHParameters; class PHG4Subsystem; class PHG4GDMLConfig; +class RawTowerGeomContainer; class PHG4IHCalDetector : public PHG4Detector { @@ -50,6 +51,7 @@ class PHG4IHCalDetector : public PHG4Detector int GetSectorId(G4VPhysicalVolume *volume) const; private: + void AddGeometryNode(); int map_towerid(const int tower_id); int map_layerid(const int layer_id); int ConstructIHCal(G4LogicalVolume *sandwich); @@ -81,6 +83,8 @@ class PHG4IHCalDetector : public PHG4Detector PHG4GDMLConfig *gdml_config = nullptr; std::string m_GDMPath; + RawTowerGeomContainer *m_RawTowerGeom = nullptr; + std::string m_TowerGeomNodeName; }; #endif // G4IHCAL_PHG4IHCALDETECTOR_H diff --git a/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.cc b/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.cc index 66122f3fea..8a2c998c17 100644 --- a/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.cc +++ b/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.cc @@ -13,8 +13,20 @@ #include // for PHG4SteppingAction #include +#include +#include // for PHIODataNode +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject #include +#include + +#include +#include +#include +#include + #include // Root headers @@ -24,22 +36,22 @@ #include // for G4ParticleDefinition #include // for G4ReferenceCountedHandle #include -#include // for G4StepPoint -#include // for fGeomBoundary, fAtRest... -#include // for G4String +#include // for G4StepPoint +#include // for fGeomBoundary, fAtRest... +#include // for G4String #include -#include // for G4ThreeVector -#include // for G4TouchableHandle -#include // for G4Track -#include // for fStopAndKill +#include // for G4ThreeVector +#include // for G4TouchableHandle +#include // for G4Track +#include // for fStopAndKill #include -#include // for G4double -#include // for G4VPhysicalVolume -#include // for G4VTouchable -#include // for G4VUserTrackInformation +#include // for G4double +#include // for G4VPhysicalVolume +#include // for G4VTouchable +#include // for G4VUserTrackInformation -#include // for isfinite -#include // for getenv +#include // for isfinite +#include // for getenv #include #include #include // for operator<<, operator+ @@ -55,6 +67,10 @@ PHG4IHCalSteppingAction::PHG4IHCalSteppingAction(PHG4IHCalDetector* detector, co , m_IsActive(m_Params->get_int_param("active")) , m_IsBlackHole(m_Params->get_int_param("blackhole")) , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model")) + , m_doG4Hit(m_Params->get_int_param("saveg4hit")) + , m_tmin(m_Params->get_double_param("tmin")) + , m_tmax(m_Params->get_double_param("tmax")) + , m_dt(m_Params->get_double_param("dt")) { SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm, m_Params->get_double_param("light_balance_inner_corr"), @@ -74,7 +90,7 @@ PHG4IHCalSteppingAction::~PHG4IHCalSteppingAction() } //____________________________________________________________________________.. -int PHG4IHCalSteppingAction::Init() +int PHG4IHCalSteppingAction::InitWithNode(PHCompositeNode* topNode) { if (m_LightScintModelFlag) { @@ -100,12 +116,133 @@ int PHG4IHCalSteppingAction::Init() file->Close(); delete file; } + if (!m_doG4Hit) + { + try + { + CreateNodeTree(topNode); + } + catch (std::exception& e) + { + std::cout << e.what() << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + if (Verbosity() > 1) topNode->print(); + } + return 0; } +//____________________________________________________________________________.. +bool PHG4IHCalSteppingAction::NoHitSteppingAction(const G4Step* aStep) +{ + G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); + G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); + // get volume of the current step + G4VPhysicalVolume* volume = touch->GetVolume(); + + // m_Detector->IsInIHCal(volume) + // returns + // 0 is outside of IHCal + // 1 is inside scintillator + // -1 is steel absorber + + int whichactive = m_Detector->IsInIHCal(volume); + + if (!whichactive) + { + return false; + } + int layer_id = -1; + int tower_id = -1; + // int sector_id = -1; + if (whichactive > 0) // scintillator + { + std::tuple layer_tower = m_Detector->GetLayerTowerId(volume); + // sector_id = std::get<0>(layer_tower); + layer_id = std::get<1>(layer_tower); + tower_id = std::get<2>(layer_tower); + + // std::cout<<"******** Inner HCal\t"<GetName()<<"\t"<GetPreStepPoint(); + G4StepPoint* postPoint = aStep->GetPostStepPoint(); + // time window cut + double pretime = prePoint->GetGlobalTime() / nanosecond; + double posttime = postPoint->GetGlobalTime() / nanosecond; + if (posttime < m_tmin || pretime > m_tmax) return false; + if ((posttime - pretime) > m_dt) return false; + G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV; + const G4Track* aTrack = aStep->GetTrack(); + // we only need visible energy here + double light_yield = eion; + + // correct evis using light map + if (m_LightScintModelFlag) + { + light_yield = GetVisibleEnergyDeposition(aStep); + if (m_MapCorrHist) + { + const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle(); + const G4ThreeVector& worldPosition = postPoint->GetPosition(); + G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition); + float lx = localPosition.x() / cm; + float ly = localPosition.y() / cm; + + // adjust to tilemap coordinates + int lcx = (int) (5.0 * lx) + 1; + int lcy = (int) (5.0 * (ly + 2.0)) + 1; + + if ((lcy >= 1) && (lcy <= m_MapCorrHist->GetNbinsY()) && + (lcx >= 1) && (lcx <= m_MapCorrHist->GetNbinsX())) + { + light_yield *= m_MapCorrHist->GetBinContent(lcx, lcy); + } + else + { + light_yield = 0.0; + } + } + else + { + light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y()); + } + } + // find the tower index for this step, tower_id is ieta, layer_id/4 is iphi + unsigned int ieta = tower_id; + unsigned int iphi = (unsigned int) layer_id / 4; + unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi); + m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield); + // set keep for the track + if (light_yield > 0) + { + if (G4VUserTrackInformation* p = aTrack->GetUserInformation()) + { + if (PHG4TrackUserInfoV1* pp = dynamic_cast(p)) + { + pp->SetKeep(1); // we want to keep the track + } + } + } + + return true; +} //____________________________________________________________________________.. bool PHG4IHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { + if ((!m_doG4Hit) && (!m_IsBlackHole)) + { + return NoHitSteppingAction(aStep); + } + G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); // get volume of the current step @@ -222,18 +359,18 @@ bool PHG4IHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) { m_Hit = new PHG4Hitv1(); } - //here we set the entrance values in cm + // here we set the entrance values in cm m_Hit->set_x(0, prePoint->GetPosition().x() / cm); m_Hit->set_y(0, prePoint->GetPosition().y() / cm); m_Hit->set_z(0, prePoint->GetPosition().z() / cm); // time in ns m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond); - //set and save the track ID + // set and save the track ID m_Hit->set_trkid(aTrack->GetTrackID()); m_SaveTrackId = aTrack->GetTrackID(); - //set the initial energy deposit + // set the initial energy deposit m_Hit->set_edep(0); - if (whichactive > 0) // return of IsInIHCalDetector, > 0 hit in scintillator, < 0 hit in absorber + if (whichactive > 0) // return of IsInIHCalDetector, > 0 hit in scintillator, < 0 hit in absorber { m_Hit->set_sector(sector_id); // the slat id m_Hit->set_scint_id(tower_id); // the slat id @@ -302,7 +439,7 @@ bool PHG4IHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond); - //sum up the energy to get total deposited + // sum up the energy to get total deposited m_Hit->set_edep(m_Hit->get_edep() + edep); if (whichactive > 0) // return of IsInIHCalDetector, > 0 hit in scintillator, < 0 hit in absorber { @@ -320,7 +457,7 @@ bool PHG4IHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool) float lx = localPosition.x() / cm; float ly = localPosition.y() / cm; - //adjust to tilemap coordinates + // adjust to tilemap coordinates int lcx = (int) (5.0 * lx) + 1; int lcy = (int) (5.0 * (ly + 2.0)) + 1; @@ -436,3 +573,26 @@ void PHG4IHCalSteppingAction::SetHitNodeName(const std::string& type, const std: gSystem->Exit(1); return; } + +void PHG4IHCalSteppingAction::CreateNodeTree(PHCompositeNode* topNode) +{ + PHNodeIterator nodeItr(topNode); + PHCompositeNode* dst_node = dynamic_cast( + nodeItr.findFirst("PHCompositeNode", "DST")); + if (!dst_node) + { + std::cout << "PHComposite node created: DST" << std::endl; + dst_node = new PHCompositeNode("DST"); + topNode->addNode(dst_node); + } + PHNodeIterator dstiter(dst_node); + PHCompositeNode* DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector())); + if (!DetNode) + { + DetNode = new PHCompositeNode(m_Detector->SuperDetector()); + dst_node->addNode(DetNode); + } + m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL); + PHIODataNode* towerNode = new PHIODataNode(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject"); + DetNode->addNode(towerNode); +} diff --git a/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.h b/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.h index 244fead22e..aba6140b65 100644 --- a/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.h +++ b/simulation/g4simulation/g4ihcal/PHG4IHCalSteppingAction.h @@ -10,6 +10,7 @@ class G4Step; class G4VPhysicalVolume; class PHCompositeNode; +class TowerInfoContainer; class PHG4IHCalDetector; class PHParameters; class PHG4Hit; @@ -29,14 +30,17 @@ class PHG4IHCalSteppingAction : public PHG4SteppingAction //! stepping action bool UserSteppingAction(const G4Step *, bool) override; - int Init() override; + int InitWithNode(PHCompositeNode *topNode) override; //! reimplemented from base class void SetInterfacePointers(PHCompositeNode *) override; void SetHitNodeName(const std::string &type, const std::string &name) override; + void CreateNodeTree(PHCompositeNode *topNode); + private: + bool NoHitSteppingAction(const G4Step *aStep); //! pointer to the detector PHG4IHCalDetector *m_Detector = nullptr; @@ -61,8 +65,15 @@ class PHG4IHCalSteppingAction : public PHG4SteppingAction int m_IsActive = 0; int m_IsBlackHole = 0; int m_LightScintModelFlag = 0; + bool m_doG4Hit = true; + double m_tmin = -20.; + double m_tmax = 60.; + double m_dt = 100.; + std::string m_AbsorberNodeName; std::string m_HitNodeName; + + TowerInfoContainer *m_CaloInfoContainer = nullptr; }; #endif // G4IHCAL_PHG4IHCALSTEPPINGACTION_H diff --git a/simulation/g4simulation/g4ihcal/PHG4IHCalSubsystem.cc b/simulation/g4simulation/g4ihcal/PHG4IHCalSubsystem.cc index 0a0fabf553..67a4a7c30b 100644 --- a/simulation/g4simulation/g4ihcal/PHG4IHCalSubsystem.cc +++ b/simulation/g4simulation/g4ihcal/PHG4IHCalSubsystem.cc @@ -95,7 +95,7 @@ int PHG4IHCalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) // create stepping action m_SteppingAction = new PHG4IHCalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); m_SteppingAction->SetHitNodeName("G4HIT", m_HitNodeName); m_SteppingAction->SetHitNodeName("G4HIT_ABSORBER", m_AbsorberNodeName); } @@ -105,7 +105,7 @@ int PHG4IHCalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) if (GetParams()->get_int_param("blackhole")) { m_SteppingAction = new PHG4IHCalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); } } return 0; @@ -152,6 +152,9 @@ void PHG4IHCalSubsystem::SetDefaultParameters() set_default_double_param("light_balance_inner_radius", NAN); set_default_double_param("light_balance_outer_corr", NAN); set_default_double_param("light_balance_outer_radius", NAN); + set_default_double_param("phistart", NAN); + set_default_double_param("scinti_eta_coverage_neg", 1.1); + set_default_double_param("scinti_eta_coverage_pos", 1.1); set_default_double_param(PHG4HcalDefs::outerrad, 274.010 / 2 + 3); set_default_double_param("place_x", 0.); set_default_double_param("place_y", 0.); @@ -161,11 +164,18 @@ void PHG4IHCalSubsystem::SetDefaultParameters() set_default_double_param("rot_z", 0.); set_default_double_param("size_z", 435.000 + 10 ); set_default_double_param("Birk_const", 0.07943); + set_default_double_param("tmin", -20.); + set_default_double_param("tmax", 60.); + set_default_double_param("dt", 100.); + set_default_int_param("light_scint_model", 1); set_default_int_param(PHG4HcalDefs::n_towers, 64); set_default_int_param(PHG4HcalDefs::scipertwr, 4); set_default_int_param(PHG4HcalDefs::n_scinti_tiles, 12); + set_default_int_param("etabins", 24); + set_default_int_param("saveg4hit", 1); + set_default_string_param("GDMPath", "DefaultParameters-InvadPath"); const char* Calibroot = getenv("CALIBRATIONROOT"); diff --git a/simulation/g4simulation/g4intt/Makefile.am b/simulation/g4simulation/g4intt/Makefile.am index 93d5dbab5a..ee55b8a01b 100644 --- a/simulation/g4simulation/g4intt/Makefile.am +++ b/simulation/g4simulation/g4intt/Makefile.am @@ -29,8 +29,7 @@ pkginclude_HEADERS = \ PHG4InttDefs.h \ PHG4InttDigitizer.h \ PHG4InttHitReco.h \ - PHG4InttSubsystem.h \ - TruthInttClusterBuilder.h + PHG4InttSubsystem.h ROOTDICTS = \ InttDeadMap_Dict.cc \ @@ -50,8 +49,7 @@ libg4intt_la_SOURCES = \ PHG4InttFPHXParameterisation.cc \ PHG4InttHitReco.cc \ PHG4InttSteppingAction.cc \ - PHG4InttSubsystem.cc \ - TruthInttClusterBuilder.cc + PHG4InttSubsystem.cc libg4intt_la_LIBADD = \ libg4intt_io.la \ diff --git a/simulation/g4simulation/g4intt/PHG4InttDigitizer.cc b/simulation/g4simulation/g4intt/PHG4InttDigitizer.cc index 816c6ffa0b..6981d9c0e6 100644 --- a/simulation/g4simulation/g4intt/PHG4InttDigitizer.cc +++ b/simulation/g4simulation/g4intt/PHG4InttDigitizer.cc @@ -1,7 +1,6 @@ // This is the new trackbase container version #include "PHG4InttDigitizer.h" - #include "InttDeadMap.h" #include @@ -189,10 +188,10 @@ void PHG4InttDigitizer::DigitizeLadderCells(PHCompositeNode *topNode) } // Get the TrkrHitSetContainer node - TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_INTT"); if (!trkrhitsetcontainer) { - std::cout << "Could not locate TRKR_HITSET node, quit! " << std::endl; + std::cout << "Could not locate TRKR_HITSET_INTT node, quit! " << std::endl; exit(1); } @@ -264,16 +263,14 @@ void PHG4InttDigitizer::DigitizeLadderCells(PHCompositeNode *topNode) } const float mip_e = _energy_scale[layer]; - std::vector > vadcrange = _max_fphx_adc[layer]; + std::vector& vadcrange = _max_fphx_adc[layer]; + + // c++ upper_bound finds the bin location above the test value (or vadcrange.end() if there isn't one) + auto irange = std::upper_bound(vadcrange.begin(), vadcrange.end(), + hit->getEnergy() / TrkrDefs::InttEnergyScaleup * (double) mip_e); + int adc = (irange-vadcrange.begin())-1; + if (adc == -1) adc = 0; - int adc = 0; - for (unsigned int irange = 0; irange < vadcrange.size(); ++irange) - { - if (hit->getEnergy() / TrkrDefs::InttEnergyScaleup >= vadcrange[irange].first * (double) mip_e && hit->getEnergy() / TrkrDefs::InttEnergyScaleup < vadcrange[irange].second * (double) mip_e) - { - adc = (unsigned short) irange; - } - } hit->setAdc(adc); if (Verbosity() > 2) @@ -283,7 +280,7 @@ void PHG4InttDigitizer::DigitizeLadderCells(PHCompositeNode *topNode) } } // end loop over hits in this hitset - // remove hits on dead channel in TRKR_HITSET and TRKR_HITTRUTHASSOC + // remove hits on dead channel in TRKR_HITSET_INTT and TRKR_HITTRUTHASSOC for (const auto &key : dead_hits) { if (Verbosity() > 2) @@ -334,26 +331,13 @@ float PHG4InttDigitizer::added_noise() return noise; } -void PHG4InttDigitizer::set_adc_scale(const int &layer, const std::vector &userrange) +void PHG4InttDigitizer::set_adc_scale(const int &layer, std::vector userrange) { if (userrange.size() != nadcbins) { std::cout << "Error: vector in set_fphx_adc_scale(vector) must have eight elements." << std::endl; gSystem->Exit(1); } - //sort(userrange.begin(), userrange.end()); // TODO, causes GLIBC error - - std::vector > vadcrange; - for (unsigned int irange = 0; irange < userrange.size(); ++irange) - { - if (irange == userrange.size() - 1) - { - vadcrange.push_back(std::make_pair(userrange[irange], FLT_MAX)); - } - else - { - vadcrange.push_back(std::make_pair(userrange[irange], userrange[irange + 1])); - } - } - _max_fphx_adc.insert(std::make_pair(layer, vadcrange)); + std::sort(userrange.begin(), userrange.end()); + _max_fphx_adc.insert(std::make_pair(layer, userrange)); } diff --git a/simulation/g4simulation/g4intt/PHG4InttDigitizer.h b/simulation/g4simulation/g4intt/PHG4InttDigitizer.h index a2b1de81c0..35695c4b94 100644 --- a/simulation/g4simulation/g4intt/PHG4InttDigitizer.h +++ b/simulation/g4simulation/g4intt/PHG4InttDigitizer.h @@ -33,7 +33,7 @@ class PHG4InttDigitizer : public SubsysReco, public PHParameterInterface void Detector(const std::string &d) { detector = d; } - void set_adc_scale(const int &layer, const std::vector &userrange); + void set_adc_scale(const int &layer, std::vector userrange_copy); private: void CalculateLadderCellADCScale(PHCompositeNode *topNode); @@ -57,7 +57,7 @@ class PHG4InttDigitizer : public SubsysReco, public PHParameterInterface //SvtxHitMap *_hitmap; const unsigned int nadcbins = 8; - std::map > > _max_fphx_adc; + std::map> _max_fphx_adc; unsigned int m_nCells = 0; unsigned int m_nDeadCells = 0; diff --git a/simulation/g4simulation/g4intt/PHG4InttHitReco.cc b/simulation/g4simulation/g4intt/PHG4InttHitReco.cc index 79439dcece..88e2359419 100644 --- a/simulation/g4simulation/g4intt/PHG4InttHitReco.cc +++ b/simulation/g4simulation/g4intt/PHG4InttHitReco.cc @@ -1,12 +1,16 @@ #include "PHG4InttHitReco.h" + #include #include // for PHG4CylinderGeom #include +#include +#include #include #include #include +#include #include #include // for TrkrHit #include @@ -15,7 +19,6 @@ #include #include #include // for TrkrHit -#include #include // for PHParameterInterface @@ -45,6 +48,9 @@ #include // for pair, swap, make_... #include // for vector + +// update to make sure to clusterize clusters in loopers + PHG4InttHitReco::PHG4InttHitReco(const std::string &name) : SubsysReco(name) , PHParameterInterface(name) @@ -52,6 +58,7 @@ PHG4InttHitReco::PHG4InttHitReco(const std::string &name) , m_Tmin(NAN) , m_Tmax(NAN) , m_crossingPeriod(NAN) + , m_truth_hits { new TrkrHitSetContainerv1 } { InitializeParameters(); @@ -68,7 +75,7 @@ PHG4InttHitReco::~PHG4InttHitReco() gsl_vector_free(m_LocalOutVec); gsl_vector_free(m_PathVec); gsl_vector_free(m_SegmentVec); - delete m_truth_clusterer; + delete m_truth_hits; } int PHG4InttHitReco::InitRun(PHCompositeNode *topNode) @@ -117,19 +124,19 @@ int PHG4InttHitReco::InitRun(PHCompositeNode *topNode) exit(1); } - auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_INTT"); if (!hitsetcontainer) { PHNodeIterator dstiter(dstNode); - PHCompositeNode *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + PHCompositeNode *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "INTT")); if (!DetNode) { - DetNode = new PHCompositeNode("TRKR"); + DetNode = new PHCompositeNode("INTT"); dstNode->addNode(DetNode); } hitsetcontainer = new TrkrHitSetContainerv1; - PHIODataNode *newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + PHIODataNode *newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET_INTT", "PHObject"); DetNode->addNode(newNode); } @@ -176,40 +183,30 @@ int PHG4InttHitReco::InitRun(PHCompositeNode *topNode) m_Tmax = get_double_param("tmax"); m_crossingPeriod = get_double_param("beam_crossing_period"); - // + // get the nodes for the truth clustering m_truthtracks = findNode::getClass(topNode, "TRKR_TRUTHTRACKCONTAINER"); if (!m_truthtracks) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); - if (!DetNode) - { - DetNode = new PHCompositeNode("TRKR"); - dstNode->addNode(DetNode); - } - m_truthtracks = new TrkrTruthTrackContainerv1(); auto newNode = new PHIODataNode(m_truthtracks, "TRKR_TRUTHTRACKCONTAINER", "PHObject"); - DetNode->addNode(newNode); + dstNode->addNode(newNode); } + m_truthclusters = findNode::getClass(topNode, "TRKR_TRUTHCLUSTERCONTAINER"); if (!m_truthclusters) { - PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); - if (!DetNode) - { - DetNode = new PHCompositeNode("TRKR"); - dstNode->addNode(DetNode); - } - m_truthclusters = new TrkrClusterContainerv4; auto newNode = new PHIODataNode(m_truthclusters, "TRKR_TRUTHCLUSTERCONTAINER", "PHObject"); - DetNode->addNode(newNode); + dstNode->addNode(newNode); } - m_truth_clusterer = new TruthInttClusterBuilder(m_truthclusters, - m_truthtracks, Verbosity() ); + m_truthinfo = findNode::getClass(topNode, "G4TruthInfo"); + if (!m_truthinfo) + { + std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl; + assert(m_truthinfo); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -224,10 +221,10 @@ int PHG4InttHitReco::process_event(PHCompositeNode *topNode) } // Get the TrkrHitSetContainer node - auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_INTT"); if (!hitsetcontainer) { - std::cout << "Could not locate TRKR_HITSET node, quit! " << std::endl; + std::cout << "Could not locate TRKR_HITSET_INTT node, quit! " << std::endl; exit(1); } @@ -251,24 +248,11 @@ int PHG4InttHitReco::process_event(PHCompositeNode *topNode) PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits(); - // get nodes for the truth_clusterer - PHG4TruthInfoContainer *truthinfo = - findNode::getClass(topNode, "G4TruthInfo"); - m_truth_clusterer->set_truthinfo(truthinfo); - - // get the geometry node - PHG4CylinderGeomContainer* geom_container = findNode::getClass(topNode, "CYLINDERGEOM_INTT"); - if (!geom_container) { - std::cout << PHWHERE << "Failed to get geom_container in TruthInttClusterBuilder.cc" << std::endl; - } - m_truth_clusterer->set_geom_container(geom_container); - for (PHG4HitContainer::ConstIterator hiter = hit_begin_end.first; hiter != hit_begin_end.second; ++hiter) { const int sphxlayer = hiter->second->get_detid(); CylinderGeomIntt *layergeom = dynamic_cast(geo->GetLayerGeom(sphxlayer)); - m_truth_clusterer->check_g4hit(hiter->second); // checking ADC timing integration window cut // uses default values for now @@ -276,6 +260,8 @@ int PHG4InttHitReco::process_event(PHCompositeNode *topNode) if (hiter->second->get_t(0) > m_Tmax) continue; if (hiter->second->get_t(1) < m_Tmin) continue; + truthcheck_g4hit(hiter->second, topNode); + float time = (hiter->second->get_t(0) + hiter->second->get_t(1)) / 2.0; // I made this (small) diffusion up for now, we will get actual values for the Intt later @@ -488,7 +474,7 @@ int PHG4InttHitReco::process_event(PHCompositeNode *topNode) double hit_energy = venergy[i1].first * TrkrDefs::InttEnergyScaleup; hit->addEnergy(hit_energy); - m_truth_clusterer->addhitset(hitsetkey, hitkey, hit_energy); + addtruthhitset(hitsetkey, hitkey, hit_energy); // Add this hit to the association map hittruthassoc->addAssoc(hitsetkey, hitkey, hiter->first); @@ -499,7 +485,6 @@ int PHG4InttHitReco::process_event(PHCompositeNode *topNode) } } } // end loop over g4hits - m_truth_clusterer->reset(); // print the list of entries in the association table if (Verbosity() > 0) @@ -508,8 +493,15 @@ int PHG4InttHitReco::process_event(PHCompositeNode *topNode) hitsetcontainer->identify(); hittruthassoc->identify(); } + + if (m_is_emb) { + cluster_truthhits(topNode); // the last track was truth -- make it's clusters + prior_g4hit = nullptr; + } + + end_event_truthcluster( topNode ); return Fun4AllReturnCodes::EVENT_OK; -} +} // end process_event void PHG4InttHitReco::SetDefaultParameters() { @@ -522,3 +514,320 @@ void PHG4InttHitReco::SetDefaultParameters() return; } + +void PHG4InttHitReco::truthcheck_g4hit(PHG4Hit* g4hit, PHCompositeNode* topNode) { + if (g4hit==nullptr) return; + int new_trkid = g4hit->get_trkid(); + + bool is_new_track = (new_trkid != m_trkid); + if (Verbosity()>5) std::cout << PHWHERE << std::endl << " -> Checking status of PHG4Hit. Track id("<get_x(0)-g4hit->get_x(0)) > max_g4hitstep + || std::abs(prior_g4hit->get_y(0)-g4hit->get_y(0)) > max_g4hitstep + ) + ) + { + // this is a looper track -- cluster hits up to this point already + cluster_truthhits(topNode); + } + prior_g4hit = g4hit; + } + return; + } + // <- STATUS: this is a new track + if (Verbosity()>2) std::cout << PHWHERE << std::endl << " -> Found new embedded track with id: " << new_trkid << std::endl; + if (m_is_emb) { + //cluster the old track + cluster_truthhits(topNode); // cluster m_truth_hits and add m_current_track + m_current_track = nullptr; + prior_g4hit = nullptr; + } + m_trkid = new_trkid; + m_is_emb = m_truthinfo->isEmbeded(m_trkid); + if (m_is_emb) { + m_current_track = m_truthtracks->getTruthTrack(m_trkid, m_truthinfo); + prior_g4hit = g4hit; + } +} + +void PHG4InttHitReco::end_event_truthcluster ( PHCompositeNode* topNode ) { + if (m_is_emb) { + cluster_truthhits(topNode); // cluster m_truth_hits and add m_current_track + m_current_track = nullptr; + m_trkid = -1; + m_is_emb = false; + } + m_hitsetkey_cnt.clear(); +} + +void PHG4InttHitReco::addtruthhitset( + TrkrDefs::hitsetkey hitsetkey, + TrkrDefs::hitkey hitkey, + float neffelectrons) +{ + if (!m_is_emb) return; + TrkrHitSetContainer::Iterator hitsetit = m_truth_hits->findOrAddHitSet(hitsetkey); + // See if this hit already exists + TrkrHit *hit = nullptr; + hit = hitsetit->second->getHit(hitkey); + if (!hit) + { + // create a new one + hit = new TrkrHitv2(); + hitsetit->second->addHitSpecificKey(hitkey, hit); + } + // Either way, add the energy to it -- adc values will be added at digitization + hit->addEnergy(neffelectrons); +} + +void PHG4InttHitReco::cluster_truthhits(PHCompositeNode* topNode) { + // ----------------------------------------------- + // Digitize, adapted from g4intt/PHG4InttDigitizer + // ----------------------------------------------- + // + // Note: not using digitization, because as currently implemented, the SvtxTrack clusters + // don't use the adc weighting from the digitization code anyway. + // + // don't use the dead map for truth tracks + /* TrkrHitSetContainer::ConstRange hitset_range = m_truth_hits->getHitSets(TrkrDefs::TrkrId::inttId); */ + /* for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range.first; */ + /* hitset_iter != hitset_range.second; */ + /* ++hitset_iter) */ + /* { */ + /* // we have an itrator to one TrkrHitSet for the intt from the trkrHitSetContainer */ + /* // get the hitset key so we can find the layer */ + /* TrkrDefs::hitsetkey hitsetkey = hitset_iter->first; */ + /* const int layer = TrkrDefs::getLayer(hitsetkey); */ + /* const int ladder_phi = InttDefs::getLadderPhiId(hitsetkey); */ + /* const int ladder_z = InttDefs::getLadderZId(hitsetkey); */ + + /* if (Verbosity() > 1) */ + /* { */ + /* std::cout << "PHG4InttDigitizer: found hitset with key: " << hitsetkey << " in layer " << layer << std::endl; */ + /* } */ + /* // get all of the hits from this hitset */ + /* TrkrHitSet *hitset = hitset_iter->second; */ + /* TrkrHitSet::ConstRange hit_range = hitset->getHits(); */ + /* /1* std::set dead_hits; // hits on dead channel *1/ // no dead channels implemented */ + /* for (TrkrHitSet::ConstIterator hit_iter = hit_range.first; */ + /* hit_iter != hit_range.second; */ + /* ++hit_iter) */ + /* { */ + /* // ++m_nCells; // not really used by PHG4InttDigitizer */ + + /* TrkrHit *hit = hit_iter->second; */ + /* TrkrDefs::hitkey hitkey = hit_iter->first; */ + /* int strip_col = InttDefs::getCol(hitkey); // strip z index */ + /* int strip_row = InttDefs::getRow(hitkey); // strip phi index */ + + /* // FIXME need energy scales here */ + /* if (_energy_scale.count(layer) > 1) */ + /* { */ + /* assert(!"Error: _energy_scale has two or more keys."); */ + /* } */ + /* const float mip_e = _energy_scale[layer]; */ + + /* std::vector > vadcrange = _max_fphx_adc[layer]; */ + + /* int adc = 0; */ + /* for (unsigned int irange = 0; irange < vadcrange.size(); ++irange) */ + /* { */ + /* if (hit->getEnergy() / TrkrDefs::InttEnergyScaleup >= vadcrange[irange].first * */ + /* (double) mip_e && hit->getEnergy() / TrkrDefs::InttEnergyScaleup */ + /* < vadcrange[irange].second * (double) mip_e) */ + /* { */ + /* adc = (unsigned short) irange; */ + /* } */ + /* } */ + /* hit->setAdc(adc); */ + + /* if (Verbosity() > 2) */ + /* { */ + /* std::cout << "PHG4InttDigitizer: found hit with layer " << layer << " ladder_z " << ladder_z << " ladder_phi " << ladder_phi */ + /* << " strip_col " << strip_col << " strip_row " << strip_row << " adc " << hit->getAdc() << std::endl; */ + /* } */ + /* } // end loop over hits in this hitset */ + + /* // remove hits on dead channel in TRKR_HITSET and TRKR_HITTRUTHASSOC */ + /* for (const auto &key : dead_hits) */ + /* { */ + /* if (Verbosity() > 2) */ + /* { */ + /* std::cout << " PHG4InttDigitizer: remove hit with key: " << key << std::endl; */ + /* } */ + /* hitset->removeHit(key); */ + /* } */ + /* } // end loop over hitsets */ + + // ----------------------------------------------- + // Cluster, adapted from intt/InttClusterizer + // ----------------------------------------------- + if (Verbosity() > 1) std::cout << "Clustering truth clusters" << std::endl; + + //----------- + // Clustering + //----------- + // get the geometry node + PHG4CylinderGeomContainer* geom_container = findNode::getClass(topNode, "CYLINDERGEOM_INTT"); + if (!geom_container) return; + + + // loop over the InttHitSet objects + TrkrHitSetContainer::ConstRange hitsetrange = + m_truth_hits->getHitSets(TrkrDefs::TrkrId::inttId); // from TruthClusterizerBase + + for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; + hitsetitr != hitsetrange.second; ++hitsetitr) + { + // Each hitset contains only hits that are clusterizable - i.e. belong to a single sensor + TrkrHitSet* hitset = hitsetitr->second; + TrkrDefs::hitsetkey hitsetkey = hitset->getHitSetKey(); + + // cluster this hitset; all pixels in it are, by definition, part of the same clusters + + if ( Verbosity() > 1 ) std::cout << "InttClusterizer found hitsetkey " << hitsetitr->first << std::endl; + if ( Verbosity() > 2 ) hitset->identify(); + + // we have a single hitset, get the info that identifies the sensor + + if (Verbosity() > 2) + std::cout << "Filling cluster with hitsetkey " << ((int)hitsetkey) << std::endl; + + // get the bunch crossing number from the hitsetkey + /* short int crossing = InttDefs::getTimeBucketId(hitset->getHitSetKey()); */ + + // determine the size of the cluster in phi and z, useful for track fitting the cluster + std::set phibins; + std::set zbins; + + // determine the cluster position... + double xlocalsum = 0.0; + double ylocalsum = 0.0; + double zlocalsum = 0.0; + unsigned int clus_energy = 0.0; + unsigned nhits = 0; + + // aggregate the adc values + double sum_energy {0}; + TrkrHitSet::ConstRange hitrangei = hitset->getHits(); + for ( auto ihit = hitrangei.first; ihit != hitrangei.second; ++ihit) { + sum_energy += ihit->second->getEnergy(); + } + + // tune this energy threshold in the same maner of the MVTX, namely to get the same kind of pixel sizes + // as the SvtxTrack clusters + /* const double threshold = sum_energy * m_truth_pixelthreshold; */ + const double threshold = sum_energy * m_pixel_thresholdrat; //FIXME -- tune this as needed + + int layer = TrkrDefs::getLayer ( hitsetkey ); + CylinderGeomIntt* geom = dynamic_cast(geom_container->GetLayerGeom(layer)); + + int ladder_z_index = InttDefs::getLadderZId ( hitsetkey ); + + for ( auto ihit = hitrangei.first; ihit != hitrangei.second; ++ihit) + { + if (ihit->second->getEnergy() < threshold) continue; + + clus_energy += ihit->second->getEnergy(); + + int col = InttDefs::getCol ( ihit->first ); + int row = InttDefs::getRow ( ihit->first ); + + zbins .insert(col); + phibins .insert(row); + + // now get the positions from the geometry + double local_hit_location[3] = {0., 0., 0.}; + + geom->find_strip_center_localcoords(ladder_z_index, row, col, local_hit_location); + + xlocalsum += local_hit_location[0]; + ylocalsum += local_hit_location[1]; + zlocalsum += local_hit_location[2]; + + ++nhits; + + if (Verbosity() > 6) + { + std::cout << " From geometry object: hit x " << local_hit_location[0] + << " hit y " << local_hit_location[1] << " hit z " << local_hit_location[2] << std::endl; + std::cout << " nhits " << nhits << " clusx = " << xlocalsum / nhits << " clusy " + << ylocalsum / nhits << " clusz " << zlocalsum / nhits << std::endl; + } + // NOTE: + /* if (_make_e_weights[layer]) */ // these values are all false by default + /* if ( false ) // the current implementation of the code does not weight by adc values */ + /* // therefore the default here is to use use adc to cut the outliers and nothing else */ + /* { */ + /* xlocalsum += local_hit_location[0] * (double) hit_adc; */ + /* ylocalsum += local_hit_location[1] * (double) hit_adc; */ + /* zlocalsum += local_hit_location[2] * (double) hit_adc; */ + /* } */ + /* else */ + /* { */ + /* } */ + /* if(hit_adc > clus_maxadc) clus_maxadc = hit_adc; */ //FIXME: do we want this value to be set? + /* clus_energy += hit_adc; */ + } + + // add this cluster-hit association to the association map of (clusterkey,hitkey) + if (Verbosity() > 2) std::cout << " nhits = " << nhits << std::endl; + + /* static const float invsqrt12 = 1./sqrt(12); */ + // scale factors (phi direction) + /* + they corresponds to clusters of size 1 and 2 in phi + other clusters, which are very few and pathological, get a scale factor of 1 + These scale factors are applied to produce cluster pulls with width unity + */ + + /* float phierror = pitch * invsqrt12; */ + + /* static constexpr std::array scalefactors_phi = {{ 0.85, 0.4, 0.33 }}; */ + /* if( phibins.size() == 1 && layer < 5) phierror*=scalefactors_phi[0]; */ + /* else if( phibins.size() == 2 && layer < 5) phierror*=scalefactors_phi[1]; */ + /* else if( phibins.size() == 2 && layer > 4) phierror*=scalefactors_phi[2]; */ + /* // z error. All clusters have a z-size of 1. */ + /* const float zerror = length * invsqrt12; */ + if (nhits == 0) continue; + + double cluslocaly = ylocalsum / nhits; + double cluslocalz = ylocalsum / nhits; + + //if (_make_e_weights[layer]) // FIXME: this is always false for now + /* { */ + /* cluslocaly = ylocalsum / (double) clus_adc; */ + /* cluslocalz = zlocalsum / (double) clus_adc; */ + /* } */ + /* else */ + /* { */ + /* } */ + if ( m_cluster_version==4 ){ + auto clus = std::make_unique(); + clus->setAdc(clus_energy); + clus->setPhiSize(phibins.size()); + clus->setZSize(1); + + if(Verbosity() > 10) clus->identify(); + + clus->setLocalX(cluslocaly); + clus->setLocalY(cluslocalz); + // silicon has a 1-1 map between hitsetkey and surfaces. So set to 0 + clus->setSubSurfKey(0); + + m_hitsetkey_cnt.try_emplace(hitsetkey,0); + unsigned int& cnt = m_hitsetkey_cnt[hitsetkey]; + TrkrDefs::cluskey ckey = TrkrDefs::genClusKey(hitsetkey, cnt); + m_truthclusters->addClusterSpecifyKey(ckey, clus.release()); + m_current_track->addCluster(ckey); + ++cnt; + } // end loop over hitsets + } + + m_truth_hits->Reset(); + prior_g4hit = nullptr; + return; +} diff --git a/simulation/g4simulation/g4intt/PHG4InttHitReco.h b/simulation/g4simulation/g4intt/PHG4InttHitReco.h index b49824c41a..e1a9a884e1 100644 --- a/simulation/g4simulation/g4intt/PHG4InttHitReco.h +++ b/simulation/g4simulation/g4intt/PHG4InttHitReco.h @@ -3,22 +3,25 @@ #ifndef G4INTT_PHG4INTTHITRECO_H #define G4INTT_PHG4INTTHITRECO_H -#include "TruthInttClusterBuilder.h" - -#include #include - #include // for gsl_vector +#include +#include #include +#include #include class PHCompositeNode; -class TrkrTruthTrackContainer; +class PHG4Hit; +class PHG4TruthInfoContainer; class TrkrClusterContainer; - +class TrkrClusterContainer; +class TrkrHitSetContainer; +class TrkrTruthTrack; +class TrkrTruthTrackContainer; class PHG4InttHitReco : public SubsysReco, public PHParameterInterface { @@ -43,18 +46,38 @@ class PHG4InttHitReco : public SubsysReco, public PHParameterInterface std::string m_CellNodeName; std::string m_GeoNodeName; - TrkrTruthTrackContainer* m_truthtracks { nullptr }; - TrkrClusterContainer* m_truthclusters { nullptr }; - double m_Tmin; double m_Tmax; double m_crossingPeriod; - TruthInttClusterBuilder* m_truth_clusterer { nullptr }; - gsl_vector *m_LocalOutVec = nullptr; gsl_vector *m_PathVec = nullptr; gsl_vector *m_SegmentVec = nullptr; + + // needed for clustering truth tracks + private: + TrkrTruthTrackContainer* m_truthtracks { nullptr }; // output truth tracks + TrkrClusterContainer* m_truthclusters { nullptr }; // output clusters indexed to TrkrDefs::cluskeys in m_truthtracks + PHG4TruthInfoContainer* m_truthinfo { nullptr }; + int m_trkid { -1 }; + bool m_is_emb { false }; + TrkrTruthTrack* m_current_track { nullptr }; + const int m_cluster_version { 4 }; + TrkrHitSetContainer* m_truth_hits; // generate and delete a container for each truth track + std::map m_hitsetkey_cnt {}; // counter for making ckeys form hitsetkeys + + PHG4Hit* prior_g4hit { nullptr }; // used to check for jumps in g4hits for loopers; + void truthcheck_g4hit ( PHG4Hit*, PHCompositeNode* topNode ); + void addtruthhitset ( TrkrDefs::hitsetkey, TrkrDefs::hitkey, float neffelectrons ); + void cluster_truthhits ( PHCompositeNode* topNode ); + void end_event_truthcluster ( PHCompositeNode* topNode ); + + double m_pixel_thresholdrat { 0.01 }; + float max_g4hitstep { 2.0 }; + public: + void set_pixel_thresholdrat (double val) { m_pixel_thresholdrat = val; }; + void set_max_g4hitstep (float _) { max_g4hitstep =_; }; + }; #endif diff --git a/simulation/g4simulation/g4jets/ClusterJetInput.cc b/simulation/g4simulation/g4jets/ClusterJetInput.cc index 59e2508700..d8025bb46c 100644 --- a/simulation/g4simulation/g4jets/ClusterJetInput.cc +++ b/simulation/g4simulation/g4jets/ClusterJetInput.cc @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include // for Hep3Vector diff --git a/simulation/g4simulation/g4jets/Makefile.am b/simulation/g4simulation/g4jets/Makefile.am index 4001f7d99d..fdf0134ed3 100644 --- a/simulation/g4simulation/g4jets/Makefile.am +++ b/simulation/g4simulation/g4jets/Makefile.am @@ -29,7 +29,7 @@ libg4jets_la_LIBADD = \ -lfun4all \ -lphg4hit \ -lcalo_io \ - -lg4vertex_io \ + -lglobalvertex_io \ -lRecursiveTools \ -lphhepmc_io \ -ltrackbase_historic_io diff --git a/simulation/g4simulation/g4jets/TowerJetInput.cc b/simulation/g4simulation/g4jets/TowerJetInput.cc index 88c6c714b8..06b37b7db7 100644 --- a/simulation/g4simulation/g4jets/TowerJetInput.cc +++ b/simulation/g4simulation/g4jets/TowerJetInput.cc @@ -6,18 +6,15 @@ #include #include - #include #include - - #include // for encode_towerid #include #include -#include -#include +#include +#include #include diff --git a/simulation/g4simulation/g4main/Makefile.am b/simulation/g4simulation/g4main/Makefile.am index 2d0d45ecc9..98c37a5f23 100644 --- a/simulation/g4simulation/g4main/Makefile.am +++ b/simulation/g4simulation/g4main/Makefile.am @@ -37,7 +37,6 @@ libg4testbench_la_LDFLAGS = \ libg4testbench_la_LIBADD = \ libphg4hit.la \ -lboost_filesystem \ - -leASTPhysicsList \ -leicsmear \ -lffamodules \ -lfun4all \ diff --git a/simulation/g4simulation/g4main/PHG4Reco.cc b/simulation/g4simulation/g4main/PHG4Reco.cc index 1d9b15758d..c98e354f27 100644 --- a/simulation/g4simulation/g4main/PHG4Reco.cc +++ b/simulation/g4simulation/g4main/PHG4Reco.cc @@ -16,8 +16,6 @@ #include "PHG4UIsession.h" #include "PHG4Utils.h" -#include - #include #include @@ -31,7 +29,7 @@ #include #include -#include +#include #include #include @@ -50,8 +48,8 @@ #include +#include // for G4HadronicParameters #include -#include #include // for G4Element #include // for G4EventManager #include @@ -75,6 +73,7 @@ #include #include #include +#include #include #include // for G4String #include @@ -86,7 +85,6 @@ #include #include #include // for G4VisManager -#include // for G4HadronicParameters // physics lists #include @@ -125,15 +123,11 @@ PHG4Reco::PHG4Reco(const std::string &name) : SubsysReco(name) , m_Fun4AllMessenger(new Fun4AllMessenger(Fun4AllServer::instance())) { - for (int i = 0; i < 3; i++) - { - m_WorldSize[i] = 1000.; - } return; } //_________________________________________________________________ -PHG4Reco::~PHG4Reco(void) +PHG4Reco::~PHG4Reco() { // one can delete null pointer (it results in a nop), so checking if // they are non zero is not needed @@ -161,11 +155,14 @@ int PHG4Reco::Init(PHCompositeNode *topNode) G4Seed(iseed); // fixed seed handled in PHRandomSeed() // create GEANT run manager - if (Verbosity() > 1) std::cout << "PHG4Reco::Init - create run manager" << std::endl; + if (Verbosity() > 1) + { + std::cout << "PHG4Reco::Init - create run manager" << std::endl; + } // redirect GEANT verbosity to nowhere // if (Verbosity() < 1) - if (0) + if (false) { G4UImanager *uimanager = G4UImanager::GetUIpointer(); m_UISession = new PHG4UIsession(); @@ -223,10 +220,6 @@ int PHG4Reco::Init(PHCompositeNode *topNode) setenv("AllowForHeavyElements", "1", 1); myphysicslist = new QGSP_INCLXX_HP(Verbosity()); } - else if (m_PhysicsList == "EAST") - { - myphysicslist = new eASTPhysicsList(Verbosity()); - } else { std::cout << "Physics List " << m_PhysicsList << " not implemented" << std::endl; @@ -237,7 +230,7 @@ int PHG4Reco::Init(PHCompositeNode *topNode) if (m_Decayer == kPYTHIA6Decayer) { std::cout << "Use PYTHIA Decayer" << std::endl; - G4HadronicParameters::Instance()->SetEnableBCParticles(false); //Disable the Geant4 built in HF Decay and use external decayers for them + G4HadronicParameters::Instance()->SetEnableBCParticles(false); // Disable the Geant4 built in HF Decay and use external decayers for them P6DExtDecayerPhysics *decayer = new P6DExtDecayerPhysics(); if (m_ActiveForceDecayFlag) { @@ -249,11 +242,14 @@ int PHG4Reco::Init(PHCompositeNode *topNode) if (m_Decayer == kEvtGenDecayer) { std::cout << "Use EvtGen Decayer" << std::endl; - G4HadronicParameters::Instance()->SetEnableBCParticles(false); //Disable the Geant4 built in HF Decay and use external decayers for them - EvtGenExtDecayerPhysics *decayer = new EvtGenExtDecayerPhysics(); - if(CustomizeDecay) decayer->CustomizeEvtGenDecay(EvtGenDecayFile); + G4HadronicParameters::Instance()->SetEnableBCParticles(false); // Disable the Geant4 built in HF Decay and use external decayers for them + EvtGenExtDecayerPhysics *decayer = new EvtGenExtDecayerPhysics(); + if (CustomizeDecay) + { + decayer->CustomizeEvtGenDecay(EvtGenDecayFile); + } - myphysicslist->RegisterPhysics(decayer); + myphysicslist->RegisterPhysics(decayer); } if (m_Decayer == kGEANTInternalDecayer) @@ -269,7 +265,7 @@ int PHG4Reco::Init(PHCompositeNode *topNode) DefineRegions(); // initialize registered subsystems - for (SubsysReco *reco: m_SubsystemList) + for (SubsysReco *reco : m_SubsystemList) { reco->Init(topNode); } @@ -283,14 +279,17 @@ int PHG4Reco::Init(PHCompositeNode *topNode) int PHG4Reco::InitField(PHCompositeNode *topNode) { - if (Verbosity() > 1) std::cout << "PHG4Reco::InitField - create magnetic field setup" << std::endl; + if (Verbosity() > 1) + { + std::cout << "PHG4Reco::InitField - create magnetic field setup" << std::endl; + } std::unique_ptr default_field_cfg(nullptr); if (m_FieldMapFile == "CDB") { // loading from database - std::string url = XploadInterface::instance()->getUrl("FIELDMAPBIG", m_FieldMapFile); + std::string url = CDBInterface::instance()->getUrl("FIELDMAPBIG", m_FieldMapFile); default_field_cfg.reset(new PHFieldConfigv1(m_FieldConfigType, url, m_MagneticFieldRescale)); } else if (m_FieldMapFile != "NONE") @@ -302,7 +301,10 @@ int PHG4Reco::InitField(PHCompositeNode *topNode) default_field_cfg.reset(new PHFieldConfigv2(0, 0, m_MagneticField * m_MagneticFieldRescale)); } - if (Verbosity() > 1) std::cout << "PHG4Reco::InitField - create magnetic field setup" << std::endl; + if (Verbosity() > 1) + { + std::cout << "PHG4Reco::InitField - create magnetic field setup" << std::endl; + } PHField *phfield = PHFieldUtility::GetFieldMapNode(default_field_cfg.get(), topNode, Verbosity() + 1); assert(phfield); @@ -336,9 +338,9 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) recoConsts *rc = recoConsts::instance(); rc->set_StringFlag("WorldMaterial", m_WorldMaterial); -// build world material - so in subsequent code we can call -// G4Material::GetMaterial(rc->get_StringFlag("WorldMaterial")) -// if the world material is not in the nist DB, we need to implement it here + // build world material - so in subsequent code we can call + // G4Material::GetMaterial(rc->get_StringFlag("WorldMaterial")) + // if the world material is not in the nist DB, we need to implement it here G4NistManager::Instance()->FindOrBuildMaterial(m_WorldMaterial); // G4NistManager::Instance()->FindOrBuildMaterial("G4_Galactic"); // G4NistManager::Instance()->FindOrBuildMaterial("G4_Be"); @@ -348,7 +350,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) rc->set_FloatFlag("WorldSizey", m_WorldSize[1]); rc->set_FloatFlag("WorldSizez", m_WorldSize[2]); - //setup the global field + // setup the global field const int field_ret = InitField(topNode); if (field_ret != Fun4AllReturnCodes::EVENT_OK) { @@ -357,7 +359,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) } // initialize registered subsystems - for (SubsysReco *reco: m_SubsystemList) + for (SubsysReco *reco : m_SubsystemList) { if (Verbosity() >= 1) { @@ -369,7 +371,10 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) // create phenix detector, add subsystems, and register to GEANT // create display settings before detector m_DisplayAction = new PHG4PhenixDisplayAction(Name()); - if (Verbosity() > 1) std::cout << "PHG4Reco::Init - create detector" << std::endl; + if (Verbosity() > 1) + { + std::cout << "PHG4Reco::Init - create detector" << std::endl; + } m_Detector = new PHG4PhenixDetector(this); m_Detector->Verbosity(Verbosity()); m_Detector->SetWorldSizeX(m_WorldSize[0] * cm); @@ -378,7 +383,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) m_Detector->SetWorldShape(m_WorldShape); m_Detector->SetWorldMaterial(m_WorldMaterial); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { if (g4sub->GetDetector()) { @@ -390,15 +395,15 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) if (m_disableUserActions) { std::cout << "PHG4Reco::InitRun - WARNING - event/track/stepping action disabled! " - << "This is aimed to reduce resource consumption for G4 running only. E.g. dose analysis. " - << "Meanwhile, it will disable all Geant4 based analysis. Toggle this feature on/off with PHG4Reco::setDisableUserActions()" << std::endl; + << "This is aimed to reduce resource consumption for G4 running only. E.g. dose analysis. " + << "Meanwhile, it will disable all Geant4 based analysis. Toggle this feature on/off with PHG4Reco::setDisableUserActions()" << std::endl; } setupInputEventNodeReader(topNode); // create main event action, add subsystemts and register to GEANT m_EventAction = new PHG4PhenixEventAction(); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { PHG4EventAction *evtact = g4sub->GetEventAction(); if (evtact) @@ -414,7 +419,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) // create main stepping action, add subsystems and register to GEANT m_StackingAction = new PHG4PhenixStackingAction(); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { PHG4StackingAction *action = g4sub->GetStackingAction(); if (action) @@ -434,7 +439,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) // create main stepping action, add subsystems and register to GEANT m_SteppingAction = new PHG4PhenixSteppingAction(); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { PHG4SteppingAction *action = g4sub->GetSteppingAction(); if (action) @@ -455,7 +460,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) // create main tracking action, add subsystems and register to GEANT m_TrackingAction = new PHG4PhenixTrackingAction(); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { m_TrackingAction->AddAction(g4sub->GetTrackingAction()); @@ -485,12 +490,12 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) std::cout << PHWHERE << "Could not initialize EmSaturation, Birks constants will fail" << std::endl; } #endif - + // add cerenkov and optical photon processes // std::cout << std::endl << "Ignore the next message - we implemented this correctly" << std::endl; G4Cerenkov *theCerenkovProcess = new G4Cerenkov("Cerenkov"); // std::cout << "End of bogus warning message" << std::endl << std::endl; - G4Scintillation* theScintillationProcess = new G4Scintillation("Scintillation"); + G4Scintillation *theScintillationProcess = new G4Scintillation("Scintillation"); /* if (Verbosity() > 0) @@ -533,7 +538,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) pmanager->SetProcessOrderingToLast(theScintillationProcess, idxAtRest); pmanager->SetProcessOrderingToLast(theScintillationProcess, idxPostStep); } - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { g4sub->AddProcesses(particle); } @@ -550,7 +555,7 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) // needs large amount of memory which kills central hijing events // store generated trajectories - //if( G4TrackingManager* trackingManager = G4EventManager::GetEventManager()->GetTrackingManager() ){ + // if( G4TrackingManager* trackingManager = G4EventManager::GetEventManager()->GetTrackingManager() ){ // trackingManager->SetStoreTrajectory( true ); //} @@ -582,13 +587,13 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) } // dump geometry to root file - if( m_ExportGeometry ) + if (m_ExportGeometry) { std::cout << "PHG4Reco::InitRun - writing geometry to " << m_ExportGeomFilename << std::endl; PHGeomUtility::ExportGeomtry(topNode, m_ExportGeomFilename); } - if (PHRandomSeed::Verbosity()>=2) + if (PHRandomSeed::Verbosity() >= 2) { // at high verbosity, to save the random number to file G4RunManager::GetRunManager()->SetRandomNumberStore(true); @@ -597,14 +602,14 @@ int PHG4Reco::InitRun(PHCompositeNode *topNode) } //________________________________________________________________ -//Dump TGeo File +// Dump TGeo File void PHG4Reco::Dump_GDML(const std::string &filename) { PHG4GDMLUtility ::Dump_GDML(filename, m_Detector->GetPhysicalVolume()); } //________________________________________________________________ -//Dump TGeo File using native Geant4 tools +// Dump TGeo File using native Geant4 tools void PHG4Reco::Dump_G4_GDML(const std::string &filename) { PHG4GDMLUtility::Dump_G4_GDML(filename, m_Detector->GetPhysicalVolume()); @@ -648,7 +653,7 @@ int PHG4Reco::InitUImanager() //_________________________________________________________________ int PHG4Reco::process_event(PHCompositeNode *topNode) { - if (PHRandomSeed::Verbosity()>=2) + if (PHRandomSeed::Verbosity() >= 2) { G4Random::showEngineStatus(); } @@ -657,10 +662,12 @@ int PHG4Reco::process_event(PHCompositeNode *topNode) PHG4InEvent *ineve = findNode::getClass(topNode, "PHG4INEVENT"); m_GeneratorAction->SetInEvent(ineve); - for (SubsysReco *reco: m_SubsystemList) + for (SubsysReco *reco : m_SubsystemList) { if (Verbosity() >= 2) + { std::cout << "PHG4Reco::process_event - " << reco->Name() << "->process_event" << std::endl; + } try { @@ -669,7 +676,7 @@ int PHG4Reco::process_event(PHCompositeNode *topNode) catch (const std::exception &e) { std::cout << PHWHERE << " caught exception thrown during process_event from " - << reco->Name() << std::endl; + << reco->Name() << std::endl; std::cout << "error: " << e.what() << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -679,15 +686,17 @@ int PHG4Reco::process_event(PHCompositeNode *topNode) if (Verbosity() >= 2) { std::cout << " PHG4Reco::process_event - " - << "run one event :" << std::endl; + << "run one event :" << std::endl; ineve->identify(); } m_RunManager->BeamOn(1); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { if (Verbosity() >= 2) + { std::cout << " PHG4Reco::process_event - " << g4sub->Name() << "->process_after_geant" << std::endl; + } try { g4sub->process_after_geant(topNode); @@ -695,7 +704,7 @@ int PHG4Reco::process_event(PHCompositeNode *topNode) catch (const std::exception &e) { std::cout << PHWHERE << " caught exception thrown during process_after_geant from " - << g4sub->Name() << std::endl; + << g4sub->Name() << std::endl; std::cout << "error: " << e.what() << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -705,7 +714,7 @@ int PHG4Reco::process_event(PHCompositeNode *topNode) int PHG4Reco::ResetEvent(PHCompositeNode *topNode) { - for (SubsysReco *reco: m_SubsystemList) + for (SubsysReco *reco : m_SubsystemList) { reco->ResetEvent(topNode); } @@ -714,7 +723,7 @@ int PHG4Reco::ResetEvent(PHCompositeNode *topNode) void PHG4Reco::Print(const std::string &what) const { - for (SubsysReco *reco: m_SubsystemList) + for (SubsysReco *reco : m_SubsystemList) { if (what.empty() || what == "ALL" || (reco->Name()).find(what) != std::string::npos) { @@ -758,7 +767,7 @@ void PHG4Reco::G4Seed(const unsigned int i) { CLHEP::HepRandom::setTheSeed(i); - if (PHRandomSeed::Verbosity()>=2) + if (PHRandomSeed::Verbosity() >= 2) { G4Random::showEngineStatus(); } @@ -769,10 +778,10 @@ void PHG4Reco::G4Seed(const unsigned int i) //____________________________________________________________________________ void PHG4Reco::DefineMaterials() { - G4String symbol,name; //a=mass of a mole; - G4double density; //z=mean number of protons; - G4double fractionmass,a; - G4int ncomponents, natoms,z; + G4String symbol, name; // a=mass of a mole; + G4double density; // z=mean number of protons; + G4double fractionmass, a; + G4int ncomponents, natoms, z; // this is for FTFP_BERT_HP where the neutron code barfs // if the z difference to the last known element (U) is too large // home made compounds @@ -918,7 +927,7 @@ void PHG4Reco::DefineMaterials() // E864 Pb-Scifi calorimeter // E864 Calorimeter is 99% Pb, 1% Antimony - //Nuclear Instruments and Methods in Physics Research A 406 (1998) 227 258 + // Nuclear Instruments and Methods in Physics Research A 406 (1998) 227 258 G4double density_e864 = (0.99 * 11.34 + 0.01 * 6.697) * g / cm3; G4Material *absorber_e864 = new G4Material("E864_Absorber", density_e864, 2); absorber_e864->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_Pb"), 0.99); @@ -933,14 +942,14 @@ void PHG4Reco::DefineMaterials() W_Epoxy->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_W"), fractionmass = 0.5); W_Epoxy->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_POLYSTYRENE"), fractionmass = 0.5); - //from http://www.physi.uni-heidelberg.de/~adler/TRD/TRDunterlagen/RadiatonLength/tgc2.htm - //Epoxy (for FR4 ) - //density = 1.2*g/cm3; + // from http://www.physi.uni-heidelberg.de/~adler/TRD/TRDunterlagen/RadiatonLength/tgc2.htm + // Epoxy (for FR4 ) + // density = 1.2*g/cm3; G4Material *Epoxy = new G4Material("Epoxy", 1.2 * g / cm3, ncomponents = 2); Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), natoms = 2); Epoxy->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 2); - //FR4 (Glass + Epoxy) + // FR4 (Glass + Epoxy) density = 1.86 * g / cm3; G4Material *FR4 = new G4Material("FR4", density, ncomponents = 2); FR4->AddMaterial(quartz, fractionmass = 0.528); @@ -978,7 +987,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 PMMA->AddElement(G4NistManager::Instance()->FindOrBuildElement("H"), 5.7 / (3.6 + 5.7 + 1.4)); PMMA->AddElement(G4NistManager::Instance()->FindOrBuildElement("O"), 1.4 / (3.6 + 5.7 + 1.4)); - //scintillator for HCal, use a new name in order to change the Birks' constant + // scintillator for HCal, use a new name in order to change the Birks' constant G4Material *Uniplast_scintillator = new G4Material("Uniplast_scintillator", 1.06 * g / cm3, ncomponents = 1); Uniplast_scintillator->AddMaterial(G4NistManager::Instance()->FindOrBuildMaterial("G4_POLYSTYRENE"), fractionmass = 1.); @@ -1004,10 +1013,10 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 CF4->AddElement(G4NistManager::Instance()->FindOrBuildElement("C"), natoms = 1); CF4->AddElement(G4NistManager::Instance()->FindOrBuildElement("F"), natoms = 4); - G4Element* elLu = new G4Element(name="Lutetium", symbol="Lu", z=71., a=174.97*g/mole); - G4Material *LSO = new G4Material("LSO", //its name - density = 7.4*g/cm3, //its density - ncomponents = 3); //number of components + G4Element *elLu = new G4Element(name = "Lutetium", symbol = "Lu", z = 71., a = 174.97 * g / mole); + G4Material *LSO = new G4Material("LSO", // its name + density = 7.4 * g / cm3, // its density + ncomponents = 3); // number of components LSO->AddElement(G4NistManager::Instance()->FindOrBuildElement("Si"), natoms = 1); LSO->AddElement(elLu, natoms = 2); @@ -1099,8 +1108,8 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 G4MaterialPropertiesTable *MPT_CF4 = new G4MaterialPropertiesTable(); #if G4VERSION_NUMBER >= 1100 - MPT_CF4->AddProperty("RINDEX", PhotonEnergy_CF4, RefractiveIndex_CF4, nEntries_CF4,false,true); - MPT_CF4->AddProperty("ABSLENGTH", PhotonEnergy_CF4, Absorption_CF4, nEntries_CF4,false,true); + MPT_CF4->AddProperty("RINDEX", PhotonEnergy_CF4, RefractiveIndex_CF4, nEntries_CF4, false, true); + MPT_CF4->AddProperty("ABSLENGTH", PhotonEnergy_CF4, Absorption_CF4, nEntries_CF4, false, true); #else MPT_CF4->AddProperty("RINDEX", PhotonEnergy_CF4, RefractiveIndex_CF4, nEntries_CF4)->SetSpline(true); MPT_CF4->AddProperty("ABSLENGTH", PhotonEnergy_CF4, Absorption_CF4, nEntries_CF4)->SetSpline(true); @@ -1162,8 +1171,8 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 G4MaterialPropertiesTable *MPT_LiF = new G4MaterialPropertiesTable(); #if G4VERSION_NUMBER >= 1100 - MPT_LiF->AddProperty("RINDEX", PhotonEnergy_LiF, RefractiveIndex_LiF, nEntries_LiF,false,true); - MPT_LiF->AddProperty("ABSLENGTH", PhotonEnergy_LiF, Absorption_LiF, nEntries_LiF,false,true); + MPT_LiF->AddProperty("RINDEX", PhotonEnergy_LiF, RefractiveIndex_LiF, nEntries_LiF, false, true); + MPT_LiF->AddProperty("ABSLENGTH", PhotonEnergy_LiF, Absorption_LiF, nEntries_LiF, false, true); #else MPT_LiF->AddProperty("RINDEX", PhotonEnergy_LiF, RefractiveIndex_LiF, nEntries_LiF)->SetSpline(true); MPT_LiF->AddProperty("ABSLENGTH", PhotonEnergy_LiF, Absorption_LiF, nEntries_LiF)->SetSpline(true); @@ -1214,8 +1223,8 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 G4MaterialPropertiesTable *MPT_CsI = new G4MaterialPropertiesTable(); #if G4VERSION_NUMBER >= 1100 - MPT_CsI->AddProperty("RINDEX", PhotonEnergy_CsI, RefractiveIndex_CsI, nEntries_CsI,false,true); - MPT_CsI->AddProperty("ABSLENGTH", PhotonEnergy_CsI, Absorption_CsI, nEntries_CsI,false,true); + MPT_CsI->AddProperty("RINDEX", PhotonEnergy_CsI, RefractiveIndex_CsI, nEntries_CsI, false, true); + MPT_CsI->AddProperty("ABSLENGTH", PhotonEnergy_CsI, Absorption_CsI, nEntries_CsI, false, true); #else MPT_CsI->AddProperty("RINDEX", PhotonEnergy_CsI, RefractiveIndex_CsI, nEntries_CsI)->SetSpline(true); MPT_CsI->AddProperty("ABSLENGTH", PhotonEnergy_CsI, Absorption_CsI, nEntries_CsI)->SetSpline(true); @@ -1251,7 +1260,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 // mRICH_Acrylic --------------- const int mRICH_nEntries1 = 32; - //same photon energy array as aerogel 1 + // same photon energy array as aerogel 1 G4double mRICH_PhotonEnergy[mRICH_nEntries1] = {2.034 * eV, 2.068 * eV, 2.103 * eV, 2.139 * eV, // 610, 600, 590, 580, (nm) 2.177 * eV, 2.216 * eV, 2.256 * eV, 2.298 * eV, // 570, 560, 550, 540, @@ -1303,7 +1312,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 1.02572, 1.0258, 1.02585, 1.0259, 1.02595, 1.026, 1.02608}; - G4double mRICH_Agel1Absorption[mRICH_nEntries1] = //from Hubert + G4double mRICH_Agel1Absorption[mRICH_nEntries1] = // from Hubert {3.448 * m, 4.082 * m, 6.329 * m, 9.174 * m, 12.346 * m, 13.889 * m, 15.152 * m, 17.241 * m, 18.868 * m, 20.000 * m, 26.316 * m, 35.714 * m, 45.455 * m, 47.619 * m, 52.632 * m, 52.632 * m, 55.556 * m, 52.632 * m, @@ -1312,7 +1321,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 17.500 * m, 14.500 * m}; G4double mRICH_Agel1Rayleigh[mRICH_nEntries1]; - //const G4double AerogelTypeAClarity = 0.00719*micrometer*micrometer*micrometer*micrometer/cm; + // const G4double AerogelTypeAClarity = 0.00719*micrometer*micrometer*micrometer*micrometer/cm; const G4double AerogelTypeAClarity = 0.0020 * micrometer * micrometer * micrometer * micrometer / cm; G4double Cparam = AerogelTypeAClarity * cm / (micrometer * micrometer * micrometer * micrometer); G4double PhotMomWaveConv = 1239 * eV * nm; @@ -1322,7 +1331,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 for (int i = 0; i < mRICH_nEntries1; i++) { G4double ephoton = mRICH_PhotonEnergy[i]; - //In the following the 1000 is to convert form nm to micrometer + // In the following the 1000 is to convert form nm to micrometer G4double wphoton = (PhotMomWaveConv / ephoton) / (1000.0 * nm); mRICH_Agel1Rayleigh[i] = (std::pow(wphoton, 4)) / Cparam; } @@ -1331,7 +1340,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 G4MaterialPropertiesTable *mRICH_Agel1_myMPT = new G4MaterialPropertiesTable(); mRICH_Agel1_myMPT->AddProperty("RINDEX", mRICH_PhotonEnergy, mRICH_Agel1RefractiveIndex, mRICH_nEntries1); mRICH_Agel1_myMPT->AddProperty("ABSLENGTH", mRICH_PhotonEnergy, mRICH_Agel1Absorption, mRICH_nEntries1); - mRICH_Agel1_myMPT->AddProperty("RAYLEIGH", mRICH_PhotonEnergy, mRICH_Agel1Rayleigh, mRICH_nEntries1); //Need table of rayleigh Scattering!!! + mRICH_Agel1_myMPT->AddProperty("RAYLEIGH", mRICH_PhotonEnergy, mRICH_Agel1Rayleigh, mRICH_nEntries1); // Need table of rayleigh Scattering!!! mRICH_Agel1_myMPT->AddConstProperty("SCINTILLATIONYIELD", 0. / MeV); mRICH_Agel1_myMPT->AddConstProperty("RESOLUTIONSCALE", 1.0); @@ -1367,7 +1376,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 1.03196, 1.03212, 1.03228, 1.03244, 1.03261, 1.03279, 1.03297, 1.03315, 1.03334, 1.03354}; - G4double mRICH_Agel2Absorption[mRICH_nEntries2] = //from Marco + G4double mRICH_Agel2Absorption[mRICH_nEntries2] = // from Marco {17.5000 * cm, 17.7466 * cm, 17.9720 * cm, 18.1789 * cm, 18.3694 * cm, 18.5455 * cm, 18.7086 * cm, 18.8602 * cm, 19.0015 * cm, 19.1334 * cm, 19.2569 * cm, 19.3728 * cm, 19.4817 * cm, 19.5843 * cm, 19.6810 * cm, @@ -1379,7 +1388,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 1.7296 * cm, 1.5696 * cm, 1.4266 * cm, 1.2986 * cm, 1.1837 * cm, 1.0806 * cm, 0.9877 * cm, 0.9041 * cm, 0.8286 * cm, 0.7603 * cm}; - G4double mRICH_Agel2Rayleigh[mRICH_nEntries2] = //from Marco + G4double mRICH_Agel2Rayleigh[mRICH_nEntries2] = // from Marco {35.1384 * cm, 29.24805 * cm, 24.5418 * cm, 20.7453 * cm, 17.6553 * cm, 15.1197 * cm, 13.02345 * cm, 11.2782 * cm, 9.81585 * cm, 8.58285 * cm, 7.53765 * cm, 6.6468 * cm, 5.88375 * cm, 5.22705 * cm, 4.6596 * cm, @@ -1404,7 +1413,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 mRICH_Aerogel2->SetMaterialPropertiesTable(mRICH_Agel2MPT); // mRICH_Borosilicate ---------- - //using the same photon energy array as mRICH_Acrylic + // using the same photon energy array as mRICH_Acrylic G4double mRICH_glassRefractiveIndex[mRICH_nEntries1] = {1.47, 1.47, 1.47, 1.47, 1.47, @@ -1426,7 +1435,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 00.001 * cm, 00.001 * cm, 00.001 * cm, 00.001 * cm}; G4MaterialPropertiesTable *mRICH_glass_myMPT = new G4MaterialPropertiesTable(); - //same photon energy array as aerogel 1 + // same photon energy array as aerogel 1 mRICH_glass_myMPT->AddProperty("RINDEX", mRICH_PhotonEnergy, mRICH_glassRefractiveIndex, mRICH_nEntries1); mRICH_glass_myMPT->AddProperty("ABSLENGTH", mRICH_PhotonEnergy, mRICH_glassAbsorption, mRICH_nEntries1); @@ -1435,7 +1444,7 @@ PMMA -3 12.01 1.008 15.99 6. 1. 8. 1.19 3.6 5.7 1.4 mRICH_Borosilicate->SetMaterialPropertiesTable(mRICH_glass_myMPT); // mRICH_Air ------------------ - //using same photon energy array as mRICH_Acrylic + // using same photon energy array as mRICH_Acrylic G4double mRICH_AirRefractiveIndex[mRICH_nEntries1] = {1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, @@ -1473,7 +1482,7 @@ void PHG4Reco::DefineRegions() PHG4Subsystem * PHG4Reco::getSubsystem(const std::string &name) { - for (PHG4Subsystem *subsys: m_SubsystemList) + for (PHG4Subsystem *subsys : m_SubsystemList) { if (subsys->Name() == name) { @@ -1504,7 +1513,7 @@ void PHG4Reco::ApplyDisplayAction() } G4VPhysicalVolume *physworld = m_Detector->GetPhysicalVolume(); m_DisplayAction->ApplyDisplayAction(physworld); - for (PHG4Subsystem *g4sub: m_SubsystemList) + for (PHG4Subsystem *g4sub : m_SubsystemList) { PHG4DisplayAction *action = g4sub->GetDisplayAction(); if (action) diff --git a/simulation/g4simulation/g4main/PHG4Reco.h b/simulation/g4simulation/g4main/PHG4Reco.h index f762e947bf..180ae3966e 100644 --- a/simulation/g4simulation/g4main/PHG4Reco.h +++ b/simulation/g4simulation/g4main/PHG4Reco.h @@ -46,7 +46,7 @@ class PHG4Reco : public SubsysReco }; // Decayer Option for User to Choose: 0 - GEANT 4 Internal Decayer (with momentum conservation issues), 1, PYTHIA 6 Decayer, 2 - EvtGen Decayer //! constructor - PHG4Reco(const std::string &name = "PHG4RECO"); + explicit PHG4Reco(const std::string &name = "PHG4RECO"); //! destructor ~PHG4Reco() override; @@ -103,15 +103,15 @@ class PHG4Reco : public SubsysReco m_ForceDecayType = force_decay_type; } - void set_decayer(DecayerOptions type) {m_Decayer = type;} + void set_decayer(DecayerOptions type) { m_Decayer = type; } //! export geometry to root file - void export_geometry( bool b, const std::string& filename = "sPHENIXGeom.root" ) + void export_geometry(bool b, const std::string &filename = "sPHENIXGeom.root") { m_ExportGeometry = b; m_ExportGeomFilename = filename; } - + //! Save geometry from Geant4 to DST void save_DST_geometry(bool b) { m_SaveDstGeometryFlag = b; } void SetWorldSizeX(const double sx) { m_WorldSize[0] = sx; } @@ -140,10 +140,10 @@ class PHG4Reco : public SubsysReco void setDisableUserActions(bool b = true) { m_disableUserActions = b; } void ApplyDisplayAction(); - void CustomizeEvtGenDecay(std::string& DecayFile) + void CustomizeEvtGenDecay(const std::string &DecayFile) { - EvtGenDecayFile = DecayFile; - if(!EvtGenDecayFile.empty()) CustomizeDecay = true; + EvtGenDecayFile = DecayFile; + if (!EvtGenDecayFile.empty()) CustomizeDecay = true; } private: @@ -154,7 +154,7 @@ class PHG4Reco : public SubsysReco float m_MagneticField = 0.; float m_MagneticFieldRescale = 1.0; - double m_WorldSize[3]; + double m_WorldSize[3]{1000., 1000., 1000.}; //! magnetic field G4TBMagneticFieldSetup *m_Field = nullptr; @@ -207,14 +207,13 @@ class PHG4Reco : public SubsysReco bool m_ExportGeometry = false; std::string m_ExportGeomFilename = "sPHENIXGeom.root"; - + // settings for the external Pythia6 decayer - //bool m_ActiveDecayerFlag = true; //< turn on/off decayer + // bool m_ActiveDecayerFlag = true; //< turn on/off decayer bool m_ActiveForceDecayFlag = false; //< turn on/off force decay channels - DecayerOptions m_Decayer = kEvtGenDecayer; // Here we use EvtGen as default - std::string EvtGenDecayFile = ""; + std::string EvtGenDecayFile = ""; bool CustomizeDecay = false; EDecayType m_ForceDecayType = kAll; //< forced decay channel setting diff --git a/simulation/g4simulation/g4main/PHG4SteppingAction.h b/simulation/g4simulation/g4main/PHG4SteppingAction.h index d16ab02a0d..7911367f07 100644 --- a/simulation/g4simulation/g4main/PHG4SteppingAction.h +++ b/simulation/g4simulation/g4main/PHG4SteppingAction.h @@ -29,6 +29,7 @@ class PHG4SteppingAction virtual void Verbosity(const int i) { m_Verbosity = i; } virtual int Verbosity() const { return m_Verbosity; } virtual int Init() { return 0; } + virtual int InitWithNode(PHCompositeNode* ){ return 0; }; //! get scintillation photon count. It require a custom set SCINTILLATIONYIELD property to work virtual double GetScintLightYield(const G4Step* step); @@ -48,7 +49,7 @@ class PHG4SteppingAction virtual bool ValidCorrection() const; //! Set the G4HIT node names from Subsystem rather than constructing your own - virtual void SetHitNodeName(const std::string &, const std::string &) {return;} + virtual void SetHitNodeName(const std::string&, const std::string&) { return; } private: int m_Verbosity; diff --git a/simulation/g4simulation/g4main/PHG4TruthInfoContainer.cc b/simulation/g4simulation/g4main/PHG4TruthInfoContainer.cc index 8609f49474..64c840a806 100644 --- a/simulation/g4simulation/g4main/PHG4TruthInfoContainer.cc +++ b/simulation/g4simulation/g4main/PHG4TruthInfoContainer.cc @@ -23,21 +23,21 @@ PHG4TruthInfoContainer::~PHG4TruthInfoContainer() { Reset(); } void PHG4TruthInfoContainer::Reset() { - for (Iterator iter = particlemap.begin(); iter != particlemap.end(); ++iter) + for (auto& iter : particlemap) { - delete iter->second; + delete iter.second; } particlemap.clear(); - for (VtxIterator iter = vtxmap.begin(); iter != vtxmap.end(); ++iter) + for (auto& iter : vtxmap) { - delete iter->second; + delete iter.second; } vtxmap.clear(); - for (ShowerIterator iter = showermap.begin(); iter != showermap.end(); ++iter) + for (auto& iter : showermap) { - delete iter->second; + delete iter.second; } showermap.clear(); @@ -50,42 +50,38 @@ void PHG4TruthInfoContainer::Reset() void PHG4TruthInfoContainer::identify(ostream& os) const { os << "---particlemap--------------------------" << endl; - for (ConstIterator iter = particlemap.begin(); iter != particlemap.end(); ++iter) + for (auto iter : particlemap) { - os << "particle id " << iter->first << endl; - (iter->second)->identify(); + os << "particle id " << iter.first << endl; + (iter.second)->identify(); } os << "---vtxmap-------------------------------" << endl; - for (ConstVtxIterator vter = vtxmap.begin(); vter != vtxmap.end(); ++vter) + for (auto vter : vtxmap) { - os << "vtx id: " << vter->first << endl; - (vter->second)->identify(); + os << "vtx id: " << vter.first << endl; + (vter.second)->identify(); } os << "---showermap-------------------------------" << endl; - for (ConstShowerIterator ster = showermap.begin(); ster != showermap.end(); ++ster) + for (auto ster : showermap) { - os << "shower id: " << ster->first << endl; - (ster->second)->identify(); + os << "shower id: " << ster.first << endl; + (ster.second)->identify(); } os << "---list of embeded track flags-------------------" << endl; - for (std::map::const_iterator eter = particle_embed_flags.begin(); - eter != particle_embed_flags.end(); - ++eter) + for (auto particle_embed_flag : particle_embed_flags) { - os << "embeded track id: " << eter->first - << " flag: " << eter->second << endl; + os << "embeded track id: " << particle_embed_flag.first + << " flag: " << particle_embed_flag.second << endl; } os << "---list of embeded vtx flags-------------------" << endl; - for (std::map::const_iterator eter = vertex_embed_flags.begin(); - eter != vertex_embed_flags.end(); - ++eter) + for (auto vertex_embed_flag : vertex_embed_flags) { - os << "embeded vertex id: " << eter->first - << " flag: " << eter->second << endl; + os << "embeded vertex id: " << vertex_embed_flag.first + << " flag: " << vertex_embed_flag.second << endl; } os << "---primary vertex-------------------" << endl; @@ -101,7 +97,10 @@ PHG4TruthInfoContainer::AddParticle(const int trackid, PHG4Particle* newparticle ConstIterator it; bool added = false; boost::tie(it, added) = particlemap.insert(std::make_pair(key, newparticle)); - if (added) return it; + if (added) + { + return it; + } cerr << "PHG4TruthInfoContainer::AddParticle" << " - Attempt to add particle with existing trackid " @@ -119,15 +118,24 @@ PHG4Particle* PHG4TruthInfoContainer::GetParticle(const int trackid) { int key = trackid; Iterator it = particlemap.find(key); - if (it != particlemap.end()) return it->second; + if (it != particlemap.end()) + { + return it->second; + } return nullptr; } PHG4Particle* PHG4TruthInfoContainer::GetPrimaryParticle(const int trackid) { - if (trackid <= 0) return nullptr; + if (trackid <= 0) + { + return nullptr; + } Iterator it = particlemap.find(trackid); - if (it != particlemap.end()) return it->second; + if (it != particlemap.end()) + { + return it->second; + } return nullptr; } @@ -135,15 +143,24 @@ PHG4VtxPoint* PHG4TruthInfoContainer::GetVtx(const int vtxid) { int key = vtxid; VtxIterator it = vtxmap.find(key); - if (it != vtxmap.end()) return it->second; + if (it != vtxmap.end()) + { + return it->second; + } return nullptr; } PHG4VtxPoint* PHG4TruthInfoContainer::GetPrimaryVtx(const int vtxid) { - if (vtxid <= 0) return nullptr; + if (vtxid <= 0) + { + return nullptr; + } VtxIterator it = vtxmap.find(vtxid); - if (it != vtxmap.end()) return it->second; + if (it != vtxmap.end()) + { + return it->second; + } return nullptr; } @@ -151,15 +168,24 @@ PHG4Shower* PHG4TruthInfoContainer::GetShower(const int showerid) { int key = showerid; ShowerIterator it = showermap.find(key); - if (it != showermap.end()) return it->second; + if (it != showermap.end()) + { + return it->second; + } return nullptr; } PHG4Shower* PHG4TruthInfoContainer::GetPrimaryShower(const int showerid) { - if (showerid <= 0) return nullptr; + if (showerid <= 0) + { + return nullptr; + } ShowerIterator it = showermap.find(showerid); - if (it != showermap.end()) return it->second; + if (it != showermap.end()) + { + return it->second; + } return nullptr; } @@ -220,48 +246,84 @@ PHG4TruthInfoContainer::AddShower(const int id, PHG4Shower* newshower) int PHG4TruthInfoContainer::maxtrkindex() const { int key = 0; - if (!particlemap.empty()) key = particlemap.rbegin()->first; - if (key < 0) key = 0; + if (!particlemap.empty()) + { + key = particlemap.rbegin()->first; + } + if (key < 0) + { + key = 0; + } return key; } int PHG4TruthInfoContainer::mintrkindex() const { int key = 0; - if (!particlemap.empty()) key = particlemap.begin()->first; - if (key > 0) key = 0; + if (!particlemap.empty()) + { + key = particlemap.begin()->first; + } + if (key > 0) + { + key = 0; + } return key; } int PHG4TruthInfoContainer::maxvtxindex() const { int key = 0; - if (!vtxmap.empty()) key = vtxmap.rbegin()->first; - if (key < 0) key = 0; + if (!vtxmap.empty()) + { + key = vtxmap.rbegin()->first; + } + if (key < 0) + { + key = 0; + } return key; } int PHG4TruthInfoContainer::minvtxindex() const { int key = 0; - if (!vtxmap.empty()) key = vtxmap.begin()->first; - if (key > 0) key = 0; + if (!vtxmap.empty()) + { + key = vtxmap.begin()->first; + } + if (key > 0) + { + key = 0; + } return key; } int PHG4TruthInfoContainer::maxshowerindex() const { int key = 0; - if (!showermap.empty()) key = showermap.rbegin()->first; - if (key < 0) key = 0; + if (!showermap.empty()) + { + key = showermap.rbegin()->first; + } + if (key < 0) + { + key = 0; + } return key; } int PHG4TruthInfoContainer::minshowerindex() const { int key = 0; - if (!showermap.empty()) key = showermap.begin()->first; - if (key > 0) key = 0; + if (!showermap.empty()) + { + key = showermap.begin()->first; + } + if (key > 0) + { + key = 0; + } return key; } @@ -276,7 +338,9 @@ void PHG4TruthInfoContainer::delete_particle(int trackid) { Iterator it = particlemap.find(trackid); if (it != particlemap.end()) + { delete_particle(it); + } } void PHG4TruthInfoContainer::delete_vtx(VtxIterator viter) @@ -290,7 +354,9 @@ void PHG4TruthInfoContainer::delete_vtx(int vtxid) { VtxIterator it = vtxmap.find(vtxid); if (it != vtxmap.end()) + { delete_vtx(it); + } } void PHG4TruthInfoContainer::delete_shower(ShowerIterator siter) diff --git a/simulation/g4simulation/g4main/PHG4TruthInfoContainer.h b/simulation/g4simulation/g4main/PHG4TruthInfoContainer.h index ea067a884f..627586bd8b 100644 --- a/simulation/g4simulation/g4main/PHG4TruthInfoContainer.h +++ b/simulation/g4simulation/g4main/PHG4TruthInfoContainer.h @@ -38,7 +38,7 @@ class PHG4TruthInfoContainer : public PHObject PHG4TruthInfoContainer(); ~PHG4TruthInfoContainer() override; -// from PHObject + // from PHObject void Reset() override; void identify(std::ostream& os = std::cout) const override; @@ -232,7 +232,6 @@ class PHG4TruthInfoContainer : public PHObject ClassDefOverride(PHG4TruthInfoContainer, 1) }; - /** * Equality operators for the types used in the publicly accessible internal * containers of PHG4TruthInfoContainer. diff --git a/simulation/g4simulation/g4micromegas/PHG4MicromegasDigitizer.cc b/simulation/g4simulation/g4micromegas/PHG4MicromegasDigitizer.cc index 16477c0cf4..123f7a1198 100644 --- a/simulation/g4simulation/g4micromegas/PHG4MicromegasDigitizer.cc +++ b/simulation/g4simulation/g4micromegas/PHG4MicromegasDigitizer.cc @@ -91,7 +91,7 @@ int PHG4MicromegasDigitizer::process_event(PHCompositeNode *topNode) { // Get Nodes // Get the TrkrHitSetContainer node - auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); assert( trkrhitsetcontainer ); // Get the TrkrHitTruthAssoc node diff --git a/simulation/g4simulation/g4micromegas/PHG4MicromegasHitReco.cc b/simulation/g4simulation/g4micromegas/PHG4MicromegasHitReco.cc index e5bdd1ee2b..26b072f215 100644 --- a/simulation/g4simulation/g4micromegas/PHG4MicromegasHitReco.cc +++ b/simulation/g4simulation/g4micromegas/PHG4MicromegasHitReco.cc @@ -151,23 +151,24 @@ int PHG4MicromegasHitReco::InitRun(PHCompositeNode *topNode) } // create hitset container if needed - auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); if (!hitsetcontainer) { - std::cout << "PHG4MicromegasHitReco::InitRun - creating TRKR_HITSET." << std::endl; + if (Verbosity()) + std::cout << "PHG4MicromegasHitReco::InitRun - creating TRKR_HITSET_MICROMEGAS." << std::endl; // find or create TRKR node PHNodeIterator dstiter(dstNode); - auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "MICROMEGAS")); if (!trkrnode) { - trkrnode = new PHCompositeNode("TRKR"); + trkrnode = new PHCompositeNode("MICROMEGAS"); dstNode->addNode(trkrnode); } // create container and add to the tree hitsetcontainer = new TrkrHitSetContainerv1; - auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET_MICROMEGAS", "PHObject"); trkrnode->addNode(newNode); } @@ -212,7 +213,7 @@ int PHG4MicromegasHitReco::process_event(PHCompositeNode *topNode) assert(geonode); // Get the TrkrHitSetContainer node - auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MICROMEGAS"); assert(trkrhitsetcontainer); // Get the TrkrHitTruthAssoc node diff --git a/simulation/g4simulation/g4mvtx/Makefile.am b/simulation/g4simulation/g4mvtx/Makefile.am index 554e7315f2..bbaed214b8 100644 --- a/simulation/g4simulation/g4mvtx/Makefile.am +++ b/simulation/g4simulation/g4mvtx/Makefile.am @@ -23,6 +23,7 @@ libg4mvtx_la_LIBADD = \ -lg4detectors \ -ltrack_io \ -lg4tracking_io \ + -lmvtx \ -lmvtx_io pkginclude_HEADERS = \ @@ -30,8 +31,7 @@ pkginclude_HEADERS = \ PHG4MvtxHitReco.h \ PHG4MvtxSubsystem.h \ PHG4EICMvtxSubsystem.h \ - PHG4MvtxDigitizer.h \ - TruthMvtxClusterBuilder.h + PHG4MvtxDigitizer.h libg4mvtx_la_SOURCES = \ PHG4MvtxHitReco.cc \ @@ -45,8 +45,7 @@ libg4mvtx_la_SOURCES = \ PHG4MvtxDigitizer.cc \ PHG4MvtxCable.cc \ PHG4MvtxServiceStructure.cc \ - PHG4MvtxSupport.cc \ - TruthMvtxClusterBuilder.cc + PHG4MvtxSupport.cc ################################################ # linking tests diff --git a/simulation/g4simulation/g4mvtx/PHG4MvtxDigitizer.cc b/simulation/g4simulation/g4mvtx/PHG4MvtxDigitizer.cc index dba2d09e54..ad4d4a07e3 100644 --- a/simulation/g4simulation/g4mvtx/PHG4MvtxDigitizer.cc +++ b/simulation/g4simulation/g4mvtx/PHG4MvtxDigitizer.cc @@ -142,10 +142,10 @@ void PHG4MvtxDigitizer::DigitizeMvtxLadderCells(PHCompositeNode *topNode) // new containers //============= // Get the TrkrHitSetContainer node - TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MVTX"); if (!trkrhitsetcontainer) { - cout << "Could not locate TRKR_HITSET node, quit! " << endl; + cout << "Could not locate TRKR_HITSET_MVTX node, quit! " << endl; exit(1); } diff --git a/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.cc b/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.cc index 8444315010..e75d7be304 100644 --- a/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.cc +++ b/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.cc @@ -3,6 +3,7 @@ #include "PHG4MvtxHitReco.h" #include +#include #include #include @@ -14,10 +15,12 @@ #include #include // for TrkrHit -#include -#include +#include #include #include +#include +#include +#include #include // for PHG4CylinderGeom #include @@ -49,6 +52,7 @@ #include #include // for allocator_tra... #include // for vector +#include // for vector PHG4MvtxHitReco::PHG4MvtxHitReco(const std::string &name, const std::string &detector) : SubsysReco(name) @@ -58,6 +62,7 @@ PHG4MvtxHitReco::PHG4MvtxHitReco(const std::string &name, const std::string &det , m_tmax(5000.) , m_strobe_width(5.) , m_strobe_separation(0.) + , m_truth_hits { new TrkrHitSetContainerv1 } { if (Verbosity()) { @@ -113,19 +118,19 @@ int PHG4MvtxHitReco::InitRun(PHCompositeNode *topNode) SaveToNodeTree(runDetNode, paramNodeName); // create hitset container if needed - auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_MVTX"); if (!hitsetcontainer) { PHNodeIterator dstiter(dstNode); - auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto trkrnode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "MVTX")); if (!trkrnode) { - trkrnode = new PHCompositeNode("TRKR"); + trkrnode = new PHCompositeNode("MVTX"); dstNode->addNode(trkrnode); } hitsetcontainer = new TrkrHitSetContainerv1; - auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET_MVTX", "PHObject"); trkrnode->addNode(newNode); } @@ -146,38 +151,30 @@ int PHG4MvtxHitReco::InitRun(PHCompositeNode *topNode) trkrnode->addNode(newNode); } + // get the nodes for the truth clustering m_truthtracks = findNode::getClass(topNode, "TRKR_TRUTHTRACKCONTAINER"); if (!m_truthtracks) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); - if (!DetNode) - { - DetNode = new PHCompositeNode("TRKR"); - dstNode->addNode(DetNode); - } - m_truthtracks = new TrkrTruthTrackContainerv1(); auto newNode = new PHIODataNode(m_truthtracks, "TRKR_TRUTHTRACKCONTAINER", "PHObject"); - DetNode->addNode(newNode); + dstNode->addNode(newNode); } + m_truthclusters = findNode::getClass(topNode, "TRKR_TRUTHCLUSTERCONTAINER"); if (!m_truthclusters) { - PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); - if (!DetNode) - { - DetNode = new PHCompositeNode("TRKR"); - dstNode->addNode(DetNode); - } - m_truthclusters = new TrkrClusterContainerv4; auto newNode = new PHIODataNode(m_truthclusters, "TRKR_TRUTHCLUSTERCONTAINER", "PHObject"); - DetNode->addNode(newNode); + dstNode->addNode(newNode); + } + + m_truthinfo = findNode::getClass(topNode, "G4TruthInfo"); + if (!m_truthinfo) + { + std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl; + assert(m_truthinfo); } - m_truth_clusterer = new TruthMvtxClusterBuilder(m_truthclusters, m_truthtracks, Verbosity()); - m_truth_clusterer->set_verbosity(Verbosity()); return Fun4AllReturnCodes::EVENT_OK; } @@ -191,16 +188,6 @@ int PHG4MvtxHitReco::process_event(PHCompositeNode *topNode) exit(1); } - PHG4CylinderGeomContainer* geom_container = findNode::getClass(topNode, "CYLINDERGEOM_MVTX"); - if (!geom_container) { - std::cout << PHWHERE << " Couldn't get geometry container CYLINDERGEOM_MVTX" << std::endl; - } - m_truth_clusterer->set_geom_container(geom_container); - - PHG4TruthInfoContainer *truthinfo = - findNode::getClass(topNode, "G4TruthInfo"); - m_truth_clusterer->set_truthinfo(truthinfo); - // load relevant nodes // G4Hits const std::string g4hitnodename = "G4HIT_" + m_detector; auto g4hitContainer = findNode::getClass(topNode, g4hitnodename); @@ -212,7 +199,7 @@ int PHG4MvtxHitReco::process_event(PHCompositeNode *topNode) assert(geoNode); // Get the TrkrHitSetContainer node - auto trkrHitSetContainer = findNode::getClass(topNode, "TRKR_HITSET"); + auto trkrHitSetContainer = findNode::getClass(topNode, "TRKR_HITSET_MVTX"); assert(trkrHitSetContainer); // Get the TrkrHitTruthAssoc node @@ -264,7 +251,7 @@ int PHG4MvtxHitReco::process_event(PHCompositeNode *topNode) // get hit auto g4hit = g4hit_it->second; - m_truth_clusterer->check_g4hit(g4hit); + truthcheck_g4hit(g4hit, topNode); //cout << "From PHG4MvtxHitReco: Call hit print method: " << std::endl; if (Verbosity() > 4) @@ -642,7 +629,7 @@ int PHG4MvtxHitReco::process_event(PHCompositeNode *topNode) double hitenergy = venergy[i1].first * TrkrDefs::MvtxEnergyScaleup; hit->addEnergy(hitenergy); - m_truth_clusterer->addhitset(hitsetkey, hitkey, hitenergy); + addtruthhitset(hitsetkey, hitkey, hitenergy); if (Verbosity() > 0) std::cout << " added hit " << hitkey << " to hitset " << hitsetkey << " with strobe id " << strobe << " in layer " << layer @@ -662,7 +649,6 @@ int PHG4MvtxHitReco::process_event(PHCompositeNode *topNode) } // end loop over layers - m_truth_clusterer->reset(); // print the list of entries in the association table if (Verbosity() > 2) @@ -672,7 +658,42 @@ int PHG4MvtxHitReco::process_event(PHCompositeNode *topNode) } // spit out the truth clusters - if (Verbosity() > 5) m_truth_clusterer->print_clusters(); + + end_event_truthcluster(topNode); + + if (Verbosity() > 3) { + int nclusprint = -1; + std::cout << PHWHERE << ": content of clusters " << std::endl; + auto& tmap = m_truthtracks->getMap(); + std::cout << " Number of tracks: " << tmap.size() << std::endl; + for (auto& _pair : tmap) { + auto& track = _pair.second; + + printf("id(%2i) phi:eta:pt(", (int)track->getTrackid()); + std::cout << "phi:eta:pt("; + printf("%5.2f:%5.2f:%5.2f", track->getPhi(), track->getPseudoRapidity(), track->getPt()); + /* Form("%5.2:%5.2:%5.2", track->getPhi(), track->getPseudoRapidity(), track->getPt()) */ + //<getPhi()<<":"<getPseudoRapidity()<<":"<getPt() + std::cout << ") nclusters(" << track->getClusters().size() <<") "; + int nclus = 0; + for (auto cluskey : track->getClusters()) { + std::cout << " " + << ((int) TrkrDefs::getHitSetKeyFromClusKey(cluskey)) <<":index(" << + ((int) TrkrDefs::getClusIndex(cluskey)) << ")" << std::endl; + ++nclus; + if (nclusprint > 0 && nclus >= nclusprint) { + std::cout << " ... "; + break; + } + } + } + std::cout << PHWHERE << " ----- end of clusters " << std::endl; + } + + if (m_is_emb) { + cluster_truthhits(topNode); // the last track was truth -- cluster it + prior_g4hit = nullptr; + } return Fun4AllReturnCodes::EVENT_OK; } @@ -742,5 +763,363 @@ TrkrDefs::hitsetkey PHG4MvtxHitReco::zero_strobe_bits(TrkrDefs::hitsetkey hitset } PHG4MvtxHitReco::~PHG4MvtxHitReco() { - delete m_truth_clusterer; + delete m_truth_hits; +} + +void PHG4MvtxHitReco::truthcheck_g4hit(PHG4Hit* g4hit, PHCompositeNode* topNode) { + int new_trkid = (g4hit==nullptr) ? -1 : g4hit->get_trkid(); + bool is_new_track = (new_trkid != m_trkid); + if (Verbosity()>5) std::cout << PHWHERE << std::endl << " -> Checking status of PHG4Hit. Track id("<get_x(0) << " " */ + /* << g4hit->get_y(0) << " " << g4hit->get_z(0) */ + /* << " trackid("<get_trkid() << ") " << std::endl; */ + if (m_is_emb) { + /* std::cout << " FIXME Checking MVTX g4hit : " << g4hit->get_x(0) << " " */ + /* << g4hit->get_y(0) << " " << g4hit->get_z(0) */ + /* << " trackid("<get_trkid() << ") " << std::endl; */ + if (prior_g4hit!=nullptr + && ( std::abs(prior_g4hit->get_x(0)-g4hit->get_x(0)) > max_g4hitstep + || std::abs(prior_g4hit->get_y(0)-g4hit->get_y(0)) > max_g4hitstep + ) + ) + { + // this is a looper track -- cluster hits up to this point already + cluster_truthhits(topNode); + } + prior_g4hit = g4hit; + } + return; + } + // <- STATUS: this is a new track + if (Verbosity()>2) std::cout << PHWHERE << std::endl << " -> Found new embedded track with id: " << new_trkid << std::endl; + if (m_is_emb) { + cluster_truthhits(topNode); // cluster m_truth_hits and add m_current_track + m_current_track = nullptr; + prior_g4hit = nullptr; + } + m_trkid = new_trkid; + m_is_emb = m_truthinfo->isEmbeded(m_trkid); + if (m_is_emb) { + m_current_track = m_truthtracks->getTruthTrack(m_trkid, m_truthinfo); + prior_g4hit = g4hit; + } +} + +void PHG4MvtxHitReco::end_event_truthcluster ( PHCompositeNode* topNode ) { + if (m_is_emb) { + cluster_truthhits(topNode); // cluster m_truth_hits and add m_current_track + m_current_track = nullptr; + m_trkid = -1; + m_is_emb = false; + } + m_hitsetkey_cnt.clear(); +} + +void PHG4MvtxHitReco::addtruthhitset( + TrkrDefs::hitsetkey hitsetkey, + TrkrDefs::hitkey hitkey, + float neffelectrons) +{ + if (!m_is_emb) return; + TrkrHitSetContainer::Iterator hitsetit = m_truth_hits->findOrAddHitSet(hitsetkey); + // See if this hit already exists + TrkrHit *hit = nullptr; + hit = hitsetit->second->getHit(hitkey); + if (!hit) + { + // create a new one + hit = new TrkrHitv2(); + hitsetit->second->addHitSpecificKey(hitkey, hit); + } + // Either way, add the energy to it -- adc values will be added at digitization + hit->addEnergy(neffelectrons); +} + +void PHG4MvtxHitReco::cluster_truthhits(PHCompositeNode* topNode) { + // clusterize the mvtx hits in m_truth_hits, put them in m_truthclusters, and put the id's in m_current_track + // ---------------------------------------------------------------------------------------------------- + // Digitization -- simplified from g4mvtx/PHG4MvtxDigitizer -- + // ---------------------------------------------------------------------------------------------------- + + /* // We want all hitsets for the Mvtx */ + /* TrkrHitSetContainer::ConstRange hitset_range = m_truth_hits->getHitSets(TrkrDefs::TrkrId::mvtxId); */ + /* for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range.first; */ + /* hitset_iter != hitset_range.second; */ + /* ++hitset_iter) */ + /* { */ + /* // we have an iterator to one TrkrHitSet for the mvtx from the trkrHitSetContainer */ + /* // get the hitset key so we can find the layer */ + /* TrkrDefs::hitsetkey hitsetkey = hitset_iter->first; */ + /* int layer = TrkrDefs::getLayer(hitsetkey); */ + /* // FIXME */ + /* /1* if (Verbosity() > 1) std::cout << "PHG4MvtxDigitizer: found hitset with key: " << hitsetkey << " in layer " << layer << std::endl; *1/ */ + /* std::cout << "PHG4MvtxDigitizer: found hitset with key: " << hitsetkey << " in layer " << layer << std::endl; */ + + /* // get all of the hits from this hitset */ + /* TrkrHitSet *hitset = hitset_iter->second; */ + /* TrkrHitSet::ConstRange hit_range = hitset->getHits(); */ + /* std::set hits_rm; */ + /* for (TrkrHitSet::ConstIterator hit_iter = hit_range.first; */ + /* hit_iter != hit_range.second; */ + /* ++hit_iter) */ + /* { */ + /* TrkrHit *hit = hit_iter->second; */ + + /* // Convert the signal value to an ADC value and write that to the hit */ + /* // Unsigned int adc = hit->getEnergy() / (TrkrDefs::MvtxEnergyScaleup *_energy_scale[layer]); */ + /* if (Verbosity() > 0) */ + /* std::cout << " PHG4MvtxDigitizer: found hit with key: " << hit_iter->first << " and signal " << hit->getEnergy() / TrkrDefs::MvtxEnergyScaleup << " in layer " << layer << std::endl; */ + /* // Remove the hits with energy under threshold */ + /* bool rm_hit = false; */ + /* // FIXME: */ + /* double _energy_threshold = 0.; // FIXME */ + /* const double dummy_pixel_thickness = 0.001; */ + /* const double mip_e = 0.003876; */ + /* double _energy_scale = mip_e * dummy_pixel_thickness; // FIXME: note: this doesn't actually */ + /* // matter either here or for the Svtx Tracks -- the energy is digital -- either the hit is there or it isn't */ + /* double _max_adc = 255; */ + /* if ((hit->getEnergy() / TrkrDefs::MvtxEnergyScaleup) < _energy_threshold) */ + /* { */ + /* if (Verbosity() > 0) std::cout << " remove hit, below energy threshold of " << _energy_threshold << std::endl; */ + /* rm_hit = true; */ + /* } */ + /* unsigned short adc = (unsigned short) (hit->getEnergy() / (TrkrDefs::MvtxEnergyScaleup * _energy_scale)); */ + /* if (adc > _max_adc) adc = _max_adc; */ + /* hit->setAdc(adc); */ + + /* if (rm_hit) hits_rm.insert(hit_iter->first); */ + /* } */ + + /* for (const auto &key : hits_rm) */ + /* { */ + /* if (Verbosity() > 0) std::cout << " PHG4MvtxDigitizer: remove hit with key: " << key << std::endl; */ + /* hitset->removeHit(key); */ + /* } */ + /* } */ + + // ---------------------------------------------------------------------------------------------------- + // Prune hits -- simplified from mvtx/MvtxHitReco + // ---------------------------------------------------------------------------------------------------- + std::multimap hitset_multimap; // will map (bare hitset, hitset with strobe) + std::set bare_hitset_set; // list of all physical sensor hitsetkeys (i.e. with strobe set to zero) + + TrkrHitSetContainer::ConstRange hitsetrange = m_truth_hits->getHitSets(TrkrDefs::TrkrId::mvtxId); // actually m_truth_hits can only have MVTX hits at this point... + for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; + hitsetitr != hitsetrange.second; + ++hitsetitr) + { + auto hitsetkey = hitsetitr->first; + + // get the hitsetkey value for strobe 0 + unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); + unsigned int stave = MvtxDefs::getStaveId(hitsetitr->first); + unsigned int chip = MvtxDefs::getChipId(hitsetitr->first); + auto bare_hitsetkey = MvtxDefs::genHitSetKey(layer, stave, chip, 0); + + hitset_multimap.insert(std::make_pair(bare_hitsetkey, hitsetkey)); + bare_hitset_set.insert(bare_hitsetkey); + + if(Verbosity() > 0) std::cout << " found hitsetkey " << hitsetkey << " for bare_hitsetkey " << bare_hitsetkey << std::endl; + } + + // Now consolidate all hits into the hitset with strobe 0, and delete the other hitsets + //============================================================== + for(auto bare_it = bare_hitset_set.begin(); bare_it != bare_hitset_set.end(); ++bare_it) + { + auto bare_hitsetkey = *bare_it; + TrkrHitSet* bare_hitset = (m_truth_hits->findOrAddHitSet(bare_hitsetkey))->second; + if(Verbosity() > 0) std::cout << " bare_hitset " << bare_hitsetkey << " initially has " << bare_hitset->size() << " hits " << std::endl; + + auto bare_hitsetrange= hitset_multimap.equal_range(bare_hitsetkey); + for(auto it = bare_hitsetrange.first; it != bare_hitsetrange.second; ++ it) + { + auto hitsetkey = it->second; + + int strobe = MvtxDefs::getStrobeId(hitsetkey); + if(strobe != 0) + { + if(Verbosity() > 0) std::cout << " process hitsetkey " << hitsetkey << " for bare_hitsetkey " << bare_hitsetkey << std::endl; + + // copy all hits to the hitset with strobe 0 + TrkrHitSet* hitset = m_truth_hits->findHitSet(hitsetkey); + + if(Verbosity() > 0) + std::cout << " hitsetkey " << hitsetkey << " has strobe " << strobe << " and has " << hitset->size() << " hits, so copy it" << std::endl; + + TrkrHitSet::ConstRange hitrangei = hitset->getHits(); + for (TrkrHitSet::ConstIterator hitr = hitrangei.first; + hitr != hitrangei.second; + ++hitr) + { + auto hitkey = hitr->first; + if(Verbosity() > 0) std::cout << " found hitkey " << hitkey << std::endl; + // if it is already there, leave it alone, this is a duplicate hit + auto tmp_hit = bare_hitset->getHit(hitkey); + if(tmp_hit) + { + if(Verbosity() > 0) std::cout << " hitkey " << hitkey << " is already in bare hitsest, do not copy" << std::endl; + continue; + } + + // otherwise copy the hit over + if(Verbosity() > 0) std::cout << " copying over hitkey " << hitkey << std::endl; + auto old_hit = hitr->second; + TrkrHit *new_hit = new TrkrHitv2(); + new_hit->setAdc(old_hit->getAdc()); + bare_hitset->addHitSpecificKey(hitkey, new_hit); + } + + // all hits are copied over to the strobe zero hitset, remove this hitset + m_truth_hits->removeHitSet(hitsetkey); + } + } + } + + // ---------------------------------------------------------------------------------------------------- + // cluster hits -- simplified from mvtx/MvtxClusterizer + // ---------------------------------------------------------------------------------------------------- + PHG4CylinderGeomContainer* geom_container = findNode::getClass(topNode, "CYLINDERGEOM_MVTX"); + if (!geom_container) { + std::cout << PHWHERE << std::endl; + std::cout << "WARNING: cannot find the geometry CYLINDERGEOM_MVTX" << std::endl; + m_truth_hits->Reset(); + return; + } + + //----------- + // Clustering + //----------- + + // loop over each MvtxHitSet object (chip) + hitsetrange = m_truth_hits->getHitSets(TrkrDefs::TrkrId::mvtxId); + for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; + hitsetitr != hitsetrange.second; + ++hitsetitr) + { // hitsetitr : pair(TrkrDefs::hitsetkey, TrkrHitSet>; TrkrHitSet : map + TrkrHitSet *hitset = hitsetitr->second; // hitset : map + + /* if (true) */ + if(Verbosity() > 0) + { + unsigned int layer = TrkrDefs::getLayer (hitsetitr ->first); + unsigned int stave = MvtxDefs::getStaveId (hitsetitr ->first); + unsigned int chip = MvtxDefs::getChipId (hitsetitr ->first); + unsigned int strobe = MvtxDefs::getStrobeId (hitsetitr ->first); + std::cout << "MvtxClusterizer found hitsetkey " << hitsetitr->first << " layer " << layer << " stave " << stave << " chip " << chip << " strobe " << strobe << std::endl; + } + + if (Verbosity() > 2) + hitset->identify(); + + TrkrHitSet::ConstRange hitrangei = hitset->getHits(); + + auto hitsetkey = hitset->getHitSetKey(); + auto ckey = TrkrDefs::genClusKey(hitsetkey, 0); // there is only one cluster made per cluskey + + // determine the size of the cluster in phi and z + std::set phibins; + std::set zbins; + + // determine the cluster position... + double locxsum = 0.; + double loczsum = 0.; + + double locclusx = NAN; + double locclusz = NAN; + + // we need the geometry object for this layer to get the global positions + int layer = TrkrDefs::getLayer(ckey); + auto layergeom = dynamic_cast(geom_container->GetLayerGeom(layer)); + if (!layergeom) + exit(1); + + + // make a tunable threshold for energy in a given hit + // -- percentage of someting? (total cluster energy) + double sum_energy { 0. }; + for ( auto ihit = hitrangei.first; ihit != hitrangei.second; ++ihit) { + sum_energy += ihit->second->getEnergy(); + } + const double threshold = sum_energy * m_pixel_thresholdrat; //FIXME -- tune this as needed + /* const unsigned int npixels = std::distance( hitrangei.first, hitrangei.second ); */ + // to tune this parameter: run a bunch of tracks and compare truth sizes and reco sizes, + // should come out the same + double npixels {0.}; + for ( auto ihit = hitrangei.first; ihit != hitrangei.second; ++ihit) + { + if (ihit->second->getEnergy()first); + int row = MvtxDefs::getRow( ihit->first); + zbins.insert(col); + phibins.insert(row); + + // get local coordinates, in stave reference frame, for hit + auto local_coords = layergeom->get_local_coords_from_pixel(row,col); + + /* + manually offset position along y (thickness of the sensor), + to account for effective hit position in the sensor, resulting from diffusion. + Effective position corresponds to 1um above the middle of the sensor + */ + local_coords.SetY( 1e-4 ); + + // update cluster position + locxsum += local_coords.X(); + loczsum += local_coords.Z(); + // add the association between this cluster key and this hitkey to the table + } //mapiter + + // This is the local position + locclusx = locxsum / npixels; + locclusz = loczsum / npixels; + + const double pitch = layergeom->get_pixel_x(); + const double length = layergeom->get_pixel_z(); + const double phisize = phibins.size() * pitch; + const double zsize = zbins.size() * length; + + /* if (true) { */ + if(Verbosity() > 0) { + std::cout << " MvtxClusterizer: cluskey " << ckey << " layer " << layer << " rad " << layergeom->get_radius() << " phibins " << phibins.size() << " pitch " << pitch << " phisize " << phisize + << " zbins " << zbins.size() << " length " << length << " zsize " << zsize + << " local x " << locclusx << " local y " << locclusz + << std::endl; + } + + // ok force it use use cluster version v4 for now (Valgrind is not happy with application of v5) + /* if (m_cluster_version==4){ */ + if (m_cluster_version == 4) { + auto clus = std::make_unique(); + clus->setAdc(npixels); + clus->setLocalX(locclusx); + clus->setLocalY(locclusz); + + clus->setPhiSize(phibins.size()); + clus->setZSize(zbins.size()); + // All silicon surfaces have a 1-1 map to hitsetkey. + // So set subsurface key to 0 + clus->setSubSurfKey(0); + + if (Verbosity() > 2) + clus->identify(); + + // get the count of how many clusters have allready been added to this hitsetkey (possibly from other embedded tracks tracks) + m_hitsetkey_cnt.try_emplace(hitsetkey,0); + unsigned int& cnt = m_hitsetkey_cnt[hitsetkey]; + ckey = TrkrDefs::genClusKey(hitsetkey, cnt); + m_truthclusters->addClusterSpecifyKey(ckey, clus.release()); + m_current_track->addCluster(ckey); + ++cnt; + } else { + std::cout << PHWHERE << std::endl; + std::cout << "Error: only cluster version 4 allowed." << std::endl; + } // loop over hitsets + } + m_truth_hits->Reset(); + prior_g4hit = nullptr; + return; } diff --git a/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.h b/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.h index 3f7d751947..cf1d4aaf52 100644 --- a/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.h +++ b/simulation/g4simulation/g4mvtx/PHG4MvtxHitReco.h @@ -1,8 +1,6 @@ #ifndef G4MVTX_PHG4MVTXHITRECO_H #define G4MVTX_PHG4MVTXHITRECO_H -#include "TruthMvtxClusterBuilder.h" - #include #include @@ -15,8 +13,12 @@ #include class PHCompositeNode; -class TrkrTruthTrackContainer; +class PHG4TruthInfoContainer; class TrkrClusterContainer; +class TrkrHitSetContainer; +class TrkrTruthTrack; +class TrkrTruthTrackContainer; +class PHG4Hit; class PHG4MvtxHitReco : public SubsysReco, public PHParameterInterface { @@ -62,10 +64,6 @@ class PHG4MvtxHitReco : public SubsysReco, public PHParameterInterface bool m_in_sphenix_srdo = false; - TrkrTruthTrackContainer* m_truthtracks { nullptr }; - TrkrClusterContainer* m_truthclusters { nullptr }; - TruthMvtxClusterBuilder* m_truth_clusterer { nullptr }; - class Deleter { public: @@ -74,6 +72,30 @@ class PHG4MvtxHitReco : public SubsysReco, public PHParameterInterface }; std::unique_ptr m_rng; + + // needed for clustering truth tracks + private: + TrkrTruthTrackContainer* m_truthtracks { nullptr }; // output truth tracks + TrkrClusterContainer* m_truthclusters { nullptr }; // output clusters indexed to TrkrDefs::cluskeys in m_truthtracks + PHG4TruthInfoContainer* m_truthinfo { nullptr }; + int m_trkid { -1 }; + bool m_is_emb { false }; + TrkrTruthTrack* m_current_track { nullptr }; + const int m_cluster_version { 4 }; + TrkrHitSetContainer* m_truth_hits; // generate and delete a container for each truth track + std::map m_hitsetkey_cnt {}; // counter for making ckeys form hitsetkeys + + + PHG4Hit* prior_g4hit { nullptr }; // used to check for jumps in g4hits for loopers; + void addtruthhitset ( TrkrDefs::hitsetkey, TrkrDefs::hitkey, float neffelectrons ); + void truthcheck_g4hit ( PHG4Hit*, PHCompositeNode* topNode ); + void cluster_truthhits ( PHCompositeNode* topNode ); + void end_event_truthcluster ( PHCompositeNode* topNode ); + + double m_pixel_thresholdrat { 0.01 }; + float max_g4hitstep { 3.5 }; + public: + void set_pixel_thresholdrat (double val) { m_pixel_thresholdrat = val; }; }; #endif diff --git a/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.cc b/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.cc index 2cb212fa4c..44c1d5db3a 100644 --- a/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.cc +++ b/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include // for PHWHERE #include #include @@ -116,6 +117,10 @@ void TruthMvtxClusterBuilder::cluster_hits() { if (m_verbosity > 0) cout << "Entering MvtxClusterizer::ClusterMvtx " << endl; + if (m_MvtxHitPruner) { + m_MvtxHitPruner->process_TrkrHitSetContainer(m_hits); + } + auto track = m_truthtracks->getTruthTrack(trkid, m_truthinfo); //----------- @@ -351,33 +356,32 @@ void TruthMvtxClusterBuilder::cluster_hits() { /* } */ } // clusitr loop } // loop over hitsets + if (m_verbosity>3) std::cout << "track " << track->getTrackid() << " has " << track->getClusters().size() << " mvtx clusters" << std::endl; - - return; - m_hits->Reset(); + return; }; bool TruthMvtxClusterBuilder::are_adjacent(const std::pair &lhs, const std::pair &rhs) { - /* if (GetZClustering()) */ - /* { */ - /* // column is first, row is second */ - /* if (fabs( MvtxDefs::getCol(lhs.first) - MvtxDefs::getCol(rhs.first) ) <= 1) */ - /* { */ - /* if (fabs( MvtxDefs::getRow(lhs.first) - MvtxDefs::getRow(rhs.first) ) <= 1) */ - /* { */ - /* return true; */ - /* } */ - /* } */ - /* } */ - /* else */ - //{ default to always used - if (fabs( MvtxDefs::getCol(lhs.first) - MvtxDefs::getCol(rhs.first) ) == 0) + if (GetZClustering()) { - if (fabs( MvtxDefs::getRow(lhs.first) - MvtxDefs::getRow(rhs.first) ) <= 1) + if (fabs( MvtxDefs::getCol(lhs.first) - MvtxDefs::getCol(rhs.first) ) <= 1) { - return true; + if (fabs( MvtxDefs::getRow(lhs.first) - MvtxDefs::getRow(rhs.first) ) <= 1) + { + return true; + } + } + } + else + { + if (fabs( MvtxDefs::getCol(lhs.first) - MvtxDefs::getCol(rhs.first) ) == 0) + { + if (fabs( MvtxDefs::getRow(lhs.first) - MvtxDefs::getRow(rhs.first) ) <= 1) + { + return true; + } } } //} diff --git a/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.h b/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.h index 1ad6ceba22..7b5313a213 100644 --- a/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.h +++ b/simulation/g4simulation/g4mvtx/TruthMvtxClusterBuilder.h @@ -38,12 +38,15 @@ class TrkrTruthTrack; class PHG4TruthInfoContainer; class PHG4Hit; +class MvtxHitPruner; + class TruthMvtxClusterBuilder { // member data int trkid {-1}; bool is_emb {false}; PHG4TruthInfoContainer *m_truthinfo {nullptr}; + MvtxHitPruner *m_MvtxHitPruner { nullptr }; // intermediary hits, used to cluster Truth hits TrkrHitSetContainer *m_hits {}; // save the hits as they come along @@ -68,15 +71,31 @@ class TruthMvtxClusterBuilder { void set_verbosity(int _verbosity) { m_verbosity = _verbosity; }; void set_geom_container (PHG4CylinderGeomContainer *_geom_container) { m_geom_container = _geom_container; }; + void set_HitPruner(MvtxHitPruner* _) { m_MvtxHitPruner = _; }; void print_clusters(int nclusters=-1); + //! option to turn off z-dimension clustering + void SetZClustering(const bool make_z_clustering) + { + m_makeZClustering = make_z_clustering; + } + bool GetZClustering() const + { + return m_makeZClustering; + } + private: void cluster_hits(); int m_verbosity {0}; /* bool are_adjacent(RawHit* lhs, RawHit* rhs); */ bool are_adjacent(const std::pair &lhs, const std::pair &rhs); PHG4CylinderGeomContainer* m_geom_container { nullptr }; + + bool m_makeZClustering {true}; // z_clustering_option + /* bool do_hit_assoc = true; */ + /* bool do_read_raw = false; */ + /* int m_cluster_version = 4; */ }; #endif diff --git a/simulation/g4simulation/g4ohcal/Makefile.am b/simulation/g4simulation/g4ohcal/Makefile.am index 828e6bc53e..8f5acc4568 100644 --- a/simulation/g4simulation/g4ohcal/Makefile.am +++ b/simulation/g4simulation/g4ohcal/Makefile.am @@ -17,6 +17,7 @@ AM_LDFLAGS = \ -L$(ROOTSYS)/lib libg4ohcal_la_LIBADD = \ + -lcalo_io \ -lfun4all \ -lphg4hit \ -lg4detectors diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.cc b/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.cc index bb969705bb..6b279ece8f 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.cc +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.cc @@ -10,13 +10,29 @@ #include #include #include - -#include +#include + +#include +#include + +#include +#include +#include // for PHNode +#include +#include // for PHObject +#include +#include #include #include #include +#include // for convert_name_... +#include // for RawTowerGeom +#include // for RawTowerGeomC... +#include +#include + #include #include @@ -46,12 +62,10 @@ #include #include #include -#include // for unique_ptr -#include // for __decay_and_strip<>::_... -#include // for pair, make_pair -#include // for vector, vector<>::iter... +#include // for unique_ptr +#include // for pair, make_pair +#include // for vector, vector<>::iter... -class G4Material; class PHCompositeNode; PHG4OHCalDetector::PHG4OHCalDetector(PHG4Subsystem *subsys, PHCompositeNode *Node, PHParameters *parames, const std::string &dnam) @@ -68,14 +82,17 @@ PHG4OHCalDetector::PHG4OHCalDetector(PHG4Subsystem *subsys, PHCompositeNode *Nod { gdml_config = PHG4GDMLUtility::GetOrMakeConfigNode(Node); assert(gdml_config); - - m_FieldSetup = - new PHG4OHCalFieldSetup( - m_Params->get_string_param("IronFieldMapPath"), m_Params->get_double_param("IronFieldMapScale"), - m_InnerRadius - 10*cm, // subtract 10 cm to make sure fieldmap with 2x2 grid covers it - m_OuterRadius + 10*cm, // add 10 cm to make sure fieldmap with 2x2 grid covers it - m_SizeZ/2. + 10*cm // div by 2 bc G4 convention + PHFieldConfig *fieldconf = findNode::getClass(Node, PHFieldUtility::GetDSTConfigNodeName()); + if (fieldconf->get_field_config() != PHFieldConfig::kFieldUniform) + { + m_FieldSetup = + new PHG4OHCalFieldSetup( + m_Params->get_string_param("IronFieldMapPath"), m_Params->get_double_param("IronFieldMapScale"), + m_InnerRadius - 10 * cm, // subtract 10 cm to make sure fieldmap with 2x2 grid covers it + m_OuterRadius + 10 * cm, // add 10 cm to make sure fieldmap with 2x2 grid covers it + m_SizeZ / 2. + 10 * cm // div by 2 bc G4 convention ); + } } PHG4OHCalDetector::~PHG4OHCalDetector() @@ -121,11 +138,12 @@ void PHG4OHCalDetector::ConstructMe(G4LogicalVolume *logicWorld) m_DisplayAction->SetMyTopVolume(mothervol); ConstructOHCal(hcal_envelope_log); - // allow installing new G4 subsystem installed inside the HCal envelope via macros, in particular its support rings. + // allow installing new G4 subsystem installed inside the HCal envelope via macros, in particular its support rings. PHG4Subsystem *mysys = GetMySubsystem(); - if (mysys) + if (mysys) + { mysys->SetLogicalVolume(hcal_envelope_log); - + } // disable GDML export for HCal geometries for memory saving and compatibility issues assert(gdml_config); gdml_config->exclude_physical_vol(mothervol); @@ -144,7 +162,7 @@ void PHG4OHCalDetector::ConstructMe(G4LogicalVolume *logicWorld) } } } - + if(!m_Params->get_int_param("saveg4hit")) AddGeometryNode(); return; } @@ -156,8 +174,8 @@ int PHG4OHCalDetector::ConstructOHCal(G4LogicalVolume *hcalenvelope) gdmlParser.SetOverlapCheck(OverlapCheck()); gdmlParser.Read(m_GDMPath, false); - G4AssemblyVolume *abs_asym = reader->GetAssembly("sector"); //absorber - m_ScintiMotherAssembly = reader->GetAssembly("tileAssembly24_90"); //tiles + G4AssemblyVolume *abs_asym = reader->GetAssembly("sector"); // absorber + m_ScintiMotherAssembly = reader->GetAssembly("tileAssembly24_90"); // tiles // this loop is inefficient but the assignment of the scintillator id's is much simpler when having the hcal sector std::vector::iterator it1 = abs_asym->GetVolumesIterator(); @@ -188,8 +206,8 @@ int PHG4OHCalDetector::ConstructOHCal(G4LogicalVolume *hcalenvelope) ++it1; } // Chimney assemblies - G4AssemblyVolume *chimAbs_asym = reader->GetAssembly("sectorChimney"); //absorber - m_ChimScintiMotherAssembly = reader->GetAssembly("tileAssembly24chimney_90"); //chimney tiles + G4AssemblyVolume *chimAbs_asym = reader->GetAssembly("sectorChimney"); // absorber + m_ChimScintiMotherAssembly = reader->GetAssembly("tileAssembly24chimney_90"); // chimney tiles std::vector::iterator it2 = chimAbs_asym->GetVolumesIterator(); // order sector 30,31,29 @@ -224,14 +242,17 @@ int PHG4OHCalDetector::ConstructOHCal(G4LogicalVolume *hcalenvelope) ++it2; } - for (auto & logical_vol : m_SteelAbsorberLogVolSet) + for (auto &logical_vol : m_SteelAbsorberLogVolSet) { - logical_vol->SetFieldManager(m_FieldSetup->get_Field_Manager_Iron(), true); - - if (m_Params->get_int_param("field_check")) + if (m_FieldSetup) // only if we have a field defined for the steel absorber { - std::cout <<__PRETTY_FUNCTION__<<" : setup Field_Manager_Iron for LV " - <GetName()<<" w/ # of daughter "<< logical_vol->GetNoDaughters()<SetFieldManager(m_FieldSetup->get_Field_Manager_Iron(), true); + + if (m_Params->get_int_param("field_check")) + { + std::cout << __PRETTY_FUNCTION__ << " : setup Field_Manager_Iron for LV " + << logical_vol->GetName() << " w/ # of daughter " << logical_vol->GetNoDaughters() << std::endl; + } } } @@ -449,7 +470,7 @@ int PHG4OHCalDetector::map_layerid(const unsigned int isector, const int layer_i { rowid = layer_id + 95; } - else /* if (layer_id >= 225) */ + else /* if (layer_id >= 225) */ { rowid = layer_id - 225; } @@ -468,3 +489,120 @@ int PHG4OHCalDetector::map_layerid(const unsigned int isector, const int layer_i } return rowid; } + +// This is dulplicated code, we can get rid of it when we have the code to make towergeom for real data reco. +void PHG4OHCalDetector::AddGeometryNode() +{ + PHNodeIterator iter(topNode()); + PHCompositeNode *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + if (!runNode) + { + std::cout << PHWHERE << "Run Node missing, exiting." << std::endl; + gSystem->Exit(1); + exit(1); + } + PHNodeIterator runIter(runNode); + PHCompositeNode *RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", m_SuperDetector)); + if (!RunDetNode) + { + RunDetNode = new PHCompositeNode(m_SuperDetector); + runNode->addNode(RunDetNode); + } + m_TowerGeomNodeName = "TOWERGEOM_" + m_SuperDetector; + m_RawTowerGeom = findNode::getClass(topNode(), m_TowerGeomNodeName); + if (!m_RawTowerGeom) + { + m_RawTowerGeom = new RawTowerGeomContainer_Cylinderv1(RawTowerDefs::convert_name_to_caloid(m_SuperDetector)); + PHIODataNode *newNode = new PHIODataNode(m_RawTowerGeom, m_TowerGeomNodeName, "PHObject"); + RunDetNode->addNode(newNode); + } + double innerrad = m_Params->get_double_param(PHG4HcalDefs::innerrad); + double thickness = m_Params->get_double_param(PHG4HcalDefs::outerrad) - innerrad; + m_RawTowerGeom->set_radius(innerrad); + m_RawTowerGeom->set_thickness(thickness); + m_RawTowerGeom->set_phibins(m_Params->get_int_param(PHG4HcalDefs::n_towers)); + m_RawTowerGeom->set_etabins(m_Params->get_int_param("etabins")); + double geom_ref_radius = innerrad + thickness / 2.; + double phistart = m_Params->get_double_param("phistart"); + if (!std::isfinite(phistart)) + { + std::cout << PHWHERE << " phistart is not finite: " << phistart + << ", exiting now (this will crash anyway)" << std::endl; + gSystem->Exit(1); + } + for (int i = 0; i < m_Params->get_int_param(PHG4HcalDefs::n_towers); i++) + { + double phiend = phistart + 2. * M_PI / m_Params->get_int_param(PHG4HcalDefs::n_towers); + std::pair range = std::make_pair(phiend, phistart); + phistart = phiend; + m_RawTowerGeom->set_phibounds(i, range); + } + double etalowbound = -m_Params->get_double_param("scinti_eta_coverage_neg"); + for (int i = 0; i < m_Params->get_int_param("etabins"); i++) + { + // double etahibound = etalowbound + 2.2 / get_int_param("etabins"); + double etahibound = etalowbound + + (m_Params->get_double_param("scinti_eta_coverage_neg") + m_Params->get_double_param("scinti_eta_coverage_pos")) / m_Params->get_int_param("etabins"); + std::pair range = std::make_pair(etalowbound, etahibound); + m_RawTowerGeom->set_etabounds(i, range); + etalowbound = etahibound; + } + for (int iphi = 0; iphi < m_RawTowerGeom->get_phibins(); iphi++) + { + for (int ieta = 0; ieta < m_RawTowerGeom->get_etabins(); ieta++) + { + const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::convert_name_to_caloid(m_SuperDetector), ieta, iphi); + + const double x(geom_ref_radius * cos(m_RawTowerGeom->get_phicenter(iphi))); + const double y(geom_ref_radius * sin(m_RawTowerGeom->get_phicenter(iphi))); + const double z(geom_ref_radius / tan(PHG4Utils::get_theta(m_RawTowerGeom->get_etacenter(ieta)))); + + RawTowerGeom *tg = m_RawTowerGeom->get_tower_geometry(key); + if (tg) + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - Tower geometry " << key << " already exists" << std::endl; + } + + if (fabs(tg->get_center_x() - x) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x + << std::endl; + + return; + } + if (fabs(tg->get_center_y() - y) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y + << std::endl; + return; + } + if (fabs(tg->get_center_z() - z) > 1e-4) + { + std::cout << "IHCalDetector::InitRun - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z + << std::endl; + return; + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "IHCalDetector::InitRun - building tower geometry " << key << "" << std::endl; + } + + tg = new RawTowerGeomv1(key); + + tg->set_center_x(x); + tg->set_center_y(y); + tg->set_center_z(z); + m_RawTowerGeom->add_tower_geometry(tg); + } + } + } + if (Verbosity() > 0) + { + m_RawTowerGeom->identify(); + } +} diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.h b/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.h index b56689d231..8626d71bd2 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.h +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalDetector.h @@ -20,6 +20,7 @@ class PHG4OHCalFieldSetup; class PHParameters; class PHG4Subsystem; class PHG4GDMLConfig; +class RawTowerGeomContainer; class PHG4OHCalDetector : public PHG4Detector { @@ -47,6 +48,7 @@ class PHG4OHCalDetector : public PHG4Detector std::tuple GetRowColumnId(G4VPhysicalVolume *volume) const; private: + void AddGeometryNode(); int ConstructOHCal(G4LogicalVolume *hcalenvelope); int map_towerid(const int tower_id); int map_layerid(const unsigned int isector, const int layer_id); @@ -78,6 +80,8 @@ class PHG4OHCalDetector : public PHG4Detector PHG4GDMLConfig *gdml_config = nullptr; std::string m_GDMPath; + RawTowerGeomContainer *m_RawTowerGeom = nullptr; + std::string m_TowerGeomNodeName; }; #endif // G4OHCAL_PHG4OHCALDETECTOR_H diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.cc b/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.cc index ddcfd24c72..42cd4da003 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.cc +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.cc @@ -2,7 +2,7 @@ /*! * \file PHG4OHCalFieldSetup.cc - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ @@ -12,8 +12,9 @@ #include -#include +#include // for PHFieldConfig, PHFieldCo... #include +#include #include #include @@ -23,9 +24,9 @@ #include #include #include +#include // for G4int #include -#include PHG4OHCalFieldSetup::PHG4OHCalFieldSetup(const std::string &iron_fieldmap_path, const double scale, const double inner_radius, const double outer_radius, const double size_z) : fMinStep(0.005 * mm) @@ -33,7 +34,7 @@ PHG4OHCalFieldSetup::PHG4OHCalFieldSetup(const std::string &iron_fieldmap_path, static const G4int nvar = 8; // the new HCal expect 3D magnetic field - PHFieldConfigv1 field_config (PHFieldConfig::Field3DCartesian, iron_fieldmap_path, scale); + PHFieldConfigv1 field_config(PHFieldConfig::Field3DCartesian, iron_fieldmap_path, scale); fEMfieldIron = new PHG4MagneticField(PHFieldUtility::BuildFieldMap(&field_config, inner_radius, outer_radius, size_z)); assert(fEMfieldIron); diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.h b/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.h index 8f4395aab6..a53774a5bf 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.h +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalFieldSetup.h @@ -4,7 +4,7 @@ /*! * \file PHG4OHCalFieldSetup.h - * \brief + * \brief * \author Jin Huang * \version $Revision: $ * \date $Date: $ @@ -15,6 +15,7 @@ #include // for G4double, G4int +#include // for numeric_limits #include class G4ChordFinder; @@ -29,7 +30,7 @@ class G4MagneticField; class PHG4OHCalFieldSetup { public: - PHG4OHCalFieldSetup(const std::string & iron_fieldmap_path, const double scale = 1., const double inner_radius = 0., const double outer_radius = 1.e10, const double size_z = 1.e10); + PHG4OHCalFieldSetup(const std::string& iron_fieldmap_path, const double scale = 1., const double inner_radius = 0., const double outer_radius = 1.e10, const double size_z = 1.e10); // delete copy ctor and assignment opertor (cppcheck) explicit PHG4OHCalFieldSetup(const PHG4OHCalFieldSetup&) = delete; @@ -67,7 +68,7 @@ class PHG4OHCalFieldSetup G4ChordFinder* fChordFinderIron = nullptr; G4MagneticField* fEMfieldIron = nullptr; G4MagIntegratorStepper* fStepperIron = nullptr; - G4double fMinStep = NAN; + G4double fMinStep = std::numeric_limits::quiet_NaN(); }; #endif /* G4OHCAL_PHG4OHCALFIELDSETUP_H */ diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.cc b/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.cc index 75424149ca..57a1b5b613 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.cc +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.cc @@ -1,5 +1,3 @@ - -// local headers in quotes (that is important when using include subdirs!) #include "PHG4OHCalSteppingAction.h" #include "PHG4OHCalDetector.h" @@ -11,8 +9,6 @@ #include -#include - #include #include #include @@ -20,8 +16,21 @@ #include // for PHG4SteppingAction #include +#include +#include + +#include +#include // for PHIODataNode +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject #include +#include +#include +#include +#include + // Root headers #include // for TAxis #include @@ -34,29 +43,29 @@ #include // for G4AffineTransform #include #include -#include // for G4NavigationHistory -#include // for G4ParticleDefinition +#include // for G4LogicalVolume +#include // for G4NavigationHistory +#include // for G4ParticleDefinition #include #include // for G4ReferenceCountedHandle #include -#include // for G4StepPoint -#include // for fGeomBoundary, fAtRest... -#include // for G4String +#include // for G4StepPoint +#include // for fGeomBoundary, fAtRest... +#include // for G4String #include -#include // for G4ThreeVector -#include // for G4TouchableHandle -#include // for G4Track -#include // for fStopAndKill +#include // for G4ThreeVector +#include // for G4TouchableHandle +#include // for G4Track +#include // for fStopAndKill #include -#include // for G4double -#include // for G4VPhysicalVolume -#include // for G4VTouchable -#include // for G4VUserTrackInformation +#include // for G4double +#include // for G4VPhysicalVolume +#include // for G4VTouchable +#include // for G4VUserTrackInformation // finally system headers #include #include // for isfinite, sqrt -#include #include #include #include // for operator<<, string @@ -74,6 +83,10 @@ PHG4OHCalSteppingAction::PHG4OHCalSteppingAction(PHG4OHCalDetector* detector, co , m_IsBlackHoleFlag(m_Params->get_int_param("blackhole")) , m_NScintiPlates(m_Params->get_int_param(PHG4HcalDefs::scipertwr) * m_Params->get_int_param("n_towers")) , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model")) + , m_doG4Hit(m_Params->get_int_param("saveg4hit")) + , m_tmin(m_Params->get_double_param("tmin")) + , m_tmax(m_Params->get_double_param("tmax")) + , m_dt(m_Params->get_double_param("dt")) { SetLightCorrection(m_Params->get_double_param("light_balance_inner_radius") * cm, m_Params->get_double_param("light_balance_inner_corr"), @@ -100,7 +113,7 @@ PHG4OHCalSteppingAction::~PHG4OHCalSteppingAction() } } -int PHG4OHCalSteppingAction::Init() +int PHG4OHCalSteppingAction::InitWithNode(PHCompositeNode* topNode) { m_EnableFieldCheckerFlag = m_Params->get_int_param("field_check"); @@ -146,12 +159,153 @@ int PHG4OHCalSteppingAction::Init() file->Close(); delete file; } + if (!m_doG4Hit) + { + try + { + CreateNodeTree(topNode); + } + catch (std::exception& e) + { + std::cout << e.what() << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + if (Verbosity() > 1) topNode->print(); + } return 0; } +//____________________________________________________________________________.. +bool PHG4OHCalSteppingAction::NoHitSteppingAction(const G4Step* aStep) +{ + G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); + G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); + // get volume of the current step + G4VPhysicalVolume* volume = touch->GetVolume(); + + // m_Detector->IsInIHCal(volume) + // returns + // 0 is outside of IHCal + // 1 is inside scintillator + // -1 is steel absorber + + int whichactive = m_Detector->IsInOHCal(volume); + + if (!whichactive) + { + return false; + } + if (m_EnableFieldCheckerFlag) + { + FieldChecker(aStep); + } + int layer_id = -1; + int tower_id = -1; + int sector_id = -1; + if (whichactive > 0) // scintillator + { + std::tuple layer_tower = m_Detector->GetRowColumnId(volume); + sector_id = std::get<0>(layer_tower); + layer_id = std::get<1>(layer_tower); + tower_id = std::get<2>(layer_tower); + + // std::cout<<"******** Outer HCal\t"<GetName()<<"\t"<GetPreStepPoint(); + G4StepPoint* postPoint = aStep->GetPostStepPoint(); + // time window cut + double pretime = prePoint->GetGlobalTime() / nanosecond; + double posttime = postPoint->GetGlobalTime() / nanosecond; + if (posttime < m_tmin || pretime > m_tmax) return false; + if ((posttime - pretime) > m_dt) return false; + G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV; + const G4Track* aTrack = aStep->GetTrack(); + // we only need visible energy here + double light_yield = eion; + + // correct evis using light map + if (m_LightScintModelFlag) + { + light_yield = GetVisibleEnergyDeposition(aStep); + if ((m_MapCorrHistChim[tower_id]) || (m_MapCorrHist[tower_id])) + { + const G4TouchableHandle& theTouchable = prePoint->GetTouchableHandle(); + const G4ThreeVector& worldPosition = postPoint->GetPosition(); + G4ThreeVector localPosition = theTouchable->GetHistory()->GetTopTransform().TransformPoint(worldPosition); + float lx = (localPosition.x() / cm); + float ly = (localPosition.y() / cm); + + // convert to the map bin coordinates: + int lcx = (int) (2.0 * lx) + 1; + int lcy = (int) (2.0 * (ly + 0.5)) + 1; + + if ((sector_id == 29) || (sector_id == 30) || (sector_id == 31)) + { + if ((lcy >= 1) && (lcy <= m_MapCorrHistChim[tower_id]->GetNbinsY()) && + (lcx >= 1) && (lcx <= m_MapCorrHistChim[tower_id]->GetNbinsX())) + { + light_yield *= (double) (m_MapCorrHistChim[tower_id]->GetBinContent(lcx, lcy)); + } + else + { + light_yield = 0.0; + } + } + else + { + if ((lcy >= 1) && (lcy <= m_MapCorrHist[tower_id]->GetNbinsY()) && + (lcx >= 1) && (lcx <= m_MapCorrHist[tower_id]->GetNbinsX())) + { + light_yield *= (double) (m_MapCorrHist[tower_id]->GetBinContent(lcx, lcy)); + } + else + { + light_yield = 0.0; + } + } + } + else + { + // old correction (linear ligh yield dependence along r), never tested + light_yield = light_yield * GetLightCorrection(postPoint->GetPosition().x(), postPoint->GetPosition().y()); + } + } + // find the tower index for this step, tower_id is ieta, layer_id/5 is iphi + unsigned int ieta = tower_id; + unsigned int iphi = (unsigned int) layer_id / 5; + unsigned int tower_key = TowerInfoDefs::encode_hcal(ieta, iphi); + m_CaloInfoContainer->get_tower_at_key(tower_key)->set_energy(m_CaloInfoContainer->get_tower_at_key(tower_key)->get_energy() + light_yield); + // set keep for the track + if (light_yield > 0) + { + if (G4VUserTrackInformation* p = aTrack->GetUserInformation()) + { + if (PHG4TrackUserInfoV1* pp = dynamic_cast(p)) + { + pp->SetKeep(1); // we want to keep the track + } + } + } + + return true; +} + //____________________________________________________________________________.. bool PHG4OHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool /*was_used*/) { + if ((!m_doG4Hit) && (!m_IsBlackHoleFlag)) + { + return NoHitSteppingAction(aStep); + } + G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle(); G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle(); // get volume of the current step @@ -273,19 +427,19 @@ bool PHG4OHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool /*was { m_Hit = new PHG4Hitv1(); } - //here we set the entrance values in cm + // here we set the entrance values in cm m_Hit->set_x(0, prePoint->GetPosition().x() / cm); m_Hit->set_y(0, prePoint->GetPosition().y() / cm); m_Hit->set_z(0, prePoint->GetPosition().z() / cm); // time in ns m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond); - //set the track ID + // set the track ID m_Hit->set_trkid(aTrack->GetTrackID()); m_SaveTrackId = aTrack->GetTrackID(); - //set the initial energy deposit + // set the initial energy deposit m_Hit->set_edep(0); - if (whichactive > 0) // return of IsInOHCalDetector, > 0 hit in scintillator, < 0 hit in absorber + if (whichactive > 0) // return of IsInOHCalDetector, > 0 hit in scintillator, < 0 hit in absorber { m_Hit->set_sector(sector_id); // the sector id m_Hit->set_scint_id(tower_id); // the slat id @@ -352,7 +506,7 @@ bool PHG4OHCalSteppingAction::UserSteppingAction(const G4Step* aStep, bool /*was m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond); - //sum up the energy to get total deposited + // sum up the energy to get total deposited m_Hit->set_edep(m_Hit->get_edep() + edep); if (whichactive > 0) @@ -494,7 +648,7 @@ void PHG4OHCalSteppingAction::FieldChecker(const G4Step* aStep) static const std::string h_field_name = "hOHCalField"; - if (not se->isHistoRegistered(h_field_name)) + if (!se->isHistoRegistered(h_field_name)) { TH2F* h = new TH2F(h_field_name.c_str(), "Magnetic field (Tesla) in HCal;X (cm);Y (cm)", 2400, -300, 300, 2400, -300, 300); @@ -531,12 +685,10 @@ void PHG4OHCalSteppingAction::FieldChecker(const G4Step* aStep) if (h->GetBinContent(binx, binx) == 0) { // only fille unfilled bins - G4TransportationManager* transportMgr = - G4TransportationManager::GetTransportationManager(); + G4TransportationManager* transportMgr = G4TransportationManager::GetTransportationManager(); assert(transportMgr); - G4PropagatorInField* fFieldPropagator = - transportMgr->GetPropagatorInField(); + G4PropagatorInField* fFieldPropagator = transportMgr->GetPropagatorInField(); assert(fFieldPropagator); G4FieldManager* fieldMgr = fFieldPropagator->FindAndSetFieldManager(volume); @@ -579,3 +731,26 @@ void PHG4OHCalSteppingAction::SetHitNodeName(const std::string& type, const std: gSystem->Exit(1); return; } + +void PHG4OHCalSteppingAction::CreateNodeTree(PHCompositeNode* topNode) +{ + PHNodeIterator nodeItr(topNode); + PHCompositeNode* dst_node = dynamic_cast( + nodeItr.findFirst("PHCompositeNode", "DST")); + if (!dst_node) + { + std::cout << "PHComposite node created: DST" << std::endl; + dst_node = new PHCompositeNode("DST"); + topNode->addNode(dst_node); + } + PHNodeIterator dstiter(dst_node); + PHCompositeNode* DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", m_Detector->SuperDetector())); + if (!DetNode) + { + DetNode = new PHCompositeNode(m_Detector->SuperDetector()); + dst_node->addNode(DetNode); + } + m_CaloInfoContainer = new TowerInfoContainerv1(TowerInfoContainer::DETECTOR::HCAL); + PHIODataNode* towerNode = new PHIODataNode(m_CaloInfoContainer, "TOWERINFO_SIM_" + m_Detector->SuperDetector(), "PHObject"); + DetNode->addNode(towerNode); +} diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.h b/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.h index 0cece6b355..0433f8fd83 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.h +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalSteppingAction.h @@ -10,6 +10,7 @@ class G4Step; class G4VPhysicalVolume; class PHCompositeNode; +class TowerInfoContainer; class PHG4OHCalDetector; class PHParameters; class PHG4Hit; @@ -29,7 +30,7 @@ class PHG4OHCalSteppingAction : public PHG4SteppingAction //! stepping action bool UserSteppingAction(const G4Step *, bool) override; - int Init() override; + int InitWithNode(PHCompositeNode *topNode) override; //! reimplemented from base class void SetInterfacePointers(PHCompositeNode *) override; @@ -38,8 +39,9 @@ class PHG4OHCalSteppingAction : public PHG4SteppingAction void FieldChecker(const G4Step *); void EnableFieldChecker(const int i = 1) { m_EnableFieldCheckerFlag = i; } - + void CreateNodeTree(PHCompositeNode *topNode); private: + bool NoHitSteppingAction(const G4Step *aStep); //! pointer to the detector PHG4OHCalDetector *m_Detector = nullptr; @@ -68,8 +70,14 @@ class PHG4OHCalSteppingAction : public PHG4SteppingAction int m_IsBlackHoleFlag = 0; int m_NScintiPlates = -1; int m_LightScintModelFlag = 0; + bool m_doG4Hit = true; + double m_tmin = -20.; + double m_tmax = 60.; + double m_dt = 100.; std::string m_AbsorberNodeName; std::string m_HitNodeName; + + TowerInfoContainer *m_CaloInfoContainer = nullptr; }; #endif // G4OHCAL_PHG4OHCALSTEPPINGACTION_H diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.cc b/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.cc index 7b127d71b6..d08147a84a 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.cc +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.cc @@ -9,7 +9,7 @@ #include -#include // for PHG4DisplayAction +#include // for PHG4DisplayAction #include #include // for PHG4SteppingAction @@ -21,9 +21,9 @@ #include #include // for NAN +#include // for getenv #include // for operator<<, basic_ostream #include // for set -#include // for getenv class PHG4Detector; //_______________________________________________________________________ @@ -48,13 +48,12 @@ int PHG4OHCalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) // create display settings before detector m_DisplayAction = new PHG4OHCalDisplayAction(Name()); - if (get_string_param("IronFieldMapPath") == "DefaultParameters-InvadPath" ) + if (get_string_param("IronFieldMapPath") == "DefaultParameters-InvadPath") { - std::cout <<__PRETTY_FUNCTION__<<": invalid string parameter IronFieldMapPath, where we expect a 3D field map"<SuperDetector(SuperDetector()); @@ -99,7 +98,7 @@ int PHG4OHCalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) } // create stepping action m_SteppingAction = new PHG4OHCalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); m_SteppingAction->SetHitNodeName("G4HIT", m_HitNodeName); m_SteppingAction->SetHitNodeName("G4HIT_ABSORBER", m_AbsorberNodeName); } @@ -108,7 +107,7 @@ int PHG4OHCalSubsystem::InitRunSubsystem(PHCompositeNode *topNode) if (GetParams()->get_int_param("blackhole")) { m_SteppingAction = new PHG4OHCalSteppingAction(m_Detector, GetParams()); - m_SteppingAction->Init(); + m_SteppingAction->InitWithNode(topNode); } } @@ -155,12 +154,15 @@ void PHG4OHCalSubsystem::SetLightCorrection(const double inner_radius, const dou void PHG4OHCalSubsystem::SetDefaultParameters() { - set_default_double_param("inner_radius", 182.423 - 5); + set_default_double_param("inner_radius", 182.423 - 5); set_default_double_param("light_balance_inner_corr", NAN); set_default_double_param("light_balance_inner_radius", NAN); set_default_double_param("light_balance_outer_corr", NAN); set_default_double_param("light_balance_outer_radius", NAN); - set_default_double_param("outer_radius", 269.317 + 5 ); + set_default_double_param("phistart", NAN); + set_default_double_param("scinti_eta_coverage_neg", 1.1); + set_default_double_param("scinti_eta_coverage_pos", 1.1); + set_default_double_param("outer_radius", 269.317 + 5); set_default_double_param("place_x", 0.); set_default_double_param("place_y", 0.); set_default_double_param("place_z", 0.); @@ -169,30 +171,34 @@ void PHG4OHCalSubsystem::SetDefaultParameters() set_default_double_param("rot_z", 0.); set_default_double_param("size_z", 639.240 + 10); set_default_double_param("Birk_const", 0.07943); + set_default_double_param("tmin", -20.); + set_default_double_param("tmax", 60.); + set_default_double_param("dt", 100.); set_default_int_param("field_check", 0); set_default_int_param("light_scint_model", 1); set_default_int_param("n_towers", 64); set_default_int_param(PHG4HcalDefs::scipertwr, 5); set_default_int_param("n_scinti_tiles", 12); + set_default_int_param("etabins", 24); + set_default_int_param("saveg4hit", 1); set_default_string_param("GDMPath", "DefaultParameters-InvadPath"); std::string defaultmapfilename; - const char* Calibroot = getenv("CALIBRATIONROOT"); + const char *Calibroot = getenv("CALIBRATIONROOT"); if (Calibroot) - { - defaultmapfilename = Calibroot; - defaultmapfilename += "/HCALOUT/tilemap/ohcalgdmlmapfiles102022.root"; - } + { + defaultmapfilename = Calibroot; + defaultmapfilename += "/HCALOUT/tilemap/ohcalgdmlmapfiles102022.root"; + } set_default_string_param("MapFileName", defaultmapfilename); set_default_string_param("MapHistoName", "ohcal_mephi_map_towerid_"); - + if (!Calibroot) { - std::cout<<__PRETTY_FUNCTION__ << ": no CALIBRATIONROOT environment variable" << std::endl; + std::cout << __PRETTY_FUNCTION__ << ": no CALIBRATIONROOT environment variable" << std::endl; exit(1); } - set_default_string_param("IronFieldMapPath", std::string(Calibroot) + "/Field/Map/sphenix3dbigmapxyz_steel_rebuild.root" ); + set_default_string_param("IronFieldMapPath", std::string(Calibroot) + "/Field/Map/sphenix3dbigmapxyz_steel_rebuild.root"); set_default_double_param("IronFieldMapScale", 1.); - } diff --git a/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.h b/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.h index f447f9061b..625b718ca4 100644 --- a/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.h +++ b/simulation/g4simulation/g4ohcal/PHG4OHCalSubsystem.h @@ -49,7 +49,7 @@ class PHG4OHCalSubsystem : public PHG4DetectorSubsystem // Subsystems which can be mothervolume need to implement this // and return true bool CanBeMotherSubsystem() const override { return true; } - + private: void SetDefaultParameters() override; diff --git a/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.cc b/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.cc index aaa4a64ed1..d9305da6c1 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.cc +++ b/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ #include #include // for gsl_rng_alloc +#include #include // for exit #include #include @@ -31,8 +33,6 @@ PHG4TpcDigitizer::PHG4TpcDigitizer(const std::string &name) : SubsysReco(name) - , TpcMinLayer(7) - , TpcNLayers(48) , ADCThreshold(2700) // electrons , TpcEnc(670) // electrons , Pedestal(50000) // electrons @@ -67,7 +67,7 @@ int PHG4TpcDigitizer::InitRun(PHCompositeNode *topNode) // The noise is by definition the RMS noise width voltage divided by ChargeToPeakVolts ADCNoiseConversionGain = ChargeToPeakVolts * 1.60e-04; // 20 (or 30) mV/fC * fC/electron - ADCThreshold_mV = ADCThreshold * ADCNoiseConversionGain; + ADCThreshold_mV = ADCThreshold * ADCNoiseConversionGain; //------------- // Add Hit Node @@ -152,8 +152,6 @@ void PHG4TpcDigitizer::CalculateCylinderCellADCScale(PHCompositeNode *topNode) void PHG4TpcDigitizer::DigitizeCylinderCells(PHCompositeNode *topNode) { - unsigned int print_layer = 18; // to print diagnostic output for layer 47 - // Digitizes the Tpc cells that were created in PHG4CylinderCellTpcReco // These contain as edep the number of electrons out of the GEM stack, distributed between Z bins by shaper response and ADC clock window // - i.e. all of the phi and Z bins in a cluster have edep values that add up to the primary charge in the layer times 2000 @@ -170,28 +168,28 @@ void PHG4TpcDigitizer::DigitizeCylinderCells(PHCompositeNode *topNode) // Thus a MIP produces a charge value out of the GEM stack of 64000/6.242x10^18 = 10.2 fC // SAMPA: - // See https://indico.cern.ch/event/489996/timetable/#all.detailed + // See https://indico.cern.ch/event/489996/timetable/#all.detailed // "SAMPA Chip: the New ASIC for the ALICE Tpc and MCH Upgrades", M Bregant // The SAMPA has a maximum output voltage of 2200 mV (but the pedestal is about 200 mV) // The SAMPA shaper is set to 80 ns peaking time // The ADC Digitizes the SAMPA shaper output into 1024 channels - // Conversion gains of 20 mV/fC or 30 mV/fC are possible - 1 fC charge input produces a peak voltage out of + // Conversion gains of 20 mV/fC or 30 mV/fC are possible - 1 fC charge input produces a peak voltage out of // the shaper of 20 or 30 mV // At 30 mV/fC, the input signal saturates at 2.2 V / 30 mV/fC = 73 fC (say 67 with pedestal not at zero) // At 20 mV/fC, the input signal saturates at 2.2 V / 20 mV/fC = 110 fC (say 100 fC with pedestal not at zero) - assume 20 mV/fC // The equivalent noise charge RMS at 20 mV/fC was measured (w/o detector capacitance) at 490 electrons - // - note: this appears to be just the pedestal RMS voltage spread divided by the conversion gain, so it is a bit of a + // - note: this appears to be just the pedestal RMS voltage spread divided by the conversion gain, so it is a bit of a // funny number (see below) // - it is better to think of noise and signal in terms of voltage at the input of the ADC // Bregant's slides say 670 electrons ENC for the full chip with 18 pf detector, as in ALICE - should use that number // Signal: - // To normalize the signal in each cell, take the entire charge on the pad and multiply by 20 mV/fC to get the adc + // To normalize the signal in each cell, take the entire charge on the pad and multiply by 20 mV/fC to get the adc // input AT THE PEAK of the shaper // The cell contents should thus be multipied by the normalization given by: // V_peak = Q_pad (electrons) * 1.6e-04 fC/electron * 20 mV/fC // From the sims, for 80 ns and 18.8 MHz, if we take the input charge and spread it a across the shaping time (which is how it has always been done, and is - // not the best way to think about it, because the ADC does not see charge it sees voltage out of a charge integrating + // not the best way to think about it, because the ADC does not see charge it sees voltage out of a charge integrating // preamp followed by a shaper), to get // the voltage at the ADC input right, then the values of Q_(pad,z) have to be scaled up by 2.4 // V_(pad,z) = 2.4 * Q_(pad,z) (electrons) * 1.6e-04 fC/electron * 20 mV/fC = Q_(pad,z) * 7.68e-03 (in mV) @@ -199,17 +197,17 @@ void PHG4TpcDigitizer::DigitizeCylinderCells(PHCompositeNode *topNode) // Remember that Q_(pad,z) is the GEM output charge // Noise: - // The ENC is defined as the RMS spread of the ADC pedestal distribution coming out from the SAMPA + // The ENC is defined as the RMS spread of the ADC pedestal distribution coming out from the SAMPA // divided by the corresponding conversion gain. // The full range of the ADC input is 2.2V (which will become 1024 adc counts, i.e. 1024 ADU's). // If you see the RMS of the pedestal in adc counts as 1 at the gain of 20mV/fC, the ENC would be defined by: // (2200 [mV]) * (1/1024) / (20[mV/fC]) / (1.6*10^-4 [fC]) = 671 [electrons] - // The RMS noise voltage would be: + // The RMS noise voltage would be: // V_RMS = ENC (electrons) *1.6e-04 fC/electron * 20 mV/fC = ENC (electrons) * 3.2e-03 (in mV) // The ADC readout would be: ADU = V_RMS * (1024 ADU / 2200 mV) = V_RMS * 0.465 // The cells that we need to digitize here contain as the energy "edep", which is the number of electrons out of the GEM stack - // distributed over the pads and ADC time bins according to the output time distribution of the SAMPA shaper + // distributed over the pads and ADC time bins according to the output time distribution of the SAMPA shaper // - not what really happens, see above // We convert to volts at the input to the ADC and add noise generated with the RMS value of the noise voltage at the ADC input // We assume the pedestal is zero, for simplicity, so the noise fluctuates above and below zero @@ -229,404 +227,101 @@ void PHG4TpcDigitizer::DigitizeCylinderCells(PHCompositeNode *topNode) } // Get the TrkrHitSetContainer node - TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + TrkrHitSetContainer *trkrhitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (!trkrhitsetcontainer) { - std::cout << "Could not locate TRKR_HITSET node, quit! " << std::endl; - exit(1); - } - - TrkrHitTruthAssoc *hittruthassoc = findNode::getClass(topNode, "TRKR_HITTRUTHASSOC"); - if (!hittruthassoc) - { - std::cout << PHWHERE << " Could not locate TRKR_HITTRUTHASSOC node, quit! " << std::endl; + std::cout << "Could not locate TRKR_HITSET_TPC node, quit! " << std::endl; exit(1); } - - //------------- // Digitization //------------- - // Loop over all TPC layers - for(unsigned int layer = TpcMinLayer; layer < TpcMinLayer+TpcNLayers; ++layer) - { - // we need the geometry object for this layer - PHG4TpcCylinderGeom *layergeom = geom_container->GetLayerCellGeom(layer); - if (!layergeom) exit(1); - - int nphibins = layergeom->get_phibins(); - if(Verbosity() > 1) - std::cout << " nphibins " << nphibins << std::endl; - - for(unsigned int side = 0; side < 2; ++side) - { - - if(Verbosity() > 1) - std::cout << "TPC layer " << layer << " side " << side << std::endl; - - // for this layer and side, use a vector of a vector of cells for each phibin - phi_sorted_hits.clear(); - for (int iphi = 0; iphi < nphibins; iphi++) - { - phi_sorted_hits.push_back(std::vector()); - } - - // Loop over all hitsets containing signals for this layer and add them to phi_sorted_hits for their phibin - TrkrHitSetContainer::ConstRange hitset_range = trkrhitsetcontainer->getHitSets(TrkrDefs::TrkrId::tpcId, layer); - for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range.first; - hitset_iter != hitset_range.second; - ++hitset_iter) - { - - // we have an iterator to one TrkrHitSet for the Tpc from the trkrHitSetContainer - // get the hitset key - TrkrDefs::hitsetkey hitsetkey = hitset_iter->first; - unsigned int this_side = TpcDefs::getSide(hitsetkey); - // skip this hitset if it is not on this side - if(this_side != side) continue; - - if (Verbosity() > 2) - if (layer == print_layer) - std::cout << "new: PHG4TpcDigitizer: processing signal hits for layer " << layer - << " hitsetkey " << hitsetkey << " side " << side << std::endl; - - // get all of the hits from this hitset - TrkrHitSet *hitset = hitset_iter->second; - TrkrHitSet::ConstRange hit_range = hitset->getHits(); - for (TrkrHitSet::ConstIterator hit_iter = hit_range.first; - hit_iter != hit_range.second; - ++hit_iter) - { - // Fill the vector of signal hits for each phibin - unsigned int phibin = TpcDefs::getPad(hit_iter->first); - phi_sorted_hits[phibin].push_back(hit_iter); - } - // For this hitset we now have the signal hits sorted into vectors for each phi - } - - // Process one phi bin at a time - if(Verbosity() > 1) std::cout << " phi_sorted_hits size " << phi_sorted_hits.size() << std::endl; - for (unsigned int iphi = 0; iphi < phi_sorted_hits.size(); iphi++) - { - // Make a fixed length vector to indicate whether each time bin is signal or noise - int ntbins = layergeom->get_zbins(); - is_populated.clear(); - is_populated.assign(ntbins, 2); // mark all as noise only, for now - - // add an empty vector of hits for each t bin - t_sorted_hits.clear(); - for (int it = 0; it < ntbins; it++) - { - t_sorted_hits.push_back(std::vector()); - } - - // add a signal hit from phi_sorted_hits for each t bin that has one - for (unsigned int it = 0; it < phi_sorted_hits[iphi].size(); it++) - { - int tbin = TpcDefs::getTBin(phi_sorted_hits[iphi][it]->first); - is_populated[tbin] = 1; // this bin is a associated with a hit - t_sorted_hits[tbin].push_back(phi_sorted_hits[iphi][it]); - - if (Verbosity() > 2) - if (layer == print_layer) - { - TrkrDefs::hitkey hitkey = phi_sorted_hits[iphi][it]->first; - std::cout << "iphi " << iphi << " adding existing signal hit to t vector for layer " << layer - << " side " << side - << " tbin " << tbin << " hitkey " << hitkey - << " pad " << TpcDefs::getPad(hitkey) - << " t bin " << TpcDefs::getTBin(hitkey) - << " energy " << (phi_sorted_hits[iphi][it]->second)->getEnergy() - << std::endl; - } - } - - adc_input.clear(); - adc_hitid.clear(); - // initialize entries to zero for each t bin - adc_input.assign(ntbins, 0.0); - adc_hitid.assign(ntbins, 0); - - // Now for this phibin we process all bins ordered by t into hits with noise - //====================================================== - // For this step we take the edep value and convert it to mV at the ADC input - // See comments above for how to do this for signal and noise - - for (int it = 0; it < ntbins; it++) - { - if (is_populated[it] == 1) - { - // This tbin has a hit, add noise - float signal_with_noise = add_noise_to_bin( (t_sorted_hits[it][0]->second)->getEnergy()) ; - adc_input[it] = signal_with_noise ; - adc_hitid[it] = t_sorted_hits[it][0]->first; - - if (Verbosity() > 2) - if (layer == print_layer) - std::cout << "existing signal hit: layer " << layer << " iphi " << iphi << " it " << it - << " edep " << (t_sorted_hits[it][0]->second)->getEnergy() - << " adc gain " << ADCSignalConversionGain - << " signal with noise " << signal_with_noise - << " adc_input " << adc_input[it] << std::endl; - } - else if (is_populated[it] == 2) - { - if(!skip_noise) - { - // This t bin does not have a filled cell, add noise - float noise = add_noise_to_bin(0.0); - adc_input[it]= noise; - adc_hitid[it] = 0; // there is no hit, just add a placeholder in the vector for now, replace it later - - if (Verbosity() > 2) - if (layer == print_layer) - std::cout << "noise hit: layer " << layer << " side " << side << " iphi " << iphi << " it " << it - << " adc gain " << ADCSignalConversionGain - << " noise " << noise - << " adc_input " << adc_input[it] << std::endl; - } - } - else - { - // Cannot happen - std::cout << "Impossible value of is_populated, it = " << it - << " is_populated = " << is_populated[it] << std::endl; - exit(-1); - } - } - - // Now we can digitize the entire stream of t bins for this phi bin - int binpointer = 0; - - // Since we now store the local z of the hit as time of arrival at the readout plane, - // there is no difference between north and south - // The first to arrive is always bin 0 - - for (int it = 0; it < ntbins; it++) - { - if (it < binpointer) continue; - - // optionally do not trigger on bins with no signal - if( (is_populated[it] == 2) && skip_noise) - { - binpointer++; - continue; - } - - // convert threshold in "equivalent electrons" to mV - if (adc_input[it] > ADCThreshold_mV) - { - // digitize this bin and the following 4 bins - - if (Verbosity() > 2) - if (layer == print_layer) - std::cout << std::endl - << "Hit above threshold of " - << ADCThreshold * ADCNoiseConversionGain << " for phibin " << iphi - << " it " << it << " with adc_input " << adc_input[it] - << " digitize this and 4 following bins: " << std::endl; - - for (int itup = 0; itup < 5; itup++) - { - if (it + itup < ntbins && it + itup >= 0) // stay within the bin limits - { - float input = 0; - if( (is_populated[it+itup] == 2) && skip_noise) - { - input = add_noise_to_bin(0.0); // no noise added to this bin previously because skip_noise is true - } - else - { - input = adc_input[it + itup]; - } - // input voltage x 1024 channels over 2200 mV max range - unsigned int adc_output = (unsigned int) (input * 1024.0 / 2200.0); - - if (input < 0) adc_output = 0; - if (input > 1023) adc_output = 1023; - - // Get the hitkey - TrkrDefs::hitkey hitkey = TpcDefs::genHitKey(iphi, it + itup); - TrkrHit *hit = nullptr; - - if (Verbosity() > 2) - if (layer == print_layer) - std::cout << " Digitizing: iphi " << iphi << " it+itup " << it + itup - << " adc_hitid " << adc_hitid[it + itup] - << " is_populated " << is_populated[it + itup] - << " adc_input " << adc_input[it + itup] - << " ADCThreshold " << ADCThreshold * ADCNoiseConversionGain - << " adc_output " << adc_output - << " hitkey " << hitkey - << " side " << side - << " binpointer " << binpointer - << std::endl; - - if (is_populated[it+itup] == 1) - { - // this is a signal hit, it already exists - hit = t_sorted_hits[it+itup][0]->second; // pointer valid only for signal hits - } - else - { - // Hit does not exist yet, have to make one - // we need the hitset key, requires (layer, sector, side) - unsigned int sector = 12 * iphi / nphibins; - TrkrDefs::hitsetkey hitsetkey = TpcDefs::genHitSetKey(layer, sector, side); - auto hitset_iter = trkrhitsetcontainer->findOrAddHitSet(hitsetkey); - - hit = new TrkrHitv2(); - hitset_iter->second->addHitSpecificKey(hitkey, hit); - - if (Verbosity() > 2) - if (layer == print_layer) - std::cout << " adding noise TrkrHit for iphi " << iphi - << " tbin " << it + itup - << " side " << side - << " created new hit with hitkey " << hitkey - << " energy " << adc_input[it + itup] << " adc " << adc_output - << " binpointer " << binpointer - << std::endl; - - } - - hit->setAdc(adc_output); - - } // end boundary check - binpointer++; // skip this bin in future - } // end itup loop - - } // adc threshold if - else - { - // set adc value to zero if there is a hit - // we need the hitset key, requires (layer, sector, side) - unsigned int sector = 12 * iphi / nphibins; - TrkrDefs::hitsetkey hitsetkey = TpcDefs::genHitSetKey(layer, sector, side); - auto hitset = trkrhitsetcontainer->findHitSet(hitsetkey); - if(hitset) - { - // Get the hitkey - TrkrDefs::hitkey hitkey = TpcDefs::genHitKey(iphi, it); - TrkrHit *hit = nullptr; - hit = hitset->getHit(hitkey); - if (hit) - { - hit->setAdc(0); - } - } - // bin below threshold, move on - binpointer++; - } // end adc threshold if/else - } // end time bin loop - } // end phibins loop - } // end loop over sides - } // end loop over TPC layers - - //====================================================== - if (Verbosity() > 5) + TrkrHitSetContainer::ConstRange hitset_range = trkrhitsetcontainer->getHitSets(); + for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range.first; + hitset_iter != hitset_range.second; + ++hitset_iter) + { + // we have an iterator to one TrkrHitSet for the Tpc from the trkrHitSetContainer + // get the hitset key + TrkrDefs::hitsetkey hitsetkey = hitset_iter->first; + + // get all of the hits from this hitset + TrkrHitSetTpc *hitset = dynamic_cast(hitset_iter->second); + + if (hitset == nullptr) { - std::cout << "From PHG4TpcDigitizer: hitsetcontainer dump at end before cleaning:" << std::endl; + std::cout << __PRETTY_FUNCTION__ << " : fatal error : hitset received is not a TrkrHitSetTpc with key " << hitsetkey << " and content "; + hitset_iter->second->identify(); } - std::vector> delete_hitkey_list; - - // Clean up undigitized hits - we want all hitsets for the Tpc - // This loop is pretty efficient because the remove methods all take a specified hitset as input - TrkrHitSetContainer::ConstRange hitset_range_now = trkrhitsetcontainer->getHitSets(TrkrDefs::TrkrId::tpcId); - for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range_now.first; - hitset_iter != hitset_range_now.second; - ++hitset_iter) + assert(hitset); + + if (Verbosity() > 2) { - // we have an iterator to one TrkrHitSet for the Tpc from the trkrHitSetContainer - TrkrDefs::hitsetkey hitsetkey = hitset_iter->first; const unsigned int layer = TrkrDefs::getLayer(hitsetkey); const int sector = TpcDefs::getSectorId(hitsetkey); const int side = TpcDefs::getSide(hitsetkey); - if (Verbosity() > 5) - std::cout << "PHG4TpcDigitizer: hitset with key: " << hitsetkey << " in layer " << layer << " with sector " << sector << " side " << side << std::endl; - - // get all of the hits from this hitset - TrkrHitSet *hitset = hitset_iter->second; - TrkrHitSet::ConstRange hit_range = hitset->getHits(); - for (TrkrHitSet::ConstIterator hit_iter = hit_range.first; - hit_iter != hit_range.second; - ++hit_iter) - { - TrkrDefs::hitkey hitkey = hit_iter->first; - TrkrHit *tpchit = hit_iter->second; - - if (Verbosity() > 5) - std::cout << " layer " << layer << " hitkey " << hitkey << " pad " << TpcDefs::getPad(hitkey) - << " t bin " << TpcDefs::getTBin(hitkey) - << " adc " << tpchit->getAdc() << std::endl; - - if (tpchit->getAdc() == 0) - { - if (Verbosity() > 20) - { - std::cout << " -- this hit not digitized - delete it" << std::endl; - } - // screws up the iterator to delete it here, store the hitkey for later deletion - delete_hitkey_list.push_back(std::make_pair(hitsetkey, hitkey)); - } - } - } - - // delete all undigitized hits - for (unsigned int i = 0; i < delete_hitkey_list.size(); i++) - { - TrkrHitSet *hitset = trkrhitsetcontainer->findHitSet(delete_hitkey_list[i].first); - const unsigned int layer = TrkrDefs::getLayer(delete_hitkey_list[i].first); - hitset->removeHit(delete_hitkey_list[i].second); - if (Verbosity() > 20) - if (layer == print_layer) - std::cout << "removed hit with hitsetkey " << delete_hitkey_list[i].first - << " and hitkey " << delete_hitkey_list[i].second << std::endl; - - // should also delete all entries with this hitkey from the TrkrHitTruthAssoc map - //hittruthassoc->removeAssoc(delete_hitkey_list[i].first, delete_hitkey_list[i].second); // Slow! Commented out by ADF 9/6/2022 + + std::cout << __PRETTY_FUNCTION__ << " Start processing hitsetkey " + << hitsetkey << " in layer " << layer << " with sector " << sector << " side " << side << std::endl; + hitset->identify(std::cout); } - - // Final hitset dump - if (Verbosity() > 5) - std::cout << "From PHG4TpcDigitizer: hitsetcontainer dump at end after cleaning:" << std::endl; - // We want all hitsets for the Tpc - TrkrHitSetContainer::ConstRange hitset_range_final = trkrhitsetcontainer->getHitSets(TrkrDefs::TrkrId::tpcId); - for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range_final.first; - hitset_iter != hitset_range_now.second; - ++hitset_iter) - { - // we have an itrator to one TrkrHitSet for the Tpc from the trkrHitSetContainer - TrkrDefs::hitsetkey hitsetkey = hitset_iter->first; - const unsigned int layer = TrkrDefs::getLayer(hitsetkey); - if (layer != print_layer) continue; - const int sector = TpcDefs::getSectorId(hitsetkey); - const int side = TpcDefs::getSide(hitsetkey); - if (Verbosity() > 5 && layer == print_layer) - std::cout << "PHG4TpcDigitizer: hitset with key: " << hitsetkey << " in layer " << layer << " with sector " << sector << " side " << side << std::endl; - // get all of the hits from this hitset - TrkrHitSet *hitset = hitset_iter->second; - TrkrHitSet::ConstRange hit_range = hitset->getHits(); - for (TrkrHitSet::ConstIterator hit_iter = hit_range.first; - hit_iter != hit_range.second; - ++hit_iter) + std::vector pass_zero_suppression; + + for (auto &t_sorted_hits : hitset->getTimeFrameAdcData()) { - TrkrDefs::hitkey hitkey = hit_iter->first; - TrkrHit *tpchit = hit_iter->second; - if (Verbosity() > 5) - std::cout << " LAYER " << layer << " hitkey " << hitkey << " pad " << TpcDefs::getPad(hitkey) << " t bin " << TpcDefs::getTBin(hitkey) - << " adc " << tpchit->getAdc() << std::endl; + // add noise + for (auto &adc_bin : t_sorted_hits) + { + adc_bin = static_cast(add_noise_to_bin((float) adc_bin)); + } - if (tpchit->getAdc() == 0) + // zero suppression + assert(m_nPostSample >= 1); + pass_zero_suppression.resize(t_sorted_hits.size(), false); + for (int i = 0; i < (int) t_sorted_hits.size(); ++i) { - std::cout << " Oops! -- this hit not digitized and not deleted!" << std::endl; + if (t_sorted_hits[i] > ADCThreshold_mV) + { + for (int j = i - m_nPreSample; j < i + (int) m_nPostSample; ++j) + { + if (j < 0) continue; + if (j >= (int) pass_zero_suppression.size()) continue; + + pass_zero_suppression[j] = true; + } + i += m_nPostSample - 1; + } } - } - } + for (unsigned int i = 0; i < t_sorted_hits.size(); ++i) + { + if (not pass_zero_suppression[i]) t_sorted_hits[i] = 0; + } + + // mV -> ADC + for (auto &adc_bin : t_sorted_hits) + { + // input voltage x 1024 channels over 2200 mV max range + adc_bin = static_cast(adc_bin * 1024.0 / 2200.0); + + if (adc_bin < 0) adc_bin = 0; + if (adc_bin > 1023) adc_bin = 1023; + } // for (auto & adc_bin : t_sorted_hits) - //hittruthassoc->identify(); + } // for (auto & t_sorted_hits : hitset->getTimeFrameAdcData()) + + if (Verbosity() > 2) + { + const unsigned int layer = TrkrDefs::getLayer(hitsetkey); + const int sector = TpcDefs::getSectorId(hitsetkey); + const int side = TpcDefs::getSide(hitsetkey); + + std::cout << __PRETTY_FUNCTION__ << " Finished processing hitsetkey " + << hitsetkey << " in layer " << layer << " with sector " << sector << " side " << side << std::endl; + hitset->identify(std::cout); + } + } // for (TrkrHitSetContainer::ConstIterator hitset_iter = hitset_range.first; return; } @@ -634,10 +329,10 @@ void PHG4TpcDigitizer::DigitizeCylinderCells(PHCompositeNode *topNode) float PHG4TpcDigitizer::add_noise_to_bin(float signal) { // add noise to the signal and return adc input voltage - float adc_input_voltage = signal * ADCSignalConversionGain; // mV, see comments above - float noise_voltage = ( Pedestal + added_noise() ) * ADCNoiseConversionGain; // mV - from definition of noise charge and pedestal charge + float adc_input_voltage = signal * ADCSignalConversionGain; // mV, see comments above + float noise_voltage = (Pedestal + added_noise()) * ADCNoiseConversionGain; // mV - from definition of noise charge and pedestal charge adc_input_voltage += noise_voltage; - + return adc_input_voltage; } @@ -647,3 +342,9 @@ float PHG4TpcDigitizer::added_noise() return noise; } + +void PHG4TpcDigitizer:: + SetTpcMinLayer(const int) +{ + std::cout << __PRETTY_FUNCTION__ << " is deprecated. Ignore this call" << std::endl; +} diff --git a/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.h b/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.h index 4faf8e9649..ba515da366 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.h +++ b/simulation/g4simulation/g4tpc/PHG4TpcDigitizer.h @@ -41,11 +41,15 @@ class PHG4TpcDigitizer : public SubsysReco _energy_scale.insert(std::make_pair(layer, energy_per_adc)); } - void SetTpcMinLayer(const int minlayer) { TpcMinLayer = minlayer; }; void SetADCThreshold(const float thresh) { ADCThreshold = thresh; }; void SetENC(const float enc) { TpcEnc = enc; }; void set_drift_velocity(float vd) {_drift_velocity = vd;} void set_skip_noise_flag(const bool skip) {skip_noise = skip;} + void set_nPreSample(unsigned int s) {m_nPreSample = s;} + void set_nPostSample(unsigned int s) {m_nPostSample = s;} + + //! Preserve old interface + void SetTpcMinLayer(const int minlayer); private: void CalculateCylinderCellADCScale(PHCompositeNode *topNode); @@ -53,8 +57,6 @@ class PHG4TpcDigitizer : public SubsysReco float added_noise(); float add_noise_to_bin(float signal); - unsigned int TpcMinLayer; - unsigned int TpcNLayers; float ADCThreshold; float ADCThreshold_mV = 0; float TpcEnc; @@ -64,16 +66,12 @@ class PHG4TpcDigitizer : public SubsysReco float ADCSignalConversionGain; float ADCNoiseConversionGain; + //! SAMPA zero-suppression digitization parameter + unsigned int m_nPreSample = 0; + unsigned int m_nPostSample = 5; bool skip_noise = false; - std::vector > phi_sorted_hits; - std::vector > t_sorted_hits; - - std::vector adc_input; - std::vector adc_hitid; - std::vector is_populated; - // settings std::map _max_adc; std::map _energy_scale; diff --git a/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.cc b/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.cc index 8b91ba1e03..b974e2ed29 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.cc +++ b/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.cc @@ -25,6 +25,8 @@ #include #include // for TVector3, operator* +#include +#include #include // for the speed of light @@ -171,6 +173,8 @@ PHG4TpcDirectLaser::PHG4TpcDirectLaser(const std::string& name) , PHParameterInterface(name) { InitializeParameters(); + theta_p = 0; + phi_p = 0; } //_____________________________________________________________ @@ -236,13 +240,29 @@ int PHG4TpcDirectLaser::InitRun(PHCompositeNode* topNode) SetupLasers(); // print configuration - std::cout << "PHG4TpcDirectLaser::InitRun - m_autoAdvanceDirectLaser: " << m_autoAdvanceDirectLaser << std::endl; - std::cout << "PHG4TpcDirectLaser::InitRun - phi steps: " << nPhiSteps << " min: " << minPhi << " max: " << maxPhi << std::endl; - std::cout << "PHG4TpcDirectLaser::InitRun - theta steps: " << nThetaSteps << " min: " << minTheta << " max: " << maxTheta << std::endl; - std::cout << "PHG4TpcDirectLaser::InitRun - nTotalSteps: " << nTotalSteps << std::endl; - + if(m_steppingpattern == true) + { + std::cout<< "PHG4TpcDirectLaser::InitRun - m_steppingpattern: " << m_steppingpattern << std::endl; + std::cout<< "PHG4TpcDirectLaser::InitRun - nTotalSteps: " << nTotalSteps << std::endl; + } + else + { + std::cout << "PHG4TpcDirectLaser::InitRun - m_autoAdvanceDirectLaser: " << m_autoAdvanceDirectLaser << std::endl; + std::cout << "PHG4TpcDirectLaser::InitRun - phi steps: " << nPhiSteps << " min: " << minPhi << " max: " << maxPhi << std::endl; + std::cout << "PHG4TpcDirectLaser::InitRun - theta steps: " << nThetaSteps << " min: " << minTheta << " max: " << maxTheta << std::endl; + std::cout << "PHG4TpcDirectLaser::InitRun - nTotalSteps: " << nTotalSteps << std::endl; + } std::cout << "PHG4TpcDirectLaser::InitRun - electrons_per_cm: " << electrons_per_cm << std::endl; std::cout << "PHG4TpcDirectLaser::InitRun - electrons_per_gev " << electrons_per_gev << std::endl; + + //TFile * infile1 = TFile::Open("theta_phi_laser.root"); + + std::string LASER_ANGLES_ROOTFILE = std::string(getenv("CALIBRATIONROOT")) + "/TPC/DirectLaser/theta_phi_laser.root"; + TFile* infile1 = TFile::Open(LASER_ANGLES_ROOTFILE.c_str()); + + pattern = (TNtuple*) infile1->Get("angles"); + pattern->SetBranchAddress("#theta",&theta_p); + pattern->SetBranchAddress("#phi",&phi_p); return Fun4AllReturnCodes::EVENT_OK; } @@ -266,10 +286,18 @@ int PHG4TpcDirectLaser::process_event(PHCompositeNode* topNode) { AimToNextPatternStep(); } + //_________________________________________________ + + else if (m_steppingpattern) + { + AimToNextPatternStep(); + } + + //_________________________________________________ else { // use arbitrary direction - AimToThetaPhi( arbitrary_theta, arbitrary_phi); + AimToThetaPhi(arbitrary_theta, arbitrary_phi); } return Fun4AllReturnCodes::EVENT_OK; @@ -329,7 +357,21 @@ void PHG4TpcDirectLaser::SetThetaStepping(int n, double min, double max) return; } +//_____________________________________________________________ +void PHG4TpcDirectLaser::SetFileStepping(int n) +{ + if (n < 0 || n > 13802) //13802 = hard coded number of tuple entries + { + std::cout << PHWHERE << " - invalid" << std::endl; + return; + } + nTotalSteps = n; + + return; +} + //_____________________________________________________________ + void PHG4TpcDirectLaser::SetupLasers() { // clear previous lasers @@ -361,21 +403,33 @@ void PHG4TpcDirectLaser::SetupLasers() laser.m_direction = 1; laser.m_phi = M_PI / 2 * i - (15 * M_PI/180); //additional offset of 15 deg. } + // rotate around z laser.m_position.RotateZ(laser.m_phi); // append - m_lasers.push_back(laser); + m_lasers.push_back(laser); //All lasers + // if(i==0) m_lasers.push_back(laser);//Only laser 1 + // if(i==3) m_lasers.push_back(laser);// Laser 4 + // if(i<4) m_lasers.push_back(laser);//Lasers 1, 2, 3, 4 } } - + //_____________________________________________________________ void PHG4TpcDirectLaser::AimToNextPatternStep() { if (nTotalSteps >= 1) { - AimToPatternStep(currentPatternStep); - ++currentPatternStep; + if (m_steppingpattern) + { + AimToPatternStep_File(currentPatternStep); + ++currentPatternStep; + } + else + { + AimToPatternStep(currentPatternStep); + ++currentPatternStep; + } } } @@ -422,7 +476,41 @@ void PHG4TpcDirectLaser::AimToPatternStep(int n) return; } -//_____________________________________________________________ +//_____________________________________________________________ + +void PHG4TpcDirectLaser::AimToPatternStep_File(int n) +{ + //trim against overflows + n = n % nTotalSteps; + + if (Verbosity()) + { + std::cout << "PHG4TpcDirectLaser::AimToPatternStep_File - step: " << n << "/" << nTotalSteps << std::endl; + } + + // store as current pattern + currentPatternStep = n; + + pattern->GetEntry(n); + + // calculate theta + std::cout << "From file, current entry = " << n << " Theta: " << theta_p <<" Phi: " << phi_p << std::endl; + + const double theta = theta_p*M_PI/180.; + + // calculate phi + const double phi = phi_p*M_PI/180.; + + + // generate laser tracks + AimToThetaPhi(theta, phi); + + return; +} + +//_____________________________________________________________ + + void PHG4TpcDirectLaser::AppendLaserTrack(double theta, double phi, const PHG4TpcDirectLaser::Laser& laser) { if (!m_g4hitcontainer) diff --git a/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.h b/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.h index 557c649dac..6cea75296e 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.h +++ b/simulation/g4simulation/g4tpc/PHG4TpcDirectLaser.h @@ -6,6 +6,7 @@ #include #include +#include #include #include // for string, allocator @@ -46,6 +47,10 @@ class PHG4TpcDirectLaser : public SubsysReco, public PHParameterInterface /// define steps along theta void SetThetaStepping(int n, double min, double max); + /// define steps for file + void SetFileStepping(int n); + + /// get total number of steps int GetNpatternSteps() const { @@ -64,6 +69,12 @@ class PHG4TpcDirectLaser : public SubsysReco, public PHParameterInterface m_autoAdvanceDirectLaser = value; }; + /// advance automatically through pattern from file + void SetDirectLaserPatternfromFile(bool value) + { + m_steppingpattern = value; + }; + void SetArbitraryThetaPhi(double theta, double phi) { arbitrary_theta = theta; @@ -81,6 +92,12 @@ class PHG4TpcDirectLaser : public SubsysReco, public PHParameterInterface /// aim lasers to a give step void AimToPatternStep(int n); + /// aim lasers to a give step from file + void AimToPatternStep_File(int n); + + float theta_p, phi_p; + TNtuple *pattern = nullptr; + /// aim to next step void AimToNextPatternStep(); @@ -141,6 +158,10 @@ class PHG4TpcDirectLaser : public SubsysReco, public PHParameterInterface /// set to true to change direct laser tracks from one event to the other bool m_autoAdvanceDirectLaser = false; + /// set to true to get stepping patern from file + bool m_steppingpattern = false; + + /// g4hit container PHG4HitContainer *m_g4hitcontainer = nullptr; diff --git a/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.cc b/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.cc index ff9f97dc42..414fc6fff6 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.cc +++ b/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.cc @@ -12,24 +12,24 @@ #include #include // for TrkrHit -#include #include +#include +#include #include // for TrkrHitTruthA... #include #include -#include -#include #include +#include +#include #include -#include #include #include -#include #include +#include #include // for PHParameterIn... #include @@ -86,7 +86,6 @@ namespace PHG4TpcElectronDrift::PHG4TpcElectronDrift(const std::string &name) : SubsysReco(name) , PHParameterInterface(name) - , temp_hitsetcontainer(new TrkrHitSetContainerv1) , single_hitsetcontainer(new TrkrHitSetContainerv1) { InitializeParameters(); @@ -129,19 +128,19 @@ int PHG4TpcElectronDrift::InitRun(PHCompositeNode *topNode) exit(1); } // new containers - hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET"); + hitsetcontainer = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (!hitsetcontainer) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TPC")); if (!DetNode) { - DetNode = new PHCompositeNode("TRKR"); + DetNode = new PHCompositeNode("TPC"); dstNode->addNode(DetNode); } - hitsetcontainer = new TrkrHitSetContainerv1; - auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET", "PHObject"); + hitsetcontainer = new TrkrHitSetContainerv2("TrkrHitSetTpcv1", 24 * 48 /*estimated number of TPC hitsets for pre-allocated memory*/); + auto newNode = new PHIODataNode(hitsetcontainer, "TRKR_HITSET_TPC", "PHObject"); DetNode->addNode(newNode); } @@ -201,7 +200,6 @@ int PHG4TpcElectronDrift::InitRun(PHCompositeNode *topNode) runNode->addNode(newNode); } - UpdateParametersWithMacro(); PHNodeIterator runIter(runNode); auto RunDetNode = dynamic_cast(runIter.findFirst("PHCompositeNode", detector)); @@ -261,7 +259,8 @@ int PHG4TpcElectronDrift::InitRun(PHCompositeNode *topNode) min_active_radius = get_double_param("min_active_radius"); max_active_radius = get_double_param("max_active_radius"); - if (Verbosity() > 0) { + if (Verbosity() > 0) + { std::cout << PHWHERE << " drift velocity " << drift_velocity << " extended_readout_time " << get_double_param("extended_readout_time") << " max time cutoff " << max_time << std::endl; } @@ -303,18 +302,19 @@ int PHG4TpcElectronDrift::InitRun(PHCompositeNode *topNode) padplane->InitRun(topNode); padplane->CreateReadoutGeometry(topNode, seggeo); + InitTrkrHitSets(); // print all layers radii if (Verbosity()) { - const auto range = seggeo->get_begin_end(); + const auto range = seggeo->get_begin_end(); std::cout << "PHG4TpcElectronDrift::InitRun - layers: " << std::distance(range.first, range.second) << std::endl; int counter = 0; for (auto layeriter = range.first; layeriter != range.second; ++layeriter) { const auto radius = layeriter->second->get_radius(); - std::cout << Form( "%.3f ", radius ); - if( ++counter == 8 ) + std::cout << Form("%.3f ", radius); + if (++counter == 8) { counter = 0; std::cout << std::endl; @@ -322,32 +322,133 @@ int PHG4TpcElectronDrift::InitRun(PHCompositeNode *topNode) } std::cout << std::endl; } - + return Fun4AllReturnCodes::EVENT_OK; } +void PHG4TpcElectronDrift::InitTrkrHitSets() +{ + assert(seggeo); + assert(padplane); + assert(hitsetcontainer); + + const int min_layer = padplane->get_minLayer(); + const int n_layer = padplane->get_nLayer(); + + for (int layer = min_layer; layer < min_layer + n_layer; ++layer) + { + assert(seggeo); + PHG4TpcCylinderGeom *layer_geometry = seggeo->GetLayerCellGeom(layer); + assert(layer_geometry); + + const int npad = layer_geometry->get_phibins() / TpcDefs::NSectors; + + for (int side = 0; side < TpcDefs::NSides; ++side) + { + for (int sector = 0; sector < TpcDefs::NSectors; ++sector) + { + TrkrDefs::hitsetkey node_hitsetkey = TpcDefs::genHitSetKey(layer, sector, side); + + // find or add this hitset on the node tree + TrkrHitSetContainer::Iterator node_hitsetit = hitsetcontainer->findOrAddHitSet(node_hitsetkey); + TrkrHitSetTpc *hitset = dynamic_cast(node_hitsetit->second); + assert(hitset); + assert(hitset->getHitSetKey() == node_hitsetkey); + + const int start_pad = sector * npad; + + // prepare hitset + if (Verbosity() > 100) + { + std::cout << __PRETTY_FUNCTION__ << "prepare hitset with key: " + << node_hitsetkey << " in layer " << layer + << " with sector " << sector << " side " << side << std::endl; + } + + // phi setup if needed + assert(hitset->getNPads() == 0); + if (Verbosity()) + { + std::cout << __PRETTY_FUNCTION__ << " npad is inconsistent, need to resize for temp_hitset with key: " + << node_hitsetkey << " in layer " << layer + << " with sector " << sector << " side " << side + << " : setNPads " << npad + << std::endl; + } + hitset->setNPads(npad); + + // start_pad setup if needed + if (Verbosity() > 100) + { + std::cout << __PRETTY_FUNCTION__ << " prepare hitset with key: " + << node_hitsetkey << " in layer " << layer + << " with sector " << sector << " side " << side + << " : setPadIndexStart " << start_pad + << std::endl; + } + hitset->setPadIndexStart(start_pad); + + // ntbin setup if needed + // TODO: using a x2 larger zbins to ensure fitting extended readout time. Reduce down when needed. + const int ntbin = layer_geometry->get_zbins() + 1; + const int start_tbin = side == 0 ? 0 : layer_geometry->get_zbins(); + assert(hitset->getNTBins() == 0); + if (Verbosity()) + { + std::cout << __PRETTY_FUNCTION__ << " prepare hitset with key: " + << node_hitsetkey << " in layer " << layer + << " with sector " << sector << " side " << side + << " : setTBins " << ntbin + << std::endl; + } + hitset->setNTBins(ntbin); + + // ntbin start_tbin if needed + if (Verbosity() > 100) + { + std::cout << __PRETTY_FUNCTION__ << " prepare hitset with key: " + << node_hitsetkey << " in layer " << layer + << " with sector " << sector << " side " << side + << " : setTBinIndexStart " << start_tbin + << std::endl; + } + hitset->setTBinIndexStart(start_tbin); + if (Verbosity() > 100) + { + std::cout << __PRETTY_FUNCTION__ << " done start_tbin hitset from node_hitsetkey = " << node_hitsetkey << ": "; + + hitset->identify(); + } + + } // for (int sector = 0; sector< TpcDefs::NSectors; ++sector) + + } // for (int side = 0; side < TpcDefs::NSides; ++side) + + } // for(int layer = min_layer; layer < min_layer + n_layer; ++layer) +} + int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) { + truth_track = nullptr; // track to which truth clusters are built + m_tGeometry = findNode::getClass(topNode, "ActsGeometry"); - if(!m_tGeometry) + if (!m_tGeometry) { std::cout << PHWHERE << "ActsGeometry not found on node tree. Exiting" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - if (truth_clusterer == nullptr) { - /* if (Verbosity()) std::cout << " truth clusterer was a null pointer " << std::endl; */ - truth_clusterer = new TpcClusterBuilder(truthclustercontainer, m_tGeometry, seggeo); - } else { - if (Verbosity()) std::cout << " truth clusterer was NOT a null pointer " << std::endl; + if (truth_clusterer.needs_input_nodes) { + truth_clusterer.set_input_nodes( truthclustercontainer, m_tGeometry, seggeo); } + if (Verbosity()>100) + { + std::cout << __PRETTY_FUNCTION__<< " entry. Current hitsetcontainer: " << std::endl; + hitsetcontainer->identify(); + } static constexpr unsigned int print_layer = 18; - truth_clusterer->is_embedded_track = false; - std::map hitset_cnt; // needed for indexing the TrkrClusters into the TrkrClusterContainer - /* std::map> truthtrack_hits; */ - // tells m_distortionMap which event to look at if (m_distortionMap) @@ -363,33 +464,30 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) gSystem->Exit(1); } PHG4TruthInfoContainer *truthinfo = - findNode::getClass(topNode, "G4TruthInfo"); + findNode::getClass(topNode, "G4TruthInfo"); m_tGeometry = findNode::getClass(topNode, "ActsGeometry"); - if(!m_tGeometry) - { - std::cout << PHWHERE - << "ActsGeometry not found on node tree. Exiting" - << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } + if (!m_tGeometry) + { + std::cout << PHWHERE + << "ActsGeometry not found on node tree. Exiting" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits(); unsigned int count_g4hits = 0; - // int count_electrons = 0; - - // double ecollectedhits = 0.0; - int ncollectedhits = 0; double ihit = 0; - unsigned int dump_interval = 5000; // dump temp_hitsetcontainer to the node tree after this many g4hits - unsigned int dump_counter = 0; int trkid = -1; + PHG4Hit* prior_g4hit = nullptr; // used to check for jumps in g4hits; + // if there is a big jump (such as crossing into the INTT area or out of the TPC) + // then cluster the truth clusters before adding a new hit. This prevents + // clustering loopers in the same HitSetKey surfaces in multiple passes for (auto hiter = hit_begin_end.first; hiter != hit_begin_end.second; ++hiter) { count_g4hits++; - dump_counter++; const double t0 = fmax(hiter->second->get_t(0), hiter->second->get_t(1)); if (t0 > max_time) @@ -400,24 +498,43 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) int trkid_new = hiter->second->get_trkid(); if (trkid != trkid_new) { // starting a new track - truth_clusterer->cluster_and_reset(/*argument is if to reset hitsetkey as well*/ false); + prior_g4hit = nullptr; + if (truth_track) truth_clusterer.cluster_hits(truth_track); trkid = trkid_new; - truth_clusterer->is_embedded_track = (truthinfo->isEmbeded(trkid)); - if (Verbosity() > 1000){ - std::cout << " New track " << trkid << " is embed? : " - << truth_clusterer->is_embedded_track << std::endl; + + if (Verbosity() > 1000) std::cout << " New track : " << trkid << " is embed? : "; + + if (truthinfo->isEmbeded(trkid)) { + truth_track = truthtracks->getTruthTrack(trkid, truthinfo); + truth_clusterer.b_collect_hits = true; + if (Verbosity() > 1000) { std::cout << " YES embedded" << std::endl; } + } else { + truth_track = nullptr; + truth_clusterer.b_collect_hits = false; + if (Verbosity() > 1000) { std::cout << " NOT embedded" << std::endl; } + } + } + + // see if there is a jump in x or y relative to previous PHG4Hit + if (truth_clusterer.b_collect_hits) { + if (prior_g4hit) { + // if the g4hits jump in x or y by > max_g4hit_jump, cluster the truth tracks + if ( std::abs(prior_g4hit->get_x(0)-hiter->second->get_x(0)) > max_g4hitstep + || std::abs(prior_g4hit->get_y(0)-hiter->second->get_y(0)) > max_g4hitstep + ) { + if(truth_track) { + truth_clusterer.cluster_hits(truth_track); + } + } } - if (truth_clusterer->is_embedded_track) - { // build new TrkrTruthTrack - current_track = truthtracks->getTruthTrack(trkid, truthinfo); - truth_clusterer->set_current_track(current_track); - } + prior_g4hit = hiter->second; } + // for very high occupancy events, accessing the TrkrHitsets on the node tree // for every drifted electron seems to be very slow - // Instead, use a temporary map to accumulate the charge from all + // Instead, use a temporary map to accumulate the charge from all // drifted electrons, then copy to the node tree later - + double eion = hiter->second->get_eion(); unsigned int n_electrons = gsl_ran_poisson(RandomGenerator.get(), eion * electrons_per_gev); // count_electrons += n_electrons; @@ -425,26 +542,27 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) if (Verbosity() > 100) std::cout << " new hit with t0, " << t0 << " g4hitid " << hiter->first << " eion " << eion << " n_electrons " << n_electrons - << " entry z " << hiter->second->get_z(0) << " exit z " - << hiter->second->get_z(1) << " avg z" + << " entry z " << hiter->second->get_z(0) << " exit z " + << hiter->second->get_z(1) << " avg z" << (hiter->second->get_z(0) + hiter->second->get_z(1)) / 2.0 << std::endl; - if (n_electrons == 0) { continue; } + if (n_electrons == 0) + { + continue; + } if (Verbosity() > 100) { std::cout << std::endl - << "electron drift: g4hit " << hiter->first << " created electrons: " + << "electron drift: g4hit " << hiter->first << " created electrons: " << n_electrons << " from " << eion * 1000000 << " keV" << std::endl; - std::cout << " entry x,y,z = " << hiter->second->get_x(0) << " " + std::cout << " entry x,y,z = " << hiter->second->get_x(0) << " " << hiter->second->get_y(0) << " " << hiter->second->get_z(0) - << " radius " << sqrt(pow(hiter->second->get_x(0), 2) + - pow(hiter->second->get_y(0), 2)) << std::endl; - std::cout << " exit x,y,z = " << hiter->second->get_x(1) << " " + << " radius " << sqrt(pow(hiter->second->get_x(0), 2) + pow(hiter->second->get_y(0), 2)) << std::endl; + std::cout << " exit x,y,z = " << hiter->second->get_x(1) << " " << hiter->second->get_y(1) << " " << hiter->second->get_z(1) - << " radius " << sqrt(pow(hiter->second->get_x(1), 2) + - pow(hiter->second->get_y(1), 2)) << std::endl; + << " radius " << sqrt(pow(hiter->second->get_x(1), 2) + pow(hiter->second->get_y(1), 2)) << std::endl; } for (unsigned int i = 0; i < n_electrons; i++) @@ -521,15 +639,15 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) { const double phi_final_nodiff = phistart + phi_distortion; const double rad_final_nodiff = radstart + r_distortion; - deltarnodiff->Fill(radstart, rad_final_nodiff - radstart); //delta r no diffusion, just distortion - deltaphinodiff->Fill(phistart, phi_final_nodiff - phistart); //delta phi no diffusion, just distortion + deltarnodiff->Fill(radstart, rad_final_nodiff - radstart); // delta r no diffusion, just distortion + deltaphinodiff->Fill(phistart, phi_final_nodiff - phistart); // delta phi no diffusion, just distortion deltaphivsRnodiff->Fill(radstart, phi_final_nodiff - phistart); deltaRphinodiff->Fill(radstart, rad_final_nodiff * phi_final_nodiff - radstart * phistart); // Fill Diagnostic plots, written into ElectronDriftQA.root hitmapstart->Fill(x_start, y_start); // G4Hit starting positions - hitmapend->Fill(x_final, y_final); //INcludes diffusion and distortion - deltar->Fill(radstart, rad_final - radstart); //total delta r + hitmapend->Fill(x_final, y_final); // INcludes diffusion and distortion + deltar->Fill(radstart, rad_final - radstart); // total delta r deltaphi->Fill(phistart, phi_final - phistart); // total delta phi deltaz->Fill(z_start, z_distortion); // map of distortion in Z (time) } @@ -537,7 +655,9 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) // remove electrons outside of our acceptance. Careful though, electrons from just inside 30 cm can contribute in the 1st active layer readout, so leave a little margin if (rad_final < min_active_radius - 2.0 || rad_final > max_active_radius + 1.0) - { continue; } + { + continue; + } if (Verbosity() > 1000) { @@ -552,9 +672,9 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) << std::endl; std::cout << " rad_final " << rad_final << " x_final " << x_final - << " y_final " << y_final - << " z_final " << z_final << " t_final " << t_final - << " zdiff " << z_final - z_start << std::endl; + << " y_final " << y_final + << " z_final " << z_final << " t_final " << t_final + << " zdiff " << z_final - z_start << std::endl; } if (Verbosity() > 0) @@ -562,10 +682,9 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) assert(nt); nt->Fill(ihit, t_start, t_final, t_sigma, rad_final, z_start, z_final); } - // this fills the cells and updates the hits in temp_hitsetcontainer for this drifted electron hitting the GEM stack padplane->MapToPadPlane(truth_clusterer, single_hitsetcontainer.get(), - temp_hitsetcontainer.get(), hittruthassoc, x_final, y_final, t_final, - side, hiter, ntpad, nthit); + hitsetcontainer, hittruthassoc, x_final, y_final, t_final, + side, hiter, ntpad, nthit); } // end loop over electrons for this g4hit TrkrHitSetContainer::ConstRange single_hitset_range = single_hitsetcontainer->getHitSets(TrkrDefs::TrkrId::tpcId); @@ -597,83 +716,14 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) } } - // Dump the temp_hitsetcontainer to the node tree and reset it - // - after every "dump_interval" g4hits - // - if this is the last g4hit - if (dump_counter >= dump_interval || count_g4hits == g4hit->size()) - { - //std::cout << " dump_counter " << dump_counter << " count_g4hits " << count_g4hits << std::endl; - - double eg4hit = 0.0; - TrkrHitSetContainer::ConstRange temp_hitset_range = temp_hitsetcontainer->getHitSets(TrkrDefs::TrkrId::tpcId); - for (TrkrHitSetContainer::ConstIterator temp_hitset_iter = temp_hitset_range.first; - temp_hitset_iter != temp_hitset_range.second; - ++temp_hitset_iter) - { - // we have an itrator to one TrkrHitSet for the Tpc from the temp_hitsetcontainer - TrkrDefs::hitsetkey node_hitsetkey = temp_hitset_iter->first; - const unsigned int layer = TrkrDefs::getLayer(node_hitsetkey); - const int sector = TpcDefs::getSectorId(node_hitsetkey); - const int side = TpcDefs::getSide(node_hitsetkey); - if (Verbosity() > 100) - std::cout << "PHG4TpcElectronDrift: temp_hitset with key: " << node_hitsetkey << " in layer " << layer - << " with sector " << sector << " side " << side << std::endl; - - // find or add this hitset on the node tree - TrkrHitSetContainer::Iterator node_hitsetit = hitsetcontainer->findOrAddHitSet(node_hitsetkey); - - // get all of the hits from the temporary hitset - TrkrHitSet::ConstRange temp_hit_range = temp_hitset_iter->second->getHits(); - for (TrkrHitSet::ConstIterator temp_hit_iter = temp_hit_range.first; - temp_hit_iter != temp_hit_range.second; - ++temp_hit_iter) - { - TrkrDefs::hitkey temp_hitkey = temp_hit_iter->first; - TrkrHit *temp_tpchit = temp_hit_iter->second; - if (Verbosity() > 10 && layer == print_layer) - { - std::cout << " temp_hitkey " << temp_hitkey << " layer " << layer << " pad " << TpcDefs::getPad(temp_hitkey) - << " z bin " << TpcDefs::getTBin(temp_hitkey) - << " energy " << temp_tpchit->getEnergy() << " eg4hit " << eg4hit << std::endl; - - eg4hit += temp_tpchit->getEnergy(); - // ecollectedhits += temp_tpchit->getEnergy(); - ncollectedhits++; - } - - // find or add this hit to the node tree - TrkrHit *node_hit = node_hitsetit->second->getHit(temp_hitkey); - if (!node_hit) - { - // Otherwise, create a new one - node_hit = new TrkrHitv2(); - node_hitsetit->second->addHitSpecificKey(temp_hitkey, node_hit); - } - - // Either way, add the energy to it - node_hit->addEnergy(temp_tpchit->getEnergy()); - - } // end loop over temp hits - - if (Verbosity() > 100 && layer == print_layer) - std::cout << " ihit " << ihit << " collected energy = " << eg4hit << std::endl; - - } // end loop over temp hitsets - - // erase all entries in the temp hitsetcontainer - temp_hitsetcontainer->Reset(); - - // reset the dump counter - dump_counter = 0; - } // end copy of temp hitsetcontainer to node tree hitsetcontainer - ++ihit; single_hitsetcontainer->Reset(); } // end loop over g4hits - truth_clusterer->cluster_and_reset(/*argument is if to reset hitsetkey as well*/ true); + if (truth_track) truth_clusterer.cluster_hits(truth_track); + truth_clusterer.clear_hitsetkey_cnt(); if (Verbosity() > 20) { @@ -695,16 +745,7 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) // get all of the hits from this hitset TrkrHitSet *hitset = hitset_iter->second; - TrkrHitSet::ConstRange hit_range = hitset->getHits(); - for (TrkrHitSet::ConstIterator hit_iter = hit_range.first; - hit_iter != hit_range.second; - ++hit_iter) - { - TrkrDefs::hitkey hitkey = hit_iter->first; - TrkrHit *tpchit = hit_iter->second; - std::cout << " hitkey " << hitkey << " pad " << TpcDefs::getPad(hitkey) << " z bin " << TpcDefs::getTBin(hitkey) - << " energy " << tpchit->getEnergy() << std::endl; - } + hitset->identify(std::cout); } } @@ -718,15 +759,15 @@ int PHG4TpcElectronDrift::process_event(PHCompositeNode *topNode) ++event_num; // if doing more than one event, event_num will be incremented. - if (Verbosity() > 500) + if (Verbosity() > 500) { std::cout << " TruthTrackContainer results at end of event in PHG4TpcElectronDrift::process_event " << std::endl; truthtracks->identify(); } if (Verbosity()>800) { - truth_clusterer->print(truthtracks); - truth_clusterer->print_file(truthtracks,"drift_clusters.txt"); + truth_clusterer.print(truthtracks); + truth_clusterer.print_file(truthtracks,"drift_clusters.txt"); } return Fun4AllReturnCodes::EVENT_OK; @@ -796,8 +837,8 @@ void PHG4TpcElectronDrift::SetDefaultParameters() set_default_double_param("min_active_radius", 30.); // cm set_default_double_param("max_active_radius", 78.); // cm set_default_double_param("drift_velocity", 8.0 / 1000.0); // cm/ns - set_default_double_param("max_time", 13200.); //ns - set_default_double_param("extended_readout_time", 7000.); //ns + set_default_double_param("max_time", 13200.); // ns + set_default_double_param("extended_readout_time", 7000.); // ns // These are purely fudge factors, used to increase the resolution to 150 microns and 500 microns, respectively // override them from the macro to get a different resolution @@ -807,10 +848,6 @@ void PHG4TpcElectronDrift::SetDefaultParameters() return; } -PHG4TpcElectronDrift::~PHG4TpcElectronDrift() { - if (truth_clusterer != nullptr) delete truth_clusterer; -} - void PHG4TpcElectronDrift::setTpcDistortion(PHG4TpcDistortion *distortionMap) { m_distortionMap.reset(distortionMap); diff --git a/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.h b/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.h index 4d3f6ff183..9f6e645ce1 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.h +++ b/simulation/g4simulation/g4tpc/PHG4TpcElectronDrift.h @@ -1,9 +1,10 @@ // Tell emacs that this is a C++ source // -*- C++ -*-. - #ifndef G4TPC_PHG4TPCELECTRONDRIFT_H #define G4TPC_PHG4TPCELECTRONDRIFT_H +#include "TpcClusterBuilder.h" + #include #include #include @@ -35,12 +36,14 @@ class PHG4TpcElectronDrift : public SubsysReco, public PHParameterInterface { public: PHG4TpcElectronDrift(const std::string &name = "PHG4TpcElectronDrift"); - ~PHG4TpcElectronDrift() override; + ~PHG4TpcElectronDrift() override { }; int Init(PHCompositeNode *) override; int InitRun(PHCompositeNode *) override; int process_event(PHCompositeNode *) override; int End(PHCompositeNode *) override; + void InitTrkrHitSets(); + void SetDefaultParameters() override; //! detector name @@ -64,7 +67,13 @@ class PHG4TpcElectronDrift : public SubsysReco, public PHParameterInterface //! setup readout plane void registerPadPlane(PHG4TpcPadPlane *padplane); + // cluster the PHG4Tracks individually + TpcClusterBuilder truth_clusterer {}; + void set_pixel_thresholdrat (double val) { truth_clusterer.set_pixel_thresholdrat(val); }; + void set_max_g4hitstep (float _) { max_g4hitstep =_; }; + private: + float max_g4hitstep { 7. }; //! map a given x,y,z coordinates to plane hits /* TpcClusterBuilder MapToPadPlane(const double x, const double y, const */ /* double z, const unsigned int side, PHG4HitContainer::ConstIterator hiter, */ @@ -75,9 +84,8 @@ class PHG4TpcElectronDrift : public SubsysReco, public PHParameterInterface TrkrHitSetContainer *hitsetcontainer = nullptr; TrkrHitTruthAssoc *hittruthassoc = nullptr; TrkrTruthTrackContainer *truthtracks = nullptr; - TrkrTruthTrack *current_track = nullptr; + TrkrTruthTrack *truth_track = nullptr; TrkrClusterContainer *truthclustercontainer = nullptr; // the TrkrClusterContainer for truth clusters - std::unique_ptr temp_hitsetcontainer; std::unique_ptr single_hitsetcontainer; std::unique_ptr padplane; @@ -130,12 +138,6 @@ class PHG4TpcElectronDrift : public SubsysReco, public PHParameterInterface double min_time = NAN; double max_time = NAN; - - /* std::array layer_clusterers; // Generate TrkrClusterv4's for TrkrTruthTracks */ - TpcClusterBuilder* truth_clusterer { nullptr }; - - /* void buildTruthClusters(std::map&); */ - //! rng de-allocator class Deleter { diff --git a/simulation/g4simulation/g4tpc/PHG4TpcPadBaselineShift.cc b/simulation/g4simulation/g4tpc/PHG4TpcPadBaselineShift.cc index d0f3c4461c..f8f793afd6 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcPadBaselineShift.cc +++ b/simulation/g4simulation/g4tpc/PHG4TpcPadBaselineShift.cc @@ -183,10 +183,10 @@ int PHG4TpcPadBaselineShift::process_event(PHCompositeNode *topNode) } // get node containing the digitized hits - m_hits = findNode::getClass(topNode, "TRKR_HITSET"); + m_hits = findNode::getClass(topNode, "TRKR_HITSET_TPC"); if (!m_hits) { - std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; + std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET_TPC" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } diff --git a/simulation/g4simulation/g4tpc/PHG4TpcPadPlane.h b/simulation/g4simulation/g4tpc/PHG4TpcPadPlane.h index ac8b7ccda3..3319dbc970 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcPadPlane.h +++ b/simulation/g4simulation/g4tpc/PHG4TpcPadPlane.h @@ -33,9 +33,12 @@ class PHG4TpcPadPlane : public SubsysReco, public PHParameterInterface virtual int CreateReadoutGeometry(PHCompositeNode * /*topNode*/, PHG4TpcCylinderGeomContainer * /*seggeo*/) { return 0; } virtual void UpdateInternalParameters() { return; } // virtual void MapToPadPlane(PHG4CellContainer * /*g4cells*/, const double /*x_gem*/, const double /*y_gem*/, const double /*t_gem*/, const unsigned int /*side*/, PHG4HitContainer::ConstIterator /*hiter*/, TNtuple * /*ntpad*/, TNtuple * /*nthit*/) {} - virtual void MapToPadPlane(TpcClusterBuilder* /*builder*/, TrkrHitSetContainer * /*single_hitsetcontainer*/, TrkrHitSetContainer * /*hitsetcontainer*/, TrkrHitTruthAssoc * /*hittruthassoc*/, const double /*x_gem*/, const double /*y_gem*/, const double /*t_gem*/, const unsigned int /*side*/, PHG4HitContainer::ConstIterator /*hiter*/, TNtuple * /*ntpad*/, TNtuple * /*nthit*/)=0;// { return {}; } + virtual void MapToPadPlane(TpcClusterBuilder& /*builder*/, TrkrHitSetContainer * /*single_hitsetcontainer*/, TrkrHitSetContainer * /*hitsetcontainer*/, TrkrHitTruthAssoc * /*hittruthassoc*/, const double /*x_gem*/, const double /*y_gem*/, const double /*t_gem*/, const unsigned int /*side*/, PHG4HitContainer::ConstIterator /*hiter*/, TNtuple * /*ntpad*/, TNtuple * /*nthit*/)=0;// { return {}; } void Detector(const std::string &name) { detector = name; } + virtual int get_minLayer() {return 0;} + virtual int get_nLayer() {return 0;} + protected: std::string detector; }; diff --git a/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.cc b/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.cc index af41b9d117..d6d83d5433 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.cc +++ b/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.cc @@ -7,7 +7,6 @@ #include // for PHG4Hit #include - #include // Move to new storage containers @@ -16,24 +15,28 @@ #include // for TrkrHit #include #include +#include #include // for TrkrHit #include -#include #include #include +#include #include // for PHWHERE #include +#include #include #include // for gsl_rng_alloc +#include #include #include #include // for _Rb_tree_cons... #include // for pair +#include // for getenv class PHCompositeNode; class TrkrHitTruthAssoc; @@ -60,9 +63,12 @@ PHG4TpcPadPlaneReadout::PHG4TpcPadPlaneReadout(const std::string &name) : PHG4TpcPadPlane(name) { InitializeParameters(); - + //if(m_flagToUseGain==1) + ReadGain(); RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937); gsl_rng_set(RandomGenerator, PHRandomSeed()); // fixed seed is handled in this funtcion + h_gain[0] = nullptr; + h_gain[1] = nullptr; return; } @@ -70,6 +76,8 @@ PHG4TpcPadPlaneReadout::PHG4TpcPadPlaneReadout(const std::string &name) PHG4TpcPadPlaneReadout::~PHG4TpcPadPlaneReadout() { gsl_rng_free(RandomGenerator); + delete h_gain[0]; + delete h_gain[1]; } int PHG4TpcPadPlaneReadout::CreateReadoutGeometry(PHCompositeNode * /*topNode*/, PHG4TpcCylinderGeomContainer *seggeo) @@ -78,42 +86,46 @@ int PHG4TpcPadPlaneReadout::CreateReadoutGeometry(PHCompositeNode * /*topNode*/, for (int iregion = 0; iregion < 3; ++iregion) { - //int zside = 0; - for (int zside = 0; zside < 2;zside++){ + // int zside = 0; + for (int zside = 0; zside < 2; zside++) + { sector_R_bias[zside].clear(); sector_Phi_bias[zside].clear(); sector_min_Phi[zside].clear(); sector_max_Phi[zside].clear(); sector_min_Phi_sectors[zside][iregion].clear(); sector_max_Phi_sectors[zside][iregion].clear(); - //int eff_layer = 0; - for (int isector = 0; isector < NSectors; ++isector)//12 sectors + // int eff_layer = 0; + for (int isector = 0; isector < NSectors; ++isector) // 12 sectors { sector_R_bias[zside].push_back(dR[zside][isector][iregion]); sector_Phi_bias[zside].push_back(dPhi[zside][isector][iregion]); - - double sec_gap = (2*M_PI - SectorPhi[iregion]*12)/12; - double sec_max_phi = M_PI - SectorPhi[iregion]/2 - sec_gap - 2 * M_PI / 12 * isector;// * (isector+1) ; + + double sec_gap = (2 * M_PI - SectorPhi[iregion] * 12) / 12; + double sec_max_phi = M_PI - SectorPhi[iregion] / 2 - sec_gap - 2 * M_PI / 12 * isector; // * (isector+1) ; double sec_min_phi = sec_max_phi - SectorPhi[iregion]; sector_min_Phi[zside].push_back(sec_min_phi); sector_max_Phi[zside].push_back(sec_max_phi); sector_min_Phi_sectors[zside][iregion].push_back(sec_min_phi); sector_max_Phi_sectors[zside][iregion].push_back(sec_max_phi); - - }// isector + + } // isector } double sum_r = 0; for (int layer = MinLayer[iregion]; layer < MinLayer[iregion] + NTpcLayers[iregion]; ++layer) - { + { double r_length = Thickness[iregion]; - if(iregion == 0 && layer>0){ - if(layer%2==0) r_length = Thickness[4]; - else r_length = Thickness[3]; + if (iregion == 0 && layer > 0) + { + if (layer % 2 == 0) + r_length = Thickness[4]; + else + r_length = Thickness[3]; } sum_r += r_length; - } - double pad_space = (MaxRadius[iregion] - MinRadius[iregion] - sum_r)/(NTpcLayers[iregion]-1); + } + double pad_space = (MaxRadius[iregion] - MinRadius[iregion] - sum_r) / (NTpcLayers[iregion] - 1); double current_r = MinRadius[iregion]; for (int layer = MinLayer[iregion]; layer < MinLayer[iregion] + NTpcLayers[iregion]; ++layer) @@ -130,16 +142,19 @@ int PHG4TpcPadPlaneReadout::CreateReadoutGeometry(PHCompositeNode * /*topNode*/, PHG4TpcCylinderGeom *layerseggeo = new PHG4TpcCylinderGeom(); layerseggeo->set_layer(layer); - //layerseggeo->set_radius(MinRadius[iregion] + ((double) (layer - MinLayer[iregion]) + 0.5) * Thickness[iregion]); - //layerseggeo->set_thickness(Thickness[iregion]); + // layerseggeo->set_radius(MinRadius[iregion] + ((double) (layer - MinLayer[iregion]) + 0.5) * Thickness[iregion]); + // layerseggeo->set_thickness(Thickness[iregion]); double r_length = Thickness[iregion]; - if(iregion == 0 && layer>0){ - if(layer%2==0) r_length = Thickness[4]; - else r_length = Thickness[3]; + if (iregion == 0 && layer > 0) + { + if (layer % 2 == 0) + r_length = Thickness[4]; + else + r_length = Thickness[3]; } layerseggeo->set_thickness(r_length); - layerseggeo->set_radius(current_r+r_length/2); + layerseggeo->set_radius(current_r + r_length / 2); layerseggeo->set_binning(PHG4CellDefs::sizebinning); layerseggeo->set_zbins(NTBins); layerseggeo->set_zmin(MinT); @@ -182,13 +197,13 @@ double PHG4TpcPadPlaneReadout::getSingleEGEMAmplification() // for the single electron gain distribution - // and yes, the parameter you're looking for is of course the slope, which is the inverse gain. double nelec = gsl_ran_exponential(RandomGenerator, averageGEMGain); + // Put gain reading here return nelec; } - void PHG4TpcPadPlaneReadout::MapToPadPlane( - TpcClusterBuilder *tpc_truth_clusterer, + TpcClusterBuilder &tpc_truth_clusterer, TrkrHitSetContainer *single_hitsetcontainer, TrkrHitSetContainer *hitsetcontainer, TrkrHitTruthAssoc * /*hittruthassoc*/, @@ -205,24 +220,29 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( rad_gem = sqrt(x_gem * x_gem + y_gem * y_gem); - // Moving electrons from dead area to a closest pad + // Moving electrons from dead area to a closest pad for (int iregion = 0; iregion < 3; ++iregion) { - double daR = 0; - if(iregion==0 || iregion==2){ - daR=1.0;//1.0cm edge to collect electrons from - }else{ - daR = MinRadius[iregion]-MaxRadius[iregion-1]; + double daR = 0; + if (iregion == 0 || iregion == 2) + { + daR = 1.0; // 1.0cm edge to collect electrons from + } + else + { + daR = MinRadius[iregion] - MaxRadius[iregion - 1]; } - if ( rad_gem <= MinRadius[iregion] && rad_gem >= MinRadius[iregion]-daR){ - if( rad_gem <= MinRadius[iregion]-daR/2){ - rad_gem = MinRadius[iregion] - (1.1*daR) ; - }else{ - rad_gem = MinRadius[iregion] + 0.1*daR; + if (rad_gem <= MinRadius[iregion] && rad_gem >= MinRadius[iregion] - daR) + { + if (rad_gem <= MinRadius[iregion] - daR / 2) + { + rad_gem = MinRadius[iregion] - (1.1 * daR); + } + else + { + rad_gem = MinRadius[iregion] + 0.1 * daR; } - } - } phi = check_phi(side, phi, rad_gem); @@ -236,7 +256,7 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( layeriter != layerrange.second; ++layeriter) { - double rad_low = layeriter->second->get_radius() - layeriter->second->get_thickness() / 2.0; + double rad_low = layeriter->second->get_radius() - layeriter->second->get_thickness() / 2.0; double rad_high = layeriter->second->get_radius() + layeriter->second->get_thickness() / 2.0; if (rad_gem > rad_low && rad_gem < rad_high) @@ -251,7 +271,6 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( << " layer " << hiter->second->get_layer() << " want to change to " << layernum << std::endl; hiter->second->set_layer(layernum); // have to set here, since the stepping action knows nothing about layers } - } if (layernum == 0) @@ -263,7 +282,7 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( const auto phibins = LayerGeom->get_phibins(); /* pass_data.nphibins = phibins; */ - const auto tbins = LayerGeom->get_zbins(); + const auto tbins = LayerGeom->get_zbins(); // Create the distribution function of charge on the pad plane around the electron position @@ -276,6 +295,13 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( //=============================== double nelec = getSingleEGEMAmplification(); + // Applying weight with respect to the rad_gem and phi after electrons are redistributed + double phi_gain = phi; + if(phi<0)phi_gain += 2*M_PI; + double gain_weight = 1.0; + if(m_flagToUseGain==1) gain_weight = h_gain[side]->GetBinContent(h_gain[side]->FindBin(rad_gem*10,phi_gain));//rad_gem in cm -> *10 to get mm + nelec = nelec*gain_weight; + //std::cout<<"PHG4TpcPadPlaneReadout::MapToPadPlane gain_weight = "<= tbins) std::cout << " Error making key: adc_tbin " << tbin_num << " ntbins " << tbins << std::endl; + if (tbin_num >= tbins) std::cout << " Error making key: adc_tbin " << tbin_num << " ntbins " << tbins << std::endl; if (pad_num >= phibins) std::cout << " Error making key: pad_phibin " << pad_num << " nphibins " << phibins << std::endl; // collect information to do simple clustering. Checks operation of PHG4CylinderCellTpcReco, and // is also useful for comparison with PHG4TpcClusterizer result when running single track events. // The only information written to the cell other than neffelectrons is tbin and pad number, so get those from geometry - double tcenter = LayerGeom->get_zcenter(tbin_num); + double tcenter = LayerGeom->get_zcenter(tbin_num); double phicenter = LayerGeom->get_phicenter(pad_num); phi_integral += phicenter * neffelectrons; - t_integral += tcenter * neffelectrons; + t_integral += tcenter * neffelectrons; weight += neffelectrons; if (Verbosity() > 1 && layernum == print_layer) std::cout << " tbin_num " << tbin_num << " tcenter " << tcenter << " pad_num " << pad_num << " phicenter " << phicenter @@ -382,25 +408,56 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( unsigned int pads_per_sector = phibins / 12; unsigned int sector = pad_num / pads_per_sector; TrkrDefs::hitsetkey hitsetkey = TpcDefs::genHitSetKey(layernum, sector, side); + + assert(hitsetcontainer->findHitSet(hitsetkey)); // expect all TPC hitset are pre-allocated and initialized + // Use existing hitset or add new one if needed TrkrHitSetContainer::Iterator hitsetit = hitsetcontainer->findOrAddHitSet(hitsetkey); TrkrHitSetContainer::Iterator single_hitsetit = single_hitsetcontainer->findOrAddHitSet(hitsetkey); + // TrkrHitSetTpc hit update + TrkrHitSetTpc *hitset = dynamic_cast(hitsetit->second); + assert(hitset); + assert(hitset->getHitSetKey() == hitsetkey); + + if (Verbosity() > 1000) + { + std::cout << __PRETTY_FUNCTION__ << " prepare hitset with hitsetkey " << hitsetkey + << " layer " << layernum << "|" << (int) TrkrDefs::getLayer(hitsetkey) + << " with sector " << sector << "|" << (int) TpcDefs::getSectorId(hitsetkey) + << " side " << side << "|" << (int) TpcDefs::getSide(hitsetkey) + << " pads_per_sector " << pads_per_sector + << " pad_num " << pad_num + << " LayerGeom->get_phibins() " << LayerGeom->get_phibins() + << " LayerGeom->get_layer() " << LayerGeom->get_layer() + << std::endl; + hitset->identify(); + } + assert(hitset->getNPads() == pads_per_sector); + // generate the key for this hit, requires tbin and phibin TrkrDefs::hitkey hitkey = TpcDefs::genHitKey((unsigned int) pad_num, (unsigned int) tbin_num); - // See if this hit already exists - TrkrHit *hit = nullptr; - hit = hitsetit->second->getHit(hitkey); - if (!hit) + hitset->getTpcADC(hitkey) += neffelectrons; + + if (Verbosity() > 1000) { - // create a new one - hit = new TrkrHitv2(); - hitsetit->second->addHitSpecificKey(hitkey, hit); + std::cout << __PRETTY_FUNCTION__ << " done adding hit: hitkey = " + << hitkey << " pad " << TpcDefs::getPad(hitkey) + << " z bin " << TpcDefs::getTBin(hitkey) + << " neffelectrons " << neffelectrons + << "which comes from input hit in hitsetkey " << hitsetkey + << " layer " << layernum << "|" << (int) TrkrDefs::getLayer(hitsetkey) + << " with sector " << sector << "|" << (int) TpcDefs::getSectorId(hitsetkey) + << " side " << side << "|" << (int) TpcDefs::getSide(hitsetkey) + << " pads_per_sector " << pads_per_sector + << " pad_num " << pad_num + << " LayerGeom->get_phibins() " << LayerGeom->get_phibins() + << " LayerGeom->get_layer() " << LayerGeom->get_layer() + << std::endl; + hitset->identify(); } - // Either way, add the energy to it -- adc values will be added at digitization - hit->addEnergy(neffelectrons); - tpc_truth_clusterer->addhitset(hitsetkey, hitkey, neffelectrons); + tpc_truth_clusterer.addhitset(hitsetkey, hitkey, neffelectrons); // repeat for the single_hitsetcontainer // See if this hit already exists @@ -456,45 +513,53 @@ void PHG4TpcPadPlaneReadout::MapToPadPlane( m_NHits++; /* return pass_data; */ } -double PHG4TpcPadPlaneReadout::check_phi(const unsigned int side, const double phi, const double radius){ +double PHG4TpcPadPlaneReadout::check_phi(const unsigned int side, const double phi, const double radius) +{ double new_phi = phi; - int p_region=-1; + int p_region = -1; for (int iregion = 0; iregion < 3; ++iregion) - { + { if (radius < MaxRadius[iregion] && radius > MinRadius[iregion]) p_region = iregion; } - if(p_region>0){ - for(int s=0; s<12;s++){ - double daPhi = 0; - if (s==0){ - daPhi = fabs(sector_min_Phi_sectors[side][p_region][11] + 2*M_PI - sector_max_Phi_sectors[side][p_region][s]); - }else{ - daPhi = fabs(sector_min_Phi_sectors[side][p_region][s-1] - sector_max_Phi_sectors[side][p_region][s]); - } + if (p_region > 0) + { + for (int s = 0; s < 12; s++) + { + double daPhi = 0; + if (s == 0) + { + daPhi = fabs(sector_min_Phi_sectors[side][p_region][11] + 2 * M_PI - sector_max_Phi_sectors[side][p_region][s]); + } + else + { + daPhi = fabs(sector_min_Phi_sectors[side][p_region][s - 1] - sector_max_Phi_sectors[side][p_region][s]); + } double min_phi = sector_max_Phi_sectors[side][p_region][s]; - double max_phi = sector_max_Phi_sectors[side][p_region][s]+daPhi; - if (new_phi<=max_phi && new_phi>=min_phi){ - if(fabs(max_phi - new_phi) > fabs(new_phi - min_phi)){ - new_phi = min_phi-PhiBinWidth[p_region]/5;//to be changed - }else{ - new_phi = max_phi+PhiBinWidth[p_region]/5; - } - - - } - + double max_phi = sector_max_Phi_sectors[side][p_region][s] + daPhi; + if (new_phi <= max_phi && new_phi >= min_phi) + { + if (fabs(max_phi - new_phi) > fabs(new_phi - min_phi)) + { + new_phi = min_phi - PhiBinWidth[p_region] / 5; // to be changed + } + else + { + new_phi = max_phi + PhiBinWidth[p_region] / 5; + } } } - if(new_phi=-M_PI){ - new_phi += 2*M_PI; - } + } + if (new_phi < sector_min_Phi_sectors[side][p_region][11] && new_phi >= -M_PI) + { + new_phi += 2 * M_PI; + } return new_phi; } void PHG4TpcPadPlaneReadout::populate_zigzag_phibins(const unsigned int side, const unsigned int layernum, const double phi, const double cloud_sig_rp, std::vector &phibin_pad, std::vector &phibin_pad_share) { - const double radius = LayerGeom->get_radius(); + const double radius = LayerGeom->get_radius(); const double phistepsize = LayerGeom->get_phistep(); - const auto phibins = LayerGeom->get_phibins(); + const auto phibins = LayerGeom->get_phibins(); // make the charge distribution gaussian double rphi = phi * radius; @@ -507,17 +572,16 @@ void PHG4TpcPadPlaneReadout::populate_zigzag_phibins(const unsigned int side, co } // Get the range of phi values that completely contains all pads that touch the charge distribution - (nsigmas + 1/2 pad width) in each direction - const double philim_low_calc = phi - (_nsigmas * cloud_sig_rp / radius) - phistepsize; + const double philim_low_calc = phi - (_nsigmas * cloud_sig_rp / radius) - phistepsize; const double philim_high_calc = phi + (_nsigmas * cloud_sig_rp / radius) + phistepsize; // Find the pad range that covers this phi range const double philim_low = check_phi(side, philim_low_calc, radius); const double philim_high = check_phi(side, philim_high_calc, radius); - int phibin_low = LayerGeom->get_phibin(philim_high); + int phibin_low = LayerGeom->get_phibin(philim_high); int phibin_high = LayerGeom->get_phibin(philim_low); - int npads = phibin_high - phibin_low; - + int npads = phibin_high - phibin_low; if (Verbosity() > 1000) if (layernum == print_layer) @@ -534,7 +598,6 @@ void PHG4TpcPadPlaneReadout::populate_zigzag_phibins(const unsigned int side, co std::array pad_parameters; std::array pad_keep; - // Now make a loop that steps through the charge distribution and evaluates the response at that point on each pad std::array overlap = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; double pads_phi[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; @@ -552,8 +615,8 @@ void PHG4TpcPadPlaneReadout::populate_zigzag_phibins(const unsigned int side, co for (int ipad = 0; ipad <= npads; ipad++) { int pad_now = phibin_low + ipad; - //if(phibin_low<0 && phibin_high<0) pad_now = phibin_high + ipad; - // check that we do not exceed the maximum number of pads, wrap if necessary + // if(phibin_low<0 && phibin_high<0) pad_now = phibin_high + ipad; + // check that we do not exceed the maximum number of pads, wrap if necessary if (pad_now >= phibins) pad_now -= phibins; pad_keep[ipad] = pad_now; @@ -565,44 +628,48 @@ void PHG4TpcPadPlaneReadout::populate_zigzag_phibins(const unsigned int side, co if (layernum == print_layer) std::cout << " zigzags: make fpad for ipad " << ipad << " pad_now " << pad_now << " pad_rphi/2 " << pad_rphi / 2.0 << " rphi_pad_now " << rphi_pad_now << std::endl; - //} - - // use analytic integral - //for (int ipad = 0; ipad <= npads; ipad++) - //{ - //const double pitch = pad_parameters[ipad][0]; - //const double x_loc = pad_parameters[ipad][1] - rphi; - //const double sigma = cloud_sig_rp; - - const double pitch = pad_rphi / 2.0;//eshulga - double x_loc_tmp = rphi_pad_now - rphi;//eshulga - const double sigma = cloud_sig_rp;//eshulga - - // Checking if the pads are on the same side of the TPC in phi - if(fabs(sum_of_pads_phi)!= sum_of_pads_absphi){ - if(phi<-M_PI/2 && phi_now>0){ - x_loc_tmp = (phi_now - 2*M_PI) * radius - rphi; + //} + + // use analytic integral + // for (int ipad = 0; ipad <= npads; ipad++) + //{ + // const double pitch = pad_parameters[ipad][0]; + // const double x_loc = pad_parameters[ipad][1] - rphi; + // const double sigma = cloud_sig_rp; + + const double pitch = pad_rphi / 2.0; // eshulga + double x_loc_tmp = rphi_pad_now - rphi; // eshulga + const double sigma = cloud_sig_rp; // eshulga + + // Checking if the pads are on the same side of the TPC in phi + if (fabs(sum_of_pads_phi) != sum_of_pads_absphi) + { + if (phi < -M_PI / 2 && phi_now > 0) + { + x_loc_tmp = (phi_now - 2 * M_PI) * radius - rphi; } - if(phi>M_PI/2 && phi_now<0){ - x_loc_tmp = (phi_now + 2*M_PI) * radius - rphi; + if (phi > M_PI / 2 && phi_now < 0) + { + x_loc_tmp = (phi_now + 2 * M_PI) * radius - rphi; } - if(phi<0 && phi_now>0){ - x_loc_tmp = (phi_now+fabs(phi)) * radius; + if (phi < 0 && phi_now > 0) + { + x_loc_tmp = (phi_now + fabs(phi)) * radius; } - if(phi>0 && phi_now<0){ - x_loc_tmp = (2*M_PI - phi_now + phi) * radius; + if (phi > 0 && phi_now < 0) + { + x_loc_tmp = (2 * M_PI - phi_now + phi) * radius; } } const double x_loc = x_loc_tmp; // calculate fraction of the total charge on this strip - /* - this corresponds to integrating the charge distribution Gaussian function (centered on rphi and of width cloud_sig_rp), + /* + this corresponds to integrating the charge distribution Gaussian function (centered on rphi and of width cloud_sig_rp), convoluted with a strip response function, which is triangular from -pitch to +pitch, with a maximum of 1. at stript center */ overlap[ipad] = (pitch - x_loc) * (std::erf(x_loc / (M_SQRT2 * sigma)) - std::erf((x_loc - pitch) / (M_SQRT2 * sigma))) / (pitch * 2) + (pitch + x_loc) * (std::erf((x_loc + pitch) / (M_SQRT2 * sigma)) - std::erf(x_loc / (M_SQRT2 * sigma))) / (pitch * 2) + (gaus(x_loc - pitch, sigma) - gaus(x_loc, sigma)) * square(sigma) / pitch + (gaus(x_loc + pitch, sigma) - gaus(x_loc, sigma)) * square(sigma) / pitch; - } // now we have the overlap for each pad @@ -611,7 +678,7 @@ void PHG4TpcPadPlaneReadout::populate_zigzag_phibins(const unsigned int side, co phibin_pad.push_back(pad_keep[ipad]); phibin_pad_share.push_back(overlap[ipad]); if (rad_gem < output_radius) std::cout << " zigzags: for pad " << ipad << " integral is " << overlap[ipad] << std::endl; - } + } return; } @@ -621,7 +688,7 @@ void PHG4TpcPadPlaneReadout::populate_tbins(const double t, const std::arrayget_zbin(t); if (tbin < 0 || tbin > LayerGeom->get_zbins()) { - //std::cout << " t bin is outside range, return" << std::endl; + // std::cout << " t bin is outside range, return" << std::endl; return; } @@ -729,6 +796,29 @@ void PHG4TpcPadPlaneReadout::populate_tbins(const double t, const std::array0) std::cout << "PHG4TpcPadPlaneReadout: UseGain: TRUE " << std::endl; +} + +void PHG4TpcPadPlaneReadout::ReadGain() +{ + // Reading TPC Gain Maps from the file + if(m_flagToUseGain==1){ + char *calibrationsroot = getenv("CALIBRATIONROOT"); + if (calibrationsroot != nullptr) + { + std::string gain_maps_filename = std::string(calibrationsroot)+std::string("/TPC/GainMaps/TPCGainMaps.root"); + TFile *fileGain = TFile::Open(gain_maps_filename.c_str(), "READ"); + h_gain[0] = (TH2F*)fileGain->Get("RadPhiPlot0")->Clone(); + h_gain[1] = (TH2F*)fileGain->Get("RadPhiPlot1")->Clone(); + h_gain[0]->SetDirectory(nullptr); + h_gain[1]->SetDirectory(nullptr); + fileGain->Close(); + } + } +} void PHG4TpcPadPlaneReadout::SetDefaultParameters() { set_default_int_param("ntpc_layers_inner", 16); @@ -737,23 +827,21 @@ void PHG4TpcPadPlaneReadout::SetDefaultParameters() set_default_int_param("tpc_minlayer_inner", 7); - //set_default_double_param("tpc_minradius_inner", 30.0); // cm - //set_default_double_param("tpc_minradius_mid", 40.0); - //set_default_double_param("tpc_minradius_outer", 60.0); -// - //set_default_double_param("tpc_maxradius_inner", 40.0); // cm - //set_default_double_param("tpc_maxradius_mid", 60.0); - //set_default_double_param("tpc_maxradius_outer", 77.0); // from Tom - - set_default_double_param("tpc_minradius_inner", 31.105);//30.0); // cm - set_default_double_param("tpc_minradius_mid", 41.153);//40.0); - set_default_double_param("tpc_minradius_outer", 58.367);//60.0); - + // set_default_double_param("tpc_minradius_inner", 30.0); // cm + // set_default_double_param("tpc_minradius_mid", 40.0); + // set_default_double_param("tpc_minradius_outer", 60.0); + // + // set_default_double_param("tpc_maxradius_inner", 40.0); // cm + // set_default_double_param("tpc_maxradius_mid", 60.0); + // set_default_double_param("tpc_maxradius_outer", 77.0); // from Tom - set_default_double_param("tpc_maxradius_inner", 40.249);//40.0); // cm - set_default_double_param("tpc_maxradius_mid", 57.475);//60.0); - set_default_double_param("tpc_maxradius_outer", 75.911);//77.0); // from Tom + set_default_double_param("tpc_minradius_inner", 31.105); // 30.0); // cm + set_default_double_param("tpc_minradius_mid", 41.153); // 40.0); + set_default_double_param("tpc_minradius_outer", 58.367); // 60.0); + set_default_double_param("tpc_maxradius_inner", 40.249); // 40.0); // cm + set_default_double_param("tpc_maxradius_mid", 57.475); // 60.0); + set_default_double_param("tpc_maxradius_outer", 75.911); // 77.0); // from Tom set_default_double_param("neffelectrons_threshold", 1.0); set_default_double_param("maxdriftlength", 105.5); // cm @@ -762,9 +850,9 @@ void PHG4TpcPadPlaneReadout::SetDefaultParameters() set_default_double_param("sampa_shaping_lead", 32.0); // ns, for 80 ns SAMPA set_default_double_param("sampa_shaping_tail", 48.0); // ns, for 80 ns SAMPA - set_default_double_param("tpc_sector_phi_inner", 0.5024);//2 * M_PI / 12 );//sector size in phi for R1 sector - set_default_double_param("tpc_sector_phi_mid", 0.5087);//2 * M_PI / 12 );//sector size in phi for R2 sector - set_default_double_param("tpc_sector_phi_outer", 0.5097);//2 * M_PI / 12 );//sector size in phi for R3 sector + set_default_double_param("tpc_sector_phi_inner", 0.5024); // 2 * M_PI / 12 );//sector size in phi for R1 sector + set_default_double_param("tpc_sector_phi_mid", 0.5087); // 2 * M_PI / 12 );//sector size in phi for R2 sector + set_default_double_param("tpc_sector_phi_outer", 0.5097); // 2 * M_PI / 12 );//sector size in phi for R3 sector set_default_int_param("ntpc_phibins_inner", 1152); set_default_int_param("ntpc_phibins_mid", 1536); @@ -772,7 +860,7 @@ void PHG4TpcPadPlaneReadout::SetDefaultParameters() // GEM Gain /* - hp (2020/09/04): gain changed from 2000 to 1400, to accomodate gas mixture change + hp (2020/09/04): gain changed from 2000 to 1400, to accomodate gas mixture change from Ne/CF4 90/10 to Ne/CF4 50/50, and keep the average charge per particle per pad constant */ set_default_double_param("gem_amplification", 1400); @@ -799,9 +887,9 @@ void PHG4TpcPadPlaneReadout::UpdateInternalParameters() MaxRadius[1] = get_double_param("tpc_maxradius_mid"); MaxRadius[2] = get_double_param("tpc_maxradius_outer"); - //Thickness[0] = NTpcLayers[0] <= 0 ? 0 : (MaxRadius[0] - MinRadius[0]) / NTpcLayers[0]; - //Thickness[1] = NTpcLayers[1] <= 0 ? 0 : (MaxRadius[1] - MinRadius[1]) / NTpcLayers[1]; - //Thickness[2] = NTpcLayers[2] <= 0 ? 0 : (MaxRadius[2] - MinRadius[2]) / NTpcLayers[2]; + // Thickness[0] = NTpcLayers[0] <= 0 ? 0 : (MaxRadius[0] - MinRadius[0]) / NTpcLayers[0]; + // Thickness[1] = NTpcLayers[1] <= 0 ? 0 : (MaxRadius[1] - MinRadius[1]) / NTpcLayers[1]; + // Thickness[2] = NTpcLayers[2] <= 0 ? 0 : (MaxRadius[2] - MinRadius[2]) / NTpcLayers[2]; MaxRadius[0] = get_double_param("tpc_maxradius_inner"); MaxRadius[1] = get_double_param("tpc_maxradius_mid"); @@ -842,68 +930,56 @@ void PHG4TpcPadPlaneReadout::UpdateInternalParameters() averageGEMGain = get_double_param("gem_amplification"); - //The modules are segmented in [-M_PI;M_PI] interval - std::array< std::array< std::array< float,NRSectors >,NSectors >,NSides > dR_tmp = {{ - {{ - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.} - }}, - {{ - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.} - }} - }}; - - std::array< std::array< std::array< float,NRSectors >,NSectors >,NSides > dPhi_tmp = {{ - {{ - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.} - }}, - {{ - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.}, - {0.,0.,0.} - }} - }}; + // The modules are segmented in [-M_PI;M_PI] interval + std::array, NSectors>, NSides> dR_tmp = {{{{{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}}, + {{{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}}}}; + + std::array, NSectors>, NSides> dPhi_tmp = {{{{{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}}, + {{{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}}}}; dR = dR_tmp; dPhi = dPhi_tmp; diff --git a/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.h b/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.h index f7e3719d14..a5bdad188b 100644 --- a/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.h +++ b/simulation/g4simulation/g4tpc/PHG4TpcPadPlaneReadout.h @@ -5,7 +5,12 @@ #include "TpcClusterBuilder.h" #include +#include + #include + +#include + #include #include #include @@ -13,7 +18,7 @@ #include class PHCompositeNode; -//class PHG4CellContainer; +// class PHG4CellContainer; class PHG4TpcCylinderGeomContainer; class PHG4TpcCylinderGeom; class TNtuple; @@ -27,19 +32,24 @@ class PHG4TpcPadPlaneReadout : public PHG4TpcPadPlane ~PHG4TpcPadPlaneReadout() override; - void SetDriftVelocity(double vd) override { drift_velocity = vd; } + void UseGain(const int flagToUseGain); + void ReadGain(); + void SetDriftVelocity(double vd) override { drift_velocity = vd; } int CreateReadoutGeometry(PHCompositeNode *topNode, PHG4TpcCylinderGeomContainer *seggeo) override; // otherwise warning of inconsistent overload since only one MapToPadPlane methow is overridden using PHG4TpcPadPlane::MapToPadPlane; - void MapToPadPlane(TpcClusterBuilder* tpc_clustbuilder, TrkrHitSetContainer *single_hitsetcontainer, TrkrHitSetContainer *hitsetcontainer, TrkrHitTruthAssoc * /*hittruthassoc*/, const double x_gem, const double y_gem, const double t_gem, const unsigned int side, PHG4HitContainer::ConstIterator hiter, TNtuple * /*ntpad*/, TNtuple * /*nthit*/) override; + void MapToPadPlane(TpcClusterBuilder& tpc_clustbuilder, TrkrHitSetContainer *single_hitsetcontainer, TrkrHitSetContainer *hitsetcontainer, TrkrHitTruthAssoc * /*hittruthassoc*/, const double x_gem, const double y_gem, const double t_gem, const unsigned int side, PHG4HitContainer::ConstIterator hiter, TNtuple * /*ntpad*/, TNtuple * /*nthit*/) override; void SetDefaultParameters() override; void UpdateInternalParameters() override; + int get_minLayer() override { return MinLayer[0]; } + int get_nLayer() override { return NTpcLayers[0] + NTpcLayers[1] + NTpcLayers[2]; } + private: // void populate_rectangular_phibins(const unsigned int layernum, const double phi, const double cloud_sig_rp, std::vector &pad_phibin, std::vector &pad_phibin_share); void populate_zigzag_phibins(const unsigned int side, const unsigned int layernum, const double phi, const double cloud_sig_rp, std::vector &pad_phibin, std::vector &pad_phibin_share); @@ -64,12 +74,12 @@ class PHG4TpcPadPlaneReadout : public PHG4TpcPadPlane std::array MaxRadius; std::array Thickness; - static const int NSides = 2; - static const int NSectors = 12; - static const int NRSectors = 3; + static const int NSides = TpcDefs::NSides; + static const int NSectors = TpcDefs::NSectors; + static const int NRSectors = TpcDefs::NRSectors; - std::array< std::array< std::array< float,NRSectors >,NSectors >,NSides > dR; - std::array< std::array< std::array< float,NRSectors >,NSectors >,NSides > dPhi; + std::array, NSectors>, NSides> dR; + std::array, NSectors>, NSides> dPhi; double MaxZ = NAN; double MinT = NAN; @@ -87,7 +97,8 @@ class PHG4TpcPadPlaneReadout : public PHG4TpcPadPlane std::array NTpcLayers; std::array SectorPhi; int m_NHits = 0; - + // Using Gain maps is turned off by default + int m_flagToUseGain = 0; // gaussian sampling static constexpr double _nsigmas = 5; @@ -97,16 +108,18 @@ class PHG4TpcPadPlaneReadout : public PHG4TpcPadPlane std::vector pad_phibin; std::vector pad_phibin_share; std::vector adc_tbin_share; - std::array, NSides > sector_R_bias; - std::array, NSides > sector_Phi_bias; - std::array, NSides > sector_min_Phi; - std::array, NSides > sector_max_Phi; - std::array< std::array< std::vector, NRSectors >, NSides > sector_min_Phi_sectors; - std::array< std::array< std::vector, NRSectors >, NSides > sector_max_Phi_sectors; + std::array, NSides> sector_R_bias; + std::array, NSides> sector_Phi_bias; + std::array, NSides> sector_min_Phi; + std::array, NSides> sector_max_Phi; + std::array, NRSectors>, NSides> sector_min_Phi_sectors; + std::array, NRSectors>, NSides> sector_max_Phi_sectors; // return random distribution of number of electrons after amplification of GEM for each initial ionizing electron double getSingleEGEMAmplification(); gsl_rng *RandomGenerator; + + TH2F *h_gain[2]; }; #endif diff --git a/simulation/g4simulation/g4tpc/TpcClusterBuilder.cc b/simulation/g4simulation/g4tpc/TpcClusterBuilder.cc index 497a56366e..d68e5d0635 100644 --- a/simulation/g4simulation/g4tpc/TpcClusterBuilder.cc +++ b/simulation/g4simulation/g4tpc/TpcClusterBuilder.cc @@ -1,6 +1,5 @@ #include "TpcClusterBuilder.h" -/* #include */ -#include +#include #include #include #include @@ -12,37 +11,26 @@ #include // for TrkrHit #include // for sqrt, cos, sin #include // for _Rb_tree_cons... +#include #include #include +#include + +#include +#include + /* class TpcClusterBuilder; */ -using std::cout, std::endl, std::string, std::ofstream; +using std::cout, std::endl, std::string, std::ofstream, std::ostream; double TpcClusterBuilder::square(double v) { return v*v; } double TpcClusterBuilder::square(float v) { return v*v; } void TpcClusterBuilder::set_verbosity(int verbosity_level) { verbosity = verbosity_level; } -TpcClusterBuilder::TpcClusterBuilder - ( TrkrClusterContainer* _truth_cluster_container - /* , TrkrTruthTrackContainer* _truth_track_container */ - , ActsGeometry* _ActsGeometry - , PHG4TpcCylinderGeomContainer* _geom_container - ): m_clusterlist { _truth_cluster_container } - , m_tGeometry { _ActsGeometry } - , geom_container { _geom_container } -{ } - -void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { - if (verbosity) if (m_hits == nullptr) cout << " m_hits == nullptr! " << endl; - - if (!is_embedded_track) { - reset(clear_hitsetkey_cnt); - return; - } - +void TpcClusterBuilder::cluster_hits(TrkrTruthTrack* track) { // now build the TrkrCluster TrkrHitSetContainer::ConstRange hitsetrange; hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId); @@ -50,6 +38,7 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { //----------------------------------------------------- // from TpcClusterizer.cc ~line: 837 //----------------------------------------------------- + for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; hitsetitr != hitsetrange.second; ++hitsetitr) @@ -61,7 +50,7 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { int side = TpcDefs::getSide(hitsetitr->first); unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); PHG4TpcCylinderGeom *layergeom = geom_container->GetLayerCellGeom(layer); - + //get the maximum and minimum phi and time unsigned short NPhiBins = (unsigned short) layergeom->get_phibins(); unsigned short NPhiBinsSector = NPhiBins/12; @@ -77,7 +66,7 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { unsigned short phioffset = PhiOffset; unsigned short tbins = NTBinsSide; unsigned short toffset = TOffset ; - + // loop over the hits in this cluster double t_sum = 0.0; double adc_sum = 0.0; @@ -88,26 +77,68 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { // double phi2_sum = 0.0; double radius = layergeom->get_radius(); // returns center of layer - + int phibinhi = -1; - int phibinlo = 666666; + int phibinlo = INT_MAX; int tbinhi = -1; - int tbinlo = 666666; + int tbinlo = INT_MAX; auto ihit_list = hitset->getHits(); + + double sum_energy { 0. }; // energy = 4 * adc at this point + + for(auto ihit = ihit_list.first; ihit != ihit_list.second; ++ihit){ + int e = ihit->second->getEnergy(); + int adc = ihit->second->getAdc(); + if (adc*4 != e) { + if(verbosity > 1) + { + cout << " FIXME: energy: " << ihit->second->getEnergy() << " vs adc " << ihit->second->getAdc() << endl; + } + } + sum_energy += ihit->second->getEnergy(); + } + const double threshold = sum_energy * m_pixel_thresholdrat; + + // FIXME -- see why the hits are so scattered + std::set v_iphi, v_it; // FIXME + std::map m_iphi, m_it; // FIXME + for(auto iter = ihit_list.first; iter != ihit_list.second; ++iter){ unsigned int adc = iter->second->getAdc(); if (adc <= 0) continue; + if (iter->second->getEnergy()second->getEnergy() << " is below " << threshold << endl; */ + } + + if (iter->second->getEnergy()first) - phioffset; int it = TpcDefs::getTBin(iter->first) - toffset; + //FIXME + v_iphi.insert(iphi); + v_it.insert(it); + m_iphi.try_emplace(iphi,0); + m_it.try_emplace(it,0); + + m_iphi[iphi] += adc; + m_it[it] += adc; + if(iphi<0 || iphi>=phibins){ - //std::cout << "WARNING phibin out of range: " << phibin << " | " << phibins << std::endl; + //FIXME + if(verbosity > 1) + { + std::cout << "WARNING phibin out of range: " << iphi << " | " << phibins << std::endl; + } continue; } if(it<0 || it>=tbins){ - //std::cout << "WARNING z bin out of range: " << tbin << " | " << tbins << std::endl; + //FIXME + if(verbosity > 1) { + std::cout << "WARNING z bin out of range: " << it << " | " << tbins << std::endl; + } continue; } @@ -132,7 +163,17 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { adc_sum += adc; } - + + if (false) { // FIXME + int _phi_sum = 0; + for (auto _ : m_iphi) _phi_sum += _.second; + if (_phi_sum != adc_sum && verbosity > 1) std::cout << " FIXME z1 " << adc_sum << " delta phi: " << (adc_sum - _phi_sum) << std::endl; + + int _t_sum = 0; + for (auto _ : m_it) _t_sum += _.second; + if (_t_sum != adc_sum && verbosity > 1) std::cout << " FIXME z1 " << adc_sum << " delta phi: " << (adc_sum - _phi_sum) << std::endl; + } + // This is the global position double clusiphi = iphi_sum / adc_sum; double clusphi = layergeom->get_phi(clusiphi); @@ -143,19 +184,88 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { double zdriftlength = clust * m_tGeometry->get_drift_velocity(); // convert z drift length to z position in the TPC double clusz = m_tdriftmax * m_tGeometry->get_drift_velocity() - zdriftlength; - if(side == 0) clusz = -clusz; - /* const double phi_cov = phi2_sum/adc_sum - square(clusphi); */ + if (side == 0) clusz = -clusz; char tsize = tbinhi - tbinlo + 1; char phisize = phibinhi - phibinlo + 1; + if (tsize < 0 && verbosity > 1) std::cout << " FIXME z4 tsize: " << ((int)tsize) << " " << tbinlo << " to " << tbinhi << std::endl; + + // ------------------------------------------------- + // ------------------------------------------------- + // debug here: FIXME + // + /* cout << " FIXME phisize " << ((int) phisize) << endl; */ + //FIXME + if (false) { // Printing for debugging + if ((int)phisize > 10 || (int)tsize > 8) { + int _size_phi = ((int)phisize); + int _nbins_phi = v_iphi.size(); + int _delta_phi = abs(_size_phi-_nbins_phi); + int _size_z = ((int)tsize); + int _nbins_z = v_it.size(); + int _delta_z = abs(_size_z - _nbins_z); + + TString fmt; + cout << " x|"<<_delta_phi<<"|"<<_delta_z + <<"| new node FIXME A1 layer("<< layer + <<") (nset:size) phi(" + << _nbins_phi<<":"<<_size_phi << ") z(" + <<_nbins_z<<":"<<_size_z<<") " + <<"trkId("<getTrackid()<<") trkpT("<getPt()<<")" + << endl; + if (phisize>10) { + cout << " iphi-from-("; + int _prev = -1; + double tempsum = 0.; + for (auto _ : v_iphi) { + if (_prev == -1) { + cout << _<<"): "; + } else { + int _diff = ((int)_-_prev-1); + if (_diff != 0) cout<<">"<<_diff<<">"; + } + /* cout << std::setprecision(2) << std::fixed; */ + double _rat = (float)m_iphi[_] / (float)adc_sum; + fmt.Form("%.2f",_rat); + cout << fmt <<" "; + tempsum += _rat; + _prev = _; + } + if (tempsum < 0.999) cout << " Z3 sumphirat: " << tempsum; + cout << endl; + } + if (tsize>8) { + int _prev = -1; + double tempsum = 0.; + cout << " iz-from-("; + for (auto _ : v_it) { + if (_prev == -1) { + cout << _<<"): "; + } else { + int _diff = ((int)_-_prev-1); + if (_diff != 0) cout<<">"<<_diff<<">"; + } + /* cout << std::setprecision(2) << std::fixed; */ + double _rat = (float)m_it[_] / (float)adc_sum; + fmt.Form("%.2f",_rat); + cout << fmt <<" "; + tempsum += _rat; + _prev = _; + } + if (tempsum < 0.999) cout << " Z3 sumzrat: " << tempsum; + } + cout << endl; + } + } + // get the global vector3 to then get the surface local phi and z Acts::Vector3 global(clusx, clusy, clusz); TrkrDefs::subsurfkey subsurfkey = 0; Surface surface = m_tGeometry->get_tpc_surface_from_coords( hitsetkey, global, subsurfkey); - + if (!surface) { if (verbosity) std::cout << "Can't find the surface! with hitsetkey " << ((int)hitsetkey) << std::endl; continue; @@ -165,11 +275,11 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { clust = clust + m_sampa_tbias; global *= Acts::UnitConstants::cm; - + Acts::Vector3 local=surface->transform(m_tGeometry->geometry().getGeoContext()).inverse() * global; local /= Acts::UnitConstants::cm; - - auto cluster = new TrkrClusterv4; // + + auto cluster = new TrkrClusterv5; // cluster->setAdc(adc_sum); /* cluster->setOverlap(ntouch); */ /* cluster->setEdge(nedge); */ @@ -178,30 +288,21 @@ void TpcClusterBuilder::cluster_and_reset(bool clear_hitsetkey_cnt) { cluster->setSubSurfKey(subsurfkey); cluster->setLocalX(local(0)); cluster->setLocalY(clust); - + // add the clusterkey - if (hitsetkey_cnt.find(hitsetkey)==hitsetkey_cnt.end()) { - hitsetkey_cnt[hitsetkey] = 0; - } else { - hitsetkey_cnt[hitsetkey] +=1; - } + auto empl = hitsetkey_cnt.try_emplace(hitsetkey,0); + if (!empl.second) empl.first->second += 1; TrkrDefs::cluskey cluskey = TrkrDefs::genClusKey(hitsetkey, hitsetkey_cnt[hitsetkey]); m_clusterlist->addClusterSpecifyKey(cluskey, cluster); - - if (false) { // debug print statement - /* cout << hitsetkey_cnt[hitsetkey] << " " << cluster->getLocalX() << std::endl; */ - } - - if (current_track != nullptr) current_track->addCluster(cluskey); + track->addCluster(cluskey); } - - reset(clear_hitsetkey_cnt); + m_hits->Reset(); } -void TpcClusterBuilder::set_current_track(TrkrTruthTrack* track) { - current_track = track; - ++ n_tracks; -} +/* void TpcClusterBuilder::set_current_track(TrkrTruthTrack* track) { */ + /* current_track = track; */ + /* ++ n_tracks; */ +/* } */ void TpcClusterBuilder::addhitset( TrkrDefs::hitsetkey hitsetkey, @@ -210,7 +311,7 @@ void TpcClusterBuilder::addhitset( { // copy of code in PHG4TpcPadPlaneReadout::MapToPadPlane, with a switch // to ignore non embedded tracks - if (!is_embedded_track) return; + if (!b_collect_hits) return; // Add the hitset to the current embedded track // Code from PHG4TpcPadPlaneReadout::MapToPadPlane (around lines {}.cc::386-401) @@ -228,15 +329,8 @@ void TpcClusterBuilder::addhitset( hit->addEnergy(neffelectrons); } -void TpcClusterBuilder::reset(bool clear_hitsetkey_cnt) { - // clear the hitsets before the next track - m_hits->Reset(); - - // if done with the event, also clear the hitsetkey_cnt - if (clear_hitsetkey_cnt) { +void TpcClusterBuilder::clear_hitsetkey_cnt() { hitsetkey_cnt.clear(); - n_tracks = 0; - } } void TpcClusterBuilder::print( @@ -303,3 +397,14 @@ void TpcClusterBuilder::print_file( fout.close(); } +void TpcClusterBuilder::set_input_nodes( + TrkrClusterContainer* _truth_cluster_container + , ActsGeometry* _ActsGeometry + , PHG4TpcCylinderGeomContainer* _geom_container +) { + m_clusterlist = _truth_cluster_container; + m_tGeometry = _ActsGeometry; + geom_container = _geom_container; + needs_input_nodes = false; +}; + diff --git a/simulation/g4simulation/g4tpc/TpcClusterBuilder.h b/simulation/g4simulation/g4tpc/TpcClusterBuilder.h index bc83df9d3c..6cede972f2 100644 --- a/simulation/g4simulation/g4tpc/TpcClusterBuilder.h +++ b/simulation/g4simulation/g4tpc/TpcClusterBuilder.h @@ -25,13 +25,16 @@ #include #include #include +#include + +using std::ostream; -class TrkrCluster; class PHG4TpcCylinderGeom; +class PHG4TpcCylinderGeomContainer; +class TrkrCluster; class TrkrClusterContainer; class TrkrHitSetContainer; class TrkrTruthTrack; -class PHG4TpcCylinderGeomContainer; class TrkrTruthTrackContainer; // This is the basic data for each set of TrkrHits from each TrkrHitsSet @@ -40,28 +43,34 @@ class TpcClusterBuilder { double square(double); double square(float); - TrkrClusterContainer* m_clusterlist; // fill for output - ActsGeometry* m_tGeometry; // used to generate clusters - PHG4TpcCylinderGeomContainer* geom_container; + TrkrClusterContainer* m_clusterlist { nullptr }; // fill for output + ActsGeometry* m_tGeometry { nullptr }; // used to generate clusters + PHG4TpcCylinderGeomContainer* geom_container { nullptr }; // internal containers to fill and consume hits and fill with tracks TrkrHitSetContainer* m_hits { new TrkrHitSetContainerv1() }; - TrkrTruthTrack* current_track { nullptr }; + /* TrkrTruthTrack* current_track { nullptr }; */ std::map hitsetkey_cnt {}; - int n_tracks {0}; + public: + private: + int n_tracks {0}; int verbosity {0}; public: - TpcClusterBuilder( - TrkrClusterContainer* _truth_cluster_container - , ActsGeometry* _ActsGeometry - , PHG4TpcCylinderGeomContainer* _geom_container - ); + TpcClusterBuilder( ) { }; + /* TrkrClusterContainer* _truth_cluster_container */ + /* , ActsGeometry* _ActsGeometry */ + /* , PHG4TpcCylinderGeomContainer* _geom_container */ + /* ); */ - bool is_embedded_track {false}; - void cluster_and_reset (bool clear_hitsetkey_cnt); + void fixme_check(); + void fixme_short_check(); + + bool b_collect_hits { false }; + /* bool is_embedded_track {false}; */ + void cluster_hits (TrkrTruthTrack* track); void addhitset (TrkrDefs::hitsetkey, TrkrDefs::hitkey, float neffelectrons); void set_current_track (TrkrTruthTrack* _trkrtruthtrack); void print(TrkrTruthTrackContainer*, int nclusprint=-1); @@ -84,7 +93,19 @@ class TpcClusterBuilder { // From Tony Frawley July 5, 2022 double m_sampa_tbias = 39.6; // ns - void reset(bool clear_hitsetkey_cnt); + + // for pixel thresholds + private: + double m_pixel_thresholdrat { 0.01 }; + public: + void clear_hitsetkey_cnt(); + void set_pixel_thresholdrat (double val) { m_pixel_thresholdrat = val; }; + bool needs_input_nodes = true; + void set_input_nodes( + TrkrClusterContainer* _truth_cluster_container + , ActsGeometry* _ActsGeometry + , PHG4TpcCylinderGeomContainer* _geom_container + ); }; #endif //TRACKBASE_PADPLANEREADOUTSTRUCT_H diff --git a/simulation/g4simulation/g4tpc/TruthTrack.cc b/simulation/g4simulation/g4tpc/TruthTrack.cc deleted file mode 100644 index ad72adaf13..0000000000 --- a/simulation/g4simulation/g4tpc/TruthTrack.cc +++ /dev/null @@ -1,11 +0,0 @@ - -#include - - - - - TLorentzVector v1; - v1.SetPxPyPzE(px1, py1, pz1, E1); - virtual int get_vtx_id() const { return -9999; } - - PHG4TruthInfoContainer::PHG4VtxPoint* GetVtx(const int vtxid); diff --git a/simulation/g4simulation/g4tracking/EmbRecoMatchv1.h b/simulation/g4simulation/g4tracking/EmbRecoMatchv1.h index bf20563619..6b0548c5da 100644 --- a/simulation/g4simulation/g4tracking/EmbRecoMatchv1.h +++ b/simulation/g4simulation/g4tracking/EmbRecoMatchv1.h @@ -7,7 +7,7 @@ #include #include #include - + /* class VtxPoint; */ class EmbRecoMatchv1 : public EmbRecoMatch { diff --git a/simulation/g4simulation/g4tracking/Makefile.am b/simulation/g4simulation/g4tracking/Makefile.am index e7d9f20f7f..492c887f40 100644 --- a/simulation/g4simulation/g4tracking/Makefile.am +++ b/simulation/g4simulation/g4tracking/Makefile.am @@ -21,14 +21,15 @@ libg4tracking_io_la_LIBADD = \ -ltrack_io pkginclude_HEADERS = \ + TrkrTruthTrack.h \ + EmbRecoMatch.h \ EmbRecoMatchContainer.h \ EmbRecoMatchContainerv1.h \ - EmbRecoMatch.h \ EmbRecoMatchv1.h \ TrkrTruthTrackContainer.h \ TrkrTruthTrackContainerv1.h \ - TrkrTruthTrack.h \ - TrkrTruthTrackv1.h + TrkrTruthTrackv1.h \ + TruthClusterizerBase.h ROOTDICTS = \ EmbRecoMatchContainer_Dict.cc \ @@ -59,6 +60,7 @@ libg4tracking_io_la_SOURCES = \ TrkrTruthTrack.cc \ TrkrTruthTrackContainer.cc \ TrkrTruthTrackContainerv1.cc \ + TruthClusterizerBase.cc \ TrkrTruthTrackv1.cc # Rule for generating table CINT dictionaries. diff --git a/simulation/g4simulation/g4tracking/TruthClusterizerBase.cc b/simulation/g4simulation/g4tracking/TruthClusterizerBase.cc new file mode 100644 index 0000000000..6be7010575 --- /dev/null +++ b/simulation/g4simulation/g4tracking/TruthClusterizerBase.cc @@ -0,0 +1,179 @@ +#include "TruthClusterizerBase.h" + +#include +#include +#include +#include +#include +#include + +/* #include */ +#include +#include +#include +#include +#include +#include +#include +#include // for TrkrHit + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include // for PHObject +#include +#include + +#include // for TMatrixF +#include // for TMatrixT, operator* +#include // for TMatrixTRow + + +#include +#include +#include +#include +#include + +TruthClusterizerBase::TruthClusterizerBase ( ) + : m_hits { new TrkrHitSetContainerv1 } +{ } + +void TruthClusterizerBase::init_clusterizer_base( PHCompositeNode*& _topNode, int _verbosity ) { + m_topNode = _topNode; + m_verbosity = _verbosity; + PHNodeIterator iter(m_topNode); + auto dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + assert(dstNode); + PHNodeIterator dstiter(dstNode); + auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + if (!DetNode) + { + DetNode = new PHCompositeNode("TRKR"); + dstNode->addNode(DetNode); + } + + m_truthtracks = findNode::getClass(m_topNode, "TRKR_TRUTHTRACKCONTAINER"); + if (!m_truthtracks) + { + PHNodeIterator dstiter(dstNode); + m_truthtracks = new TrkrTruthTrackContainerv1(); + auto newNode = new PHIODataNode(m_truthtracks, "TRKR_TRUTHTRACKCONTAINER", "PHObject"); + DetNode->addNode(newNode); + } + + m_clusters = findNode::getClass(m_topNode, "TRKR_TRUTHCLUSTERCONTAINER"); + if (!m_clusters) + { + m_clusters = new TrkrClusterContainerv4; + auto newNode = new PHIODataNode(m_clusters, "TRKR_TRUTHCLUSTERCONTAINER", "PHObject"); + DetNode->addNode(newNode); + } + + m_truthinfo = findNode::getClass(m_topNode, "G4TruthInfo"); + if (!m_truthinfo) + { + std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl; + assert(m_truthinfo); + } +} + +TruthClusterizerBase::~TruthClusterizerBase() { + delete m_hits; +} + +void TruthClusterizerBase::check_g4hit_status(PHG4Hit* hit) { + int new_trkid = (hit==nullptr) ? -1 : hit->get_trkid(); + m_is_new_track = (new_trkid != m_trkid); + if (m_verbosity>5) std::cout << PHWHERE << std::endl << " -> Checking status of PHG4Hit. Track id("<isEmbeded(m_trkid); +} + +// to call if m_was_emb=true and after clustering +void TruthClusterizerBase::transfer_clusters(TrkrClusterContainer* pass_clusters) { + m_hits->Reset(); // clear out the old hits + for (auto hitsetkey : pass_clusters->getHitSetKeys()) { + m_hitsetkey_cnt.try_emplace(hitsetkey,0); + unsigned int& cnt = m_hitsetkey_cnt[hitsetkey]; + auto range = pass_clusters->getClusters(hitsetkey); + for (auto cluster = range.first; cluster != range.second; ++cluster) { + auto ckey = TrkrDefs::genClusKey(hitsetkey, cnt); + m_clusters->addClusterSpecifyKey(ckey, cluster->second); + m_current_track->addCluster(ckey); + ++cnt; + } + } + m_was_emb = false; +} + +// if m_is_new_track +void TruthClusterizerBase::update_track() { + m_current_track = m_is_emb ? m_truthtracks->getTruthTrack(m_trkid, m_truthinfo) : nullptr; +} + +void TruthClusterizerBase::addhitset( + TrkrDefs::hitsetkey hitsetkey, + TrkrDefs::hitkey hitkey, + float neffelectrons) +{ + if (!m_is_emb) return; + TrkrHitSetContainer::Iterator hitsetit = m_hits->findOrAddHitSet(hitsetkey); + // See if this hit already exists + TrkrHit *hit = nullptr; + hit = hitsetit->second->getHit(hitkey); + if (!hit) + { + // create a new one + hit = new TrkrHitv2(); + hitsetit->second->addHitSpecificKey(hitkey, hit); + } + // Either way, add the energy to it -- adc values will be added at digitization + hit->addEnergy(neffelectrons); +} + +void TruthClusterizerBase::print_clusters(int nclusprint) { + std::cout << PHWHERE << ": content of clusters " << std::endl; + auto& tmap = m_truthtracks->getMap(); + std::cout << " Number of tracks: " << tmap.size() << std::endl; + for (auto& _pair : tmap) { + auto& track = _pair.second; + + printf("id(%2i) phi:eta:pt(", (int)track->getTrackid()); + std::cout << "phi:eta:pt("; + printf("%5.2f:%5.2f:%5.2f", track->getPhi(), track->getPseudoRapidity(), track->getPt()); + /* Form("%5.2:%5.2:%5.2", track->getPhi(), track->getPseudoRapidity(), track->getPt()) */ + //<getPhi()<<":"<getPseudoRapidity()<<":"<getPt() + std::cout << ") nclusters(" << track->getClusters().size() <<") "; + if (m_verbosity <= 10) { std::cout << std::endl; } + else { + int nclus = 0; + for (auto cluskey : track->getClusters()) { + std::cout << " " + << ((int) TrkrDefs::getHitSetKeyFromClusKey(cluskey)) <<":index(" << + ((int) TrkrDefs::getClusIndex(cluskey)) << ")"; + ++nclus; + if (nclusprint > 0 && nclus >= nclusprint) { + std::cout << " ... "; + break; + } + } + } + } + std::cout << PHWHERE << " ----- end of clusters " << std::endl; +} + diff --git a/simulation/g4simulation/g4tracking/TruthClusterizerBase.h b/simulation/g4simulation/g4tracking/TruthClusterizerBase.h new file mode 100644 index 0000000000..b084d7346b --- /dev/null +++ b/simulation/g4simulation/g4tracking/TruthClusterizerBase.h @@ -0,0 +1,77 @@ +#ifndef G4TRACKING_TRUTHCLUSTERIZERBASE +#define G4TRACKING_TRUTHCLUSTERIZERBASE + +// Generated March 2023, David Stewart +// +// Virtual base class used to cluster TrkrHits into TrkrClusters, but using only the reconstructed hits +// from phg4 embedded (``truth'') tracks. In each of the following modules, a child-class will be derived +// with the "cluster_hits()" virtual function implemented +// - PHG4MvtxHitReco +// - PHG4InttHitReco +// - PHG4TpcElectronDrift +// - (maybe?) tpot? +// +// It's job is to: +// (1) build TrkrTruthTracks in the TrkrTruthTrackContainer +// (2) build TrkrClusters in the truth clusters TrkrClusterContainer +// It does this by collecting the TrkrHit's associated with each PHG4 truth track, and when they +// are all collected, it calls the down-stream macros (the same ones which do the Svtx clustering) +// on this subset of the TrkrHits, and assigning these clusters to the TrkrClusterContainer and +// the associated TrkrTruthTrackContainer. + +#include +#include +#include +#include + +class PHCompositeNode; +class TrkrHitSetContainer; +class TrkrClusterContainer; +class TrkrTruthTrackContainer; +class TrkrTruthTrack; +class PHG4TruthInfoContainer; +class PHG4Hit; + +class TruthClusterizerBase { + protected: + TrkrHitSetContainer* m_hits ; + int m_verbosity { 0 }; + PHCompositeNode* m_topNode { nullptr }; + TrkrTruthTrackContainer* m_truthtracks { nullptr }; + TrkrClusterContainer* m_clusters { nullptr }; // cluster container passed to individual clusterers + PHG4TruthInfoContainer* m_truthinfo { nullptr }; + int m_trkid { -1 }; + bool m_is_emb { false }; + bool m_was_emb { false }; + bool m_is_new_track { false }; + TrkrTruthTrack* m_current_track { nullptr }; + + + std::map m_hitsetkey_cnt {}; // counter for making ckeys form hitsetkeys + + // implemented individually for mvtx, intt and tpc cluster hits + /* static int dummy_cluster_hits() { */ + /* return Fun4AllReturnCodes::EVENT_OK; */ + /* }; */ + + public: + TruthClusterizerBase ( ); + void init_clusterizer_base ( PHCompositeNode*& _topNode, int verbosity ); + virtual ~TruthClusterizerBase(); + + // main use functions + void check_g4hit_status (PHG4Hit*); + void transfer_clusters(TrkrClusterContainer*); + void update_track(); + void transfer_clusters(); + + void addhitset (TrkrDefs::hitsetkey, TrkrDefs::hitkey, float neffelectrons); + + // convenience + int Verbosity() { return m_verbosity; }; + void set_verbosity(int _) { m_verbosity = _; }; + void print_clusters(int nclusprint=20); + +}; + +#endif diff --git a/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.cc b/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.cc index 39573916e2..513e2737cc 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.cc +++ b/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.cc @@ -1,40 +1,34 @@ #include "GlobalVertexFastSimReco.h" -#include "GlobalVertexMap.h" // for GlobalVertexMap -#include "GlobalVertexMapv1.h" -#include "GlobalVertex.h" // for GlobalVertex -#include "GlobalVertexv1.h" +#include // for GlobalVertex +#include // for GlobalVertexMap +#include +#include #include #include #include -#include // for SubsysReco +#include // for SubsysReco #include #include -#include // for PHNode +#include // for PHNode #include -#include // for PHObject +#include // for PHObject #include #include -#include // for PHWHERE +#include // for PHWHERE #include -#include // for gsl_rng_alloc, gsl_rng_free +#include // for gsl_rng_alloc, gsl_rng_free #include -#include // for exit +#include // for exit #include -using namespace std; - -GlobalVertexFastSimReco::GlobalVertexFastSimReco(const string &name) +GlobalVertexFastSimReco::GlobalVertexFastSimReco(const std::string &name) : SubsysReco(name) - , _x_smear(NAN) - , _y_smear(NAN) - , _z_smear(NAN) - , _t_smear(NAN) { RandomGenerator = gsl_rng_alloc(gsl_rng_mt19937); } @@ -44,11 +38,6 @@ GlobalVertexFastSimReco::~GlobalVertexFastSimReco() gsl_rng_free(RandomGenerator); } -int GlobalVertexFastSimReco::Init(PHCompositeNode */*topNode*/) -{ - return Fun4AllReturnCodes::EVENT_OK; -} - int GlobalVertexFastSimReco::InitRun(PHCompositeNode *topNode) { if (isnan(_x_smear) || @@ -56,7 +45,7 @@ int GlobalVertexFastSimReco::InitRun(PHCompositeNode *topNode) isnan(_z_smear) || isnan(_t_smear)) { - cout << PHWHERE << "::ERROR - smearing must be defined for (x,y,z,t) via set_?_smearing(float)" << endl; + std::cout << PHWHERE << "::ERROR - smearing must be defined for (x,y,z,t) via set_?_smearing(float)" << std::endl; exit(-1); } @@ -65,13 +54,13 @@ int GlobalVertexFastSimReco::InitRun(PHCompositeNode *topNode) if (Verbosity() > 0) { - cout << "=================== GlobalVertexFastSimReco::InitRun() ====================" << endl; - cout << " x smearing: " << _x_smear << " cm " << endl; - cout << " y smearing: " << _y_smear << " cm " << endl; - cout << " z smearing: " << _z_smear << " cm " << endl; - cout << " t smearing: " << _t_smear << " cm " << endl; - cout << " random seed: " << seed << endl; - cout << "===========================================================================" << endl; + std::cout << "=================== GlobalVertexFastSimReco::InitRun() ====================" << std::endl; + std::cout << " x smearing: " << _x_smear << " cm " << std::endl; + std::cout << " y smearing: " << _y_smear << " cm " << std::endl; + std::cout << " z smearing: " << _z_smear << " cm " << std::endl; + std::cout << " t smearing: " << _t_smear << " cm " << std::endl; + std::cout << " random seed: " << seed << std::endl; + std::cout << "===========================================================================" << std::endl; } return CreateNodes(topNode); @@ -79,7 +68,10 @@ int GlobalVertexFastSimReco::InitRun(PHCompositeNode *topNode) int GlobalVertexFastSimReco::process_event(PHCompositeNode *topNode) { - if (Verbosity() > 1) cout << "GlobalVertexFastSimReco::process_event -- entered" << endl; + if (Verbosity() > 1) + { + std::cout << "GlobalVertexFastSimReco::process_event -- entered" << std::endl; + } //--------------------------------- // Get Objects off of the Node Tree @@ -87,14 +79,14 @@ int GlobalVertexFastSimReco::process_event(PHCompositeNode *topNode) PHG4TruthInfoContainer *truthinfo = findNode::getClass(topNode, "G4TruthInfo"); if (!truthinfo) { - cout << PHWHERE << "::ERROR - cannot find G4TruthInfo" << endl; + std::cout << PHWHERE << "::ERROR - cannot find G4TruthInfo" << std::endl; exit(-1); } GlobalVertexMap *vertexes = findNode::getClass(topNode, "GlobalVertexMap"); if (!vertexes) { - cout << PHWHERE << "::ERROR - cannot find GlobalVertexMap" << endl; + std::cout << PHWHERE << "::ERROR - cannot find GlobalVertexMap" << std::endl; exit(-1); } @@ -104,7 +96,22 @@ int GlobalVertexFastSimReco::process_event(PHCompositeNode *topNode) PHG4VtxPoint *point = truthinfo->GetPrimaryVtx(truthinfo->GetPrimaryVertexIndex()); - GlobalVertex *vertex = new GlobalVertexv1(); + GlobalVertex *vertex = new GlobalVertexv1(GlobalVertex::TRUTH); + vertex->set_x(point->get_x()); + vertex->set_y(point->get_y()); + vertex->set_z(point->get_z()); + vertex->set_t(point->get_t()); + vertex->set_t_err(0.); + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + vertex->set_error(i, j, 0.0); + } + } + vertexes->insert(vertex); + + vertex = new GlobalVertexv1(GlobalVertex::SMEARED); vertex->set_x(point->get_x() + gsl_ran_gaussian(RandomGenerator, _x_smear)); vertex->set_y(point->get_y() + gsl_ran_gaussian(RandomGenerator, _y_smear)); @@ -130,11 +137,6 @@ int GlobalVertexFastSimReco::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } -int GlobalVertexFastSimReco::End(PHCompositeNode */*topNode*/) -{ - return Fun4AllReturnCodes::EVENT_OK; -} - int GlobalVertexFastSimReco::CreateNodes(PHCompositeNode *topNode) { PHNodeIterator iter(topNode); @@ -143,7 +145,7 @@ int GlobalVertexFastSimReco::CreateNodes(PHCompositeNode *topNode) PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); if (!dstNode) { - cout << PHWHERE << "DST Node missing, doing nothing." << endl; + std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; return Fun4AllReturnCodes::ABORTRUN; } @@ -165,7 +167,7 @@ int GlobalVertexFastSimReco::CreateNodes(PHCompositeNode *topNode) } else { - cout << PHWHERE << "::ERROR - GlobalVertexMap pre-exists, but should not if running FastSim" << endl; + std::cout << PHWHERE << "::ERROR - GlobalVertexMap pre-exists, but should not if running FastSim" << std::endl; exit(-1); } diff --git a/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.h b/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.h index 6bd5fcf334..1dcdc281b9 100644 --- a/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.h +++ b/simulation/g4simulation/g4vertex/GlobalVertexFastSimReco.h @@ -13,7 +13,8 @@ #include -#include // for string +#include +#include // for string class PHCompositeNode; @@ -27,10 +28,8 @@ class GlobalVertexFastSimReco : public SubsysReco GlobalVertexFastSimReco(const std::string &name = "GlobalVertexFastSimReco"); ~GlobalVertexFastSimReco() override; - int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; - int End(PHCompositeNode *topNode) override; void set_x_smearing(const float x_smear) { _x_smear = x_smear; } void set_y_smearing(const float y_smear) { _y_smear = y_smear; } @@ -40,11 +39,11 @@ class GlobalVertexFastSimReco : public SubsysReco private: int CreateNodes(PHCompositeNode *topNode); - float _x_smear; - float _y_smear; - float _z_smear; - float _t_smear; - gsl_rng *RandomGenerator; + float _x_smear = std::numeric_limits::quiet_NaN(); + float _y_smear = std::numeric_limits::quiet_NaN(); + float _z_smear = std::numeric_limits::quiet_NaN(); + float _t_smear = std::numeric_limits::quiet_NaN(); + gsl_rng *RandomGenerator = nullptr; }; #endif // G4VERTEX_GLOBALVERTEXFASTSIMRECO_H diff --git a/simulation/g4simulation/g4vertex/GlobalVertexMapv1.cc b/simulation/g4simulation/g4vertex/GlobalVertexMapv1.cc deleted file mode 100644 index 1cd4273fa2..0000000000 --- a/simulation/g4simulation/g4vertex/GlobalVertexMapv1.cc +++ /dev/null @@ -1,60 +0,0 @@ -#include "GlobalVertexMapv1.h" - -#include "GlobalVertex.h" -#include "GlobalVertexMap.h" - -#include // for reverse_iterator -#include // for pair, make_pair - -using namespace std; - -GlobalVertexMapv1::GlobalVertexMapv1() - : _map() -{ -} - -GlobalVertexMapv1::~GlobalVertexMapv1() -{ - clear(); -} - -void GlobalVertexMapv1::identify(ostream& os) const -{ - os << "GlobalVertexMapv1: size = " << _map.size() << endl; - return; -} - -void GlobalVertexMapv1::clear() -{ - for (Iter iter = _map.begin(); - iter != _map.end(); - ++iter) - { - delete iter->second; - } - _map.clear(); - return; -} - -const GlobalVertex* GlobalVertexMapv1::get(unsigned int id) const -{ - ConstIter iter = _map.find(id); - if (iter == _map.end()) return nullptr; - return iter->second; -} - -GlobalVertex* GlobalVertexMapv1::get(unsigned int id) -{ - Iter iter = _map.find(id); - if (iter == _map.end()) return nullptr; - return iter->second; -} - -GlobalVertex* GlobalVertexMapv1::insert(GlobalVertex* clus) -{ - unsigned int index = 0; - if (!_map.empty()) index = _map.rbegin()->first + 1; - _map.insert(make_pair(index, clus)); - _map[index]->set_id(index); - return _map[index]; -} diff --git a/simulation/g4simulation/g4vertex/GlobalVertexv1.cc b/simulation/g4simulation/g4vertex/GlobalVertexv1.cc deleted file mode 100644 index 5baeef01cb..0000000000 --- a/simulation/g4simulation/g4vertex/GlobalVertexv1.cc +++ /dev/null @@ -1,105 +0,0 @@ -#include "GlobalVertexv1.h" - -#include - -using namespace std; - -GlobalVertexv1::GlobalVertexv1() - : _id(0xFFFFFFFF) - , _t(NAN) - , _t_err(NAN) - , _pos() - , _chisq(NAN) - , _ndof(0xFFFFFFFF) - , _err() - , _vtx_ids() -{ - for (int i = 0; i < 3; ++i) _pos[i] = NAN; - - for (int j = 0; j < 3; ++j) - { - for (int i = j; i < 3; ++i) - { - set_error(i, j, NAN); - } - } -} - -GlobalVertexv1::~GlobalVertexv1() {} - -void GlobalVertexv1::identify(ostream& os) const -{ - os << "---GlobalVertexv1-----------------------" << endl; - os << "vertexid: " << get_id() << endl; - - os << " t = " << get_t() << endl; - - os << " (x,y,z) = (" << get_position(0); - os << ", " << get_position(1) << ", "; - os << get_position(2) << ") cm" << endl; - - os << " chisq = " << get_chisq() << ", "; - os << " ndof = " << get_ndof() << endl; - - os << " ( "; - os << get_error(0, 0) << " , "; - os << get_error(0, 1) << " , "; - os << get_error(0, 2) << " )" << endl; - os << " err = ( "; - os << get_error(1, 0) << " , "; - os << get_error(1, 1) << " , "; - os << get_error(1, 2) << " )" << endl; - os << " ( "; - os << get_error(2, 0) << " , "; - os << get_error(2, 1) << " , "; - os << get_error(2, 2) << " )" << endl; - - os << " list of vtx ids: " << endl; - for (ConstVtxIter iter = begin_vtxids(); iter != end_vtxids(); ++iter) - { - os << " " << iter->first << " => " << iter->second << endl; - } - os << "-----------------------------------------------" << endl; - - return; -} - -int GlobalVertexv1::isValid() const -{ - if (_id == 0xFFFFFFFF) return 0; - if (isnan(_t)) return 0; - if (isnan(_t_err)) return 0; - if (isnan(_chisq)) return 0; - if (_ndof == 0xFFFFFFFF) return 0; - - for (int i = 0; i < 3; ++i) - { - if (isnan(_pos[i])) return 0; - } - for (int j = 0; j < 3; ++j) - { - for (int i = j; i < 3; ++i) - { - if (isnan(get_error(i, j))) return 0; - } - } - if (_vtx_ids.empty()) return 0; - return 1; -} - -void GlobalVertexv1::set_error(unsigned int i, unsigned int j, float value) -{ - _err[covar_index(i, j)] = value; - return; -} - -float GlobalVertexv1::get_error(unsigned int i, unsigned int j) const -{ - return _err[covar_index(i, j)]; -} - -unsigned int GlobalVertexv1::covar_index(unsigned int i, unsigned int j) const -{ - if (i > j) std::swap(i, j); - return i + 1 + (j + 1) * (j) / 2 - 1; -} diff --git a/simulation/g4simulation/g4vertex/Makefile.am b/simulation/g4simulation/g4vertex/Makefile.am index 60caa2aa8f..7812996dcd 100644 --- a/simulation/g4simulation/g4vertex/Makefile.am +++ b/simulation/g4simulation/g4vertex/Makefile.am @@ -6,55 +6,25 @@ AM_CPPFLAGS = \ -I`root-config --incdir` lib_LTLIBRARIES = \ - libg4vertex_io.la \ libg4vertex.la AM_LDFLAGS = \ -L$(libdir) \ -L$(OFFLINE_MAIN)/lib -libg4vertex_io_la_LIBADD = \ - -lphool \ - -ltrackbase_historic_io - libg4vertex_la_LIBADD = \ + -lbbc_io \ -lg4detectors \ -lfun4all \ -lg4bbc_io \ -ltrackbase_historic_io \ - libg4vertex_io.la + -lglobalvertex_io pkginclude_HEADERS = \ - GlobalVertex.h \ - GlobalVertexv1.h \ - GlobalVertexFastSimReco.h \ - GlobalVertexMap.h \ - GlobalVertexMapv1.h \ - GlobalVertexReco.h - -ROOTDICTS = \ - GlobalVertex_Dict.cc \ - GlobalVertexv1_Dict.cc \ - GlobalVertexMap_Dict.cc \ - GlobalVertexMapv1_Dict.cc - -pcmdir = $(libdir) -nobase_dist_pcm_DATA = \ - GlobalVertex_Dict_rdict.pcm \ - GlobalVertexv1_Dict_rdict.pcm \ - GlobalVertexMap_Dict_rdict.pcm \ - GlobalVertexMapv1_Dict_rdict.pcm - -libg4vertex_io_la_SOURCES = \ - $(ROOTDICTS) \ - GlobalVertex.cc \ - GlobalVertexv1.cc \ - GlobalVertexMap.cc \ - GlobalVertexMapv1.cc + GlobalVertexFastSimReco.h libg4vertex_la_SOURCES = \ - GlobalVertexFastSimReco.cc \ - GlobalVertexReco.cc + GlobalVertexFastSimReco.cc # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h @@ -67,15 +37,11 @@ libg4vertex_la_SOURCES = \ # linking tests noinst_PROGRAMS = \ - testexternals_g4vertex_io \ testexternals_g4vertex BUILT_SOURCES = \ testexternals.cc -testexternals_g4vertex_io_SOURCES = testexternals.cc -testexternals_g4vertex_io_LDADD = libg4vertex_io.la - testexternals_g4vertex_SOURCES = testexternals.cc testexternals_g4vertex_LDADD = libg4vertex.la diff --git a/simulation/g4simulation/tpcresponse/TpcRS.cc b/simulation/g4simulation/tpcresponse/TpcRS.cc deleted file mode 100644 index 35d7dbc8ba..0000000000 --- a/simulation/g4simulation/tpcresponse/TpcRS.cc +++ /dev/null @@ -1,193 +0,0 @@ -//____________________________________________________________________________.. -// -// This is a template for a Fun4All SubsysReco module with all methods from the -// $OFFLINE_MAIN/include/fun4all/SubsysReco.h baseclass -// You do not have to implement all of them, you can just remove unused methods -// here and in TpcRS.h. -// -// TpcRS(const std::string &name = "TpcRS") -// everything is keyed to TpcRS, duplicate names do work but it makes -// e.g. finding culprits in logs difficult or getting a pointer to the module -// from the command line -// -// TpcRS::~TpcRS() -// this is called when the Fun4AllServer is deleted at the end of running. Be -// mindful what you delete - you do loose ownership of object you put on the node tree -// -// int TpcRS::Init(PHCompositeNode *topNode) -// This method is called when the module is registered with the Fun4AllServer. You -// can create historgrams here or put objects on the node tree but be aware that -// modules which haven't been registered yet did not put antyhing on the node tree -// -// int TpcRS::InitRun(PHCompositeNode *topNode) -// This method is called when the first event is read (or generated). At -// this point the run number is known (which is mainly interesting for raw data -// processing). Also all objects are on the node tree in case your module's action -// depends on what else is around. Last chance to put nodes under the DST Node -// We mix events during readback if branches are added after the first event -// -// int TpcRS::process_event(PHCompositeNode *topNode) -// called for every event. Return codes trigger actions, you find them in -// $OFFLINE_MAIN/include/fun4all/Fun4AllReturnCodes.h -// everything is good: -// return Fun4AllReturnCodes::EVENT_OK -// abort event reconstruction, clear everything and process next event: -// return Fun4AllReturnCodes::ABORT_EVENT; -// proceed but do not save this event in output (needs output manager setting): -// return Fun4AllReturnCodes::DISCARD_EVENT; -// abort processing: -// return Fun4AllReturnCodes::ABORT_RUN -// all other integers will lead to an error and abort of processing -// -// int TpcRS::ResetEvent(PHCompositeNode *topNode) -// If you have internal data structures (arrays, stl containers) which needs clearing -// after each event, this is the place to do that. The nodes under the DST node are cleared -// by the framework -// -// int TpcRS::EndRun(const int runnumber) -// This method is called at the end of a run when an event from a new run is -// encountered. Useful when analyzing multiple runs (raw data). Also called at -// the end of processing (before the End() method) -// -// int TpcRS::End(PHCompositeNode *topNode) -// This is called at the end of processing. It needs to be called by the macro -// by Fun4AllServer::End(), so do not forget this in your macro -// -// int TpcRS::Reset(PHCompositeNode *topNode) -// not really used - it is called before the dtor is called -// -// void TpcRS::Print(const std::string &what) const -// Called from the command line - useful to print information when you need it -// -//____________________________________________________________________________.. - -#include "TpcRS.h" - -#include -#include -#include -#include - -#include - -#include -#include - -#include - -//____________________________________________________________________________.. -TpcRS::TpcRS(const std::string &name) - : SubsysReco(name) -{ - std::cout << "TpcRS::TpcRS(const std::string &name) Calling ctor" << std::endl; -} - -//____________________________________________________________________________.. -TpcRS::~TpcRS() -{ - delete simulator; - std::cout << "TpcRS::~TpcRS() Calling dtor" << std::endl; -} - -//____________________________________________________________________________.. -int TpcRS::Init(PHCompositeNode *topNode) -{ - std::cout << "TpcRS::Init(PHCompositeNode *topNode) Initializing" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int TpcRS::InitRun(PHCompositeNode *topNode) -{ - std::cout << "TpcRS::InitRun(PHCompositeNode *topNode) Initializing for Run XXX" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int TpcRS::process_event(PHCompositeNode *topNode) -{ - std::cout << "TpcRS::process_event(PHCompositeNode *topNode)" << std::endl; - PHG4TruthInfoContainer *TruthInfo = findNode::getClass(topNode, "G4TruthInfo"); - if (!TruthInfo) - { - std::cout << PHWHERE << " ERROR: Can't find G4TruthInfo" << std::endl; - gSystem->Exit(-1); - } - - PHG4HitContainer *hits = findNode::getClass(topNode, "G4HIT_TPC"); - if (!hits) - { - std::cout << "no G4HITS_TPC node" << std::endl; - gSystem->Exit(-1); - } - PHG4HitContainer::ConstRange hit_range = hits->getHits(); - for (PHG4HitContainer::ConstIterator hit_iter = hit_range.first; hit_iter != hit_range.second; hit_iter++) - { - PHG4Particle *particle = TruthInfo->GetParticle(hit_iter->second->get_trkid()); - tpcrs::SimulatedHit simu_hit; - if (hit_iter->second->get_trkid() == 0) - { - std::cout << "trackid=0, x: " << hit_iter->second->get_avg_x() << std::endl; - } - simu_hit.track_id = hit_iter->second->get_trkid(); - simu_hit.particle_id = particle->get_pid(); - simu_hit.x = hit_iter->second->get_avg_x(); - simu_hit.y = hit_iter->second->get_avg_y(); - simu_hit.z = hit_iter->second->get_avg_z(); - simu_hit.px = 0.5 * (hit_iter->second->get_px(0) + hit_iter->second->get_px(1)); - simu_hit.py = 0.5 * (hit_iter->second->get_py(0) + hit_iter->second->get_py(1)); - simu_hit.pz = 0.5 * (hit_iter->second->get_pz(0) + hit_iter->second->get_pz(1)); - simu_hit.de = hit_iter->second->get_edep(); - simu_hit.ds = hit_iter->second->get_path_length(); - simu_hit.tof = hit_iter->second->get_avg_t(); - simu_hits.push_back(simu_hit); - } - simulator->Distort(begin(simu_hits), end(simu_hits), std::back_inserter(dist_hits)); - - // simulator->Digitize(begin(simu_hits), end(simu_hits), std::back_inserter(digi_hits)); - - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int TpcRS::ResetEvent(PHCompositeNode *topNode) -{ - std::cout << "TpcRS::ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event" << std::endl; - simu_hits.clear(); - dist_hits.clear(); - digi_hits.clear(); - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int TpcRS::EndRun(const int runnumber) -{ - std::cout << "TpcRS::EndRun(const int runnumber) Ending Run for Run " << runnumber << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int TpcRS::End(PHCompositeNode *topNode) -{ - std::cout << "TpcRS::End(PHCompositeNode *topNode) This is the End..." << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int TpcRS::Reset(PHCompositeNode *topNode) -{ - std::cout << "TpcRS::Reset(PHCompositeNode *topNode) being Reset" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -void TpcRS::Print(const std::string &what) const -{ - std::cout << "TpcRS::Print(const std::string &what) const Printing info for " << what << std::endl; -} - -void TpcRS::SetupConfigurator(const std::string &filename) -{ - cfg = new tpcrs::Configurator("simple", filename); - simulator = new tpcrs::Simulator(*cfg); -} diff --git a/simulation/g4simulation/tpcresponse/TpcRS.h b/simulation/g4simulation/tpcresponse/TpcRS.h deleted file mode 100644 index 0039a8a046..0000000000 --- a/simulation/g4simulation/tpcresponse/TpcRS.h +++ /dev/null @@ -1,71 +0,0 @@ -// Tell emacs that this is a C++ source -// -*- C++ -*-. -#ifndef TPCRS_H -#define TPCRS_H - -#include - -//#if defined(__CLING__) -//namespace tpcrs { -//template< typename Base_t, typename Chair_t, typename Struct_t > -// std::string ConfigStruct< Base_t, Chair_t, Struct_t >::name{}; -//} -//#endif -#include - -#include -#include - -class PHCompositeNode; - -class TpcRS : public SubsysReco -{ - public: - TpcRS(const std::string &name = "TpcRS"); - - virtual ~TpcRS(); - - /** Called during initialization. - Typically this is where you can book histograms, and e.g. - register them to Fun4AllServer (so they can be output to file - using Fun4AllServer::dumpHistos() method). - */ - int Init(PHCompositeNode *topNode) override; - - /** Called for first event when run number is known. - Typically this is where you may want to fetch data from - database, because you know the run number. A place - to book histograms which have to know the run number. - */ - int InitRun(PHCompositeNode *topNode) override; - - /** Called for each event. - This is where you do the real work. - */ - int process_event(PHCompositeNode *topNode) override; - - /// Clean up internals after each event. - int ResetEvent(PHCompositeNode *topNode) override; - - /// Called at the end of each run. - int EndRun(const int runnumber) override; - - /// Called at the end of all processing. - int End(PHCompositeNode *topNode) override; - - /// Reset - int Reset(PHCompositeNode * /*topNode*/) override; - - void Print(const std::string &what = "ALL") const override; - - void SetupConfigurator(const std::string &filename); - - private: - tpcrs::Configurator *cfg = nullptr; - tpcrs::Simulator *simulator = nullptr; - std::vector simu_hits; - std::vector dist_hits; - std::vector digi_hits; -}; - -#endif // TPCRS_H