diff --git a/include/MReadOutAssembly.h b/include/MReadOutAssembly.h index f24d4bf1..8060ab94 100644 --- a/include/MReadOutAssembly.h +++ b/include/MReadOutAssembly.h @@ -18,6 +18,7 @@ // Standard libs: #include +#include // ROOT libs: @@ -25,15 +26,17 @@ #include "MGlobal.h" #include "MReadOut.h" #include "MReadOutSequence.h" +#include "MPhysicalEvent.h" +#include "MSimEvent.h" +#include "MSimIA.h" + +// Nuclearizer libs: #include "MStripHit.h" #include "MDEEStripHit.h" #include "MCrystalHit.h" #include "MDEECrystalHit.h" #include "MGuardringHit.h" #include "MHit.h" -#include "MPhysicalEvent.h" -#include "MSimEvent.h" -#include "MSimIA.h" // Forward declarations: @@ -41,6 +44,7 @@ //////////////////////////////////////////////////////////////////////////////// +//! The read-out assembly: A container for all read-out data, reconstructed events, and derived event flags class MReadOutAssembly : public MReadOutSequence { // public interface: @@ -52,40 +56,53 @@ class MReadOutAssembly : public MReadOutSequence //! Copying is disabled - the assembly owns raw pointers MReadOutAssembly(const MReadOutAssembly&) = delete; + //! Copy assignment is disabled - the assembly owns raw pointers MReadOutAssembly& operator=(const MReadOutAssembly&) = delete; //! Reset all data virtual void Clear(); - //! Delete Hits + //! Delete all hits void DeleteHits(); - //! Set and get the Reference Time System for this event - //! The RTS is mission time in seconds since Jan 1, 2025 in TT + //! Set the Reference Time System (RTS) time for this event + //! The RTS is mission time in seconds since January 1, 2025 in TT void SetTimeRTS(const MTime& TimeRTS) { m_EventTimeRTS = TimeRTS; } + //! Return the Reference Time System (RTS) time for this event MTime GetTimeRTS() const { return m_EventTimeRTS; } - - //! Set and get the UTC time of this event + + //! Set the UTC time of this event void SetTimeUTC(const MTime& TimeUTC) { m_EventTimeUTC = TimeUTC; } + //! Return the UTC time of this event MTime GetTimeUTC() const { return m_EventTimeUTC; } - - //! Set and get simulation aspect information - void SetGalacticPointingXAxisTheta(double theta){ m_GalacticPointingXAxisTheta = theta; } - void SetGalacticPointingXAxisPhi(double phi){ m_GalacticPointingXAxisPhi = phi; } - void SetGalacticPointingZAxisTheta(double theta){ m_GalacticPointingZAxisTheta = theta; } - void SetGalacticPointingZAxisPhi(double phi){ m_GalacticPointingZAxisPhi = phi; } - - double GetGalacticPointingXAxisTheta(){ if (m_HasSimAspectInfo){return m_GalacticPointingXAxisTheta;} else{return 0;}} - double GetGalacticPointingXAxisPhi(){ if (m_HasSimAspectInfo){return m_GalacticPointingXAxisPhi;} else{return 0;}} - double GetGalacticPointingZAxisTheta(){ if (m_HasSimAspectInfo){return m_GalacticPointingZAxisTheta;} else{return 0;}} - double GetGalacticPointingZAxisPhi(){ if (m_HasSimAspectInfo){return m_GalacticPointingZAxisPhi;} else{return 0;}} - void SetSimAspectInfo(bool TF){ m_HasSimAspectInfo = TF; } - bool HasSimAspectInfo(){ return m_HasSimAspectInfo; } + //! Set and get simulation aspect information + //! Set the galactic pointing X-axis theta + void SetGalacticPointingXAxisTheta(double Theta) { m_GalacticPointingXAxisTheta = Theta; } + //! Set the galactic pointing X-axis phi + void SetGalacticPointingXAxisPhi(double Phi) { m_GalacticPointingXAxisPhi = Phi; } + //! Set the galactic pointing Z-axis theta + void SetGalacticPointingZAxisTheta(double Theta) { m_GalacticPointingZAxisTheta = Theta; } + //! Set the galactic pointing Z-axis phi + void SetGalacticPointingZAxisPhi(double Phi) { m_GalacticPointingZAxisPhi = Phi; } + + //! Return the galactic pointing X-axis theta + double GetGalacticPointingXAxisTheta() const { return m_HasSimAspectInfo ? m_GalacticPointingXAxisTheta : 0; } + //! Return the galactic pointing X-axis phi + double GetGalacticPointingXAxisPhi() const { return m_HasSimAspectInfo ? m_GalacticPointingXAxisPhi : 0; } + //! Return the galactic pointing Z-axis theta + double GetGalacticPointingZAxisTheta() const { return m_HasSimAspectInfo ? m_GalacticPointingZAxisTheta : 0; } + //! Return the galactic pointing Z-axis phi + double GetGalacticPointingZAxisPhi() const { return m_HasSimAspectInfo ? m_GalacticPointingZAxisPhi : 0; } + + //! Set whether simulation aspect information is available + void SetSimAspectInfo(bool Flag) { m_HasSimAspectInfo = Flag; } + //! Return true if simulation aspect information is available + bool HasSimAspectInfo() const { return m_HasSimAspectInfo; } //! Find out if the event contains strip hits in a given detector - bool InDetector(int DetectorID); + bool InDetector(int DetectorID) const; //! Set the guard ring veto flag void SetGuardRingVeto(bool Veto = true) { m_GuardRingVeto = Veto; } @@ -105,138 +122,126 @@ class MReadOutAssembly : public MReadOutSequence //! Return the number of strip hits unsigned int GetNStripHits() const { return m_StripHits.size(); } //! Return strip hit i + //! Ownership stays with this object MStripHit* GetStripHit(unsigned int i); //! Add a strip hit + //! Ownership is transferred to this object void AddStripHit(MStripHit* StripHit); - //! Remove a strip hit + //! Remove strip hit i without deleting it + //! The assembly relinquishes ownership of the removed pointer void RemoveStripHit(unsigned int i); - //! Return the number of T Only strip hits - //! TODO Is this a hold-over from balloon days? - unsigned int GetNStripHitsTOnly() const { return m_StripHitsTOnly.size(); } - //! Return strip hit i - MStripHit* GetStripHitTOnly(unsigned int i); - //! Adda T Only strip hit - void AddStripHitTOnly(MStripHit*); - //! Remove a strip hit - void RemoveStripHitTOnly(unsigned int i); - //! Return the number of crystal hits unsigned int GetNCrystalHits() const { return m_CrystalHits.size(); } //! Return crystal hit i + //! Ownership stays with this object MCrystalHit* GetCrystalHit(unsigned int i); //! Add a crystal hit + //! Ownership is transferred to this object void AddCrystalHit(MCrystalHit* CrystalHit); - //! Remove a crystal hit + //! Remove crystal hit i without deleting it + //! The assembly relinquishes ownership of the removed pointer void RemoveCrystalHit(unsigned int i); //! Return the number of guardring hits unsigned int GetNGuardringHits() const { return m_GuardringHits.size(); } //! Return guardring hit i + //! Ownership stays with this object MGuardringHit* GetGuardringHit(unsigned int i); //! Add a guardring hit + //! Ownership is transferred to this object void AddGuardringHit(MGuardringHit* GuardringHit) { if (GuardringHit != nullptr) m_GuardringHits.push_back(GuardringHit); } //! Return the number of hits unsigned int GetNHits() const { return m_Hits.size(); } //! Return hit i + //! Ownership stays with this object MHit* GetHit(unsigned int i); //! Add a hit + //! Ownership is transferred to this object void AddHit(MHit* Hit) { if (Hit != nullptr) m_Hits.push_back(Hit); } - //! Remove a hit + //! Remove hit i without deleting it + //! The assembly relinquishes ownership of the removed pointer void RemoveHit(unsigned int i); - //! Return the number of simulation hits - // TODO: Remove - part of m_SimEvent -// unsigned int GetNHitsSim() const { return m_HitsSim.size(); } - //! Return simulation hit i - // TODO: Remove - part of m_SimEvent -// MHit* GetHitSim(unsigned int i); - //! Move hits to simulation hits list - // TODO: Why ?? -// void MoveHitsToSim() {m_HitsSim = m_Hits; m_Hits.clear();} - - /* - //! Return the number of simulation interactions - unsigned int GetNSimIAs() const { return m_IAs.size(); } - //! Return simulation hit i - MSimIA* GetSimIA(unsigned int i); - */ - - //! Set the physical event from event reconstruction + //! Set the physical event from event reconstruction by storing a duplicate + //! Ownership of the supplied pointer stays with the caller void SetPhysicalEvent(MPhysicalEvent* Event); //! Return the physical event + //! Ownership stays with this object MPhysicalEvent* GetPhysicalEvent() { return m_PhysicalEvent; } - //! Set the simulated event; the ROA takes ownership of the pointer and deletes it + //! Set the simulated event + //! Ownership of the supplied pointer is transferred to this object + //! Any previously stored simulated event is deleted void SetSimulatedEvent(MSimEvent* Event) { if (Event != m_SimEvent) { delete m_SimEvent; m_SimEvent = Event; } } - //! Return the simulated event + //! Return the simulated event; returns nullptr if none is set + //! Ownership stays with this object MSimEvent* GetSimulatedEvent() { return m_SimEvent; } //! Return the number of low-voltage DEE strip hits unsigned int GetNDEEStripHitsLV() const { return m_DEEStripHitsLV.size(); } - //! Return low-voltage DEE Strip hit at position i + //! Add a low-voltage DEE strip hit void AddDEEStripHitLV(const MDEEStripHit& DEEStripHit) { m_DEEStripHitsLV.push_back(DEEStripHit); } //! Get a reference to the list of strip hits for direct manipulation list& GetDEEStripHitLVListReference() { return m_DEEStripHitsLV; } //! Return the number of high-voltage DEE strip hits unsigned int GetNDEEStripHitsHV() const { return m_DEEStripHitsHV.size(); } - //! Add a high-voltage DEE Strip hit + //! Add a high-voltage DEE strip hit void AddDEEStripHitHV(const MDEEStripHit& DEEStripHit) { m_DEEStripHitsHV.push_back(DEEStripHit); } //! Get a reference to the list of strip hits for direct manipulation list& GetDEEStripHitHVListReference() { return m_DEEStripHitsHV; } //! Return the number of crystal hits unsigned int GetNDEECrystalHits() const { return m_DEECrystalHits.size(); } - //! Add a crystal hit + //! Add a DEE crystal hit void AddDEECrystalHit(const MDEECrystalHit& DEECrystalHit) { m_DEECrystalHits.push_back(DEECrystalHit); } //! Get a reference to the list of crystal hits for direct manipulation list& GetDEECrystalHitListReference() { return m_DEECrystalHits; } - //Track BD Flags + // Track BD flags //! Set the energy calibration error flag - void SetEnergyCalibrationError(MString Text = "") { m_EnergyCalibrationError = true; if (Text != "") { m_EnergyCalibrationErrorString.push_back(Text); }} + void SetEnergyCalibrationError(const MString& Text = "") { m_EnergyCalibrationError = true; if (Text != "") m_EnergyCalibrationErrorString.push_back(Text); } //! Get the energy calibration error flag bool HasEnergyCalibrationError() const { return m_EnergyCalibrationError; } - - //! Set the strip pairing error flag - void SetStripPairingError(MString Text = "") { m_StripPairingError = true; if (Text != "") { m_StripPairingErrorString.push_back(Text); }} + + //! Set the strip pairing error flag + void SetStripPairingError(const MString& Text = "") { m_StripPairingError = true; if (Text != "") m_StripPairingErrorString.push_back(Text); } //! Get the strip pairing error flag bool HasStripPairingError() const { return m_StripPairingError; } //! Set the depth calibration error flag - void SetDepthCalibrationError(MString Text = "") { m_DepthCalibrationError = true; if (Text != "") { m_DepthCalibrationErrorString.push_back(Text); }} + void SetDepthCalibrationError(const MString& Text = "") { m_DepthCalibrationError = true; if (Text != "") m_DepthCalibrationErrorString.push_back(Text); } //! Get the depth calibration error flag bool HasDepthCalibrationError() const { return m_DepthCalibrationError; } //! Set the event reconstruction error flag - void SetEventReconstructionError(MString Text = "") { m_EventReconstructionError = true; if (Text != "") { m_EventReconstructionErrorString.push_back(Text); }} + void SetEventReconstructionError(const MString& Text = "") { m_EventReconstructionError = true; if (Text != "") m_EventReconstructionErrorString.push_back(Text); } //! Get the event reconstruction error flag bool HasEventReconstructionError() const { return m_EventReconstructionError; } // Track Quality Flags //! Set the Strip Hit Below Threshold quality flag - void SetStripHitBelowThreshold_QualityFlag(MString Text = ""){ m_StripHitBelowThreshold_QualityFlag = true; if (Text != "") { m_StripHitBelowThresholdString_QualityFlag.push_back(Text); }} + void SetStripHitBelowThreshold_QualityFlag(const MString& Text = "") { m_StripHitBelowThreshold_QualityFlag = true; if (Text != "") m_StripHitBelowThresholdString_QualityFlag.push_back(Text); } //! Get the Strip Hit Below Threshold quality flag bool HasStripHitBelowThreshold_QualityFlag() const { return m_StripHitBelowThreshold_QualityFlag; } - + //! Set the Strip Pairing quality flag - void SetStripPairing_QualityFlag(MString Text = ""){ m_StripPairing_QualityFlag = true; - if (Text != "") { m_StripPairingString_QualityFlag.push_back(Text); }} + void SetStripPairing_QualityFlag(const MString& Text = "") { m_StripPairing_QualityFlag = true; if (Text != "") m_StripPairingString_QualityFlag.push_back(Text); } //! Get the Strip Pairing quality flag bool HasStripPairing_QualityFlag() const { return m_StripPairing_QualityFlag; } - //! Set the Reduced Chi^2 used in MultiRoundChiSquare module (one for each detector) + //! Set the reduced chi^2 used in the MultiRoundChiSquare module (one for each detector) void SetStripPairingReducedChiSquare(double StripPairingReducedChiSquare) { m_StripPairingReducedChiSquare.push_back(StripPairingReducedChiSquare); } - //! Return all the Reduced Chi^2 (for each detector) + //! Return all the reduced chi^2 values (one for each detector) vector GetStripPairingReducedChiSquare() const { return m_StripPairingReducedChiSquare; } - // Track Vetos + // Track vetoes //! Returns true if any of the "veto" flags have been set bool IsVeto() const; @@ -244,14 +249,16 @@ class MReadOutAssembly : public MReadOutSequence //! Set the filtered-out flag void SetFilteredOut(bool Flag = true) { m_FilteredOut = Flag; } - //! Get the filgtered-out flag + //! Get the filtered-out flag bool IsFilteredOut() const { return m_FilteredOut; } //! Return the unique assembly identifier unsigned long GetAssemblyID() const { return m_AssemblyID; } - //! Returns true if none of the "bad" or "Error" flags has been set and the event has not been filtered out or rejected + //! Return true if no error flag is set and the event has not been filtered out + //! Veto and quality flags do not affect this result bool IsGood() const; - //! Returns true if any of the "bad" or "Error" flags has been set + //! Return true if any error flag is set or the event has been filtered out + //! Veto and quality flags do not affect this result bool IsBad() const; //! Set a specific analysis progress @@ -264,25 +271,25 @@ class MReadOutAssembly : public MReadOutSequence //! Parse some content from a line bool Parse(MString& Line, int Version = 1); - //! Steam the content in a way Nuclearizer can read it in again + //! Stream the content in a way Nuclearizer can read it in again bool StreamDat(ostream& S, int Version = 1); - //! Stream the content in MEGAlib's evta format - void StreamEvta(ostream& S); //! Stream the content in MEGAlib's evta format + void StreamEvta(ostream& S); + //! Stream the content in MEGAlib's tra format void StreamTra(ostream& S); - //! Stream the content in MEGAlib's roa format + //! Stream the content in MEGAlib's roa format void StreamRoa(ostream& S, bool WithADCs = true, bool WithTACs = true, bool WithEnergies = false, bool WithTimings = false, bool WithTemperatures = false, bool WithFlags = false, bool WithOrigins = false, bool WithNearestNeighbors = false); - //! Steam the BD flags + //! Stream the BD flags void StreamBDFlags(ostream& S); - //! Build the next MReadoutAssemply from a .dat file - bool GetNextFromDatFile(MFile &F); + //! Build the next MReadOutAssembly from a `.dat` file + bool GetNextFromDatFile(MFile& F); //! Compute the RTS time from known UTC time - MTime ComputeRTSfromUTCTime(MTime UTCTime); + MTime ComputeRTSfromUTCTime(MTime UTCTime) const; //! Compute the UTC time from known RTS - MTime ComputeUTCfromRTSTime(MTime RTSTime); + MTime ComputeUTCfromRTSTime(MTime RTSTime) const; // protected methods: protected: @@ -311,11 +318,15 @@ class MReadOutAssembly : public MReadOutSequence //! The time of the event in absolute UTC time MTime m_EventTimeUTC; - //! The aspect information from the simulation, only used in DEE + //! The galactic pointing X-axis theta from simulation aspect information, used only in DEE double m_GalacticPointingXAxisTheta; + //! The galactic pointing X-axis phi from simulation aspect information, used only in DEE double m_GalacticPointingXAxisPhi; + //! The galactic pointing Z-axis theta from simulation aspect information, used only in DEE double m_GalacticPointingZAxisTheta; + //! The galactic pointing Z-axis phi from simulation aspect information, used only in DEE double m_GalacticPointingZAxisPhi; + //! True if simulation aspect information is available bool m_HasSimAspectInfo; //! Guard ring veto flag @@ -328,40 +339,39 @@ class MReadOutAssembly : public MReadOutSequence bool m_Trigger; //! Whether event contains strip hits in given detector - bool m_InDetector[16]; + array m_InDetector; //! List of strip hits + //! Ownership stays with this object vector m_StripHits; - //! List of strip hits with timing only - vector m_StripHitsTOnly; - //! List of crystal hits + //! Ownership stays with this object vector m_CrystalHits; //! List of guardring hits + //! Ownership stays with this object vector m_GuardringHits; //! List of real hits + //! Ownership stays with this object vector m_Hits; //! The simulated event (nullptr if there is none) + //! Ownership stays with this object MSimEvent* m_SimEvent; - //! List of simulation hits - //! TODO: Remove: Part of m_SimEvent - vector m_HitsSim; - - //! A list of low voltage DEE strips hit - i.e. normal strip hits in the making from the simulated hits sorted by side + //! A list of low-voltage DEE strip hits, i.e. normal strip hits in the making from the simulated hits sorted by side list m_DEEStripHitsLV; - //! A list of high voltage DEE strips hit - i.e. normal strip hits in the making from the simulated hits sorted by side + //! A list of high-voltage DEE strip hits, i.e. normal strip hits in the making from the simulated hits sorted by side list m_DEEStripHitsHV; - //! A list of crystal hit - i.e. normal crystal hits in the making from the simulated hits + //! A list of crystal hits, i.e. normal crystal hits in the making from the simulated hits list m_DEECrystalHits; //! The physical event from event reconstruction + //! Ownership stays with this object MPhysicalEvent* m_PhysicalEvent; - + // Flags indicating bad events: //! Energy calibration error flag @@ -369,7 +379,7 @@ class MReadOutAssembly : public MReadOutSequence //! Energy calibration error string vector m_EnergyCalibrationErrorString; - //! String pairing error flag + //! Strip pairing error flag bool m_StripPairingError; //! Strip pairing error string vector m_StripPairingErrorString; @@ -378,37 +388,37 @@ class MReadOutAssembly : public MReadOutSequence bool m_DepthCalibrationError; //! Depth calibration error string vector m_DepthCalibrationErrorString; - + //! Event reconstruction error flag bool m_EventReconstructionError; //! Event reconstruction error string vector m_EventReconstructionErrorString; - + // Flags indicating the quality of the event: quality warning, but not to be filtered out: //! Strip hit below threshold quality flag bool m_StripHitBelowThreshold_QualityFlag; //! Strip hit below threshold quality string vector m_StripHitBelowThresholdString_QualityFlag; - + //! Strip pairing quality flag bool m_StripPairing_QualityFlag; //! Strip pairing quality string vector m_StripPairingString_QualityFlag; - //! Reduced Chi^2 of the Strip Paired Event + //! The reduced chi^2 values of the strip-paired event vector m_StripPairingReducedChiSquare; - //! True if event has been filtered out + //! True if the event has been filtered out bool m_FilteredOut; - //! The analysis progress + //! The analysis progress uint64_t m_AnalysisProgress; - - + + #ifdef ___CLING___ public: - ClassDef(MReadOutAssembly, 0) // no description + ClassDef(MReadOutAssembly, 0) // a read-out assembly #endif }; diff --git a/src/MReadOutAssembly.cxx b/src/MReadOutAssembly.cxx index 439502cd..fcc7d25c 100644 --- a/src/MReadOutAssembly.cxx +++ b/src/MReadOutAssembly.cxx @@ -59,7 +59,7 @@ MReadOutAssembly::MReadOutAssembly() : MReadOutSequence(), m_AssemblyID(++s_Next m_PhysicalEvent = nullptr; m_SimEvent = nullptr; m_HasSimAspectInfo = false; - + Clear(); } @@ -69,50 +69,10 @@ MReadOutAssembly::MReadOutAssembly() : MReadOutSequence(), m_AssemblyID(++s_Next MReadOutAssembly::~MReadOutAssembly() { - // Delete all strip hits - for (unsigned int h = 0; h < m_StripHits.size(); ++h) { - delete m_StripHits[h]; - } - m_StripHits.clear(); - - // Delete all TOnly strip hits - for (unsigned int h = 0; h < m_StripHitsTOnly.size(); ++h) { - delete m_StripHitsTOnly[h]; - } - m_StripHitsTOnly.clear(); - - // Delete all DEE Strip hits - m_DEEStripHitsLV.clear(); - m_DEEStripHitsHV.clear(); - m_DEECrystalHits.clear(); - - // Delete all crystal hits - for (unsigned int h = 0; h < m_CrystalHits.size(); ++h) { - delete m_CrystalHits[h]; - } - m_CrystalHits.clear(); - - // Delete all hits - for (unsigned int h = 0; h < m_Hits.size(); ++h) { - delete m_Hits[h]; - } - m_Hits.clear(); - - // Delete all hits from simulation - for (unsigned int h = 0; h < m_HitsSim.size(); ++h) { - delete m_HitsSim[h]; - } - m_HitsSim.clear(); - - // Delete all guardring hits - for (unsigned int h = 0; h < m_GuardringHits.size(); ++h) { - delete m_GuardringHits[h]; - } - m_GuardringHits.clear(); + // Destruct an instance of MReadOutAssembly - // Delete all Events - delete m_SimEvent; - delete m_PhysicalEvent; + // Clear() also resets state, not just owned memory, but the overhead is small compared to the code duplication it removes + Clear(); } @@ -121,10 +81,10 @@ MReadOutAssembly::~MReadOutAssembly() void MReadOutAssembly::Clear() { - //! Reset all data + // Reset all data MReadOutSequence::Clear(); - + m_ID = g_UnsignedIntNotDefined; m_EventTimeRTS = 0; m_EventTimeUTC = 0; @@ -138,10 +98,7 @@ void MReadOutAssembly::Clear() m_ShieldVeto = false; m_GuardRingVeto = false; m_Trigger = true; - - for (unsigned int DetectorID = 0; DetectorID < 16; ++DetectorID) { - m_InDetector[DetectorID] = false; - } + m_InDetector.fill(false); // Delete all strip hits for (unsigned int h = 0; h < m_StripHits.size(); ++h) { @@ -149,11 +106,6 @@ void MReadOutAssembly::Clear() } m_StripHits.clear(); - for (unsigned int h = 0; h < m_StripHitsTOnly.size(); ++h) { - delete m_StripHitsTOnly[h]; - } - m_StripHitsTOnly.clear(); - for (unsigned int h = 0; h < m_CrystalHits.size(); ++h) { delete m_CrystalHits[h]; } @@ -166,12 +118,6 @@ void MReadOutAssembly::Clear() } m_Hits.clear(); - // Delete all hits from simulation - for (unsigned int h = 0; h < m_HitsSim.size(); ++h) { - delete m_HitsSim[h]; - } - m_HitsSim.clear(); - // Delete all guardring hits for (unsigned int h = 0; h < m_GuardringHits.size(); ++h) { delete m_GuardringHits[h]; @@ -187,12 +133,12 @@ void MReadOutAssembly::Clear() m_DepthCalibrationErrorString.clear(); m_EventReconstructionError = false; m_EventReconstructionErrorString.clear(); - + m_StripPairingReducedChiSquare.clear(); - + m_StripHitBelowThreshold_QualityFlag = false; m_StripHitBelowThresholdString_QualityFlag.clear(); - + m_StripPairing_QualityFlag = false; m_StripPairingString_QualityFlag.clear(); @@ -208,7 +154,6 @@ void MReadOutAssembly::Clear() delete m_SimEvent; m_SimEvent = nullptr; - } @@ -217,8 +162,10 @@ void MReadOutAssembly::Clear() void MReadOutAssembly::DeleteHits() { - for (unsigned int h = 0; h < m_Hits.size(); ++h) { - delete m_Hits[h]; + // Delete all MHit objects + + for (auto* Hit : m_Hits) { + delete Hit; } m_Hits.clear(); } @@ -227,17 +174,20 @@ void MReadOutAssembly::DeleteHits() //////////////////////////////////////////////////////////////////////////////// -bool MReadOutAssembly::InDetector(int DetectorID) +bool MReadOutAssembly::InDetector(int DetectorID) const { - //! Find out if the event contains strip hits in a given detector - if ( (DetectorID>=0) && (DetectorID<=15) ) - { - return m_InDetector[DetectorID]; - } - else - { - return false; - } + // Find out if the event contains strip hits in a given detector + + if (DetectorID >= 0 && DetectorID <= 15) { + return m_InDetector[DetectorID]; + } + + if (g_Verbosity >= c_Error) { + cout<<"Error in MReadOutAssembly::InDetector: detector ID "<= c_Error) cout<<"Error in MReadOutAssembly::GetStripHit: index "<GetDetectorID(); @@ -300,10 +251,12 @@ void MReadOutAssembly::AddStripHit(MStripHit* StripHit) void MReadOutAssembly::RemoveStripHit(unsigned int i) { - //! Remove a strip hit + // Remove a strip hit + if (i < m_StripHits.size()) { + // BUG: MHit objects retain non-owning references to this strip hit if the caller deletes it vector::iterator it; - it = m_StripHits.begin()+i; + it = m_StripHits.begin() + i; m_StripHits.erase(it); // Recompute the per-detector flags from the remaining strip hits @@ -323,60 +276,17 @@ void MReadOutAssembly::RemoveStripHit(unsigned int i) //////////////////////////////////////////////////////////////////////////////// -MStripHit* MReadOutAssembly::GetStripHitTOnly(unsigned int i) -{ - //! Return strip hit i - - if (i < m_StripHitsTOnly.size()) { - return m_StripHitsTOnly[i]; - } - - merr<<"Index out of bounds!"<::iterator it; - it = m_StripHitsTOnly.begin()+i; - m_StripHitsTOnly.erase(it); - } -} - - -//////////////////////////////////////////////////////////////////////////////// - - MCrystalHit* MReadOutAssembly::GetCrystalHit(unsigned int i) { - //! Return strip hit i + // Return crystal hit i if (i < m_CrystalHits.size()) { return m_CrystalHits[i]; } - merr<<"Index out of bounds!"<= c_Error) cout<<"Error in MReadOutAssembly::GetCrystalHit: index "<::iterator it; - it = m_CrystalHits.begin()+i; + it = m_CrystalHits.begin() + i; m_CrystalHits.erase(it); } } @@ -416,13 +328,13 @@ void MReadOutAssembly::RemoveCrystalHit(unsigned int i) MGuardringHit* MReadOutAssembly::GetGuardringHit(unsigned int i) { - //! Return guardring hit i + // Return guardring hit i if (i < m_GuardringHits.size()) { return m_GuardringHits[i]; } - merr<<"Index out of bounds!"<= c_Error) cout<<"Error in MReadOutAssembly::GetGuardringHit: index "<= c_Error) cout<<"Error in MReadOutAssembly::GetHit: index "< tokens = Line.Tokenize(" "); - if( Line.BeginsWith("SE") ){ - if( i != 0 ){ - //we read the full event in, break now - break; - } - }else if( Line.BeginsWith("ID") ){ - unsigned int ID; - if( sscanf(&line[3],"%u",&ID) == 1 ){ - SetID( ID ); - EventRead = true; - } else { - cout<<"MReadOutAssembly::GetNextFromDatFile(): Error parsing ID line"<Parse(Line) == true ){ - AddHit(h); - EventRead = true; - } else { - delete h; - } - } else if( Line.BeginsWith("SH") ){ - MStripHit* sh = new MStripHit(); - if( sh->Parse(Line) == true ){ - AddStripHit(sh); - EventRead = true; - if( m_Hits.size() > 0 ){ - //add this SH to the last read in HT - MHit* h = m_Hits.back(); - h->AddStripHit(sh); - } - } else { - delete sh; - } - } else if( Line.BeginsWith("BD") ){ - EventRead = true; - SetFilteredOut(true); - } - - } - - if( i == MaxIter ){ - cout<<"MReadOutAssembly::GetNextFromDatFile(): reached MaxIter"<= c_Error) cout<<"Error in MReadOutAssembly::GetNextFromDatFile(): Error parsing ID line"<Parse(Line) == true) { + AddHit(h); + EventRead = true; + } else { + delete h; + } + } else if (Line.BeginsWith("SH")) { + MStripHit* sh = new MStripHit(); + if (sh->Parse(Line) == true) { + AddStripHit(sh); + EventRead = true; + if (m_Hits.size() > 0) { + // Add this SH to the last read HT + MHit* h = m_Hits.back(); + h->AddStripHit(sh); + } + } else { + delete sh; + } + } else if (Line.BeginsWith("BD")) { + EventRead = true; + SetFilteredOut(true); + } + + } + + if (i == MaxLinesToRead) { + if (g_Verbosity >= c_Error) cout<<"Error in MReadOutAssembly::GetNextFromDatFile(): Event not fully read after "<= 1 && Version <= 3) { S<<"SE"<StreamEvta(S); + m_Hits[h]->StreamEvta(S); } - + S<<"CC NStripHits "<SetDetectorID(3); MStripHit* SH1 = new MStripHit(); R.AddStripHit(SH0); R.AddStripHit(SH1); + R.AddCrystalHit(new MCrystalHit()); + R.AddGuardringHit(new MGuardringHit()); MHit* H0 = new MHit(); R.AddHit(H0); - Passed = Evaluate("GetNStripHits()", "two strip hits before Clear", "GetNStripHits() returns 2 before Clear()", - R.GetNStripHits(), (unsigned int) 2) && Passed; - Passed = Evaluate("GetNHits()", "one hit before Clear", "GetNHits() returns 1 before Clear()", - R.GetNHits(), (unsigned int) 1) && Passed; + R.AddDEEStripHitLV(MDEEStripHit()); + R.AddDEEStripHitHV(MDEEStripHit()); + R.AddDEECrystalHit(MDEECrystalHit()); + + MPhysicalEvent PhysicalEvent; + R.SetPhysicalEvent(&PhysicalEvent); + R.SetSimulatedEvent(new MSimEvent()); + + R.SetEnergyCalibrationError("energy"); + R.SetStripPairingError("pairing"); + R.SetDepthCalibrationError("depth"); + R.SetEventReconstructionError("reconstruction"); + R.SetStripHitBelowThreshold_QualityFlag("threshold"); + R.SetStripPairing_QualityFlag("quality"); + R.SetStripPairingReducedChiSquare(1.5); + R.SetFilteredOut(true); + R.SetAnalysisProgress(0x10ULL); + + MSimIA IA; + R.AddSimIA(IA); // Clear() must delete and reset all owned collections R.Clear(); + Passed = EvaluateTrue("GetID()", "after Clear", "GetID() returns g_UnsignedIntNotDefined after Clear()", + R.GetID() == g_UnsignedIntNotDefined) && Passed; + Passed = EvaluateTrue("GetTime()", "after Clear", "GetTime() returns 0 after Clear()", + R.GetTime() == MTime(0)) && Passed; + Passed = EvaluateTrue("GetTimeRTS()", "after Clear", "GetTimeRTS() returns 0 after Clear()", + R.GetTimeRTS() == MTime(0)) && Passed; + Passed = EvaluateTrue("GetTimeUTC()", "after Clear", "GetTimeUTC() returns 0 after Clear()", + R.GetTimeUTC() == MTime(0)) && Passed; + + Passed = EvaluateFalse("HasSimAspectInfo()", "after Clear", "HasSimAspectInfo() returns false after Clear()", + R.HasSimAspectInfo()) && Passed; + R.SetSimAspectInfo(true); + Passed = EvaluateNear("GetGalacticPointingXAxisTheta()", "after Clear", "GetGalacticPointingXAxisTheta() returns 0 after Clear()", + R.GetGalacticPointingXAxisTheta(), 0.0, 1e-10) && Passed; + Passed = EvaluateNear("GetGalacticPointingXAxisPhi()", "after Clear", "GetGalacticPointingXAxisPhi() returns 0 after Clear()", + R.GetGalacticPointingXAxisPhi(), 0.0, 1e-10) && Passed; + Passed = EvaluateNear("GetGalacticPointingZAxisTheta()", "after Clear", "GetGalacticPointingZAxisTheta() returns 0 after Clear()", + R.GetGalacticPointingZAxisTheta(), 0.0, 1e-10) && Passed; + Passed = EvaluateNear("GetGalacticPointingZAxisPhi()", "after Clear", "GetGalacticPointingZAxisPhi() returns 0 after Clear()", + R.GetGalacticPointingZAxisPhi(), 0.0, 1e-10) && Passed; + R.SetSimAspectInfo(false); + + Passed = EvaluateFalse("GetGuardRingVeto()", "after Clear", "GetGuardRingVeto() returns false after Clear()", + R.GetGuardRingVeto()) && Passed; + Passed = EvaluateFalse("GetShieldVeto()", "after Clear", "GetShieldVeto() returns false after Clear()", + R.GetShieldVeto()) && Passed; + Passed = EvaluateTrue("GetTrigger()", "after Clear", "GetTrigger() returns true after Clear()", + R.GetTrigger()) && Passed; + Passed = EvaluateFalse("InDetector()", "after Clear", "InDetector(3) returns false after Clear()", + R.InDetector(3)) && Passed; + Passed = Evaluate("GetNStripHits()", "empty after Clear", "GetNStripHits() returns 0 after Clear()", R.GetNStripHits(), (unsigned int) 0) && Passed; + Passed = Evaluate("GetNCrystalHits()", "empty after Clear", "GetNCrystalHits() returns 0 after Clear()", + R.GetNCrystalHits(), (unsigned int) 0) && Passed; + Passed = Evaluate("GetNGuardringHits()", "empty after Clear", "GetNGuardringHits() returns 0 after Clear()", + R.GetNGuardringHits(), (unsigned int) 0) && Passed; Passed = Evaluate("GetNHits()", "empty after Clear", "GetNHits() returns 0 after Clear()", R.GetNHits(), (unsigned int) 0) && Passed; + Passed = Evaluate("GetNDEEStripHitsLV()", "empty after Clear", "GetNDEEStripHitsLV() returns 0 after Clear()", + R.GetNDEEStripHitsLV(), (unsigned int) 0) && Passed; + Passed = Evaluate("GetNDEEStripHitsHV()", "empty after Clear", "GetNDEEStripHitsHV() returns 0 after Clear()", + R.GetNDEEStripHitsHV(), (unsigned int) 0) && Passed; + Passed = Evaluate("GetNDEECrystalHits()", "empty after Clear", "GetNDEECrystalHits() returns 0 after Clear()", + R.GetNDEECrystalHits(), (unsigned int) 0) && Passed; + Passed = Evaluate("GetNSimIAs()", "empty after Clear", "GetNSimIAs() returns 0 after Clear()", + R.GetNSimIAs(), (unsigned int) 0) && Passed; + + Passed = EvaluateTrue("GetPhysicalEvent()", "after Clear", "GetPhysicalEvent() returns nullptr after Clear()", + R.GetPhysicalEvent() == nullptr) && Passed; + Passed = EvaluateTrue("GetSimulatedEvent()", "after Clear", "GetSimulatedEvent() returns nullptr after Clear()", + R.GetSimulatedEvent() == nullptr) && Passed; + + Passed = EvaluateFalse("HasEnergyCalibrationError()", "after Clear", "HasEnergyCalibrationError() returns false after Clear()", + R.HasEnergyCalibrationError()) && Passed; + Passed = EvaluateFalse("HasStripPairingError()", "after Clear", "HasStripPairingError() returns false after Clear()", + R.HasStripPairingError()) && Passed; + Passed = EvaluateFalse("HasDepthCalibrationError()", "after Clear", "HasDepthCalibrationError() returns false after Clear()", + R.HasDepthCalibrationError()) && Passed; + Passed = EvaluateFalse("HasEventReconstructionError()", "after Clear", "HasEventReconstructionError() returns false after Clear()", + R.HasEventReconstructionError()) && Passed; + Passed = EvaluateFalse("HasStripHitBelowThreshold_QualityFlag()", "after Clear", "HasStripHitBelowThreshold_QualityFlag() returns false after Clear()", + R.HasStripHitBelowThreshold_QualityFlag()) && Passed; + Passed = EvaluateFalse("HasStripPairing_QualityFlag()", "after Clear", "HasStripPairing_QualityFlag() returns false after Clear()", + R.HasStripPairing_QualityFlag()) && Passed; + Passed = EvaluateTrue("GetStripPairingReducedChiSquare()", "after Clear", "GetStripPairingReducedChiSquare() returns an empty vector after Clear()", + R.GetStripPairingReducedChiSquare().empty()) && Passed; + Passed = EvaluateFalse("IsFilteredOut()", "after Clear", "IsFilteredOut() returns false after Clear()", + R.IsFilteredOut()) && Passed; + Passed = EvaluateTrue("GetAnalysisProgress()", "after Clear", "GetAnalysisProgress() returns 0 after Clear()", + R.GetAnalysisProgress() == 0) && Passed; // AssemblyID must survive Clear() — it is assigned once in the constructor - unsigned long ID = R.GetAssemblyID(); - R.Clear(); Passed = EvaluateTrue("GetAssemblyID()", "unchanged by Clear", "GetAssemblyID() returns the same value after Clear()", - R.GetAssemblyID() == ID) && Passed; + R.GetAssemblyID() == AssemblyID) && Passed; return Passed; } @@ -1181,13 +1265,13 @@ bool UTNReadOutAssembly::TestStreamEvta() MString S = SS.str(); Passed = EvaluateTrue("StreamEvta()", "SE line", "StreamEvta() output starts with an 'SE' line", - S.BeginsWith("SE")) && Passed; + S.BeginsWith("SE\n")) && Passed; Passed = EvaluateTrue("StreamEvta()", "ID line", "StreamEvta() output contains the 'ID 8' line", - S.Contains("ID 8")) && Passed; + S.Contains("\nID 8\n")) && Passed; Passed = EvaluateTrue("StreamEvta()", "CC NStripHits line", "StreamEvta() output contains 'CC NStripHits 1' with the strip hit count", - S.Contains("CC NStripHits 1")) && Passed; - Passed = EvaluateTrue("StreamEvta()", "PQ terminator", "StreamEvta() output contains the 'PQ' line from StreamBDFlags()", - S.Contains("PQ")) && Passed; + S.Contains("\nCC NStripHits 1\n")) && Passed; + Passed = EvaluateTrue("StreamEvta()", "PQ terminator", "StreamEvta() output ends with the 'PQ' line from StreamBDFlags()", + S.EndsWith("PQ\n")) && Passed; } // --- StreamTra() without a physical event -------------------------------- @@ -1200,11 +1284,11 @@ bool UTNReadOutAssembly::TestStreamEvta() MString S = SS.str(); Passed = EvaluateTrue("StreamTra()", "SE line", "StreamTra() output starts with an 'SE' line", - S.BeginsWith("SE")) && Passed; + S.BeginsWith("SE\n")) && Passed; Passed = EvaluateTrue("StreamTra()", "ID line without physical event", "StreamTra() output contains the 'ID 9' line when there is no physical event", - S.Contains("ID 9")) && Passed; - Passed = EvaluateTrue("StreamTra()", "PQ terminator", "StreamTra() output contains the 'PQ' line from StreamBDFlags()", - S.Contains("PQ")) && Passed; + S.Contains("\nID 9\n")) && Passed; + Passed = EvaluateTrue("StreamTra()", "PQ terminator", "StreamTra() output ends with the 'PQ' line from StreamBDFlags()", + S.EndsWith("PQ\n")) && Passed; } // --- StreamTra() with a physical event uses the event's tra string ------- @@ -1220,7 +1304,7 @@ bool UTNReadOutAssembly::TestStreamEvta() MString S = SS.str(); Passed = EvaluateTrue("StreamTra()", "SE line with physical event", "StreamTra() output starts with an 'SE' line when a physical event is set", - S.BeginsWith("SE")) && Passed; + S.BeginsWith("SE\n")) && Passed; Passed = EvaluateTrue("StreamTra()", "physical-event branch taken", "StreamTra() with a physical event does not emit the no-event branch's 'PQ' line", S.Contains("PQ") == false) && Passed; } @@ -1244,14 +1328,14 @@ bool UTNReadOutAssembly::TestStreamRoa() R.StreamRoa(SS); MString S = SS.str(); - Passed = EvaluateTrue("StreamRoa()", "SE line present", "StreamRoa() output contains 'SE'", - S.Contains("SE")) && Passed; - Passed = EvaluateTrue("StreamRoa()", "ID line present", "StreamRoa() output contains 'ID '", - S.Contains("ID ")) && Passed; + Passed = EvaluateTrue("StreamRoa()", "SE line present", "StreamRoa() output starts with an 'SE' line", + S.BeginsWith("SE\n")) && Passed; + Passed = EvaluateTrue("StreamRoa()", "ID line present", "StreamRoa() output contains the 'ID 1' line", + S.Contains("\nID 1\n")) && Passed; Passed = EvaluateTrue("StreamRoa()", "BD No hits when empty", "StreamRoa() emits 'BD No hits' when there are no strip hits", - S.Contains("BD No hits")) && Passed; + S.Contains("\nBD No hits\n")) && Passed; Passed = EvaluateTrue("StreamRoa()", "PQ terminator present", "StreamRoa() output ends with a 'PQ' line", - S.Contains("PQ")) && Passed; + S.EndsWith("PQ\n")) && Passed; } // --- ROA with one strip hit: UH line present, no "BD No hits" --- @@ -1270,11 +1354,11 @@ bool UTNReadOutAssembly::TestStreamRoa() MString S = SS.str(); Passed = EvaluateTrue("StreamRoa()", "UH line present with strip hit", "StreamRoa() output contains 'UH' when there is a strip hit", - S.Contains("UH")) && Passed; + S.Contains("\nUH ")) && Passed; Passed = EvaluateTrue("StreamRoa()", "BD No hits absent with strip hit", "StreamRoa() does not emit 'BD No hits' when there is a strip hit", - S.Contains("BD No hits") == false) && Passed; + S.Contains("\nBD No hits\n") == false) && Passed; Passed = EvaluateTrue("StreamRoa()", "PQ terminator present", "StreamRoa() output ends with a 'PQ' line", - S.Contains("PQ")) && Passed; + S.EndsWith("PQ\n")) && Passed; } // --- Nearest-neighbor filtering --- @@ -1305,9 +1389,9 @@ bool UTNReadOutAssembly::TestStreamRoa() MString S_noNN = SS_noNN.str(); size_t count = 0; size_t pos = 0; - while ((pos = S_noNN.Index("UH", pos)) != string::npos) { + while ((pos = S_noNN.Index("\nUH ", pos)) != string::npos) { ++count; - pos += 2; + pos += 4; } Passed = Evaluate("StreamRoa()", "WithNearestNeighbors=false: one UH line", "StreamRoa() with WithNearestNeighbors=false emits exactly one UH line", @@ -1319,9 +1403,9 @@ bool UTNReadOutAssembly::TestStreamRoa() MString S_withNN = SS_withNN.str(); count = 0; pos = 0; - while ((pos = S_withNN.Index("UH", pos)) != string::npos) { + while ((pos = S_withNN.Index("\nUH ", pos)) != string::npos) { ++count; - pos += 2; + pos += 4; } Passed = Evaluate("StreamRoa()", "WithNearestNeighbors=true: two UH lines", "StreamRoa() with WithNearestNeighbors=true emits two UH lines",