5 #include "G4EventManager.hh"
7 #include "G4SDManager.hh"
8 #include "G4DigiManager.hh"
10 #include "G4RotationMatrix.hh"
11 #include "G4ThreeVector.hh"
27 #ifndef WCSIMWCTRIGGER_VERBOSE
30 #ifndef HYPER_VERBOSITY
41 G4String detectorElement)
42 :G4VDigitizerModule(name), DAQMessenger(myMessenger), myDetector(inDetector), triggerClassName(
""), detectorElement(detectorElement)
45 if(detectorElement==
"tank") colName =
"WCDigitizedCollection";
46 else if(detectorElement==
"OD") colName =
"WCDigitizedCollection_OD";
47 collectionName.push_back(colName);
49 #ifdef HYPER_VERBOSITY
50 if(detectorElement==
"OD")
51 G4cout <<
"WCSimWCTriggerBase::WCSimWCTriggerBase ☆ recording collection name "<< colName <<
" for " << detectorElement << G4endl;
57 G4cerr <<
"WCSimWCDAQMessenger pointer is NULL when passed to WCSimWCTriggerBase constructor. Exiting..."
84 G4cerr <<
"WCSimWCDAQMessenger pointer is NULL when used in WCSimWCTriggerBase::GetVariables(). Exiting..."
89 G4cout << (
multiDigitsPerTrigger ?
"Using mutiple digits per PMT per trigger" :
"Using a maximum of 1 digit per PMT per trigger" ) << G4endl
92 <<
"Using NDigits trigger window " <<
ndigitsWindow <<
" ns" << G4endl
96 G4cout <<
"Saving only triggered digits" << G4endl;
98 G4cout <<
"Saving both triggered and not-triggered digits" << G4endl;
100 G4cout <<
"Saving only not-triggered digits" << G4endl;
102 G4cout <<
"Using SaveFailures trigger time" <<
saveFailuresTime <<
" ns" << G4endl
121 G4cerr <<
"WCSimWCTriggerBase::GetPreTriggerWindow() Unknown trigger type " << t
142 G4cerr <<
"WCSimWCTriggerBase::GetPostTriggerWindow() Unknown trigger type " << t
156 double average_occupancy = dark_rate_Hz * trigger_window_seconds * npmts;
158 G4cout <<
"Average number of PMTs in detector active in a " <<
ndigitsWindow
159 <<
"ns window with a dark noise rate of " <<
PMTDarkRate
160 <<
"kHz is " << average_occupancy
161 <<
" (" << npmts <<
" total PMTs)"
175 #ifdef HYPER_VERBOSITY
177 G4cout <<
"WCSimWCTriggerBase::Digitize ☆ adjusting threshold for average occupancy" << G4endl;
186 G4String collectiondetectorname;
187 if(
detectorElement==
"tank") collectiondetectorname=
"/WCSim/glassFaceWCPMT";
188 else if(
detectorElement==
"OD") collectiondetectorname=
"/WCSim/glassFaceWCPMT_OD";
191 G4DigiManager* DigiMan = G4DigiManager::GetDMpointer();
194 G4String untriggeredcollectionname;
195 if(
detectorElement==
"tank") untriggeredcollectionname=
"WCDigitizedStoreCollection";
196 else if(
detectorElement==
"OD") untriggeredcollectionname =
"WCDigitizedStoreCollection_OD";
197 G4int WCDCID = DigiMan->GetDigiCollectionID(untriggeredcollectionname);
202 #ifdef HYPER_VERBOSITY
204 G4cout<<
"WCSimWCTriggerBase::Digitize ☆ making triggered digits collection "<<collectionName[0]<<
" for "<<
detectorElement
205 <<
" and calling DoTheWork on "<<untriggeredcollectionname<<
" to fill it."<<G4endl;
213 G4cout<<
"could not find trigger PMT digits collection for "<<
detectorElement<<G4endl;
216 #ifdef HYPER_VERBOSITY
218 G4cout<<
"WCSimWCTriggerBase::Digitize ☆ storing the triggered digits collection "<<collectionName[0]
234 this_ndigitsThreshold /= 2;
242 int window_step_size = 5;
248 for (G4int i = 0 ; i < WCDCPMT->entries() ; i++) {
250 for ( G4int ip = 0 ; ip < (*WCDCPMT)[i]->GetTotalPe() ; ip++) {
251 G4double digit_time = (*WCDCPMT)[i]->GetTime(ip);
254 lasthit = digit_time;
255 if(digit_time < firsthit)
256 firsthit = digit_time;
259 int window_start_time = firsthit;
260 window_start_time -= window_start_time % 5;
261 int window_end_time = lasthit -
ndigitsWindow + window_step_size;
262 window_end_time -= window_end_time % 5;
263 #ifdef WCSIMWCTRIGGER_VERBOSE
264 G4cout <<
"WCSimWCTriggerBase::AlgNDigits. Found first/last hits. Looping from "
266 <<
" to " << window_end_time
267 <<
" in steps of " << window_step_size << G4endl;
270 std::vector<G4double> digit_times;
272 G4cout <<
"WCSimWCTriggerBase::AlgNDigits. Number of entries in input digit collection: " << WCDCPMT->entries() << G4endl;
273 #ifdef WCSIMWCTRIGGER_VERBOSE
274 int temp_total_pe = 0;
275 for (G4int i = 0 ; i < WCDCPMT->entries() ; i++) {
276 temp_total_pe += (*WCDCPMT)[i]->GetTotalPe();
278 G4cout <<
"WCSimWCTriggerBase::AlgNDigits. " << temp_total_pe <<
" total p.e. input" << G4endl;
282 while(window_start_time <= window_end_time) {
285 bool triggerfound =
false;
289 for (G4int i = 0 ; i < WCDCPMT->entries() ; i++) {
292 for ( G4int ip = 0 ; ip < (*WCDCPMT)[i]->GetTotalPe() ; ip++) {
293 G4double digit_time = (*WCDCPMT)[i]->GetTime(ip);
295 if(digit_time >= window_start_time && digit_time <= (window_start_time +
ndigitsWindow)) {
297 digit_times.push_back(digit_time);
304 if(n_digits > this_ndigitsThreshold) {
307 std::sort(digit_times.begin(), digit_times.end());
308 triggertime = digit_times[this_ndigitsThreshold];
309 triggertime -= (int)triggertime % 5;
312 TriggerInfos.push_back(std::vector<Float_t>(1, n_digits));
316 #ifdef WCSIMWCTRIGGER_VERBOSE
318 G4cout << n_digits <<
" digits found in 200nsec trigger window ["
319 << window_start_time <<
", " << window_start_time +
ndigitsWindow
320 <<
"]. Threshold is: " << this_ndigitsThreshold << G4endl;
328 window_start_time += window_step_size;
332 G4cout <<
"Found " << ntrig <<
" NDigit triggers" << G4endl;
367 for(
unsigned int itrigger = 0; itrigger <
TriggerTimes.size(); itrigger++) {
373 std::vector<Float_t> triggerinfo =
TriggerInfos[itrigger];
381 if(upperbound_previous > lowerbound) {
385 if(upperbound_previous >= upperbound)
387 lowerbound = upperbound_previous;
391 #ifdef WCSIMWCTRIGGER_VERBOSE
393 <<
" in time range [" << lowerbound <<
", " << upperbound <<
"]"
394 <<
" with trigger time " << triggertime
395 <<
" and additional trigger info";
396 for(std::vector<Float_t>::iterator it = triggerinfo.begin(); it != triggerinfo.end(); ++it)
397 G4cout <<
" " << *it;
402 for (G4int i = 0; i < WCDCPMT->entries(); i++) {
403 int tube=(*WCDCPMT)[i]->GetTubeID();
405 for ( G4int ip = 0; ip < (*WCDCPMT)[i]->GetTotalPe(); ip++){
406 G4double digit_time = (*WCDCPMT)[i]->GetTime(ip);
407 if(digit_time >= lowerbound && digit_time <= upperbound) {
412 double peSmeared = (*WCDCPMT)[i]->GetPe(ip);
413 G4double digihittime = digit_time;
418 std::vector<int> triggered_composition = (*WCDCPMT)[i]->GetDigiCompositionInfo(ip);
420 #ifdef WCSIMWCTRIGGER_VERBOSE
421 G4cout <<
"Saving digit on PMT " << tube
422 <<
" time " << digihittime
423 <<
" pe " << peSmeared
425 for(
unsigned int iv = 0; iv < triggered_composition.size(); iv++)
426 G4cout <<
" " << triggered_composition[iv];
429 assert(triggered_composition.size());
437 Digi->
SetTime (itrigger,digihittime);
438 Digi->
SetPe (itrigger,peSmeared);
445 (*DigitsCollection)[
DigiHitMap[tube]-1]->AddGate(itrigger);
446 (*DigitsCollection)[
DigiHitMap[tube]-1]->SetTime(itrigger, digihittime);
447 (*DigitsCollection)[
DigiHitMap[tube]-1]->SetPe (itrigger, peSmeared);
448 (*DigitsCollection)[
DigiHitMap[tube]-1]->AddPe ();
449 (*DigitsCollection)[
DigiHitMap[tube]-1]->AddDigiCompositionInfo(itrigger,triggered_composition);
452 (*WCDCPMT)[i]->RemoveDigitizedGate(ip);
462 G4cout <<
"WCSimWCTriggerBase::FillDigitsCollection. Number of entries in output digit collection: " <<
DigitsCollection->entries() << G4endl;
470 std::vector<Float_t> triggerinfo;
472 for (G4int i = 0 ; i < WCDCPMT->entries() ; i++) {
473 Ndigits += (*WCDCPMT)[i]->GetTotalPe();
475 triggerinfo.push_back(Ndigits);
545 G4cout <<
"TubeID: " <<
tubeID
548 std::multimap<int,double>::iterator it_pe =
pe.begin();
549 std::multimap<int,double>::iterator it_time =
time.begin();
550 for( ; it_pe !=
pe.end(), it_time !=
time.end(); ++it_pe, ++it_time) {
551 if(it_pe->first != it_time->first) {
552 G4cerr <<
"WCSimWCDigiTrigger::Print() pe and time gate counters disagree!" << G4endl;
555 G4cout <<
"Gate = " << it_pe->first
556 <<
" PE: " << it_pe->second
557 <<
" Time: " << it_time->second
571 G4String detectorElement)
584 bool remove_hits =
false;
596 G4String detectorElement)
609 bool remove_hits =
false;
623 G4String detectorElement)
642 bool remove_hits =
true;
647 bool ndigits_test =
true;
648 AlgNDigits(WCDCPMTCopy, remove_hits, ndigits_test);
std::vector< std::vector< Float_t > > TriggerInfos
Additional information associated with each trigger.
~WCSimWCTriggerNoTrigger()
void SetTubeID(G4int tube)
G4int saveFailuresPreTriggerWindow
The pretrigger window to save before an SaveFailures trigger.
std::multimap< int, double > time
Digit time.
virtual ~WCSimWCTriggerBase()
enum ETriggerType TriggerType_t
std::vector< Double_t > TriggerTimes
The times of the triggers.
G4int GetTotalNumODPmts()
void SaveOptionsToOutput(WCSimRootOptions *wcopt)
Save current values of options.
G4String triggerClassName
Save the name of the trigger class.
void SortTriggersByTime()
sort the Trigger vectors (Time, Type, Info) by Trigger Time
std::map< int, int > DigiHitMap
Keeps track of the PMTs that have been added to the output WCSimWCTriggeredDigitsCollection.
~WCSimWCTriggerNDigits2()
void TellMeAboutTheTrigger(WCSimWCTriggerBase *trigger)
void AlgNoTrigger(WCSimWCDigitsCollection *WCDCPMT, bool remove_hits, bool test=false)
void SetNDigitsWindow(int indigitsWindow)
void DoTheWork(WCSimWCDigitsCollection *WCDCPMT)
This should call the trigger algorithms, and handle any temporary DigitsCollection's.
void SetTime(G4int gate, G4double T)
void SetSaveFailuresPreTriggerWindow(int isaveFailuresPreTriggerWindow)
void SetSaveFailuresMode(int isaveFailuresMode)
virtual int GetDefaultNDigitsThreshold()
Set the default trigger class specific NDigits threshold (in ns) (overridden by .mac) ...
std::multimap< int, double > pe
Digit charge.
void AddDigiCompositionInfo(G4int gate, std::vector< int > &digi_comp)
Add a whole vector for one digit to fDigiComp. Clear input vector once added.
void DoTheWork(WCSimWCDigitsCollection *WCDCPMT)
Calls the workhorse of this class: AlgNDigits.
void SetSaveFailuresPostTriggerWindow(int isaveFailuresPostTriggerWindow)
void SetNDigitsPreTriggerWindow(int indigitsPreTriggerWindow)
void SetTriggerClassName(string itriggerClassName)
void SetNDigitsThreshold(int indigitsThreshold)
virtual void DoTheWork(WCSimWCDigitsCollection *WCDCPMT)=0
This should call the trigger algorithms, and handle any temporary DigitsCollection's.
WCSimWCTriggerNoTrigger(G4String name, WCSimDetectorConstruction *, WCSimWCDAQMessenger *, G4String detectorElement)
Create WCSimWCTriggerNoTrigger instance with knowledge of the detector and DAQ options.
double PMTDarkRate
Dark noise rate of the PMTs.
void SetMultiDigitsPerTrigger(G4bool allow_multi)
Set whether to allow the number of digits per PMT per trigger to go > 1.
G4TDigiCollection< WCSimWCDigi > WCSimWCDigitsCollection
double GetPreTriggerWindow(TriggerType_t t)
Get the pretrigger window for a given trigger algorithm.
G4TDigiCollection< WCSimWCDigiTrigger > WCSimWCTriggeredDigitsCollection
G4int ndigitsPostTriggerWindow
The posttrigger window to save after an NDigits trigger.
G4bool multiDigitsPerTrigger
Allow the number of digits per PMT saved in each trigger window to go > 1?
void ReInitialize()
Clear the Trigger* vectors and DigiHitMap.
The base class for WCSim triggering algorithms.
G4bool ndigitsAdjustForNoise
Automatically adjust the NDigits trigger threshold based on the average dark noise rate...
void SetMultiDigitsPerTrigger(bool imultiDigitsPerTrigger)
std::vector< TriggerType_t > TriggerTypes
The type of the triggers.
void SetNDigitsPostTriggerWindow(int indigitsPostTriggerWindow)
G4int saveFailuresMode
The mode for saving events which don't pass triggers.
void AlgNDigits(WCSimWCDigitsCollection *WCDCPMT, bool remove_hits, bool test=false)
An NDigits trigger algorithm.
void AdjustNDigitsThresholdForNoise()
modify the NDigits threshold based on the average dark noise rate
WCSimWCTriggerNDigits(G4String name, WCSimDetectorConstruction *, WCSimWCDAQMessenger *, G4String detectorElement)
Create WCSimWCTriggerNDigits instance with knowledge of the detector and DAQ options.
G4int ndigitsThreshold
The threshold for the NDigits trigger.
virtual int GetDefaultNDigitsWindow()
Set the default trigger class specific NDigits window (in ns) (overridden by .mac) ...
G4int saveFailuresPostTriggerWindow
The posttrigger window to save after an SaveFailures trigger.
G4int ndigitsPreTriggerWindow
The pretrigger window to save before an NDigits trigger.
static const double LongTime
An arbitrary long time to use in loops (ns)
G4int tubeID
PMT id of the digit.
double t[MAX_N_ACTIVE_TUBES]
bool digitizeCalled
Has Digitize() been called yet?
G4int totalPe
Total charge on digit.
const WCSimWCDigiTrigger & operator=(const WCSimWCDigiTrigger &)
G4int ndigitsWindow
The time window for the NDigits trigger.
WCSimDetectorConstruction * myDetector
Know about the detector, so can add appropriate PMT time smearing.
std::multimap< int, std::vector< int > > fDigiComp
Stores the unique IDs of each photon making up a digit.
static std::string EnumAsString(DigitizerType_t d)
virtual int GetDefaultNDigitsPostTriggerWindow()
Set the default trigger class specific NDigits posttrigger window (in ns) (overridden by ...
WCSimWCTriggerNDigits2(G4String name, WCSimDetectorConstruction *, WCSimWCDAQMessenger *, G4String detectorElement)
std::set< int > Gates
'Gates' specifies subevent
void SetPe(G4int gate, G4double Q)
void SetNDigitsAdjustForNoise(bool indigitsAdjustForNoise)
void SetSaveFailuresMode(G4int mode)
Set the mode for saving failed triggers (0:save only triggered events, 1:save both triggered events &...
WCSimWCTriggeredDigitsCollection * DigitsCollection
The main output of the class - collection of digits in the trigger window.
virtual int GetDefaultNDigitsPreTriggerWindow()
Set the default trigger class specific NDigits pretrigger window (in ns) (overridden by ...
G4Allocator< WCSimWCDigiTrigger > WCSimWCDigiTriggerAllocator
void SetSaveFailuresTime(double isaveFailuresTime)
void DoTheWork(WCSimWCDigitsCollection *WCDCPMT)
Calls the workhorse of this class: AlgNoTrigger.
WCSimWCTriggerBase(G4String name, WCSimDetectorConstruction *, WCSimWCDAQMessenger *, G4String)
Create WCSimWCTriggerBase instance with knowledge of the detector and DAQ options.
void FillDigitsCollection(WCSimWCDigitsCollection *WCDCPMT, bool remove_hits, TriggerType_t save_triggerType)
takes all trigger times, then loops over all Digits & fills the output DigitsCollection ...
static const double offset
Hit time offset (ns)
double GetPostTriggerWindow(TriggerType_t t)
Get the posttrigger window for a given trigger algorithm.
virtual bool GetDefaultMultiDigitsPerTrigger()
Set the default trigger class specific decision of whether to save multiple digits per PMT per trigge...
double E[MAX_N_PRIMARIES]
void GetVariables()
Get the default threshold, etc. from the derived class, and override with read from the ...
WCSimWCDAQMessenger * DAQMessenger
Get the options from the .mac file.
void Digitize()
The main user-callable routine of the class. Gets the input & creates the output WCSimWCTriggeredDigi...
G4double saveFailuresTime
The dummy trigger time for failed events.