Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions Config/Nuclearizer_EM_DEE.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ModuleSequenceItem>XmlTagLoaderSimulations</ModuleSequenceItem>
<ModuleSequenceItem>XmlTagDEESMEX</ModuleSequenceItem>
</ModuleSequence>
<GeometryFileName>$(NUCLEARIZER)/../massmodel-cosi-em-edited/COSISMEX.analysis_BGOreading.geo.setup</GeometryFileName>
<GeometryFileName>$(NUCLEARIZER)/../massmodel-cosi-em/COSISMEX.analysis_BGOreading.geo.setup</GeometryFileName>
<ModuleOptions>
<XmlTagLoaderSimulationsSMEX>
<SimulationFileName />
Expand Down Expand Up @@ -39,7 +39,7 @@
<MaximumAcceptedEvents>10000000</MaximumAcceptedEvents>
</XmlTagLoaderSimulationsSingleDet>
<XmlTagLoaderSimulations>
<SimulationFileName>/Users/parshadkp/Software/Nuclearizer_files/SingleDetBGO-GeD/Cosima/Cs137_singleDetBGO-GeD_sourceHolderPos_1166700Flux_10s_0050_Fluore_.inc1.id1.sim.gz</SimulationFileName>
<SimulationFileName>/Users/parshadkp/Software/Nuclearizer_files/SingleDetBGO-GeD/Cosima/Cs137_singleDetBGO-em-Voxel3D.inc1.id1.sim.gz</SimulationFileName>
</XmlTagLoaderSimulations>
<XmlTagMeasurementLoaderROA>
<FileName>$(NUCLEARIZER)/../Data/roas/asic_gse_240412194613.hdf.roa</FileName>
Expand Down Expand Up @@ -69,10 +69,9 @@
</XmlTagEventFilter>
<EnergyCalibrationUniversal>
<FileName>$(NUCLEARIZER)/resource/calibration/COSI_SingleDet/20240819_Am241_Cs137_Co57_LV.ecal</FileName>
<ThresholdFileEnabled>false</ThresholdFileEnabled>
<ThresholdFileName />
<ThresholdValueEnabled>false</ThresholdValueEnabled>
<ThresholdValue>0</ThresholdValue>
<SlowThresholdCutMode>0</SlowThresholdCutMode>
<SlowThresholdCutFixedValue>35</SlowThresholdCutFixedValue>
<SlowThresholdCutThresholdFileName />
</EnergyCalibrationUniversal>
<StripPairingGreedy_b>
<Mode>0</Mode>
Expand Down
9 changes: 1 addition & 8 deletions include/MSubModuleShieldTrigger.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want to track the number of vetos with this counter?


//! Get BGO hits erased
int GetBGOHitsErased() const { return m_NumBGOHitsErased; }

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -200,4 +193,4 @@ class MSubModuleShieldTrigger : public MSubModule
#endif


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
8 changes: 5 additions & 3 deletions include/MSubModuleStripTrigger.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you comment on why you removed m_StripHitsErased and all associated functionalities? Will this be dealt with in another (sub)module?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No other modules uses this and this was only used for the printing at the end of the StripTriggerModule. This was just meant to be a diagnostic printout.


//! Get trigger rate for detector
int GetTriggerRate(int det) const {
Expand Down Expand Up @@ -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;
Expand All @@ -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<vector<double>> m_ASICDeadTime;
Expand Down
6 changes: 4 additions & 2 deletions resource/calibration/COSI_SingleDet/deadtimeParameters.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
CoincidenceWindow (s); DeadtimePerStrip (s); delayAfter1 (s); delayAfter2 (s)
1.4e-6 1e-6 0.2e-6 0.2e-6
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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect any of these parameters to change detector by ASIC by ASIC or anything? Or are these parameters which will be valid for all GeDs and all shields?

6 changes: 3 additions & 3 deletions src/MModuleDEESMEX.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me that this "m_StripTrigger.HasVeto()" corresponds to a GuardRingVeto vs a Shield Veto. Can we improve the variable names to clarify it's a shield veto or GR veto. "HasVeto" should encompass both veto cases, and we should probably introduce a HasShieldVeto and HasGuardRingVeto variable. See, for example, the veto variable names in MReadOutAssembly:

Event->SetAnalysisProgress(MAssembly::c_DetectorEffectsEngine);
return true;
}
Expand Down
26 changes: 2 additions & 24 deletions src/MSubModuleDEEIntake.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so I understand. We're checking for GuardRing here because the Geometry volume we're using in the DEE has the guard ring and the GeD as separate volumes. But the simulation has them all as one solid volume. Excluding this "GuardRingDetector_GeD_" here would exclude any hits that are within the GR volume. But we're not trying to distinguish Guardring hits here, that only comes after the charge transport, so if there is a simulated hit that is within the GuardRing volume in the Nuclearizer mass model, then it gets added as a regular hit in the detector # that precedes GuardRingDetector_GeD_. Right?

DetectorName.RemoveAllInPlace("GeD_"); // The number after GeD is the COSI detector ID
int DetectorID = DetectorName.ToInt();

Expand Down Expand Up @@ -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();

Expand Down
83 changes: 41 additions & 42 deletions src/MSubModuleShieldTrigger.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we no longer need m_ShieldVetoTime? Is this redundant with m_ShieldVetoWindowSize or m_ASICDeadTimePerChannel?

m_ASICDeadTimePerChannel = 1e-6;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these variables come from the ParseDeadtimeFiles function? Is this just a placeholder for now?


m_NumShieldHitCounts = 0;
m_NumShieldVetoCounts = 0;
m_NumBGOHitsErased = 0;

m_FirstTime = std::numeric_limits<double>::max();
Expand Down Expand Up @@ -173,24 +171,21 @@ double MSubModuleShieldTrigger::CalculateASICDeadtime(vector<int> CrystalIDs)
return deadtime;
}


////////////////////////////////////////////////////////////////////////////////


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<MDEEStripHit>& 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<MDEEStripHit>& LVHits = Event->GetDEEStripHitLVListReference();
// for (const MDEEStripHit& Hit : LVHits) {
// int DetID = Hit.m_ROE.GetDetectorID();
// if (DetID >= 0 && DetID < nDets) {
// m_DetectorsHitForShieldVeto[DetID] = 1;
// }
// }
Comment on lines +181 to +188
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this commented? Do you plan on adding it back later (in a modified form)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I will remove this permanently. This was leftover from old balloon code.


// Process shield crystal hits
list<MDEECrystalHit>& CrystalHits = Event->GetDEECrystalHitListReference();
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -283,21 +262,34 @@ 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) {
cout << m_Name << ": Unable to open deadtime parameters file: " << m_DeadtimeFileName << endl;
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;
}
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -411,4 +410,4 @@ MXmlNode* MSubModuleShieldTrigger::CreateXmlConfiguration(MXmlNode* Node)


// MSubModuleShieldTrigger.cxx: the end...
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Loading