14 #include "G4RunManager.hh"
15 #include "G4EventManager.hh"
16 #include "G4UImanager.hh"
17 #include "G4TrajectoryContainer.hh"
18 #include "G4VVisManager.hh"
21 #include "G4ThreeVector.hh"
22 #include "G4TransportationManager.hh"
23 #include "G4Navigator.hh"
24 #include "G4SDManager.hh"
25 #include "G4DigiManager.hh"
26 #include "G4UnitsTable.hh"
27 #include "G4UIcmdWith3VectorAndUnit.hh"
29 #include "G4PhysicalConstants.hh"
30 #include "G4SystemOfUnits.hh"
42 #include "TStopwatch.h"
44 #ifndef _SAVE_RAW_HITS
45 #define _SAVE_RAW_HITS
54 #define NPMTS_VERBOSE -1
56 #define VERBOSE_PMT -1
58 #ifndef TIME_DAQ_STEPS
65 :runAction(myRun), generatorAction(myGenerator),
66 detectorConstructor(myDetector),
67 ConstructedDAQClasses(false),
72 G4DigiManager* DMman = G4DigiManager::GetDMpointer();
76 DMman->AddNewModule(WCDMPMT);
80 DMman->AddNewModule(WCDNM);
86 WCDMPMT_OD =
new WCSimWCPMT(
"WCReadoutPMT_OD", myDetector,
"OD");
87 DMman->AddNewModule(WCDMPMT_OD);
91 DMman->AddNewModule(WCDNM_OD);
102 G4cerr <<
"WCSimEventAction::CreateDAQInstances() has already been called. Exiting..." << G4endl;
107 G4cout <<
"Creating digitizer and trigger class instances in WCSimEventAction::CreateDAQInstances()" << G4endl;
109 G4DigiManager* DMman = G4DigiManager::GetDMpointer();
114 DMman->AddNewModule(WCDM);
124 DMman->AddNewModule(WCTM);
128 DMman->AddNewModule(WCTM);
132 DMman->AddNewModule(WCTM);
135 G4cerr <<
"Unknown TriggerChoice " <<
TriggerChoice << G4endl;
146 DMman->AddNewModule(WCDM_OD);
153 DMman->AddNewModule(WCTM_OD);
157 DMman->AddNewModule(WCTM_OD);
161 DMman->AddNewModule(WCTM);
163 G4cerr <<
"Unknown TriggerChoice " <<
TriggerChoice << G4endl;
177 G4DigiManager* DMman = G4DigiManager::GetDMpointer();
189 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
195 G4TrajectoryContainer* trajectoryContainer = evt->GetTrajectoryContainer();
197 G4int n_trajectories = 0;
198 if (trajectoryContainer) n_trajectories = trajectoryContainer->entries();
204 G4int event_id = evt->GetEventID();
211 for( Int_t u=0; u<nvtxs; u++ ){
223 G4SDManager* SDman = G4SDManager::GetSDMpointer();
226 G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
231 G4String name = WCIDCollectionName;
232 G4int collectionID = SDman->GetCollectionID(name);
235 G4cout <<
"WCSimEventAction::EndOfEventAction ☆ (WCSimWCHitsCollection*)" << WCIDCollectionName
236 <<
" has " << WCHC->entries() <<
" entries" << G4endl;
252 G4DigiManager* DMman = G4DigiManager::GetDMpointer();
256 (
WCSimWCPMT*)DMman->FindDigitizerModule(
"WCReadoutPMT");
264 #ifdef TIME_DAQ_STEPS
265 TStopwatch* ms =
new TStopwatch();
312 #ifdef TIME_DAQ_STEPS
314 G4cout <<
" Digtization : Real = " << ms->RealTime()
315 <<
" ; CPU = " << ms->CpuTime() <<
"\n";
319 G4int WCDChitsID = DMman->GetDigiCollectionID(
"WCRawPMTSignalCollection");
323 G4int WCDCID = DMman->GetDigiCollectionID(
"WCDigitizedCollection");
357 G4String name = WCODCollectionName;
358 G4int collectionID = SDman->GetCollectionID(name);
361 G4cout<<
"WCSimEventAction::EndOfEventAction() (WCSimWCHitsCollection*)" << WCODCollectionName
362 <<
" has " << WCHC_OD->entries() <<
" entries" << G4endl;
366 WCDMPMT_OD = (
WCSimWCPMT*)DMman->FindDigitizerModule(
"WCReadoutPMT_OD");
367 if(WCDMPMT_OD == 0) G4cout <<
"WCReadoutPMT_OD digitzer module not found!" << G4endl;
372 if(WCDNM_OD == 0) G4cout <<
"WCDarkNoise_OD dark noise module not found!" << G4endl;
376 if(WCDM_OD == 0) G4cout <<
"WCReadoutDigits_OD digitizer module not found!" << G4endl;
380 if(WCTM_OD == 0) G4cout <<
"WCReadout_OD trigger module not found!" << G4endl;
384 WCDChitsID_OD = DMman->GetDigiCollectionID(
"WCRawPMTSignalCollection_OD");
387 G4cout <<
"WCSimEventAction::EndOfEventAction() retrieving raw hits" << G4endl
388 <<
" (WCSimWCDigitsCollection*)WCRawPMTSignalCollection_OD for FillRootEvent, which has ";
390 G4cout << WCDC_hits_OD->entries();
394 G4cout <<
" entries" << G4endl;
396 G4int WCDCID_OD = DMman->GetDigiCollectionID(
"WCDigitizedCollection_OD");
399 G4cout <<
"WCSimEventAction::EndOfEventAction() retrieving readout hits"
400 <<
" (WCSimWCTriggeredDigitsCollection*)WCDigitizedCollection_OD for FillRootEvent, which has ";
402 G4cout << WCDC_OD->entries();
406 G4cout <<
" entries" << G4endl;
412 for(
unsigned int ivx = 0;ivx<nvtxs;ivx++)
415 for( Int_t u=0; u<nvtxs; u++ ){
434 for( Int_t u=0; u<nvtxs; u++ ){
441 G4ThreeVector beamdir;
467 double distance=10000.0;
468 for(
int idim=0;idim<3;idim++)
478 G4double targetpmag = 0.0, targetmass = 0.0;
485 targetmass = targetenergy;
487 targetmass = particleTable->FindParticle(targetpdg)->GetPDGMass();
488 if (targetenergy > targetmass)
491 targetpmag = sqrt(targetenergy*targetenergy - targetmass*targetmass);
527 G4int PDG_e=11,PDG_v_e=12,PDG_gam=22;
528 for( Int_t u=0; u<nvtxs; u++ ){
529 G4int trkid_e=INT_MAX,trkid_v_e=INT_MAX,trkid_gam=INT_MAX;
530 G4int idx_e=INT_MAX,idx_v_e=INT_MAX,idx_gam=INT_MAX;
531 for (G4int i=0; i < n_trajectories; i++)
552 if(idx_e != INT_MAX) {
581 if(idx_v_e != INT_MAX) {
611 if(idx_gam != INT_MAX) {
677 tree->SetEntries(
GetRunAction()->GetNumberOfEventsGenerated());
715 G4Navigator* tmpNavigator =
716 G4TransportationManager::GetTransportationManager()->
717 GetNavigatorForTracking();
719 G4VPhysicalVolume* tmpVolume = tmpNavigator->LocateGlobalPointAndSetup(vtx);
720 G4String vtxVolumeName = tmpVolume->GetName();
724 if ( vtxVolumeName ==
"outerTube" ||
725 vtxVolumeName ==
"innerTube" ||
726 vtxVolumeName ==
"rearEndCap"||
727 vtxVolumeName ==
"frontEndCap" )
730 else if ( vtxVolumeName.contains(
"WC") && !vtxVolumeName.contains(
"FV") )
733 if ((vtxVolumeName.contains(
"WCBarrel"))|| (vtxVolumeName.contains(
"Tank")))
735 else if (vtxVolumeName ==
"WCBox")
737 else if (vtxVolumeName.contains(
"PMT") ||
738 vtxVolumeName.contains(
"Cap") ||
739 vtxVolumeName.contains(
"Cell"))
741 else if (vtxVolumeName.contains(
"OD"))
745 G4cout << vtxVolumeName <<
" unkown vtxVolumeName " << G4endl;
749 else if ( vtxVolumeName ==
"expHall" )
751 else if ( vtxVolumeName ==
"catcher" )
762 if ( stopVolumeName.contains(
"WC") && !stopVolumeName.contains(
"FV") )
765 if ((stopVolumeName.contains(
"WCBarrel"))|| (stopVolumeName.contains(
"Tank")))
767 else if (stopVolumeName ==
"WCBox")
769 else if (stopVolumeName.contains(
"PMT") ||
770 stopVolumeName.contains(
"Cap") ||
771 stopVolumeName.contains(
"Cell"))
773 else if (stopVolumeName.contains(
"OD"))
777 G4cout << stopVolumeName <<
" unkown stopVolumeName " << G4endl;
782 else if ( stopVolumeName.contains(
"FV") )
784 if (stopVolumeName ==
"WCFVBarrel" ||
785 stopVolumeName ==
"WCFVAnnulus" ||
786 stopVolumeName ==
"WCFVRing" )
788 else if (stopVolumeName.contains(
"FVPMT"))
792 G4cout << stopVolumeName <<
" unkown stopVolumeName " << G4endl;
796 else if ( stopVolumeName ==
"expHall" )
798 else if ( stopVolumeName ==
"catcher" )
807 G4TrajectoryContainer* TC,
810 G4String detectorElement)
822 G4DigiManager* DMman = G4DigiManager::GetDMpointer();
824 if(detectorElement==
"tank"){
826 }
else if(detectorElement==
"OD"){
830 for (
int index = 0 ; index < ngates ; index++)
834 wcsimrootevent = wcsimrootsuperevent->
GetTrigger(index);
846 wcsimrootevent = wcsimrootsuperevent->
GetTrigger(0);
853 for( Int_t u=0; u<jhfNtuple.
nvtxs; u++ ){
855 for (
int j=0;j<4;j++)
862 wcsimrootevent->
SetJp(jhfNtuple.
jp);
871 for (k=0;k<jhfNtuple.
npar;k++)
877 for (
int l=0;l<3;l++)
879 dir[l]=jhfNtuple.
dir[k][l];
880 pdir[l]=jhfNtuple.
pdir[k][l];
881 stop[l]=jhfNtuple.
stop[k][l];
882 start[l]=jhfNtuple.
start[k][l];
899 jhfNtuple.
time[k],0);
904 std::set<int> pizeroList;
906 std::set<int> muonList;
907 std::set<int> antimuonList;
909 std::set<int> pionList;
910 std::set<int> antipionList;
911 std::set<int> primaryList;
917 Double_t gammaVtx[2][3];
920 G4int n_trajectories = 0;
922 n_trajectories = TC->entries();
929 for (
int i=0; i <n_trajectories; i++)
949 G4TrajectoryPoint* aa = (G4TrajectoryPoint*)trj->
GetPoint(0) ;
956 G4double mommag = mom.mag();
957 G4double
energy = sqrt(mom.mag2() + mass*mass);
959 G4ThreeVector Start = aa->GetPosition();
975 }
else if (pizeroList.count(trj->
GetParentID()) ) {
979 }
else if (antimuonList.count(trj->
GetParentID()) ) {
981 }
else if (antipionList.count(trj->
GetParentID()) ) {
985 }
else if (primaryList.count(trj->
GetParentID()) ) {
999 for (
int l=0;l<3;l++)
1001 dir[l]= mom[l]/mommag;
1004 start[l]=Start[l]/cm;
1010 if ( ! ( (ipnu==22)&&(parentType==999)) ) {
1018 if (choose_event >= ngates) choose_event = ngates-1;
1022 wcsimrootevent= wcsimrootsuperevent->
GetTrigger(choose_event);
1041 G4cout<<
"Pi0 parentType: " << parentType <<G4endl;
1042 if (parentType == 111)
1045 G4cout<<
"WARNING: more than 2 primary gammas found"<<G4endl;
1049 for (
int y=0;y<3;y++)
1051 pi0Vtx[y] = start[y];
1052 gammaVtx[r][y] = stop[y];
1060 G4cout<<
"Pi0 data: " <<
id <<G4endl;
1061 wcsimrootevent->
SetPi0Info(pi0Vtx, gammaID, gammaE, gammaVtx);
1069 wcsimrootevent = wcsimrootsuperevent->
GetTrigger(0);
1073 #ifdef _SAVE_RAW_HITS
1080 #ifdef _SAVE_RAW_HITS_VERBOSE
1081 G4cout<<
"RAW HITS"<<G4endl;
1084 std::vector<double> truetime, smeartime;
1085 std::vector<int> primaryParentID;
1086 double hit_time_smear, hit_time_true;
1089 for(
int idigi = 0; idigi < WCDC_hits->entries(); idigi++) {
1090 int digi_tubeid = (*WCDC_hits)[idigi]->GetTubeID();
1091 for(G4int
id = 0;
id < (*WCDC_hits)[idigi]->GetTotalPe();
id++){
1092 hit_time_true = (*WCDC_hits)[idigi]->GetPreSmearTime(
id);
1093 hit_parentid = (*WCDC_hits)[idigi]->GetParentID(
id);
1094 truetime.push_back(hit_time_true);
1095 primaryParentID.push_back(hit_parentid);
1096 #ifdef _SAVE_RAW_HITS_VERBOSE
1097 hit_time_smear = (*WCDC_hits)[idigi]->GetTime(
id);
1098 smeartime.push_back(hit_time_smear);
1101 #ifdef _SAVE_RAW_HITS_VERBOSE
1103 G4cout <<
"Adding " << truetime.size()
1104 <<
" Cherenkov hits in tube " << digi_tubeid
1105 <<
" with truetime:smeartime:primaryparentID";
1106 for(G4int
id = 0;
id < truetime.size();
id++) {
1107 G4cout <<
" " << truetime[id]
1108 <<
"\t" << smeartime[id]
1109 <<
"\t" << primaryParentID[id] << G4endl;
1119 primaryParentID.clear();
1122 #endif //_SAVE_RAW_HITS
1128 #ifdef SAVE_DIGITS_VERBOSE
1129 G4cout <<
"DIGI HITS" << G4endl;
1132 G4double sumq_tmp = 0.;
1134 for (
int index = 0 ; index < ngates ; index++)
1138 int countdigihits = 0;
1139 wcsimrootevent = wcsimrootsuperevent->
GetTrigger(index);
1140 for (k=0;k<WCDC->entries();k++)
1142 if ( (*WCDC)[k]->HasHitsInGate(index)) {
1143 std::vector<double> vec_pe = (*WCDC)[k]->GetPe(index);
1144 std::vector<double> vec_time = (*WCDC)[k]->GetTime(index);
1145 std::vector<std::vector<int> > vec_digicomp = (*WCDC)[k]->GetDigiCompositionInfo(index);
1146 const int tubeID = (*WCDC)[k]->GetTubeID();
1147 assert(vec_pe.size() == vec_time.size());
1148 assert(vec_pe.size() == vec_digicomp.size());
1149 for(
unsigned int iv = 0; iv < vec_pe.size(); iv++) {
1150 #ifdef SAVE_DIGITS_VERBOSE
1152 G4cout <<
"Adding digit " << iv
1153 <<
" for PMT " << tubeID
1154 <<
" pe " << vec_pe[iv]
1155 <<
" time " << vec_time[iv]
1157 for(
unsigned int ivv = 0; ivv < vec_digicomp[iv].size(); ivv++)
1158 G4cout <<
" " << vec_digicomp[iv][ivv];
1162 assert(vec_digicomp[iv].size() > 0);
1164 tubeID, vec_digicomp[iv]);
1165 sumq_tmp += vec_pe[iv];
1171 wcsimrootevent->
SetSumQ(sumq_tmp);
1173 #ifdef SAVE_DIGITS_VERBOSE
1174 G4cout <<
"checking digi hits ...\n";
1175 G4cout <<
"hits collection size (number of PMTs hit) = " <<
1177 G4cout <<
"hits collection size (number of true photon + dark noise hits) = " <<
1179 G4cout <<
"digihits collection size = " <<
1181 G4cout <<
"tracks collection size = " <<
1182 wcsimrootevent->
GetTracks()->GetEntries()
1183 <<
" get ntracks = " << wcsimrootevent->
GetNtrack() <<
"\n";
1192 wcsimrootevent = wcsimrootsuperevent->
GetTrigger(0);
1198 wcsimrootevent = wcsimrootsuperevent->
GetTrigger(i);
1199 G4cout <<
">>>Root event "
1206 #ifdef _SAVE_RAW_HITS
double pdir[MAX_N_PRIMARIES][3]
WCSimPrimaryGeneratorAction * generatorAction
void SetRelativeDigitizedHitTime(bool val)
A simple NDigits trigger class.
void SetNumDigitizedTubes(Int_t i)
G4double GetTargetEnergy(G4int n=0)
void SaveOptionsToOutput(WCSimRootOptions *wcopt)
Save current values of options.
TBranch * GetBranch(G4String detectorElement="tank")
G4ThreeVector GetInitialMomentum() const
Double_t GetTriggerTime(int i)
Get the time of the ith trigger.
bool ConstructedDAQClasses
int stopvol[MAX_N_PRIMARIES]
double stop[MAX_N_PRIMARIES][3]
void EndOfEventAction(const G4Event *)
virtual G4VTrajectoryPoint * GetPoint(G4int i) const
WCSimRootCherenkovHit * AddCherenkovHit(Int_t tubeID, std::vector< Double_t > truetime, std::vector< Int_t > primParID)
double time[MAX_N_PRIMARIES]
WCSimRootEvent * GetRootEvent(G4String detectorElement="tank")
TriggerType_t GetTriggerType(int i)
Get the trigger type of the ith trigger.
TClonesArray * GetCherenkovHitTimes() const
int vtxsvol[MAX_N_VERTICES]
WCSimRootEventHeader * GetHeader()
void SetVtxs(Int_t n, Int_t i, Double_t f)
void SetNumTubesHit(Int_t i)
WCSimWCDAQMessenger * DAQMessenger
TClonesArray * GetCherenkovHits() const
G4int WCSimEventFindStartingVolume(G4ThreeVector vtx)
WCSimRunAction * GetRunAction()
G4THitsCollection< WCSimWCHit > WCSimWCHitsCollection
int NumberOfGatesInThisEvent()
Returns the number of trigger gates in the event (i.e. the number of triggers passed) ...
G4double GetBeamEnergy(G4int n=0)
G4bool GetSaveFlag() const
G4ThreeVector GetVtx(G4int n=0)
virtual void DrawTrajectory(G4int i_mode=0) const
G4int GetPDGEncoding() const
TClonesArray * GetTracks() const
G4TDigiCollection< WCSimWCDigi > WCSimWCDigitsCollection
WCSimRootCherenkovDigiHit * AddCherenkovDigiHit(Double_t q, Double_t t, Int_t tubeid, std::vector< int > photon_ids)
G4String GetIDCollectionName()
G4TDigiCollection< WCSimWCDigiTrigger > WCSimWCTriggeredDigitsCollection
G4ThreeVector GetStoppingPoint() const
double dir[MAX_N_PRIMARIES][3]
int parent[MAX_N_PRIMARIES]
The base class for WCSim triggering algorithms.
void SetTriggerInfo(TriggerType_t trigger_type, std::vector< Float_t > trigger_info)
G4double GetGlobalTime() const
void CreateDAQInstances()
Create instances of the user-chosen digitizer and trigger classes.
void SetPi0Info(Double_t pi0Vtx[3], Int_t gammaID[2], Double_t gammaE[2], Double_t gammaVtx[2][3])
WCSimRootTrigger * GetTrigger(int number)
double start[MAX_N_PRIMARIES][3]
G4int GetTargetPDG(G4int n=0)
void SaveOptionsToOutput(WCSimRootOptions *wcopt)
Save current values of options.
G4ParticleDefinition * GetParticleDefinition()
G4int WCSimEventFindStoppingVolume(G4String stopVolumeName)
int startvol[MAX_N_PRIMARIES]
Int_t GetNumberOfEvents() const
G4ThreeVector GetTargetDir(G4int n=0)
std::vector< Float_t > GetTriggerInfo(int i)
Get the additional trigger information associated with the ith trigger.
int flag[MAX_N_PRIMARIES]
G4int GetParentID() const
void SetDarkRate(double idarkrate)
Knowledge of the dark rate (use for automatically adjusting for noise)
G4double GetVertexTime(G4int n=0)
void SaveOptionsToOutput(WCSimRootOptions *wcopt)
WCSimRootTrack * AddTrack(Int_t ipnu, Int_t flag, Double_t m, Double_t p, Double_t E, Int_t startvol, Int_t stopvol, Double_t dir[3], Double_t pdir[3], Double_t stop[3], Double_t start[3], Int_t parenttype, Double_t time, Int_t id)
G4String GetODCollectionName()
WCSimRunAction * runAction
bool GetIsODConstructed()
TClonesArray * GetCherenkovDigiHits() const
void SetHeader(Int_t i, Int_t run, int64_t date, Int_t subevtn=1)
G4int GetBeamPDG(G4int n=0)
G4VPhysicalVolume * GetStoppingVolume() const
WCSimDetectorConstruction * detectorConstructor
void FillRootEvent(G4int, const struct ntupleStruct &, G4TrajectoryContainer *, WCSimWCDigitsCollection *, WCSimWCTriggeredDigitsCollection *, G4String detectorElement="tank")
struct ntupleStruct jhfNtuple
double vtxs[MAX_N_VERTICES][4]
double m[MAX_N_PRIMARIES]
WCSimEventAction(WCSimRunAction *, WCSimDetectorConstruction *, WCSimPrimaryGeneratorAction *)
G4ThreeVector GetBeamDir(G4int n=0)
double p[MAX_N_PRIMARIES]
static const int MAX_N_VERTICES
void SetVecRecNumber(Int_t i)
G4double GetCharge() const
WCSimRootOptions * GetRootOptions()
void BeginOfEventAction(const G4Event *)
void SetVtxsvol(Int_t i, Int_t v)
void SaveOptionsToOutput(WCSimRootOptions *wcopt, string tag)
double E[MAX_N_PRIMARIES]
An (incomplete) example of running two trigger algorithms, one after the other.
void incrementEventsGenerated()
void Digitize()
The main user-callable routine of the class. Gets the input & creates the output WCSimWCTriggeredDigi...
int ipnu[MAX_N_PRIMARIES]