diff --git a/Config/Nuclearizer_EM_DEE.cfg b/Config/Nuclearizer_EM_DEE.cfg
index dafb0983..16f7989b 100644
--- a/Config/Nuclearizer_EM_DEE.cfg
+++ b/Config/Nuclearizer_EM_DEE.cfg
@@ -4,7 +4,7 @@
XmlTagLoaderSimulations
XmlTagDEESMEX
- $(NUCLEARIZER)/../massmodel-cosi-em-edited/COSISMEX.analysis_BGOreading.geo.setup
+ $(NUCLEARIZER)/../massmodel-cosi-em/COSISMEX.analysis_BGOreading.geo.setup
@@ -39,7 +39,7 @@
10000000
- /Users/parshadkp/Software/Nuclearizer_files/SingleDetBGO-GeD/Cosima/Cs137_singleDetBGO-GeD_sourceHolderPos_1166700Flux_10s_0050_Fluore_.inc1.id1.sim.gz
+ /Users/parshadkp/Software/Nuclearizer_files/SingleDetBGO-GeD/Cosima/Cs137_singleDetBGO-em-Voxel3D.inc1.id1.sim.gz
$(NUCLEARIZER)/../Data/roas/asic_gse_240412194613.hdf.roa
@@ -69,10 +69,9 @@
$(NUCLEARIZER)/resource/calibration/COSI_SingleDet/20240819_Am241_Cs137_Co57_LV.ecal
- false
-
- false
- 0
+ 0
+ 35
+
0
diff --git a/include/MSubModuleShieldTrigger.h b/include/MSubModuleShieldTrigger.h
index 7d05d454..cd1e485a 100644
--- a/include/MSubModuleShieldTrigger.h
+++ b/include/MSubModuleShieldTrigger.h
@@ -97,9 +97,6 @@ class MSubModuleShieldTrigger : public MSubModule
//! Get shield hit counts
int GetShieldHitCounts() const { return m_NumShieldHitCounts; }
- //! Get shield veto counter
- int GetShieldVetoCounter() const { return m_NumShieldVetoCounts; }
-
//! Get BGO hits erased
int GetBGOHitsErased() const { return m_NumBGOHitsErased; }
@@ -155,14 +152,10 @@ class MSubModuleShieldTrigger : public MSubModule
//! Number of shield hits before deadtime
unsigned long m_NumShieldHitCounts;
- //! Number of shield veto counts
- unsigned long m_NumShieldVetoCounts;
//! Number of BGO hits erased due to deadtime
unsigned long m_NumBGOHitsErased;
//! Bool to store if corresponding shield ASIC is dead or not
bool m_IsShieldDead;
- //! Time of last shield veto hit (used for veto window calculation)
- double m_ShieldVetoTime;
//! First event time in seconds
double m_FirstTime;
@@ -200,4 +193,4 @@ class MSubModuleShieldTrigger : public MSubModule
#endif
-////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
+////////////////////////////////////////////////////////////////////////////////
diff --git a/include/MSubModuleStripTrigger.h b/include/MSubModuleStripTrigger.h
index 6ae719ad..e88c766c 100644
--- a/include/MSubModuleStripTrigger.h
+++ b/include/MSubModuleStripTrigger.h
@@ -92,7 +92,7 @@ class MSubModuleStripTrigger : public MSubModule
double GetStripsTotalDeadtime() const { return m_StripsTotalDeadtime; }
//! Get number of strip hits erased
- int GetStripHitsErased() const { return m_StripHitsErased; }
+ // int GetStripHitsErased() const { return m_StripHitsErased; }
//! Get trigger rate for detector
int GetTriggerRate(int det) const {
@@ -174,9 +174,11 @@ class MSubModuleStripTrigger : public MSubModule
//! Stores total dead time of the instrument
double m_StripsTotalDeadtime;
//! Hits erased due to deadtime
- int m_StripHitsErased;
+ // int m_StripHitsErased;
//! Total strip hits counter
int m_TotalStripHitsCounter;
+ //! Total GR hits counter
+ int m_TotalGRHitsCounter;
//! First event time for statistics
double m_FirstTime;
@@ -186,7 +188,7 @@ class MSubModuleStripTrigger : public MSubModule
//! Number of detectors
static const int nDets = 16;
//! Number of ASICs per detector
- static const int nASICs = 4;
+ static const int nASICs = 6;
//! Stores dead time for each ASIC
vector> m_ASICDeadTime;
diff --git a/resource/calibration/COSI_SingleDet/deadtimeParameters.txt b/resource/calibration/COSI_SingleDet/deadtimeParameters.txt
index 61fe6955..1936f865 100644
--- a/resource/calibration/COSI_SingleDet/deadtimeParameters.txt
+++ b/resource/calibration/COSI_SingleDet/deadtimeParameters.txt
@@ -1,2 +1,4 @@
-CoincidenceWindow (s); DeadtimePerStrip (s); delayAfter1 (s); delayAfter2 (s)
-1.4e-6 1e-6 0.2e-6 0.2e-6
\ No newline at end of file
+CoincidenceWindow (s); StripDeadtimePerStrip (s); delayAfter1 (s); delayAfter2 (s)
+1.4e-6 1e-6 0.2e-6 0.2e-6
+ShieldDeadtimePerStrip (s); ShieldVetoWindow (s); ShieldPulseDuration (s); ShieldDelayBefore (s); ShieldDelayAfter (s)
+1e-6 1.5e-6 1.7e-6 0.1e-6 0.4e-6
diff --git a/src/MModuleDEESMEX.cxx b/src/MModuleDEESMEX.cxx
index 313a723d..52a6dd29 100644
--- a/src/MModuleDEESMEX.cxx
+++ b/src/MModuleDEESMEX.cxx
@@ -156,12 +156,13 @@ bool MModuleDEESMEX::AnalyzeEvent(MReadOutAssembly* Event)
m_ShieldTrigger.Clear();
m_ShieldTrigger.AnalyzeEvent(Event);
if (m_ShieldTrigger.HasVeto() == true) {
+ Event->SetShieldVeto(true);
if (m_ShieldTrigger.GetDeadTimeEnd() > m_DeadTimeEnd) {
m_DeadTimeEnd = m_ShieldTrigger.GetDeadTimeEnd();
}
// Clean up
-
+
Event->SetAnalysisProgress(MAssembly::c_DetectorEffectsEngine);
return true;
} else if (m_ShieldTrigger.HasTrigger() == true) { // = energy read out
@@ -192,8 +193,7 @@ bool MModuleDEESMEX::AnalyzeEvent(MReadOutAssembly* Event)
if (m_StripTrigger.GetDeadTimeEnd() > m_DeadTimeEnd) {
m_DeadTimeEnd = m_StripTrigger.GetDeadTimeEnd();
}
- // Clean up
-
+ Event->SetGuardRingVeto(true); // <-- mark the event so EventSaver can filter it
Event->SetAnalysisProgress(MAssembly::c_DetectorEffectsEngine);
return true;
}
diff --git a/src/MSubModuleDEEIntake.cxx b/src/MSubModuleDEEIntake.cxx
index 571b32b8..244f9080 100644
--- a/src/MSubModuleDEEIntake.cxx
+++ b/src/MSubModuleDEEIntake.cxx
@@ -132,7 +132,8 @@ bool MSubModuleDEEIntake::AnalyzeEvent(MReadOutAssembly* Event)
double DetectorDepth = Shape->GetSizeZ();
MString DetectorName = Detector->GetName();
- if (DetectorName.BeginsWith("GeD") == true) {
+ if (DetectorName.BeginsWith("GeD") == true || DetectorName.BeginsWith("GuardRing") == true) {
+ DetectorName.RemoveAllInPlace("GuardRingDetector_GeD_"); // Remove prefix GuardRing if existent
DetectorName.RemoveAllInPlace("GeD_"); // The number after GeD is the COSI detector ID
int DetectorID = DetectorName.ToInt();
@@ -198,29 +199,6 @@ bool MSubModuleDEEIntake::AnalyzeEvent(MReadOutAssembly* Event)
return false;
}
- // int DetectorID = -1;
- // if (Tokens[1] == "X0") {
- // DetectorID = 0;
- // }
- // else if (Tokens[1] == "X1") {
- // DetectorID = 1;
- // }
- // else if (Tokens[1] == "Y0") {
- // DetectorID = 2;
- // }
- // else if (Tokens[1] == "Y1") {
- // DetectorID = 3;
- // }
- // else if (Tokens[1] == "Z0") {
- // DetectorID = 4;
- // }
- // else if (Tokens[1] == "Z1") {
- // DetectorID = 5;
- // }
- // else {
- // cerr << "ERROR: Detector name does not correspond to any panel " << Tokens[1] << endl;
- // return false;
- // }
MString DetectorID = Tokens[1];
int CrystalID = Tokens[2].ToInt();
diff --git a/src/MSubModuleShieldTrigger.cxx b/src/MSubModuleShieldTrigger.cxx
index 17b9ab7b..bb0b121f 100644
--- a/src/MSubModuleShieldTrigger.cxx
+++ b/src/MSubModuleShieldTrigger.cxx
@@ -65,11 +65,9 @@ MSubModuleShieldTrigger::MSubModuleShieldTrigger() : MSubModule()
m_ShieldDelayBefore = 0.1e-6;
m_ShieldDelayAfter = 0.4e-6;
m_ShieldVetoWindowSize = 1.5e-6;
- m_ASICDeadTimePerChannel = 0.0;
- m_ShieldVetoTime = 0.0;
+ m_ASICDeadTimePerChannel = 1e-6;
m_NumShieldHitCounts = 0;
- m_NumShieldVetoCounts = 0;
m_NumBGOHitsErased = 0;
m_FirstTime = std::numeric_limits::max();
@@ -173,7 +171,6 @@ double MSubModuleShieldTrigger::CalculateASICDeadtime(vector CrystalIDs)
return deadtime;
}
-
////////////////////////////////////////////////////////////////////////////////
@@ -181,16 +178,14 @@ bool MSubModuleShieldTrigger::ProcessShieldHits(MReadOutAssembly* Event)
{
// Process shield crystal hits to determine veto status
- m_EventTime = Event->GetTime().GetAsSeconds();
-
- // Track which GeD detectors got hit (for later deadtime update)
- list& LVHits = Event->GetDEEStripHitLVListReference();
- for (const MDEEStripHit& Hit : LVHits) {
- int DetID = Hit.m_ROE.GetDetectorID();
- if (DetID >= 0 && DetID < nDets) {
- m_DetectorsHitForShieldVeto[DetID] = 1;
- }
- }
+ // // Track which GeD detectors got hit (for later deadtime update)
+ // list& LVHits = Event->GetDEEStripHitLVListReference();
+ // for (const MDEEStripHit& Hit : LVHits) {
+ // int DetID = Hit.m_ROE.GetDetectorID();
+ // if (DetID >= 0 && DetID < nDets) {
+ // m_DetectorsHitForShieldVeto[DetID] = 1;
+ // }
+ // }
// Process shield crystal hits
list& CrystalHits = Event->GetDEECrystalHitListReference();
@@ -232,22 +227,17 @@ bool MSubModuleShieldTrigger::ProcessShieldHits(MReadOutAssembly* Event)
continue;
}
- // cout << m_ShieldLastHitTime[ShieldDetGroup] + m_ShieldDeadtime[ShieldDetGroup] << " " << m_EventTime << endl;
// Check deadtime conditions
if (m_EventTime > (m_ShieldLastHitTime[ShieldDetGroup] + m_ShieldDeadtime[ShieldDetGroup])) {
// Event occurred after deadtime - start new veto window
m_ShieldHitCrystalID[ShieldDetGroup].clear();
m_ShieldLastHitTime[ShieldDetGroup] = m_EventTime;
- m_ShieldVetoTime = m_EventTime;
m_ShieldHitCrystalID[ShieldDetGroup].push_back(CrystalID);
- m_HasVeto = true;
m_TotalShieldDeadtime[ShieldDetGroup] += m_ShieldDeadtime[ShieldDetGroup];
}
else if (m_EventTime <= (m_ShieldLastHitTime[ShieldDetGroup] + m_ShieldDelayBefore)) {
// Event occurred within coincidence window - add to existing veto
- m_ShieldVetoTime = m_EventTime;
m_ShieldHitCrystalID[ShieldDetGroup].push_back(CrystalID);
- m_HasVeto = true;
}
else {
// Event occurred within deadtime
@@ -259,18 +249,7 @@ bool MSubModuleShieldTrigger::ProcessShieldHits(MReadOutAssembly* Event)
// Calculate deadtime for each panel group after processing all hits
for (int group = 0; group < nShieldPanels; group++) {
- if (!m_IsShieldDead) {
m_ShieldDeadtime[group] = CalculateASICDeadtime(m_ShieldHitCrystalID[group]);
- }
- }
-
- // Check if event is within veto window
- if ((m_EventTime <= (m_ShieldVetoTime + m_ShieldVetoWindowSize)) &&
- (m_EventTime >= m_ShieldVetoTime)) {
- m_HasVeto = true;
- if (Event->GetSimulatedEvent() != nullptr) {
- m_NumShieldVetoCounts += Event->GetSimulatedEvent()->GetNHTs();
- }
}
return true;
@@ -283,7 +262,11 @@ bool MSubModuleShieldTrigger::ProcessShieldHits(MReadOutAssembly* Event)
bool MSubModuleShieldTrigger::ParseDeadtimeFile()
{
// Read in deadtime parameters file
- // Format: StripCoincidenceWindow ASICDeadTimePerChannel StripDelayAfter1 StripDelayAfter2
+ // Format:
+ // Row 1: strip trigger header
+ // Row 2: strip trigger parameters
+ // Row 3: shield trigger header
+ // Row 4: shield trigger parameters
MParser Parser;
if (Parser.Open(m_DeadtimeFileName) == false) {
@@ -291,13 +274,22 @@ bool MSubModuleShieldTrigger::ParseDeadtimeFile()
return false;
}
- if (Parser.GetNLines() < 2) {
+ if (Parser.GetNLines() < 4) {
cout << m_Name << ": Deadtime file does not have enough data" << endl;
return false;
}
- // We only need the ASICDeadTimePerChannel (second value) for shield
- m_ASICDeadTimePerChannel = Parser.GetTokenizerAt(1)->GetTokenAtAsDouble(1);
+ MTokenizer* ShieldTokenizer = Parser.GetTokenizerAt(3);
+ if (ShieldTokenizer->GetNTokens() < 5) {
+ cout << m_Name << ": Shield deadtime row does not have enough data" << endl;
+ return false;
+ }
+
+ m_ASICDeadTimePerChannel = ShieldTokenizer->GetTokenAtAsDouble(0);
+ m_ShieldVetoWindowSize = ShieldTokenizer->GetTokenAtAsDouble(1);
+ m_ShieldPulseDuration = ShieldTokenizer->GetTokenAtAsDouble(2);
+ m_ShieldDelayBefore = ShieldTokenizer->GetTokenAtAsDouble(3);
+ m_ShieldDelayAfter = ShieldTokenizer->GetTokenAtAsDouble(4);
return true;
}
@@ -314,16 +306,24 @@ bool MSubModuleShieldTrigger::AnalyzeEvent(MReadOutAssembly* Event)
m_HasVeto = false;
m_IsShieldDead = false;
+ m_EventTime = Event->GetTime().GetAsSeconds();
+
+ // First: veto based on shield state from previous events
+ for (int group = 0; group < nShieldPanels; ++group) {
+ if (m_EventTime >= m_ShieldLastHitTime[group] &&
+ m_EventTime <= m_ShieldLastHitTime[group] + m_ShieldVetoWindowSize) {
+ m_HasVeto = true;
+ }
+ }
+
// Process shield hits and check for veto conditions
ProcessShieldHits(Event);
- // Update time tracking for statistics
- double eventTime = Event->GetTime().GetAsSeconds();
- if (eventTime < m_FirstTime) {
- m_FirstTime = eventTime;
+ if (m_EventTime < m_FirstTime) {
+ m_FirstTime = m_EventTime;
}
- if (eventTime > m_LastTime) {
- m_LastTime = eventTime;
+ if (m_EventTime > m_LastTime) {
+ m_LastTime = m_EventTime;
}
// If vetoed, set the dead time end
@@ -370,7 +370,6 @@ void MSubModuleShieldTrigger::Finalize()
}
cout << "BGO hits erased due to BGO being dead: " << m_NumBGOHitsErased << endl;
- cout << "Shield vetoes: " << m_NumShieldVetoCounts << endl;
if (simTime > 0) {
double rateAfterDT = (m_NumShieldHitCounts - m_NumBGOHitsErased) / simTime;
@@ -411,4 +410,4 @@ MXmlNode* MSubModuleShieldTrigger::CreateXmlConfiguration(MXmlNode* Node)
// MSubModuleShieldTrigger.cxx: the end...
-////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/MSubModuleStripTrigger.cxx b/src/MSubModuleStripTrigger.cxx
index 57648665..1613df5e 100644
--- a/src/MSubModuleStripTrigger.cxx
+++ b/src/MSubModuleStripTrigger.cxx
@@ -69,8 +69,9 @@ MSubModuleStripTrigger::MSubModuleStripTrigger() : MSubModule()
m_StripsCurrentDeadtime = 0.0;
m_ASICLastHitTime = -10.0;
m_StripsTotalDeadtime = 0.0;
- m_StripHitsErased = 0;
+ // m_StripHitsErased = 0;
m_TotalStripHitsCounter = 0;
+ m_TotalGRHitsCounter = 0;
m_FirstTime = std::numeric_limits::max();
m_LastTime = 0.0;
@@ -154,10 +155,7 @@ double MSubModuleStripTrigger::CalculateASICDeadtime(vector ASICChannels)
// Loop through each channel ID and add nearest neighbors
for (int ID : ASICChannels) {
if (ID == 64) {
- if (g_Verbosity >= c_Warning) {
- cout << m_Name << ": Warning - Strip ID is 64; should not happen" << endl;
- }
- continue;
+ ASICChannelsSet.insert(ID);
} else if (ID == 0 || ID == 32) {
// Edge case: If ID is 0 or 32, add the channel and the next channel
ASICChannelsSet.insert(ID);
@@ -207,10 +205,8 @@ bool MSubModuleStripTrigger::CountRate(vector ASICChannels, vector
size_t temp_size = ASICChannelsSet.size();
if (ID == 64) {
- if (g_Verbosity >= c_Warning) {
- cout << m_Name << ": Warning - Strip ID is 64; should not happen" << endl;
- }
- continue;
+ // ASICChannelsSet.insert(ID);
+ continue; // Do not include GR hits in count rate calculation as it has its own readout and does not cause nearest neighbor readout
} else if (ID == 0 || ID == 32) {
ASICChannelsSet.insert(ID);
ASICChannelsSet.insert(ID + 1);
@@ -340,10 +336,14 @@ bool MSubModuleStripTrigger::ProcessStripHits(MReadOutAssembly* Event)
ASICofDet = 2;
} else if (!IsLV && StripID >= 32 && StripID <= 63) {
ASICofDet = 3;
- // } else if (!IsLV && StripID = 64) {
- // ASICofDet = 4;
- // } else if (IsLV && StripID = 64) {
- // ASICofDet = 5;
+ } else if (!IsLV && StripID == 64) {
+ m_HasVeto = true;
+ m_TotalGRHitsCounter++;
+ ASICofDet = 4;
+ } else if (IsLV && StripID == 64) {
+ m_HasVeto = true;
+ m_TotalGRHitsCounter++;
+ ASICofDet = 5;
} else {
if (g_Verbosity >= c_Warning) {
cout << m_Name << ": Warning - Strip not associated with any ASIC" << endl;
@@ -383,7 +383,7 @@ bool MSubModuleStripTrigger::ProcessStripHits(MReadOutAssembly* Event)
m_ASICHitStripID_noDT[det][ASICofDet].push_back(StripID);
m_TempEvtTimes[det][ASICofDet].push_back(m_EventTime);
m_IsGeDDead = true;
- m_StripHitsErased++;
+ // m_StripHitsErased++;
HitIter = Hits.erase(HitIter);
continue;
}
@@ -490,6 +490,7 @@ void MSubModuleStripTrigger::Finalize()
}
cout << "Total strip hits after charge sharing (before deadtime): " << m_TotalStripHitsCounter << endl;
+ cout << "Total GR hits (before deadtime): " << m_TotalGRHitsCounter << endl;
cout << "Total dead time of the instrument: " << m_StripsTotalDeadtime << " seconds" << endl;
if (simTime > 0) {
@@ -497,7 +498,7 @@ void MSubModuleStripTrigger::Finalize()
cout << "Livetime fraction: " << liveFraction << endl;
}
- cout << "Hits erased due to detector being dead: " << m_StripHitsErased << endl;
+ // cout << "Hits erased due to detector being dead: " << m_StripHitsErased << endl;
if (m_TotalStripHitsCounter > 0) {
cout << "Avg deadtime per strip hit: " << m_StripsTotalDeadtime / m_TotalStripHitsCounter << " seconds" << endl;