From 2462565ca4dcc3361ca92c977e140e9dd80f7759 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 4 Mar 2025 13:13:17 -0800 Subject: [PATCH 01/90] added modules for TAC calibration from sean's fork --- include/MGUIExpoTACcut.h | 124 ++++++++++++++++ include/MGUIOptionsTACcut.h | 93 ++++++++++++ include/MModuleTACcut.h | 131 +++++++++++++++++ src/MGUIExpoTACcut.cxx | 284 ++++++++++++++++++++++++++++++++++++ src/MGUIOptionsTACcut.cxx | 158 ++++++++++++++++++++ 5 files changed, 790 insertions(+) create mode 100644 include/MGUIExpoTACcut.h create mode 100644 include/MGUIOptionsTACcut.h create mode 100644 include/MModuleTACcut.h create mode 100644 src/MGUIExpoTACcut.cxx create mode 100644 src/MGUIOptionsTACcut.cxx diff --git a/include/MGUIExpoTACcut.h b/include/MGUIExpoTACcut.h new file mode 100644 index 00000000..b0880fc7 --- /dev/null +++ b/include/MGUIExpoTACcut.h @@ -0,0 +1,124 @@ +/* + * MGUIExpoTACcut.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MGUIExpoTACcut__ +#define __MGUIExpoTACcut__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// ROOT libs: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MGlobal.h" +#include "MGUIERBList.h" + +// NuSTAR libs +#include "MGUIExpo.h" + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +class MGUIExpoTACcut : public MGUIExpo +{ + // public Session: + public: + //! Default constructor + MGUIExpoTACcut(MModule* Module); + //! Default destructor + virtual ~MGUIExpoTACcut(); + + //! The creation part which gets overwritten + virtual void Create(); + + //! Update the frame + virtual void Update(); + + //! Reset the data in the UI + virtual void Reset(); + + //! Export the data in the UI + virtual void Export(const MString& FileName); + + //! Set the arrangment of the TAC histogram + //! 0 1 2 3 + //! 4 5 6 7 + //! 8 9 10 11 + void SetTACHistogramArrangement(vector* DetIDs); + + //! Set the energy histogram parameters + void SetTACHistogramParameters(unsigned int DetID, unsigned int NBins, double TACMin, double TACMax); + + //! Set the energy histogram parameters + void SetTACHistogramName(unsigned int DetID, MString Name); + + //! Add data to the TAC histogram + //! 0 1 2 3 + //! 4 5 6 7 + //! 8 9 10 11 + void AddTAC(unsigned int DetID, double TAC); + + // protected methods: + protected: + + + // protected members: + protected: + + // private members: + private: + //! TAC canvas + unordered_map m_TACCanvases; + //! TAC vs detector ID histogram + unordered_map m_TACHistograms; + + //! Detectors in x direction + unsigned int m_NColumns; + //! Detectors in y direction + unsigned int m_NRows; + + // Map the detector ID to the x,y position of histograms. + vector> m_DetectorMap; + + //! The number of bins of the histogram + unordered_map m_NBins; + //! The minimum TAC + unordered_map m_Min; + //! The maximum TAC + unordered_map m_Max; + + +#ifdef ___CLING___ + public: + ClassDef(MGUIExpoTACcut, 1) // basic class for dialog windows +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/include/MGUIOptionsTACcut.h b/include/MGUIOptionsTACcut.h new file mode 100644 index 00000000..760a44b8 --- /dev/null +++ b/include/MGUIOptionsTACcut.h @@ -0,0 +1,93 @@ +/* + * MGUIOptionsTACcut.h + * + * Copyright (C) 2008-2010 by Jau-Shian Liang. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MGUIOptionsTACcut__ +#define __MGUIOptionsTACcut__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// ROOT libs: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MGlobal.h" +#include "MGUIERBList.h" +#include "MModule.h" +#include "MGUIOptions.h" + +// Forward declarations: +class MGUIEFileSelector; +class MGUIEMinMaxEntry; + +//////////////////////////////////////////////////////////////////////////////// + + +class MGUIOptionsTACcut : public MGUIOptions +{ + // public Session: + public: + //! Default constructor + MGUIOptionsTACcut(MModule* Module); + //! Default destructor + virtual ~MGUIOptionsTACcut(); + + //! Process all button, etc. messages + virtual bool ProcessMessage(long Message, long Parameter1, long Parameter2); + + //! The creation part which gets overwritten + virtual void Create(); + + // protected methods: + protected: + + //! Actions after the Apply or OK button has been pressed + virtual bool OnApply(); + + + // protected members: + protected: + //! The detector IDs as a string + TGTextEntry* m_Detectors; + //! The total TAC selection + MGUIEMinMaxEntry* m_TAC; + + //! Select TAC Calibration file to load, converts readout timing to nanoseconds + MGUIEFileSelector* m_TACCalFileSelector; + + TGCheckButton* m_SingleSiteOnly; + + // private members: + private: + + +#ifdef ___CLING___ + public: + ClassDef(MGUIOptionsTACcut, 1) // basic class for dialog windows +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/include/MModuleTACcut.h b/include/MModuleTACcut.h new file mode 100644 index 00000000..6896e307 --- /dev/null +++ b/include/MModuleTACcut.h @@ -0,0 +1,131 @@ +/* + * MModuleTACcut.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MModuleTACcut__ +#define __MModuleTACcut__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// Standard libs: +#include + +// ROOT libs: +#include "TGClient.h" +#include "TH1.h" + +// MEGAlib libs: +#include "MGlobal.h" +#include "MModule.h" +#include "MGUIExpoTACcut.h" + + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +class MModuleTACcut : public MModule +{ + // public interface: + public: + //! Default constructor + MModuleTACcut(); + //! Default destructor + virtual ~MModuleTACcut(); + + //! Create a new object of this class + virtual MModuleTACcut* Clone() { return new MModuleTACcut(); } + + //! Initialize the module + virtual bool Initialize(); + + //! Create expos + virtual void CreateExpos(); + + //! Finalize the module + virtual void Finalize(); + + //! Main data analysis routine, which updates the event to a new level + virtual bool AnalyzeEvent(MReadOutAssembly* Event); + + //! Show the options GUI + virtual void ShowOptionsGUI(); + + + //! Read the configuration data from an XML node + virtual bool ReadXmlConfiguration(MXmlNode* Node); + //! Create an XML node tree from the configuration + virtual MXmlNode* CreateXmlConfiguration(); + + ///////////// Creating functions that will update and get the min/max TAC values ////////////////////////// + + //! Set the minimum TAC value! + void SetMinimumTAC(unsigned int MinimumTAC) { m_MinimumTAC = MinimumTAC; } + //! Get the minimum TAC value! + unsigned int GetMinimumTAC() const { return m_MinimumTAC; } + + //! Set the maximum TAC value! + void SetMaximumTAC(unsigned int MaximumTAC) { m_MaximumTAC = MaximumTAC; } + //! Get the maximum TAC value! + unsigned int GetMaximumTAC() const { return m_MaximumTAC; } + + //! Set filename for TAC Calibration + void SetTACCalFileName( const MString& FileName) {m_TACCalFile = FileName;} + //! Get filename for TAC Calibration + MString GetTACCalFileName() const {return m_TACCalFile;} + + //! Load the TAC calibration file + bool LoadTACCalFile(MString FName); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + // protected methods: + protected: + + + // private methods: + private: + + + + // protected members: + protected: + + // private members: + private: + +// declare min and max TAC variables here +unsigned int m_MinimumTAC, m_MaximumTAC; +MString m_TACCalFile; +unordered_map>> m_HVTACCal; +unordered_map>> m_LVTACCal; + +vector m_DetectorIDs; + +MGUIExpoTACcut* m_ExpoTACcut; + + +#ifdef ___CLING___ + public: + ClassDef(MModuleTACcut, 0) // no description +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MGUIExpoTACcut.cxx b/src/MGUIExpoTACcut.cxx new file mode 100644 index 00000000..93319cf1 --- /dev/null +++ b/src/MGUIExpoTACcut.cxx @@ -0,0 +1,284 @@ +/* + * MGUIExpoTACcut.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +// Include the header: +#include "MGUIExpoTACcut.h" + +// Standard libs: + +// ROOT libs: +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MStreams.h" + + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MGUIExpoTACcut) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIExpoTACcut::MGUIExpoTACcut(MModule* Module) : MGUIExpo(Module) +{ + // standard constructor + + // Set the new title of the tab here: + m_TabTitle = "TAC Calibration"; + + // Set the histogram arrangment + // SetTACHistogramArrangement(1, 1); + + // use hierarchical cleaning + SetCleanup(kDeepCleanup); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIExpoTACcut::~MGUIExpoTACcut() +{ + // kDeepCleanup is activated +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::Reset() +{ + //! Reset the data in the UI + + m_Mutex.Lock(); + for (auto H: m_TACHistograms) { + (H.second)->Reset(); + } + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::SetTACHistogramArrangement(vector* DetIDs) +{ + // Take in the list of detector IDs and determine the number in X and number in Y + // Update the variable m_DetectorMap. + m_Mutex.Lock(); + + unsigned int column = 0; + unsigned int row = 0; + + unsigned int max_columns = 4; + + unsigned int NDetectors = DetIDs->size(); + cout<<"MGUIExpoTACcut::SetTACHistogramArrangement: Number of detectors:" << NDetectors< new_row; + m_DetectorMap.push_back(new_row); + column = 1; + } + + unsigned int DetID = DetIDs->at(i); + m_DetectorMap[row-1].push_back(DetID); + + TH1D* TAC = new TH1D("", "TAC", m_NBins[DetID], m_Min[DetID], m_Max[DetID]); + TAC->SetXTitle("TAC [cm]"); + TAC->SetYTitle("counts"); + TAC->SetFillColor(kAzure+7); + + m_TACHistograms[DetID] = TAC; + // m_TACCanvases[DetID] = 0; + + ++column; + } + + if ( NDetectors < max_columns ){ + m_NColumns = NDetectors; + } + else{ + m_NColumns=max_columns; + } + + m_NRows = (NDetectors/max_columns) + 1; + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::SetTACHistogramParameters(unsigned int DetID, unsigned int NBins, double MinimumTAC, double MaximumTAC) +{ + // Set the energy histogram parameters + + m_Mutex.Lock(); + + m_NBins[DetID] = NBins; + m_Min[DetID] = MinimumTAC; + m_Max[DetID] = MaximumTAC; + TH1D* H = m_TACHistograms[DetID]; + H->SetBins(NBins, MinimumTAC, MaximumTAC); + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::SetTACHistogramName(unsigned int DetID, MString Name) +{ + // Set the title of the histogram + + m_Mutex.Lock(); + + if (m_TACHistograms.find(DetID) != m_TACHistograms.end()) { + m_TACHistograms[DetID]->SetTitle(Name); + } + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::AddTAC(unsigned int DetID, double TAC) +{ + // Add data to the energy histogram + + m_Mutex.Lock(); + + if (m_TACHistograms.find(DetID) != m_TACHistograms.end()) { + m_TACHistograms[DetID]->Fill(TAC); + } + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::Create() +{ + // Add the GUI options here + + // Do not create it twice! + if (m_IsCreated == true) return; + + m_Mutex.Lock(); + + TGLayoutHints* CanvasLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2); + + for (unsigned int y = 0; y < m_DetectorMap.size(); ++y) { + TGHorizontalFrame* HFrame = new TGHorizontalFrame(this); + AddFrame(HFrame, CanvasLayout); + + for (unsigned int x = 0; x < m_DetectorMap[y].size(); ++x) { + unsigned int DetID = m_DetectorMap[y][x]; + TRootEmbeddedCanvas* TACCanvas = new TRootEmbeddedCanvas("TAC", HFrame, 100, 100); + HFrame->AddFrame(TACCanvas, CanvasLayout); + m_TACCanvases[DetID] = TACCanvas; + + TACCanvas->GetCanvas()->cd(); + m_TACHistograms[DetID]->Draw("colz"); + TACCanvas->GetCanvas()->Update(); + } + } + + m_IsCreated = true; + + m_Mutex.UnLock(); +} + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::Update() +{ + //! Update the frame + + m_Mutex.Lock(); + + double Max = 0; + // for (auto H : m_TACHistograms) { + for ( const auto dethistpair : m_TACHistograms ){ + TH1D* H = dethistpair.second; + for (int bx = 2; bx < H->GetNbinsX(); ++bx) { // Skip first and last + if (Max < H->GetBinContent(bx)) { + Max = H->GetBinContent(bx); + } + } + } + Max *= 1.1; + for ( const auto dethistpair : m_TACHistograms ){ + TH1D* H = dethistpair.second; + H->SetMaximum(Max); + } + + for (auto C : m_TACCanvases) { + + (C.second)->GetCanvas()->Modified(); + (C.second)->GetCanvas()->Update(); + } + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTACcut::Export(const MString& FileName) +{ + // Add data to the energy histogram + + m_Mutex.Lock(); + + TCanvas* P = new TCanvas(); + P->Divide(m_NColumns, m_NRows); + for (unsigned int y = 0; y < m_DetectorMap.size(); ++y) { + for (unsigned int x = 0; x < m_DetectorMap[y].size(); ++x) { + unsigned int DetID = m_DetectorMap[y][x]; + P->cd((x+1) + m_NColumns*y); + m_TACHistograms[DetID]->DrawCopy("colz"); + } + } + P->SaveAs(FileName); + delete P; + + m_Mutex.UnLock(); +} diff --git a/src/MGUIOptionsTACcut.cxx b/src/MGUIOptionsTACcut.cxx new file mode 100644 index 00000000..f08b417e --- /dev/null +++ b/src/MGUIOptionsTACcut.cxx @@ -0,0 +1,158 @@ +/* + * MGUIOptionsTACcut +.cxx + * + * + * Copyright (C) by Andreas Zoglauer + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Jau-Shian Liang. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +// Include the header: +#include "MGUIOptionsTACcut.h" + +// Standard libs: + +// ROOT libs: +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MStreams.h" +#include "MString.h" +#include "MGUIEFileSelector.h" +#include "MGUIEMinMaxEntry.h" + +// Nuclearizer libs: +#include "MModuleTACcut.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MGUIOptionsTACcut +) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIOptionsTACcut::MGUIOptionsTACcut(MModule* Module) + : MGUIOptions(Module) +{ + // standard constructor +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIOptionsTACcut::~MGUIOptionsTACcut() +{ + // kDeepCleanup is activated +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIOptionsTACcut::Create() +{ + PreCreate(); + + // Modify here + + TGLayoutHints* TACLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + m_TAC = new MGUIEMinMaxEntry(m_OptionsFrame, + "Choose the minimum and maximum TAC cut (in imaginary TAC units):", + false, + dynamic_cast(m_Module)->GetMinimumTAC(), + dynamic_cast(m_Module)->GetMaximumTAC(), + true, 0.0); + m_OptionsFrame->AddFrame(m_TAC, TACLayout); + + m_TACCalFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Calibration file:", + dynamic_cast(m_Module)->GetTACCalFileName()); + m_TACCalFileSelector->SetFileType("TAC", "*.csv"); + TGLayoutHints* Label3Layout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + m_OptionsFrame->AddFrame(m_TACCalFileSelector, Label3Layout); + + + // TGLabel* TACLabel = new TGLabel(m_OptionsFrame, + // "This is a TAC cut and this text is here because.\n" + // "I'm not sure if I can remove it yet"); + // m_OptionsFrame->AddFrame(TACLabel, TACLayout); + + + PostCreate(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MGUIOptionsTACcut::ProcessMessage(long Message, long Parameter1, long Parameter2) +{ + // Modify here if you have more buttons + + bool Status = true; + + switch (GET_MSG(Message)) { + case kC_COMMAND: + switch (GET_SUBMSG(Message)) { + case kCM_BUTTON: + break; + default: + break; + } + break; + default: + break; + } + + if (Status == false) { + return false; + } + + // Call also base class + return MGUIOptions::ProcessMessage(Message, Parameter1, Parameter2); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MGUIOptionsTACcut::OnApply() +{ + // Store the data in the module + + dynamic_cast(m_Module)->SetMinimumTAC(m_TAC->GetMinValue()); + dynamic_cast(m_Module)->SetMaximumTAC(m_TAC->GetMaxValue()); + + dynamic_cast(m_Module)->SetTACCalFileName(m_TACCalFileSelector->GetFileName()); + + + return true; +} + + +// MGUIOptionsTACcut: the end... +//////////////////////////////////////////////////////////////////////////////// From 533da18d12a5fc4b6463bd2543f92b055dc5f2f2 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 4 Mar 2025 14:15:35 -0800 Subject: [PATCH 02/90] added TAC calibration modules to assemly and makefiles as well as as a preceeding module in the universal energy calibration --- Makefile | 4 +++ include/MAssembly.h | 38 ++++++++++++----------- src/MAssembly.cxx | 4 +++ src/MModuleEnergyCalibrationUniversal.cxx | 1 + 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index d9924ad1..679c91c2 100755 --- a/Makefile +++ b/Makefile @@ -116,6 +116,10 @@ $(LB)/MModuleDiagnostics.o \ $(LB)/MModuleDiagnosticsEnergyPerStrip.o \ $(LB)/MGUIExpoDiagnosticsEnergyPerStrip.o \ $(LB)/MGUIExpoDiagnostics.o \ +$(LB)/MModuleTACcut.o \ +$(LB)/MGUIExpoTACcut.o \ +$(LB)/MGUIOptionsTACcut.o \ + diff --git a/include/MAssembly.h b/include/MAssembly.h index 044edc85..7f0aa339 100644 --- a/include/MAssembly.h +++ b/include/MAssembly.h @@ -53,24 +53,26 @@ class MAssembly static const uint64_t c_EventLoaderMeasurement = (1 << 2); // = 4 static const uint64_t c_EventOrdering = (1 << 3); // = 8 static const uint64_t c_Coincidence = (1 << 4); // = 16 - static const uint64_t c_DetectorEffectsEngine = (1 << 5); // = 32 - static const uint64_t c_EventFilter = (1 << 6); // = 64 - static const uint64_t c_EnergyCalibration = (1 << 7); // = 128 - static const uint64_t c_ChargeSharingCorrection = (1 << 8); // = 256 - static const uint64_t c_DepthCorrection = (1 << 9); // = 512 - static const uint64_t c_StripPairing = (1 << 10); // = 1024 - static const uint64_t c_Aspect = (1 << 11); // = 2048 - static const uint64_t c_CrosstalkCorrection = (1 << 12); // = 4096 - static const uint64_t c_EventReconstruction = (1 << 13); // = 8196 - static const uint64_t c_Else = (1 << 14); - static const uint64_t c_NoRestriction = (1 << 15); - static const uint64_t c_EventSaver = (1 << 16); - static const uint64_t c_EventTransmitter = (1 << 17); - static const uint64_t c_PositionDetermiation = (1 << 18); - static const uint64_t c_Statistics = (1 << 19); - static const uint64_t c_FlagHits = (1 << 20); - static const uint64_t c_Diagnostics = (1 << 21); - static const uint64_t c_ResponseGeneration = (1 << 22); + static const uint64_t c_TACcut = (1 << 5); // = 32 + static const uint64_t c_DetectorEffectsEngine = (1 << 6); + static const uint64_t c_EventFilter = (1 << 7); // = 64 + static const uint64_t c_EnergyCalibration = (1 << 8); // = 128 + static const uint64_t c_ChargeSharingCorrection = (1 << 9); // = 256 + static const uint64_t c_DepthCorrection = (1 << 10); // = 512 + static const uint64_t c_StripPairing = (1 << 11); // = 1024 + static const uint64_t c_Aspect = (1 << 12); // = 2048 + static const uint64_t c_CrosstalkCorrection = (1 << 13); // = 4096 + static const uint64_t c_EventReconstruction = (1 << 14); // = 8196 + static const uint64_t c_Else = (1 << 15); + static const uint64_t c_NoRestriction = (1 << 16); + static const uint64_t c_EventSaver = (1 << 17); + static const uint64_t c_EventTransmitter = (1 << 18); + static const uint64_t c_PositionDetermiation = (1 << 19); + static const uint64_t c_Statistics = (1 << 20); + static const uint64_t c_FlagHits = (1 << 21); + static const uint64_t c_Diagnostics = (1 << 22); + static const uint64_t c_ResponseGeneration = (1 << 23); + // IMPORTANT: // If you add one analysis level, make sure you also handle it in: diff --git a/src/MAssembly.cxx b/src/MAssembly.cxx index 14f6e193..f9d6c6bc 100644 --- a/src/MAssembly.cxx +++ b/src/MAssembly.cxx @@ -74,6 +74,9 @@ using namespace std; #include "MModuleEventFilter.h" #include "MModuleEventSaver.h" #include "MModuleResponseGenerator.h" + +#include "MModuleTACcut.h" + #include "MModuleDiagnostics.h" #include "MModuleDiagnosticsEnergyPerStrip.h" @@ -130,6 +133,7 @@ MAssembly::MAssembly() m_Supervisor->AddAvailableModule(new MModuleEventSaver()); m_Supervisor->AddAvailableModule(new MModuleTransmitterRealta()); m_Supervisor->AddAvailableModule(new MModuleResponseGenerator()); + m_Supervisor->AddAvailableModule(new MModuleTACcut()); m_Supervisor->AddAvailableModule(new MModuleDiagnostics()); m_Supervisor->AddAvailableModule(new MModuleDiagnosticsEnergyPerStrip()); diff --git a/src/MModuleEnergyCalibrationUniversal.cxx b/src/MModuleEnergyCalibrationUniversal.cxx index 3180cba1..ce39060f 100644 --- a/src/MModuleEnergyCalibrationUniversal.cxx +++ b/src/MModuleEnergyCalibrationUniversal.cxx @@ -74,6 +74,7 @@ MModuleEnergyCalibrationUniversal::MModuleEnergyCalibrationUniversal() : MModule // Set all modules, which have to be done before this module AddPreceedingModuleType(MAssembly::c_EventLoader); + AddPreceedingModuleType(MAssembly::c_TACcut); // Set all types this modules handles AddModuleType(MAssembly::c_EnergyCalibration); From 434fafdaeeab4371df312669936af1d9b80a4324 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 4 Mar 2025 14:27:41 -0800 Subject: [PATCH 03/90] added MModuleTACcut.cxx --- src/MModuleTACcut.cxx | 290 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 src/MModuleTACcut.cxx diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx new file mode 100644 index 00000000..9ff5cf01 --- /dev/null +++ b/src/MModuleTACcut.cxx @@ -0,0 +1,290 @@ +/* + * MModuleTACcut.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +//////////////////////////////////////////////////////////////////////////////// +// +// MModuleTACcut +// +//////////////////////////////////////////////////////////////////////////////// + + +// Include the header: +#include "MModuleTACcut.h" + +// Standard libs: + +// ROOT libs: +#include "TGClient.h" + +// MEGAlib libs: +#include "MModule.h" +#include "MGUIOptionsTACcut.h" +#include "MGUIExpoTACcut.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MModuleTACcut) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleTACcut::MModuleTACcut() : MModule() +{ + // Construct an instance of MModuleTACcut + + // Set all module relevant information + + // Set the module name --- has to be unique + m_Name = "TAC Cut"; + + // Set the XML tag --- has to be unique --- no spaces allowed + m_XmlTag = "XmlTagTACcut"; + + // Set all modules, which have to be done before this module + AddPreceedingModuleType(MAssembly::c_EventLoader); + //AddPreceedingModuleType(MAssembly::c_DetectorEffectsEngine); + + // AddPreceedingModuleType(MAssembly::c_EnergyCalibration); + // AddPreceedingModuleType(MAssembly::c_ChargeSharingCorrection); + // AddPreceedingModuleType(MAssembly::c_DepthCorrection); + // AddPreceedingModuleType(MAssembly::c_StripPairing); + + // Set all types this modules handles + AddModuleType(MAssembly::c_TACcut); + + + // Set all modules, which can follow this module + AddSucceedingModuleType(MAssembly::c_StripPairing); + AddSucceedingModuleType(MAssembly::c_DepthCorrection); + + // Set if this module has an options GUI + // Overwrite ShowOptionsGUI() with the call to the GUI! + m_HasOptionsGUI = true; + // If true, you have to derive a class from MGUIOptions (use MGUIOptionsTACcut) + // and implement all your GUI options + + // Can the program be run multi-threaded + m_AllowMultiThreading = true; + + // Can we use multiple instances of this class + m_AllowMultipleInstances = false; + + //initialize a min and max TAC value + m_MinimumTAC = 0; + m_MaximumTAC = 20000; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleTACcut::~MModuleTACcut() +{ + // Delete this instance of MModuleTACcut +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTACcut::Initialize() +{ + // Initialize the module + + if( LoadTACCalFile(m_TACCalFile) == false ){ + cout << "TAC Calibration file could not be loaded." << endl; + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// + +void MModuleTACcut::CreateExpos() +{ + // Create all expos + + if (HasExpos() == true) return; + + // Set the histogram display + m_ExpoTACcut = new MGUIExpoTACcut(this); + m_ExpoTACcut->SetTACHistogramArrangement(&m_DetectorIDs); + for(unsigned int i = 0; i < m_DetectorIDs.size(); ++i){ + unsigned int DetID = m_DetectorIDs[i]; + m_ExpoTACcut->SetTACHistogramParameters(DetID, 120, 0, 20000); + } + m_Expos.push_back(m_ExpoTACcut); +} + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) +{ + // Main data analysis routine, which updates the event to a new level + + // Apply cuts to the TAC values: + for (unsigned int i = 0; i < Event->GetNStripHits(); ) { + MStripHit* SH = Event->GetStripHit(i); + + if ( HasExpos()==true ){ + m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTiming()); + } + // takes inputted min and max TAC values from the GUI module to make cuts + if ( SH->GetTiming() < m_MinimumTAC || SH->GetTiming() > m_MaximumTAC) { + // cout<<"HACK: Removing strip ht due to TAC "<GetTiming()<<" cut or energy "<GetEnergy()<RemoveStripHit(i); + delete SH; + } else { + ++i; + } + } + + for (unsigned int i = 0; i < Event->GetNStripHits(); ++i){ + MStripHit* SH = Event->GetStripHit(i); + double TAC_timing = SH->GetTiming(); + double ns_timing; + int DetID = SH->GetDetectorID(); + int StripID = SH->GetStripID(); + if ( SH->IsLowVoltageStrip() == true ){ + ns_timing = (TAC_timing*m_LVTACCal[DetID][StripID][0] + m_LVTACCal[DetID][StripID][1]); + } + else{ + ns_timing = TAC_timing*m_HVTACCal[DetID][StripID][0] + m_HVTACCal[DetID][StripID][1]; + } + SH->SetTiming(ns_timing); + } + + Event->SetAnalysisProgress(MAssembly::c_TACcut); + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MModuleTACcut::Finalize() +{ + MModule::Finalize(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MModuleTACcut::ShowOptionsGUI() +{ + //! Show the options GUI --- has to be overwritten! + + MGUIOptionsTACcut* Options = new MGUIOptionsTACcut(this); + Options->Create(); + gClient->WaitForUnmap(Options); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) +{ + //! Read the configuration data from an XML node + + /* + MXmlNode* SomeTagNode = Node->GetNode("SomeTag"); + if (SomeTagNode != 0) { + m_SomeTagValue = SomeTagNode->GetValue(); + } + */ + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MXmlNode* MModuleTACcut::CreateXmlConfiguration() +{ + //! Create an XML node tree from the configuration + + MXmlNode* Node = new MXmlNode(0, m_XmlTag); + + /* + MXmlNode* SomeTagNode = new MXmlNode(Node, "SomeTag", "SomeValue"); + */ + + return Node; +} + +bool MModuleTACcut::LoadTACCalFile(MString FName) +{ + // Read in the TAC Calibration file, which should contain for each strip: + // DetID, h or l for high or low voltage, TAC cal, TAC cal error, TAC cal offset, TAC offset error + MFile F; + if (F.Open(FName) == false) { + cout << "MModuleTACcut: failed to open TAC Calibration file." << endl; + return false; + } else { + MString Line; + while( F.ReadLine( Line ) ){ + if( !Line.BeginsWith("#") ){ + std::vector Tokens = Line.Tokenize(","); + if( Tokens.size() == 7 ){ + int DetID = Tokens[0].ToInt(); + int StripID = Tokens[2].ToInt(); + double taccal = Tokens[3].ToDouble(); + double taccal_err = Tokens[4].ToDouble(); + double offset = Tokens[5].ToDouble(); + double offset_err = Tokens[6].ToDouble(); + vector cal_vals; + cal_vals.push_back(taccal); cal_vals.push_back(offset); cal_vals.push_back(taccal_err); cal_vals.push_back(offset_err); + + if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { + unordered_map> temp_map_HV; + m_HVTACCal[DetID] = temp_map_HV; + unordered_map> temp_map_LV; + m_LVTACCal[DetID] = temp_map_LV; + m_DetectorIDs.push_back(DetID); + } + + if ( Tokens[1] == "l" ){ + m_LVTACCal[DetID][StripID] = cal_vals; + } + else if ( Tokens[1] == "h" ){ + m_HVTACCal[DetID][StripID] = cal_vals; + } + } + } + } + F.Close(); + sort(m_DetectorIDs.begin(), m_DetectorIDs.end()); + } + + return true; + +} + + +// MModuleTACcut.cxx: the end... From 14fc30937066a2892d2084ab6aca203938b04b6d Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 4 Mar 2025 17:08:45 -0800 Subject: [PATCH 04/90] fixed formatting issues to adhere to nuclearizer style guide --- include/MGUIExpoTACcut.h | 2 +- src/MGUIExpoTACcut.cxx | 18 ++++++++---------- src/MGUIOptionsTACcut.cxx | 17 +++-------------- src/MModuleTACcut.cxx | 6 +++--- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/include/MGUIExpoTACcut.h b/include/MGUIExpoTACcut.h index b0880fc7..056efa56 100644 --- a/include/MGUIExpoTACcut.h +++ b/include/MGUIExpoTACcut.h @@ -67,7 +67,7 @@ class MGUIExpoTACcut : public MGUIExpo //! 0 1 2 3 //! 4 5 6 7 //! 8 9 10 11 - void SetTACHistogramArrangement(vector* DetIDs); + void SetTACHistogramArrangement(const vector DetIDs); //! Set the energy histogram parameters void SetTACHistogramParameters(unsigned int DetID, unsigned int NBins, double TACMin, double TACMax); diff --git a/src/MGUIExpoTACcut.cxx b/src/MGUIExpoTACcut.cxx index 93319cf1..664d3705 100644 --- a/src/MGUIExpoTACcut.cxx +++ b/src/MGUIExpoTACcut.cxx @@ -86,7 +86,7 @@ void MGUIExpoTACcut::Reset() //////////////////////////////////////////////////////////////////////////////// -void MGUIExpoTACcut::SetTACHistogramArrangement(vector* DetIDs) +void MGUIExpoTACcut::SetTACHistogramArrangement(const vector DetIDs) { // Take in the list of detector IDs and determine the number in X and number in Y // Update the variable m_DetectorMap. @@ -97,10 +97,10 @@ void MGUIExpoTACcut::SetTACHistogramArrangement(vector* DetIDs) unsigned int max_columns = 4; - unsigned int NDetectors = DetIDs->size(); - cout<<"MGUIExpoTACcut::SetTACHistogramArrangement: Number of detectors:" << NDetectors<* DetIDs) column = 1; } - unsigned int DetID = DetIDs->at(i); + unsigned int DetID = DetIDs.at(i); m_DetectorMap[row-1].push_back(DetID); TH1D* TAC = new TH1D("", "TAC", m_NBins[DetID], m_Min[DetID], m_Max[DetID]); - TAC->SetXTitle("TAC [cm]"); + TAC->SetXTitle("TAC"); TAC->SetYTitle("counts"); TAC->SetFillColor(kAzure+7); @@ -123,15 +123,13 @@ void MGUIExpoTACcut::SetTACHistogramArrangement(vector* DetIDs) ++column; } - if ( NDetectors < max_columns ){ + if (NDetectors < max_columns) { m_NColumns = NDetectors; - } - else{ + } else{ m_NColumns=max_columns; } m_NRows = (NDetectors/max_columns) + 1; - m_Mutex.UnLock(); } diff --git a/src/MGUIOptionsTACcut.cxx b/src/MGUIOptionsTACcut.cxx index f08b417e..007d9a03 100644 --- a/src/MGUIOptionsTACcut.cxx +++ b/src/MGUIOptionsTACcut.cxx @@ -77,14 +77,7 @@ void MGUIOptionsTACcut::Create() // Modify here TGLayoutHints* TACLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); - m_TAC = new MGUIEMinMaxEntry(m_OptionsFrame, - "Choose the minimum and maximum TAC cut (in imaginary TAC units):", - false, - dynamic_cast(m_Module)->GetMinimumTAC(), - dynamic_cast(m_Module)->GetMaximumTAC(), - true, 0.0); + m_TAC = new MGUIEMinMaxEntry(m_OptionsFrame, "Choose the minimum and maximum TAC cut (in imaginary TAC units):", false, dynamic_cast(m_Module)->GetMinimumTAC(), dynamic_cast(m_Module)->GetMaximumTAC(), true, 0.0); m_OptionsFrame->AddFrame(m_TAC, TACLayout); m_TACCalFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Calibration file:", @@ -142,14 +135,10 @@ bool MGUIOptionsTACcut::OnApply() { // Store the data in the module - dynamic_cast(m_Module)->SetMinimumTAC(m_TAC->GetMinValue()); - dynamic_cast(m_Module)->SetMaximumTAC(m_TAC->GetMaxValue()); - + dynamic_cast(m_Module)->SetMinimumTAC(m_TAC->GetMinValue()); + dynamic_cast(m_Module)->SetMaximumTAC(m_TAC->GetMaxValue()); dynamic_cast(m_Module)->SetTACCalFileName(m_TACCalFileSelector->GetFileName()); - return true; } diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 9ff5cf01..bc3f2051 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -55,7 +55,7 @@ MModuleTACcut::MModuleTACcut() : MModule() // Set all module relevant information // Set the module name --- has to be unique - m_Name = "TAC Cut"; + m_Name = "TAC Calibration"; // Set the XML tag --- has to be unique --- no spaces allowed m_XmlTag = "XmlTagTACcut"; @@ -76,7 +76,7 @@ MModuleTACcut::MModuleTACcut() : MModule() // Set all modules, which can follow this module AddSucceedingModuleType(MAssembly::c_StripPairing); AddSucceedingModuleType(MAssembly::c_DepthCorrection); - + AddSucceedingModuleType(MAssembly::c_EnergyCalibration); // Set if this module has an options GUI // Overwrite ShowOptionsGUI() with the call to the GUI! m_HasOptionsGUI = true; @@ -129,7 +129,7 @@ void MModuleTACcut::CreateExpos() // Set the histogram display m_ExpoTACcut = new MGUIExpoTACcut(this); - m_ExpoTACcut->SetTACHistogramArrangement(&m_DetectorIDs); + m_ExpoTACcut->SetTACHistogramArrangement(m_DetectorIDs); for(unsigned int i = 0; i < m_DetectorIDs.size(); ++i){ unsigned int DetID = m_DetectorIDs[i]; m_ExpoTACcut->SetTACHistogramParameters(DetID, 120, 0, 20000); From 207b6fa674f983d73e2967d7d90dd2cbd3b1c1e6 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 5 Mar 2025 11:30:05 -0800 Subject: [PATCH 05/90] added TAC cal/cut as a preceeding module in depth cal and strip pairing modules --- src/MModuleDepthCalibration2024.cxx | 1 + src/MModuleStripPairingChiSquare.cxx | 1 + src/MModuleStripPairingGreedy.cxx | 1 + 3 files changed, 3 insertions(+) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 3dd095ee..76e250e0 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -63,6 +63,7 @@ MModuleDepthCalibration2024::MModuleDepthCalibration2024() : MModule() AddPreceedingModuleType(MAssembly::c_EventLoader, true); AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); AddPreceedingModuleType(MAssembly::c_StripPairing, true); + AddPreceedingModuleType(MAssembly::c_TACcut, true); // AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection, false); // Soft requirement // Set all types this modules handles diff --git a/src/MModuleStripPairingChiSquare.cxx b/src/MModuleStripPairingChiSquare.cxx index fe60b8d4..28c846d2 100644 --- a/src/MModuleStripPairingChiSquare.cxx +++ b/src/MModuleStripPairingChiSquare.cxx @@ -62,6 +62,7 @@ MModuleStripPairingChiSquare::MModuleStripPairingChiSquare() : MModule() // Set all modules, which have to be done before this module AddPreceedingModuleType(MAssembly::c_EventLoader); AddPreceedingModuleType(MAssembly::c_EnergyCalibration); + AddPreceedingModuleType(MAssembly::c_TACcut); // Set all types this modules handles AddModuleType(MAssembly::c_StripPairing); diff --git a/src/MModuleStripPairingGreedy.cxx b/src/MModuleStripPairingGreedy.cxx index 124aa061..a697a947 100644 --- a/src/MModuleStripPairingGreedy.cxx +++ b/src/MModuleStripPairingGreedy.cxx @@ -61,6 +61,7 @@ MModuleStripPairingGreedy::MModuleStripPairingGreedy() : MModule() // Set all modules, which have to be done before this module AddPreceedingModuleType(MAssembly::c_EventLoader); AddPreceedingModuleType(MAssembly::c_EnergyCalibration); + AddPreceedingModuleType(MAssembly::c_TACcut); //AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection); // Set all types this modules handles From 2986357d80e516e5c5d812b5e8d42a8e97478839 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 5 Mar 2025 15:09:48 -0800 Subject: [PATCH 06/90] Cleanup: if/else and loop style conventions --- src/MGUIExpoTACcut.cxx | 10 +++++----- src/MModuleTACcut.cxx | 28 +++++++++++++--------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/MGUIExpoTACcut.cxx b/src/MGUIExpoTACcut.cxx index 664d3705..835dbfda 100644 --- a/src/MGUIExpoTACcut.cxx +++ b/src/MGUIExpoTACcut.cxx @@ -100,9 +100,9 @@ void MGUIExpoTACcut::SetTACHistogramArrangement(const vector DetID unsigned int NDetectors = DetIDs.size(); cout<<"MGUIExpoTACcut::SetTACHistogramArrangement: Number of detectors:"<< NDetectors< new_row; m_DetectorMap.push_back(new_row); @@ -125,7 +125,7 @@ void MGUIExpoTACcut::SetTACHistogramArrangement(const vector DetID if (NDetectors < max_columns) { m_NColumns = NDetectors; - } else{ + } else { m_NColumns=max_columns; } @@ -233,7 +233,7 @@ void MGUIExpoTACcut::Update() double Max = 0; // for (auto H : m_TACHistograms) { - for ( const auto dethistpair : m_TACHistograms ){ + for (const auto dethistpair : m_TACHistograms) { TH1D* H = dethistpair.second; for (int bx = 2; bx < H->GetNbinsX(); ++bx) { // Skip first and last if (Max < H->GetBinContent(bx)) { @@ -242,7 +242,7 @@ void MGUIExpoTACcut::Update() } } Max *= 1.1; - for ( const auto dethistpair : m_TACHistograms ){ + for (const auto dethistpair : m_TACHistograms) { TH1D* H = dethistpair.second; H->SetMaximum(Max); } diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index bc3f2051..cfcd7ee3 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -111,7 +111,7 @@ bool MModuleTACcut::Initialize() { // Initialize the module - if( LoadTACCalFile(m_TACCalFile) == false ){ + if (LoadTACCalFile(m_TACCalFile) == false) { cout << "TAC Calibration file could not be loaded." << endl; return false; } @@ -130,7 +130,7 @@ void MModuleTACcut::CreateExpos() // Set the histogram display m_ExpoTACcut = new MGUIExpoTACcut(this); m_ExpoTACcut->SetTACHistogramArrangement(m_DetectorIDs); - for(unsigned int i = 0; i < m_DetectorIDs.size(); ++i){ + for (unsigned int i = 0; i < m_DetectorIDs.size(); ++i) { unsigned int DetID = m_DetectorIDs[i]; m_ExpoTACcut->SetTACHistogramParameters(DetID, 120, 0, 20000); } @@ -145,14 +145,14 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) // Main data analysis routine, which updates the event to a new level // Apply cuts to the TAC values: - for (unsigned int i = 0; i < Event->GetNStripHits(); ) { + for (unsigned int i = 0; i < Event->GetNStripHits();) { MStripHit* SH = Event->GetStripHit(i); - if ( HasExpos()==true ){ + if (HasExpos()==true) { m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTiming()); } // takes inputted min and max TAC values from the GUI module to make cuts - if ( SH->GetTiming() < m_MinimumTAC || SH->GetTiming() > m_MaximumTAC) { + if (SH->GetTiming() < m_MinimumTAC || SH->GetTiming() > m_MaximumTAC) { // cout<<"HACK: Removing strip ht due to TAC "<GetTiming()<<" cut or energy "<GetEnergy()<RemoveStripHit(i); delete SH; @@ -161,16 +161,15 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) } } - for (unsigned int i = 0; i < Event->GetNStripHits(); ++i){ + for (unsigned int i = 0; i < Event->GetNStripHits(); ++i) { MStripHit* SH = Event->GetStripHit(i); double TAC_timing = SH->GetTiming(); double ns_timing; int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); - if ( SH->IsLowVoltageStrip() == true ){ + if (SH->IsLowVoltageStrip() == true) { ns_timing = (TAC_timing*m_LVTACCal[DetID][StripID][0] + m_LVTACCal[DetID][StripID][1]); - } - else{ + } else { ns_timing = TAC_timing*m_HVTACCal[DetID][StripID][0] + m_HVTACCal[DetID][StripID][1]; } SH->SetTiming(ns_timing); @@ -248,10 +247,10 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) return false; } else { MString Line; - while( F.ReadLine( Line ) ){ - if( !Line.BeginsWith("#") ){ + while (F.ReadLine(Line)) { + if (!Line.BeginsWith("#")) { std::vector Tokens = Line.Tokenize(","); - if( Tokens.size() == 7 ){ + if (Tokens.size() == 7) { int DetID = Tokens[0].ToInt(); int StripID = Tokens[2].ToInt(); double taccal = Tokens[3].ToDouble(); @@ -269,10 +268,9 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) m_DetectorIDs.push_back(DetID); } - if ( Tokens[1] == "l" ){ + if (Tokens[1] == "l") { m_LVTACCal[DetID][StripID] = cal_vals; - } - else if ( Tokens[1] == "h" ){ + } else if (Tokens[1] == "h") { m_HVTACCal[DetID][StripID] = cal_vals; } } From 0675723bc1829a3d123314c27437b1615fe3242d Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 5 Mar 2025 15:31:48 -0800 Subject: [PATCH 07/90] CHG: Remove TAC cut and calibration from depth and energy calibration modules. --- include/MGUIOptionsDepthCalibration2024.h | 3 - include/MModuleDepthCalibration2024.h | 11 --- src/MGUIOptionsDepthCalibration2024.cxx | 7 -- src/MModuleDepthCalibration2024.cxx | 82 +---------------------- src/MModuleEnergyCalibrationUniversal.cxx | 3 +- 5 files changed, 2 insertions(+), 104 deletions(-) diff --git a/include/MGUIOptionsDepthCalibration2024.h b/include/MGUIOptionsDepthCalibration2024.h index a9853d86..15c72ed6 100644 --- a/include/MGUIOptionsDepthCalibration2024.h +++ b/include/MGUIOptionsDepthCalibration2024.h @@ -74,9 +74,6 @@ class MGUIOptionsDepthCalibration2024 : public MGUIOptions //! Select spline file to load, splines will convert CTD->Depth MGUIEFileSelector* m_SplinesFileSelector; - //! Select TAC Calibration file to load, converts readout timing to nanoseconds - MGUIEFileSelector* m_TACCalFileSelector; - //! Check button if working with the Card Cage at UCSD TGCheckButton* m_UCSDOverride; diff --git a/include/MModuleDepthCalibration2024.h b/include/MModuleDepthCalibration2024.h index 5e03bb0a..6ec71d88 100644 --- a/include/MModuleDepthCalibration2024.h +++ b/include/MModuleDepthCalibration2024.h @@ -72,11 +72,6 @@ class MModuleDepthCalibration2024 : public MModule //! Get filename for CTD->Depth splines MString GetSplinesFileName() const {return m_SplinesFile;} - //! Set filename for TAC Calibration - void SetTACCalFileName( const MString& FileName) {m_TACCalFile = FileName;} - //! Get filename for TAC Calibration - MString GetTACCalFileName() const {return m_TACCalFile;} - //! Set whether the data came from the card cage at UCSD void SetUCSDOverride( bool Override ) {m_UCSDOverride = Override;} //! Get whether the data came from the card cage at UCSD @@ -112,8 +107,6 @@ class MModuleDepthCalibration2024 : public MModule vector* GetPixelCoeffs(int pixel_code); //! Load the splines file bool LoadSplinesFile(MString FName); - //! Load the TAC Calibration file - bool LoadTACCalFile(MString FName); //! Get the timing FWHM noise for the specified pixel and Energy double GetTimingNoiseFWHM(int pixel_code, double Energy); @@ -127,11 +120,8 @@ class MModuleDepthCalibration2024 : public MModule unordered_map> m_Coeffs; double m_Coeffs_Energy; - unordered_map>> m_HVTACCal; - unordered_map>> m_LVTACCal; MString m_CoeffsFile; MString m_SplinesFile; - MString m_TACCalFile; unordered_map m_DetectorNames; unordered_map m_Thicknesses; unordered_map m_NXStrips; @@ -156,7 +146,6 @@ class MModuleDepthCalibration2024 : public MModule unordered_map> m_DepthGrid; bool m_SplinesFileIsLoaded; bool m_CoeffsFileIsLoaded; - bool m_TACCalFileIsLoaded; // boolean for use with the card cage at UCSD since it tags all events as detector 11 bool m_UCSDOverride; diff --git a/src/MGUIOptionsDepthCalibration2024.cxx b/src/MGUIOptionsDepthCalibration2024.cxx index 53688321..cd6c07ec 100644 --- a/src/MGUIOptionsDepthCalibration2024.cxx +++ b/src/MGUIOptionsDepthCalibration2024.cxx @@ -78,12 +78,6 @@ void MGUIOptionsDepthCalibration2024::Create() TGLayoutHints* Label2Layout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); m_OptionsFrame->AddFrame(m_SplinesFileSelector, Label2Layout); - m_TACCalFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Calibration file:", - dynamic_cast(m_Module)->GetTACCalFileName()); - m_TACCalFileSelector->SetFileType("TAC", "*.csv"); - TGLayoutHints* Label3Layout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); - m_OptionsFrame->AddFrame(m_TACCalFileSelector, Label3Layout); - m_UCSDOverride = new TGCheckButton(m_OptionsFrame, "Check this box if you're using the card cage at UCSD", 1); m_UCSDOverride->SetOn(dynamic_cast(m_Module)->GetUCSDOverride()); TGLayoutHints* Label4Layout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); @@ -133,7 +127,6 @@ bool MGUIOptionsDepthCalibration2024::OnApply() dynamic_cast(m_Module)->SetCoeffsFileName(m_CoeffsFileSelector->GetFileName()); dynamic_cast(m_Module)->SetSplinesFileName(m_SplinesFileSelector->GetFileName()); - dynamic_cast(m_Module)->SetTACCalFileName(m_TACCalFileSelector->GetFileName()); dynamic_cast(m_Module)->SetUCSDOverride(m_UCSDOverride->IsOn()); return true; diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 76e250e0..ed5f45c8 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -120,10 +120,6 @@ bool MModuleDepthCalibration2024::Initialize() // ie DetID=0 should be the 0th detector in m_Detectors, DetID=1 should the 1st, etc. m_Detectors = m_Geometry->GetDetectorList(); - if( LoadTACCalFile(m_TACCalFile) == false ){ - cout << "No TAC Calibration file loaded. Proceeding without TAC Calibration." << endl; - } - // Look through the Geometry and get the names and thicknesses of all the detectors. for(unsigned int i = 0; i < m_Detectors.size(); ++i){ // For now, DetID is in order of detectors, which puts contraints on how the geometry file should be written. @@ -279,28 +275,6 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) // TODO: For Card Cage, may need to add noise double XTiming = XSH->GetTiming(); double YTiming = YSH->GetTiming(); - if ( !m_UCSDOverride ) { - if ( m_TACCalFileIsLoaded ) { - if ( XSH->IsLowVoltageStrip() ){ - XTiming = XTiming*m_LVTACCal[DetID][XStripID][0] + m_LVTACCal[DetID][XStripID][1]; - YTiming = YTiming*m_HVTACCal[DetID][YStripID][0] + m_HVTACCal[DetID][YStripID][1]; - } - else { - XTiming = XTiming*m_HVTACCal[DetID][XStripID][0] + m_HVTACCal[DetID][XStripID][1]; - YTiming = YTiming*m_LVTACCal[DetID][YStripID][0] + m_LVTACCal[DetID][YStripID][1]; - } - } - else { - if ( XSH->IsLowVoltageStrip() ){ - XTiming = XTiming*0.405 - 525.; - YTiming = YTiming*0.43 - 500.; - } - else { - XTiming = XTiming*0.43 - 500.; - YTiming = YTiming*0.405 -525.; - } - } - } // cout << "Got the coefficients: " << Coeffs << endl; @@ -514,54 +488,6 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) } -bool MModuleDepthCalibration2024::LoadTACCalFile(MString FName) -{ - // Read in the TAC Calibration file, which should contain for each strip: - // DetID, h or l for high or low voltage, TAC cal, TAC cal error, TAC cal offset, TAC offset error - MFile F; - if( F.Open(FName) == false ){ - cout << "MModuleDepthCalibration2024: failed to open TAC Calibration file." << endl; - m_TACCalFileIsLoaded = false; - return false; - } else { - for(unsigned int i = 0; i < m_Detectors.size(); ++i){ - unordered_map> temp_map_HV; - m_HVTACCal[i] = temp_map_HV; - unordered_map> temp_map_LV; - m_LVTACCal[i] = temp_map_LV; - } - MString Line; - while( F.ReadLine( Line ) ){ - if( !Line.BeginsWith("#") ){ - std::vector Tokens = Line.Tokenize(","); - if( Tokens.size() == 7 ){ - int DetID = Tokens[0].ToInt(); - int StripID = Tokens[2].ToInt(); - double taccal = Tokens[3].ToDouble(); - double taccal_err = Tokens[4].ToDouble(); - double offset = Tokens[5].ToDouble(); - double offset_err = Tokens[6].ToDouble(); - vector cal_vals; - cal_vals.push_back(taccal); cal_vals.push_back(offset); cal_vals.push_back(taccal_err); cal_vals.push_back(offset_err); - if ( Tokens[1] == "l" ){ - m_LVTACCal[DetID][StripID] = cal_vals; - } - else if ( Tokens[1] == "h" ){ - m_HVTACCal[DetID][StripID] = cal_vals; - } - } - } - } - F.Close(); - } - - m_TACCalFileIsLoaded = true; - - return true; - -} - - std::vector* MModuleDepthCalibration2024::GetPixelCoeffs(int pixel_code) { // Check to see if the stretch and offset have been loaded. If so, try to get the coefficients for the specified pixel. @@ -871,11 +797,6 @@ bool MModuleDepthCalibration2024::ReadXmlConfiguration(MXmlNode* Node) m_SplinesFile = SplinesFileNameNode->GetValue(); } - MXmlNode* TACCalFileNameNode = Node->GetNode("TACCalFileName"); - if (TACCalFileNameNode != 0) { - m_TACCalFile = TACCalFileNameNode->GetValue(); - } - return true; } @@ -889,8 +810,7 @@ MXmlNode* MModuleDepthCalibration2024::CreateXmlConfiguration() MXmlNode* Node = new MXmlNode(0,m_XmlTag); new MXmlNode(Node, "CoeffsFileName", m_CoeffsFile); new MXmlNode(Node, "SplinesFileName", m_SplinesFile); - new MXmlNode(Node, "TACCalFileName", m_TACCalFile); - + return Node; } diff --git a/src/MModuleEnergyCalibrationUniversal.cxx b/src/MModuleEnergyCalibrationUniversal.cxx index ce39060f..a2d59dc1 100644 --- a/src/MModuleEnergyCalibrationUniversal.cxx +++ b/src/MModuleEnergyCalibrationUniversal.cxx @@ -397,8 +397,7 @@ bool MModuleEnergyCalibrationUniversal::AnalyzeEvent(MReadOutAssembly* Event) for (unsigned int i = 0; i < Event->GetNStripHits(); ) { MStripHit* SH = Event->GetStripHit(i); - if (SH->GetEnergy() < 8 || SH->GetTiming() < 8700 || SH->GetTiming() > 12000) { - // cout<<"HACK: Removing strip hit due to TAC "<GetTiming()<<" cut or energy "<GetEnergy()<GetEnergy() < 8) { Event->RemoveStripHit(i); delete SH; } else { From f3cb5dafa2fc2674882b945a9801bdd0bef297db Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 5 Mar 2025 15:49:50 -0800 Subject: [PATCH 08/90] BUG: Call MModule:Initialize --- src/MModuleTACcut.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index cfcd7ee3..5adfcec8 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -116,7 +116,7 @@ bool MModuleTACcut::Initialize() return false; } - return true; + return MModule::Initialize(); } //////////////////////////////////////////////////////////////////////////////// From 524bcfec0a6066af333f0c876577855900b188de Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 5 Mar 2025 15:50:56 -0800 Subject: [PATCH 09/90] ADD: MStripHit now has an m_TAC variable in addition to m_Timing --- include/MStripHit.h | 27 ++++++++++++++++++++++++--- src/MModuleLoaderMeasurementsROA.cxx | 2 +- src/MModuleTACcut.cxx | 7 +++---- src/MStripHit.cxx | 5 ++++- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/include/MStripHit.h b/include/MStripHit.h index d9aa131a..7a1e3269 100644 --- a/include/MStripHit.h +++ b/include/MStripHit.h @@ -101,11 +101,26 @@ class MStripHit //! Return the calibrated energy double GetEnergyResolution() const { return m_EnergyResolution; } - //! Set the Timing of the top side + //! Set the TAC + void SetTAC(double TAC) { m_TAC = TAC; } + //! Return the TAC + double GetTAC() const { return m_TAC; } + + //! Set the TAC resolution + void SetTACResolution(double TACResolution) { m_TACResolution = TACResolution; } + //! Return the TAC resolution + double GetTACResolution() const { return m_TACResolution; } + + //! Set the Timing in nanoseconds void SetTiming(double Timing) { m_Timing = Timing; } - //! Return the Timing of the top side + //! Return the Timing in nanoseconds double GetTiming() const { return m_Timing; } + //! Set the Timing resolution + void SetTimingResolution(double TimingResolution) { m_TimingResolution = TimingResolution; } + //! Return the Timing resolution + double GetTimingResolution() const { return m_TimingResolution; } + //! Set the Temperature of the relavent preamp (in degrees C) void SetPreampTemp(double PreampTemp) { m_PreampTemp = PreampTemp; } //! Return the Temperature of the relavent preamp (in degrees C) @@ -152,8 +167,14 @@ class MStripHit double m_Energy; //! The energy resolution double m_EnergyResolution; - //! Timing of the top side + //! TAC timing + double m_TAC; + //! TAC timing resolution + double m_TACResolution; + //! Timing in ns double m_Timing; + //! Timing resolution in ns + double m_TimingResolution; //! Temperature of Preamp double m_PreampTemp; diff --git a/src/MModuleLoaderMeasurementsROA.cxx b/src/MModuleLoaderMeasurementsROA.cxx index ba7da260..cf19aedd 100644 --- a/src/MModuleLoaderMeasurementsROA.cxx +++ b/src/MModuleLoaderMeasurementsROA.cxx @@ -195,7 +195,7 @@ bool MModuleLoaderMeasurementsROA::ReadNextEvent(MReadOutAssembly* Event) SH->SetStripID(Strip->GetStripID()); if (Timing != nullptr) { - SH->SetTiming(Timing->GetTiming()); + SH->SetTAC(Timing->GetTiming()); } else { cout<GetStripHit(i); if (HasExpos()==true) { - m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTiming()); + m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTAC()); } // takes inputted min and max TAC values from the GUI module to make cuts - if (SH->GetTiming() < m_MinimumTAC || SH->GetTiming() > m_MaximumTAC) { - // cout<<"HACK: Removing strip ht due to TAC "<GetTiming()<<" cut or energy "<GetEnergy()<GetTAC() < m_MinimumTAC || SH->GetTAC() > m_MaximumTAC) { Event->RemoveStripHit(i); delete SH; } else { @@ -163,7 +162,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) for (unsigned int i = 0; i < Event->GetNStripHits(); ++i) { MStripHit* SH = Event->GetStripHit(i); - double TAC_timing = SH->GetTiming(); + double TAC_timing = SH->GetTAC(); double ns_timing; int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); diff --git a/src/MStripHit.cxx b/src/MStripHit.cxx index 03491538..e79350a4 100644 --- a/src/MStripHit.cxx +++ b/src/MStripHit.cxx @@ -81,7 +81,10 @@ void MStripHit::Clear() m_ADCUnits = 0; m_Energy = 0; m_EnergyResolution = 0; + m_TAC = 0; + m_TACResolution = 0; m_Timing = 0; + m_TimingResolution = 0; m_PreampTemp = 0; m_Origins.clear(); } @@ -190,7 +193,7 @@ void MStripHit::StreamRoa(ostream& S) <GetStripID()<<" " <<((m_ReadOutElement->IsLowVoltageStrip() == true) ? "l" : "h")<<" " < Date: Wed, 5 Mar 2025 16:07:42 -0800 Subject: [PATCH 10/90] Cleanup: removed unused single-site only button --- include/MGUIOptionsTACcut.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/MGUIOptionsTACcut.h b/include/MGUIOptionsTACcut.h index 760a44b8..294c638a 100644 --- a/include/MGUIOptionsTACcut.h +++ b/include/MGUIOptionsTACcut.h @@ -73,8 +73,6 @@ class MGUIOptionsTACcut : public MGUIOptions //! Select TAC Calibration file to load, converts readout timing to nanoseconds MGUIEFileSelector* m_TACCalFileSelector; - - TGCheckButton* m_SingleSiteOnly; // private members: private: From 79c95c78fd2f70d03ef286603d0c85b2a8bff3b6 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 5 Mar 2025 18:01:41 -0800 Subject: [PATCH 11/90] ADD: Charge trapping correction app --- apps/TrappingCorrection.cxx | 759 ++++++++++++++++++++++++++++++++++++ 1 file changed, 759 insertions(+) create mode 100644 apps/TrappingCorrection.cxx diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx new file mode 100644 index 00000000..12963ec8 --- /dev/null +++ b/apps/TrappingCorrection.cxx @@ -0,0 +1,759 @@ +/* + * TrappingCorrection.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + +// Standard +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +// ROOT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace ROOT::Minuit2; + +// MEGAlib +#include "MGlobal.h" +#include "MFile.h" +#include "MReadOutElementDoubleStrip.h" +#include "MFileReadOuts.h" +#include "MReadOutAssembly.h" +#include "MStripHit.h" +#include "MReadOutSequence.h" +#include "MSupervisor.h" +#include "MModuleLoaderMeasurementsROA.h" +#include "MModuleEnergyCalibrationUniversal.h" +#include "MModuleEventFilter.h" +#include "MModuleStripPairingGreedy.h" +#include "MModuleStripPairingChiSquare.h" +#include "MModuleTACcut.h" +#include "MAssembly.h" + + +int g_HistBins = 75; +double g_MinCTD = -200; +double g_MaxCTD = 200; +double g_MinRatio = 0.94; +double g_MaxRatio = 1.06; + + +//////////////////////////////////////////////////////////////////////////////// + + +class SymmetryFCN : public FCNBase +{ +public: + //! Operator which returns the symmetry of m_CTDHistogram given the parameters passed + double operator()(vector const &v) const override; + double Up() const override { return 1; } + + void AddCTD(double CTD){ m_CTD.push_back(CTD); } + void AddHVEnergy(double HVEnergy, double HVEnergyResolution){ m_HVEnergy.push_back(HVEnergy); m_HVEnergyResolution.push_back(HVEnergyResolution); } + void AddLVEnergy(double LVEnergy, double LVEnergyResolution){ m_LVEnergy.push_back(LVEnergy); m_LVEnergyResolution.push_back(LVEnergyResolution); } + + vector GetCTD(){ return m_CTD; } + vector GetHVEnergy(){ return m_HVEnergy; } + vector GetLVEnergy(){ return m_LVEnergy; } + vector GetHVEnergyResolution(){ return m_HVEnergyResolution; } + vector GetLVEnergyResolution(){ return m_LVEnergyResolution; } + + void SetCTD(vector CTD){ m_CTD = CTD; } + void SetHVEnergy(vector HVEnergy, vector HVEnergyResolution){ m_HVEnergy = HVEnergy; m_HVEnergyResolution = HVEnergyResolution; } + void SetLVEnergy(vector LVEnergy, vector LVEnergyResolution){ m_LVEnergy = LVEnergy; m_LVEnergyResolution = LVEnergyResolution; } + + //! The measured CTD and HV/LV energies + vector m_CTD; + vector m_HVEnergy; + vector m_LVEnergy; + vector m_HVEnergyResolution; + vector m_LVEnergyResolution; + +}; + + +//////////////////////////////////////////////////////////////////////////////// + + +class ChiSquaredFCN : public SymmetryFCN +{ +public: + //! Operator which returns the symmetry of m_CTDHistogram given the parameters passed + double operator()(vector const &v) const override; + double Up() const override { return 1; } + +}; + + +//////////////////////////////////////////////////////////////////////////////// + + + +//! A standalone program based on MEGAlib and ROOT +class TrappingCorrection +{ +public: + //! Default constructor + TrappingCorrection(); + //! Default destructor + ~TrappingCorrection(); + + //! Parse the command line + bool ParseCommandLine(int argc, char** argv); + //! Analyze what eveer needs to be analyzed... + bool Analyze(); + //!load cross talk correction + vector > > LoadCrossTalk(); + //! Interrupt the analysis + void Interrupt() { m_Interrupt = true; } + + void dummy_func() { return; } + + MStripHit* GetDominantStrip(vector& Strips, double& EnergyFraction); + +private: + //! True, if the analysis needs to be interrupted + bool m_Interrupt; + //! The input file name + MString m_FileName; + MString m_EcalFile; + MString m_TACFile; + //! output file names + MString m_OutFile; + //! energy E0 + // float m_E0; + //! option to correct charge loss or not + // bool m_CorrectCL; + //! option to do a pixel-by-pixel calibration (instead of detector-by-detector) + bool m_PixelCorrect; + bool m_GreedyPairing; + bool m_CardCageOverride; + + double m_MinEnergy; + double m_MaxEnergy; + +}; + +//////////////////////////////////////////////////////////////////////////////// + + +double SymmetryFCN::operator()(vector const &v) const +{ + double HVSlope = v[0]; + double HVIntercept = v[1]; + double LVSlope = v[2]; + double LVIntercept = v[3]; + + char name[64]; sprintf(name,"name"); + int HistBins = g_HistBins; + if (HistBins%2 == 0) { + HistBins += 1; + } + TH2D CorrectedHistogram(name, name, HistBins, g_MinCTD, g_MaxCTD, HistBins, g_MinRatio, g_MaxRatio); + + for (unsigned int i = 0; i < m_CTD.size(); ++i) { + double CTDHVShift = m_CTD[i] + g_MaxCTD; + double CTDLVShift = m_CTD[i] + g_MinCTD; + // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. + double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); + double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); + CorrectedHistogram.Fill(m_CTD[i], CorrectedHVEnergy/CorrectedLVEnergy); + } + + vector> BinValues; + vector> ReflectedBinValues; + double Asymmetry = 0; + + for (unsigned int y = 0; y < CorrectedHistogram.GetNbinsY(); ++y) { + + vector XValues; + + for (unsigned int x = 0; x < CorrectedHistogram.GetNbinsX(); ++x) { + XValues.push_back(CorrectedHistogram.GetBinContent(x,y)); + } + + // BinValues.push_back(XValues); + vector ReflectedXValues = XValues; + reverse(ReflectedXValues.begin(), ReflectedXValues.end()); + + for (unsigned int x = 0; x < XValues.size(); ++x) { + Asymmetry += pow(XValues[x] - ReflectedXValues[x], 2)/(XValues[x] + ReflectedXValues[x]); + } + } + + return Asymmetry; + +} + + +//////////////////////////////////////////////////////////////////////////////// + + +double ChiSquaredFCN::operator()(vector const &v) const +{ + double HVSlope = v[0]; + double HVIntercept = v[1]; + double LVSlope = v[2]; + double LVIntercept = v[3]; + + double ChiSquare = 0; + + for (unsigned int i = 0; i < m_CTD.size(); ++i) { + double CTDHVShift = m_CTD[i] + g_MaxCTD; + double CTDLVShift = m_CTD[i] + g_MinCTD; + // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. + double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); + double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); + + ChiSquare += pow(CorrectedHVEnergy - CorrectedLVEnergy, 2)/(m_HVEnergyResolution[i] + m_LVEnergyResolution[i]); + } + + // ChiSquare /= m_CTD.size(); + + return ChiSquare; + +} + + +//! Default constructor +TrappingCorrection::TrappingCorrection() : m_Interrupt(false) +{ + gStyle->SetPalette(1, 0); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Default destructor +TrappingCorrection::~TrappingCorrection() +{ + // Intentionally left blank +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Parse the command line +bool TrappingCorrection::ParseCommandLine(int argc, char** argv) +{ + ostringstream Usage; + Usage<"< i+1) && + (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ + cout<<"Error: Option "< i+2) && + (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0) && + (argv[i+2][0] != '-' || isalpha(argv[i+2][1]) == 0))){ + cout<<"Error: Option "<SetBinContent(i,j,c); + } + } + TCanvas *ctemp = new TCanvas(); + h2->Draw("colz"); + ctemp->Print("frac_map.pdf"); +*/ + //time code just to see + TStopwatch watch; + watch.Start(); + + if (m_Interrupt == true) return false; + + MSupervisor* S = MSupervisor::GetSupervisor(); + + MModuleLoaderMeasurementsROA* Loader; + MModuleTACcut* TACCalibrator; + MModuleEnergyCalibrationUniversal* EnergyCalibrator; + MModuleEventFilter* EventFilter; + + unsigned int MNumber = 0; + cout<<"Creating ROA loader"<SetFileName(m_FileName); + S->SetModule(Loader, MNumber); + ++MNumber; + + if (m_CardCageOverride==false) { + cout<<"Creating TAC calibrator"<SetTACCalFileName(m_TACFile); + S->SetModule(TACCalibrator, MNumber); + ++MNumber; + } + + cout<<"Creating energy calibrator"<SetFileName(m_EcalFile); + EnergyCalibrator->EnablePreampTempCorrection(false); + S->SetModule(EnergyCalibrator, MNumber); + ++MNumber; + + cout<<"Creating Event filter"<SetMinimumLVStrips(1); + EventFilter->SetMaximumLVStrips(1); + EventFilter->SetMinimumHVStrips(1); + EventFilter->SetMaximumHVStrips(1); + EventFilter->SetMinimumTotalEnergy(m_MinEnergy); + EventFilter->SetMaximumTotalEnergy(m_MaxEnergy); + S->SetModule(EventFilter, MNumber); + ++MNumber; + + cout<<"Creating strip pairing"<(Pairing); + Pairing = new MModuleStripPairingGreedy(); + } + else { + // Pairing = dynamic_cast(Pairing); + Pairing = new MModuleStripPairingChiSquare(); + } + S->SetModule(Pairing, MNumber); + + cout<<"Initializing Loader"<Initialize() == false) return false; + if (m_CardCageOverride==false) { + cout<<"Initializing TAC calibrator"<Initialize() == false) return false; + } + cout<<"Initializing Energy calibrator"<Initialize() == false) return false; + cout<<"Initializing Event filter"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; + + map Histograms; + map FCNs; + + bool IsFinished = false; + MReadOutAssembly* Event = new MReadOutAssembly(); + + cout<<"Analyzing..."<Clear(); + + if (Loader->IsReady() ){ + Loader->AnalyzeEvent(Event); + + if (m_CardCageOverride==false) { + TACCalibrator->AnalyzeEvent(Event); + } + + EnergyCalibrator->AnalyzeEvent(Event); + bool Unfiltered = EventFilter->AnalyzeEvent(Event); + Pairing->AnalyzeEvent(Event); + + if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true)) { + for (unsigned int h = 0; h < Event->GetNHits(); ++h) { + double HVEnergy = 0.0; + double LVEnergy = 0.0; + double HVEnergyResolution = 0.0; + double LVEnergyResolution = 0.0; + vector HVStrips; + vector LVStrips; + + MHit* H = Event->GetHit(h); + + int DetID = H->GetStripHit(0)->GetDetectorID(); + TH2D* Hist = Histograms[DetID]; + SymmetryFCN* FCN = FCNs[DetID]; + + if (Hist == nullptr) { + char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); + Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); + Hist->SetXTitle("CTD (ns)"); + Hist->SetYTitle("HV/LV Energy Ratio"); + Histograms[DetID] = Hist; + } + + if (FCN == nullptr) { + FCN = new SymmetryFCN(); + FCNs[DetID] = FCN; + } + + for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { + MStripHit* SH = H->GetStripHit(sh); + + if (SH->IsLowVoltageStrip()==true) { + LVEnergy += SH->GetEnergy(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } + } + + double HVEnergyFraction = 0; + double LVEnergyFraction = 0; + MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + double EnergyFraction = HVEnergy/LVEnergy; + double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + if (m_CardCageOverride == true) { + CTD *= -1; + } + Hist->Fill(CTD, EnergyFraction); + FCN->AddCTD(CTD); + FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); + FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); + } + } + } + IsFinished = Loader->IsFinished(); + } + + //setup output file + ofstream OutputCalFile; + OutputCalFile.open(m_OutFile+MString("_parameters.txt")); + OutputCalFile<<"Det"<<'\t'<<"HV Slope"<<'\t'<<"HV Intercept"<<'\t'<<"LV Slope"<<'\t'<<"LV Intercept"<SetLogz(); + C->cd(); + H.second->Draw("colz"); + + H.second->Write(); + f.Close(); + + } + + for (auto F: FCNs) { + + int DetID = F.first; + MnUserParameters* InitialStateSym = new MnUserParameters(); + InitialStateSym->Add("HVSlope", 1e-3, 1e-4, 0, 3e-1); + InitialStateSym->Add("HVIntercept", 0, 0.01, -2, 2); + InitialStateSym->Add("LVSlope", 0, 1e-4, -3e-2, 0); + InitialStateSym->Add("LVIntercept", 0, 0.01, -2, 2); + + InitialStateSym->Fix("LVSlope"); + InitialStateSym->Fix("LVIntercept"); + InitialStateSym->Fix("HVIntercept"); + + + MnMigrad migradSym(*F.second, *InitialStateSym); + // Minimize + FunctionMinimum MinimumSym = migradSym(); + + MnUserParameters ParametersSym = MinimumSym.UserParameters(); + // double HVSlope = ParametersSym.Value("HVSlope"); + // double HVIntercept = ParametersSym.Value("HVIntercept"); + // double LVSlope = ParametersSym.Value("LVSlope"); + // double LVIntercept = ParametersSym.Value("LVIntercept"); + + // output + cout<Add("HVSlope", ParametersSym.Value("HVSlope"), ParametersSym.Error("HVSlope")); + InitialStateChi->Add("HVIntercept", 0, 0.01, -2, 2); + InitialStateChi->Add("LVSlope", 0, 1e-4, -3e-2, 0); + InitialStateChi->Add("LVIntercept", 0, 0.01, -2, 2); + + InitialStateChi->Fix("LVSlope"); + InitialStateChi->Fix("LVIntercept"); + InitialStateChi->Fix("HVSlope"); + + + ChiSquaredFCN* ChiSquaredF = new ChiSquaredFCN(); + ChiSquaredF->SetCTD(F.second->GetCTD()); + ChiSquaredF->SetHVEnergy(F.second->GetHVEnergy(), F.second->GetHVEnergyResolution()); + ChiSquaredF->SetLVEnergy(F.second->GetLVEnergy(), F.second->GetLVEnergyResolution()); + MnMigrad migradChi(*ChiSquaredF, *InitialStateChi); + // Minimize + FunctionMinimum MinimumChi = migradChi(); + + MnUserParameters ParametersChi = MinimumChi.UserParameters(); + double HVSlope = ParametersChi.Value("HVSlope"); + double HVIntercept = ParametersChi.Value("HVIntercept"); + double LVSlope = ParametersChi.Value("LVSlope"); + double LVIntercept = ParametersChi.Value("LVIntercept"); + // output + cout<SetXTitle("CTD (ns)"); + Hist->SetYTitle("HV/LV Energy Ratio"); + + vector CTDList = F.second->GetCTD(); + vector HVEnergyList = F.second->GetHVEnergy(); + vector LVEnergyList = F.second->GetLVEnergy(); + for (unsigned int i=0; iFill(CTDList[i], CorrectedHVEnergy/CorrectedLVEnergy); + } + + TCanvas* C = new TCanvas(); + C->SetLogz(); + C->cd(); + Hist->Draw("colz"); + + TFile f(m_OutFile+MString("_Det")+DetID+MString("_Hist_Corr.root"),"recreate"); + Hist->Write(); + f.Close(); + + OutputCalFile<& Strips, double& EnergyFraction) +{ + double MaxEnergy = -numeric_limits::max(); // AZ: When both energies are zero (which shouldn't happen) we still pick one + double TotalEnergy = 0.0; + MStripHit* MaxStrip = nullptr; + + // Iterate through strip hits and get the strip with highest energy + for (const auto SH : Strips) { + double Energy = SH->GetEnergy(); + TotalEnergy += Energy; + if (Energy > MaxEnergy) { + MaxStrip = SH; + MaxEnergy = Energy; + } + } + if (TotalEnergy == 0) { + EnergyFraction = 0; + } else { + EnergyFraction = MaxEnergy/TotalEnergy; + } + return MaxStrip; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Called when an interrupt signal is flagged +//! All catched signals lead to a well defined exit of the program +void CatchSignal(int a) +{ + if (g_Prg != 0 && g_NInterruptCatches-- > 0) { + cout<<"Catched signal Ctrl-C (ID="<Interrupt(); + } else { + abort(); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Main program +int main(int argc, char** argv) +{ + // Catch a user interupt for graceful shutdown + signal(SIGINT, CatchSignal); + + // Initialize global MEGALIB variables, especially mgui, etc. + MGlobal::Initialize("Standalone", "a standalone example program"); + + TApplication TrappingCorrectionApp("TrappingCorrectionApp", 0, 0); + + g_Prg = new TrappingCorrection(); + + if (g_Prg->ParseCommandLine(argc, argv) == false) { + cerr<<"Error during parsing of command line!"<Analyze() == false) { + cerr<<"Error during analysis!"< Date: Wed, 5 Mar 2025 18:14:56 -0800 Subject: [PATCH 12/90] CHG: Handle all number of strip hits. New error messages --- include/MModuleDepthCalibration2024.h | 2 ++ src/MModuleDepthCalibration2024.cxx | 35 +++++++++++++-------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/MModuleDepthCalibration2024.h b/include/MModuleDepthCalibration2024.h index 6ec71d88..40eefe9a 100644 --- a/include/MModuleDepthCalibration2024.h +++ b/include/MModuleDepthCalibration2024.h @@ -136,6 +136,8 @@ class MModuleDepthCalibration2024 : public MModule uint64_t m_Error5; uint64_t m_Error6; uint64_t m_ErrorSH; + uint64_t m_ErrorNullSH; + uint64_t m_ErrorNoE; vector m_Detectors; vector m_DetectorIDs; MModuleEnergyCalibrationUniversal* m_EnergyCalibration; diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index ed5f45c8..95e9b33c 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -91,6 +91,8 @@ MModuleDepthCalibration2024::MModuleDepthCalibration2024() : MModule() m_Error5 = 0; m_Error6 = 0; m_ErrorSH = 0; + m_ErrorNullSH=0; + m_ErrorNoE=0; } @@ -203,30 +205,25 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) // Handle different grades differently // GRADE=-1 is an error. Break from the loop and continue. - if ( Grade == -1 ){ + if ( Grade < 0 ){ H->SetNoDepth(); Event->SetDepthCalibrationIncomplete(); - ++m_ErrorSH; - } - - // GRADE=5 is some complicated geometry with multiple hits on a single strip. - // GRADE=4 means there are more than 2 strip hits on one or both sides. - else if( Grade > 3 ){ + if (Grade == -1) { + ++m_ErrorSH; + } else if (Grade == -2) { + ++m_ErrorNullSH; + } else if (Grade == -3) { + ++m_ErrorNoE; + } + } else if (Grade > 4) { // GRADE=5 is some complicated geometry with multiple hits on a single strip. GRADE=6 means not all strips are adjacent. H->SetNoDepth(); Event->SetDepthCalibrationIncomplete(); - if(Grade==4){ - ++m_Error4; - } - else if(Grade==5){ + if (Grade==5) { ++m_Error5; - } - else if(Grade==6){ + } else if (Grade==6) { ++m_Error6; } - } - - // If the Grade is 0-3, we can handle it. - else { + } else { // If the Grade is 0-4, we can handle it. MVector LocalPosition, PositionResolution, GlobalPosition, GlobalResolution, LocalOrigin; @@ -638,7 +635,7 @@ int MModuleDepthCalibration2024::GetHitGrade(MHit* H){ int return_value; // If 1 strip on each side, GRADE=0 // This represents the center of the pixel - if( (PStrips.size() == 1) && (NStrips.size() == 1) ){ + if( (PStrips.size() == 1) && (NStrips.size() == 1) || (PStrips.size() == 3) && (NStrips.size() == 3) ){ return_value = 0; } // If 2 hits on N side and 1 on P, GRADE=1 @@ -829,6 +826,8 @@ void MModuleDepthCalibration2024::Finalize() cout << "Number of hits with non-adjacent strip hits: " << m_Error6 << endl; cout << "Number of hits with too many strip hits: " << m_Error4 << endl; cout << "Number of hits with no strip hits on one or both sides: " << m_ErrorSH << endl; + cout << "Number of hits with null strip hits: " << m_ErrorNullSH << endl; + cout << "Number of hits 0 energy on a strip hit: " << m_ErrorNoE << endl; /* TFile* rootF = new TFile("EHist.root","recreate"); rootF->WriteTObject( EHist ); From 91130d4b3d99984701f5bd6d835b23cfc6873108 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 5 Mar 2025 18:15:38 -0800 Subject: [PATCH 13/90] CHG: Only plot depth if Strip pairing is complete --- src/MModuleDepthCalibration2024.cxx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 95e9b33c..63cb4196 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -363,12 +363,11 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) Zsigma = sqrt(depth_var/prob_sum); Zpos = mean_depth - (m_Thicknesses[DetID]/2.0); - // Zpos = mean_depth; - // cout << "calculated depth: " << Zpos << endl; // Add the depth to the GUI histogram. - m_ExpoDepthCalibration->AddDepth(DetID, Zpos); - + if (Event->IsStripPairingIncomplete()==false) { + m_ExpoDepthCalibration->AddDepth(DetID, Zpos); + } m_NoError+=1; } } From c1524f26ddecc790a6d09089fc9ea6fbff1794bc Mon Sep 17 00:00:00 2001 From: parshadkp Date: Thu, 6 Mar 2025 17:51:08 -0500 Subject: [PATCH 14/90] Fix for TAC calibration file not remembering. --- src/MModuleTACcut.cxx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index e68c9fed..b2a9f886 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -209,12 +209,10 @@ bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) { //! Read the configuration data from an XML node - /* - MXmlNode* SomeTagNode = Node->GetNode("SomeTag"); - if (SomeTagNode != 0) { - m_SomeTagValue = SomeTagNode->GetValue(); + MXmlNode* TACCalFileNameNode = Node->GetNode("TACCalFileName"); + if (TACCalFileNameNode != 0) { + SetTACCalFileName(TACCalFileNameNode->GetValue()); } - */ return true; } @@ -229,9 +227,7 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() MXmlNode* Node = new MXmlNode(0, m_XmlTag); - /* - MXmlNode* SomeTagNode = new MXmlNode(Node, "SomeTag", "SomeValue"); - */ + new MXmlNode(Node, "TACCalFileName", m_TACCalFile); return Node; } From 1a7f0c8fb5beacca69d08a68994adb6243654b7b Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 6 Mar 2025 15:12:55 -0800 Subject: [PATCH 15/90] BUG: Save and load the state of the card cage override button --- src/MModuleDepthCalibration2024.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 63cb4196..7b7bb82c 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -793,6 +793,11 @@ bool MModuleDepthCalibration2024::ReadXmlConfiguration(MXmlNode* Node) m_SplinesFile = SplinesFileNameNode->GetValue(); } + MXmlNode* UCSDOverrideNode = Node->GetNode("UCSDOverride"); + if( UCSDOverrideNode != NULL ){ + m_UCSDOverride = (bool) UCSDOverrideNode->GetValueAsInt(); + } + return true; } @@ -806,6 +811,7 @@ MXmlNode* MModuleDepthCalibration2024::CreateXmlConfiguration() MXmlNode* Node = new MXmlNode(0,m_XmlTag); new MXmlNode(Node, "CoeffsFileName", m_CoeffsFile); new MXmlNode(Node, "SplinesFileName", m_SplinesFile); + new MXmlNode(Node, "UCSDOverride",(unsigned int) m_UCSDOverride); return Node; } From 1966091e1c98b0b3a24c38fb4b9c5c97ff26caf4 Mon Sep 17 00:00:00 2001 From: parshadkp Date: Thu, 6 Mar 2025 18:45:32 -0500 Subject: [PATCH 16/90] Maximum and Minimum TAC value added as parameters to config file. --- src/MModuleTACcut.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index b2a9f886..83af1e0b 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -214,6 +214,15 @@ bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) SetTACCalFileName(TACCalFileNameNode->GetValue()); } + MXmlNode* MinimumTACNode = Node->GetNode("MinimumTAC"); + if (MinimumTACNode != 0) { + m_MinimumTAC = MinimumTACNode->GetValueAsInt(); + } + MXmlNode* MaximumTACNode = Node->GetNode("MaximumTAC"); + if (MaximumTACNode != 0) { + m_MaximumTAC = MaximumTACNode->GetValueAsInt(); + } + return true; } @@ -228,6 +237,8 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() MXmlNode* Node = new MXmlNode(0, m_XmlTag); new MXmlNode(Node, "TACCalFileName", m_TACCalFile); + new MXmlNode(Node, "MinimumTAC", m_MinimumTAC); + new MXmlNode(Node, "MaximumTAC", m_MaximumTAC); return Node; } From b8a3da632c3ead32e1491ad57d7b5f89ebeb54cb Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 21 Mar 2025 12:06:26 -0700 Subject: [PATCH 17/90] ADD: Variables for nanosecond TAC cut --- include/MGUIOptionsTACcut.h | 12 ++++++++++++ include/MModuleTACcut.h | 21 +++++++++++++++++++++ src/MModuleTACcut.cxx | 29 +++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/include/MGUIOptionsTACcut.h b/include/MGUIOptionsTACcut.h index 294c638a..586a61fc 100644 --- a/include/MGUIOptionsTACcut.h +++ b/include/MGUIOptionsTACcut.h @@ -71,6 +71,18 @@ class MGUIOptionsTACcut : public MGUIOptions //! The total TAC selection MGUIEMinMaxEntry* m_TAC; + //! The shaping offset: measured time between test pulse and pulse peak + MGUIEEntry* m_ShapingOffset; + + //! FPGA setting of time between FLAG rising and ENABLE falling + MGUIEEntry* m_DisableTime; + + //! internal FPGA delay between FLAG rising and FPGA reacting + MGUIEEntry* m_FlagToEnDelay; + + //! Coincidence window after strip hit with largest TAC (first strip hit) + MGUIEEntry* m_CoincidenceWindow; + //! Select TAC Calibration file to load, converts readout timing to nanoseconds MGUIEFileSelector* m_TACCalFileSelector; diff --git a/include/MModuleTACcut.h b/include/MModuleTACcut.h index 6896e307..2ec787cb 100644 --- a/include/MModuleTACcut.h +++ b/include/MModuleTACcut.h @@ -85,6 +85,26 @@ class MModuleTACcut : public MModule //! Get filename for TAC Calibration MString GetTACCalFileName() const {return m_TACCalFile;} + //! Set the shaping offset + void SetShapingOffset(double ShapingOffset) { m_ShapingOffset = ShapingOffset; } + //! Get the shaping offset + unsigned int GetShapingOffset() const { return m_ShapingOffset; } + + //! Set the disable time + void SetDisableTime(double DisableTime) { m_DisableTime = DisableTime; } + //! Get the disable time + unsigned int GetDisableTime() const { return m_DisableTime; } + + //! Set the shaping flag_to_en_delay + void SetFlagToEnDelay(double FlagToEnDelay) { m_FlagToEnDelay = FlagToEnDelay; } + //! Get the shaping flag_to_en_delay + unsigned int GetFlagToEnDelay() const { return m_FlagToEnDelay; } + + //! Set the shaping coincidence window + void SetCoincidenceWindow(double CoincidenceWindow) { m_CoincidenceWindow = CoincidenceWindow; } + //! Get the shaping coincidence window + unsigned int GetCoincidenceWindow() const { return m_CoincidenceWindow; } + //! Load the TAC calibration file bool LoadTACCalFile(MString FName); @@ -109,6 +129,7 @@ class MModuleTACcut : public MModule // declare min and max TAC variables here unsigned int m_MinimumTAC, m_MaximumTAC; +double m_ShapingOffset, m_DisableTime, m_FlagToEnDelay, m_CoincidenceWindow; MString m_TACCalFile; unordered_map>> m_HVTACCal; unordered_map>> m_LVTACCal; diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 83af1e0b..41196cad 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -92,6 +92,11 @@ MModuleTACcut::MModuleTACcut() : MModule() //initialize a min and max TAC value m_MinimumTAC = 0; m_MaximumTAC = 20000; + + m_ShapingOffset = 2255; + m_DisableTime = 1396; + m_FlagToEnDelay = 104; + m_CoincidenceWindow = 500; } @@ -223,6 +228,26 @@ bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) m_MaximumTAC = MaximumTACNode->GetValueAsInt(); } + MXmlNode* ShapingOffsetNode = Node->GetNode("ShapingOffset"); + if (ShapingOffsetNode != 0) { + m_ShapingOffset = ShapingOffsetNode->GetValueAsDouble(); + } + + MXmlNode* DisableTimeNode = Node->GetNode("DisableTime"); + if (DisableTimeNode != 0) { + m_DisableTime = DisableTimeNode->GetValueAsDouble(); + } + + MXmlNode* FlagToEnDelayNode = Node->GetNode("FlagToEnDelay"); + if (FlagToEnDelayNode != 0) { + m_FlagToEnDelay = FlagToEnDelayNode->GetValueAsDouble(); + } + + MXmlNode* CoincidenceWindowNode = Node->GetNode("CoincidenceWindow"); + if (CoincidenceWindowNode != 0) { + m_CoincidenceWindow = CoincidenceWindowNode->GetValueAsDouble(); + } + return true; } @@ -239,6 +264,10 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() new MXmlNode(Node, "TACCalFileName", m_TACCalFile); new MXmlNode(Node, "MinimumTAC", m_MinimumTAC); new MXmlNode(Node, "MaximumTAC", m_MaximumTAC); + new MXmlNode(Node, "ShapingOffset", m_ShapingOffset); + new MXmlNode(Node, "DisableTime", m_DisableTime); + new MXmlNode(Node, "FlagToEnDelay", m_FlagToEnDelay); + new MXmlNode(Node, "CoincidenceWindow", m_CoincidenceWindow); return Node; } From 01feb3049ee269e1571f642066ede4324c899ed4 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 21 Mar 2025 12:07:17 -0700 Subject: [PATCH 18/90] ADD: Options to input nanosecond TAC cut parameters --- include/MGUIOptionsTACcut.h | 1 + src/MGUIOptionsTACcut.cxx | 31 ++++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/MGUIOptionsTACcut.h b/include/MGUIOptionsTACcut.h index 586a61fc..3cbe8555 100644 --- a/include/MGUIOptionsTACcut.h +++ b/include/MGUIOptionsTACcut.h @@ -38,6 +38,7 @@ // Forward declarations: class MGUIEFileSelector; class MGUIEMinMaxEntry; +class MGUIEEntry; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/MGUIOptionsTACcut.cxx b/src/MGUIOptionsTACcut.cxx index 007d9a03..419e1b52 100644 --- a/src/MGUIOptionsTACcut.cxx +++ b/src/MGUIOptionsTACcut.cxx @@ -34,6 +34,7 @@ #include "MString.h" #include "MGUIEFileSelector.h" #include "MGUIEMinMaxEntry.h" +#include "MGUIEEntry.h" // Nuclearizer libs: #include "MModuleTACcut.h" @@ -76,9 +77,9 @@ void MGUIOptionsTACcut::Create() // Modify here - TGLayoutHints* TACLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); - m_TAC = new MGUIEMinMaxEntry(m_OptionsFrame, "Choose the minimum and maximum TAC cut (in imaginary TAC units):", false, dynamic_cast(m_Module)->GetMinimumTAC(), dynamic_cast(m_Module)->GetMaximumTAC(), true, 0.0); - m_OptionsFrame->AddFrame(m_TAC, TACLayout); + // TGLayoutHints* TACLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + // m_TAC = new MGUIEMinMaxEntry(m_OptionsFrame, "Choose the minimum and maximum TAC cut (in imaginary TAC units):", false, dynamic_cast(m_Module)->GetMinimumTAC(), dynamic_cast(m_Module)->GetMaximumTAC(), true, 0.0); + // m_OptionsFrame->AddFrame(m_TAC, TACLayout); m_TACCalFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Calibration file:", dynamic_cast(m_Module)->GetTACCalFileName()); @@ -86,6 +87,22 @@ void MGUIOptionsTACcut::Create() TGLayoutHints* Label3Layout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); m_OptionsFrame->AddFrame(m_TACCalFileSelector, Label3Layout); + TGLayoutHints* ShapingOffsetLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); + m_ShapingOffset = new MGUIEEntry(m_OptionsFrame, "Shaping Offset [ns]:", false, dynamic_cast(m_Module)->GetShapingOffset(), false, -numeric_limits::max()/2, numeric_limits::max()/2); + m_OptionsFrame->AddFrame(m_ShapingOffset, ShapingOffsetLayout); + + TGLayoutHints* DisableTimeLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); + m_DisableTime = new MGUIEEntry(m_OptionsFrame, "Diable Time [ns]:", false, dynamic_cast(m_Module)->GetDisableTime(), false, -numeric_limits::max()/2, numeric_limits::max()/2); + m_OptionsFrame->AddFrame(m_DisableTime, DisableTimeLayout); + + TGLayoutHints* FlagToEnDelayLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); + m_FlagToEnDelay = new MGUIEEntry(m_OptionsFrame, "FLAG to ENABLE delay [ns]:", false, dynamic_cast(m_Module)->GetFlagToEnDelay(), false, -numeric_limits::max()/2, numeric_limits::max()/2); + m_OptionsFrame->AddFrame(m_FlagToEnDelay, FlagToEnDelayLayout); + + TGLayoutHints* CoincidenceWindowLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); + m_CoincidenceWindow = new MGUIEEntry(m_OptionsFrame, "Coincidence Window [ns]:", false, dynamic_cast(m_Module)->GetCoincidenceWindow(), false, -numeric_limits::max()/2, numeric_limits::max()/2); + m_OptionsFrame->AddFrame(m_CoincidenceWindow, CoincidenceWindowLayout); + // TGLabel* TACLabel = new TGLabel(m_OptionsFrame, // "This is a TAC cut and this text is here because.\n" @@ -135,9 +152,13 @@ bool MGUIOptionsTACcut::OnApply() { // Store the data in the module - dynamic_cast(m_Module)->SetMinimumTAC(m_TAC->GetMinValue()); - dynamic_cast(m_Module)->SetMaximumTAC(m_TAC->GetMaxValue()); + // dynamic_cast(m_Module)->SetMinimumTAC(m_TAC->GetMinValue()); + // dynamic_cast(m_Module)->SetMaximumTAC(m_TAC->GetMaxValue()); dynamic_cast(m_Module)->SetTACCalFileName(m_TACCalFileSelector->GetFileName()); + dynamic_cast(m_Module)->SetShapingOffset(m_ShapingOffset->GetAsDouble()); + dynamic_cast(m_Module)->SetDisableTime(m_DisableTime->GetAsDouble()); + dynamic_cast(m_Module)->SetFlagToEnDelay(m_FlagToEnDelay->GetAsDouble()); + dynamic_cast(m_Module)->SetCoincidenceWindow(m_CoincidenceWindow->GetAsDouble()); return true; } From 7765c123452445d75bc43ba00f1d822b62d56ae1 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 21 Mar 2025 12:08:56 -0700 Subject: [PATCH 19/90] ADD: perform nanosecond TAC cut after TAC calibration --- src/MModuleTACcut.cxx | 52 +++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 41196cad..e46069c9 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -149,22 +149,23 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) { // Main data analysis routine, which updates the event to a new level - // Apply cuts to the TAC values: - for (unsigned int i = 0; i < Event->GetNStripHits();) { - MStripHit* SH = Event->GetStripHit(i); - - if (HasExpos()==true) { - m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTAC()); - } - // takes inputted min and max TAC values from the GUI module to make cuts - if (SH->GetTAC() < m_MinimumTAC || SH->GetTAC() > m_MaximumTAC) { - Event->RemoveStripHit(i); - delete SH; - } else { - ++i; - } - } - + // // Apply cuts to the TAC values: + // for (unsigned int i = 0; i < Event->GetNStripHits();) { + // MStripHit* SH = Event->GetStripHit(i); + + // if (HasExpos()==true) { + // m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTiming()); + // } + // // takes inputted min and max TAC values from the GUI module to make cuts + // if (SH->GetTAC() < m_MinimumTAC || SH->GetTAC() > m_MaximumTAC) { + // Event->RemoveStripHit(i); + // delete SH; + // } else { + // ++i; + // } + // } + double TotalOffset = m_ShapingOffset + m_DisableTime + m_FlagToEnDelay; + double MaxTAC = -numeric_limits::max(); for (unsigned int i = 0; i < Event->GetNStripHits(); ++i) { MStripHit* SH = Event->GetStripHit(i); double TAC_timing = SH->GetTAC(); @@ -172,11 +173,28 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); if (SH->IsLowVoltageStrip() == true) { - ns_timing = (TAC_timing*m_LVTACCal[DetID][StripID][0] + m_LVTACCal[DetID][StripID][1]); + ns_timing = TAC_timing*m_LVTACCal[DetID][StripID][0] + m_LVTACCal[DetID][StripID][1]; } else { ns_timing = TAC_timing*m_HVTACCal[DetID][StripID][0] + m_HVTACCal[DetID][StripID][1]; } SH->SetTiming(ns_timing); + if (HasExpos()==true) { + m_ExpoTACcut->AddTAC(SH->GetDetectorID(), ns_timing); + } + if (ns_timing > MaxTAC) { + MaxTAC = ns_timing; + } + } + + for (unsigned int i = 0; i < Event->GetNStripHits();) { + MStripHit* SH = Event->GetStripHit(i); + double SHTiming = SH->GetTiming(); + if ((SHTiming < TotalOffset + m_CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - m_CoincidenceWindow)){ + ++i; + } else { + Event->RemoveStripHit(i); + delete SH; + } } Event->SetAnalysisProgress(MAssembly::c_TACcut); From 924c7e030bd914e0def61eba6afbca59719e26ae Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 21 Mar 2025 12:09:36 -0700 Subject: [PATCH 20/90] CHG: new x-axis range and label --- src/MGUIExpoTACcut.cxx | 2 +- src/MModuleTACcut.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MGUIExpoTACcut.cxx b/src/MGUIExpoTACcut.cxx index 835dbfda..aa7ed9f4 100644 --- a/src/MGUIExpoTACcut.cxx +++ b/src/MGUIExpoTACcut.cxx @@ -113,7 +113,7 @@ void MGUIExpoTACcut::SetTACHistogramArrangement(const vector DetID m_DetectorMap[row-1].push_back(DetID); TH1D* TAC = new TH1D("", "TAC", m_NBins[DetID], m_Min[DetID], m_Max[DetID]); - TAC->SetXTitle("TAC"); + TAC->SetXTitle("Calibrated TAC (ns)"); TAC->SetYTitle("counts"); TAC->SetFillColor(kAzure+7); diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index e46069c9..542d89d2 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -137,7 +137,7 @@ void MModuleTACcut::CreateExpos() m_ExpoTACcut->SetTACHistogramArrangement(m_DetectorIDs); for (unsigned int i = 0; i < m_DetectorIDs.size(); ++i) { unsigned int DetID = m_DetectorIDs[i]; - m_ExpoTACcut->SetTACHistogramParameters(DetID, 120, 0, 20000); + m_ExpoTACcut->SetTACHistogramParameters(DetID, 120, 0, 7000); } m_Expos.push_back(m_ExpoTACcut); } From 98b180fd9466fd02ce3adbcb9662bca312276149 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 21 Mar 2025 12:09:57 -0700 Subject: [PATCH 21/90] CHG: TAC calibration occurs after energy calibration --- src/MModuleEnergyCalibrationUniversal.cxx | 4 ++-- src/MModuleTACcut.cxx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MModuleEnergyCalibrationUniversal.cxx b/src/MModuleEnergyCalibrationUniversal.cxx index a2d59dc1..a0d3be0c 100644 --- a/src/MModuleEnergyCalibrationUniversal.cxx +++ b/src/MModuleEnergyCalibrationUniversal.cxx @@ -74,13 +74,13 @@ MModuleEnergyCalibrationUniversal::MModuleEnergyCalibrationUniversal() : MModule // Set all modules, which have to be done before this module AddPreceedingModuleType(MAssembly::c_EventLoader); - AddPreceedingModuleType(MAssembly::c_TACcut); + // AddPreceedingModuleType(MAssembly::c_TACcut); // Set all types this modules handles AddModuleType(MAssembly::c_EnergyCalibration); // Set all modules, which can follow this module - AddSucceedingModuleType(MAssembly::c_NoRestriction); + AddSucceedingModuleType(MAssembly::c_TACcut); // Set if this module has an options GUI m_HasOptionsGUI = true; diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 542d89d2..167f18c5 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -64,7 +64,7 @@ MModuleTACcut::MModuleTACcut() : MModule() AddPreceedingModuleType(MAssembly::c_EventLoader); //AddPreceedingModuleType(MAssembly::c_DetectorEffectsEngine); - // AddPreceedingModuleType(MAssembly::c_EnergyCalibration); + AddPreceedingModuleType(MAssembly::c_EnergyCalibration); // AddPreceedingModuleType(MAssembly::c_ChargeSharingCorrection); // AddPreceedingModuleType(MAssembly::c_DepthCorrection); // AddPreceedingModuleType(MAssembly::c_StripPairing); @@ -76,7 +76,7 @@ MModuleTACcut::MModuleTACcut() : MModule() // Set all modules, which can follow this module AddSucceedingModuleType(MAssembly::c_StripPairing); AddSucceedingModuleType(MAssembly::c_DepthCorrection); - AddSucceedingModuleType(MAssembly::c_EnergyCalibration); + // AddSucceedingModuleType(MAssembly::c_EnergyCalibration); // Set if this module has an options GUI // Overwrite ShowOptionsGUI() with the call to the GUI! m_HasOptionsGUI = true; From 6ff65f05182b4ad34aaad31b2c478b54df539b31 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 31 Mar 2025 15:14:33 -0700 Subject: [PATCH 22/90] CHG: Look for Strip3D type detectors with 1 sensitive volume. Do not use Named Detectors. --- include/MModuleDepthCalibration2024.h | 2 +- src/MModuleDepthCalibration2024.cxx | 64 ++++++++++++++------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/include/MModuleDepthCalibration2024.h b/include/MModuleDepthCalibration2024.h index 40eefe9a..78e9c325 100644 --- a/include/MModuleDepthCalibration2024.h +++ b/include/MModuleDepthCalibration2024.h @@ -138,7 +138,7 @@ class MModuleDepthCalibration2024 : public MModule uint64_t m_ErrorSH; uint64_t m_ErrorNullSH; uint64_t m_ErrorNoE; - vector m_Detectors; + unordered_map m_Detectors; vector m_DetectorIDs; MModuleEnergyCalibrationUniversal* m_EnergyCalibration; MGUIExpoDepthCalibration2024* m_ExpoDepthCalibration; diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 7b7bb82c..d61aec5b 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -120,45 +120,49 @@ bool MModuleDepthCalibration2024::Initialize() // The detectors need to be in the same order as DetIDs. // ie DetID=0 should be the 0th detector in m_Detectors, DetID=1 should the 1st, etc. - m_Detectors = m_Geometry->GetDetectorList(); + vector DetList = m_Geometry->GetDetectorList(); + unsigned int DetID = 0; // Look through the Geometry and get the names and thicknesses of all the detectors. - for(unsigned int i = 0; i < m_Detectors.size(); ++i){ + for(unsigned int i = 0; i < DetList.size(); ++i){ // For now, DetID is in order of detectors, which puts contraints on how the geometry file should be written. // If using the card cage at UCSD, default to DetID=11. unsigned int DetID = i; if ( m_UCSDOverride ){ DetID = 11; } - MDDetector* det = m_Detectors[i]; - // MString det_name = (det->GetDetectorVolume())->GetNamedDetectorName(0); - if (det->GetNNamedDetectors() > 0){ - // TODO: determine thickness of each detector using the geometry file - // cout << "Trying to get thickness from the geometry file..." << endl; - // cout << "step 1" << endl; - // MDVolume* vol = det->GetSensitiveVolume(0); - // cout << "step 2" << endl; - // MDShapeBRIK* shape = dynamic_cast(vol->GetShape()); - // cout << "step 3" << endl; - // double thickness = (shape->GetSize()).GetZ(); - // cout << "Success, the thickness is " << thickness << " cm" << endl; - // m_Thicknesses[DetID] = thickness; - MString det_name = det->GetNamedDetectorName(0); - m_DetectorNames[DetID] = det_name; - MDStrip3D* strip = dynamic_cast(det); - m_XPitches[DetID] = strip->GetPitchX(); - m_YPitches[DetID] = strip->GetPitchY(); - m_NXStrips[DetID] = strip->GetNStripsX(); - m_NYStrips[DetID] = strip->GetNStripsY(); - cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; - cout << "Number of X strips: " << m_NXStrips[DetID] << endl; - cout << "Number of Y strips: " << m_NYStrips[DetID] << endl; - cout << "X strip pitch: " << m_XPitches[DetID] << endl; - cout << "Y strip pitch: " << m_YPitches[DetID] << endl; - m_DetectorIDs.push_back(DetID); + + MDDetector* det = DetList[i]; + vector DetectorNames; + if (det->GetTypeName() == "Strip3D") { + if (det->GetNSensitiveVolumes() == 1) { + MDVolume* vol = det->GetSensitiveVolume(0); + string det_name = vol->GetName().GetString(); + if (find(DetectorNames.begin(), DetectorNames.end(), det_name) == DetectorNames.end()) { + DetectorNames.push_back(det_name); + m_Thicknesses[DetID] = 2*(det->GetStructuralSize().GetZ()); + MDStrip3D* strip = dynamic_cast(det); + m_XPitches[DetID] = strip->GetPitchX(); + m_YPitches[DetID] = strip->GetPitchY(); + m_NXStrips[DetID] = strip->GetNStripsX(); + m_NYStrips[DetID] = strip->GetNStripsY(); + cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; + cout << "Detector thickness: " << m_Thicknesses[DetID] << endl; + cout << "Number of X strips: " << m_NXStrips[DetID] << endl; + cout << "Number of Y strips: " << m_NYStrips[DetID] << endl; + cout << "X strip pitch: " << m_XPitches[DetID] << endl; + cout << "Y strip pitch: " << m_YPitches[DetID] << endl; + m_DetectorIDs.push_back(DetID); + m_Detectors[DetID] = det; + } + } } } + if (m_DetectorIDs.size() == 0) { + cout<<"No Strip3D detectors were found."<GetAvailableModuleByXmlTag("EnergyCalibrationUniversal"); if (m_EnergyCalibration == nullptr) { @@ -375,12 +379,12 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) LocalPosition.SetXYZ(Xpos, Ypos, Zpos); LocalOrigin.SetXYZ(0.0,0.0,0.0); // cout << m_DetectorNames[DetID] << endl; - GlobalPosition = m_Geometry->GetGlobalPosition(LocalPosition, m_DetectorNames[DetID]); + GlobalPosition = m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalPosition); // cout << "Found the GlobalPosition" << endl; // Make sure XYZ resolution are correctly mapped to the global coord system. PositionResolution.SetXYZ(Xsigma, Ysigma, Zsigma); - GlobalResolution = (m_Geometry->GetGlobalPosition(PositionResolution, m_DetectorNames[DetID]) - m_Geometry->GetGlobalPosition(LocalOrigin, m_DetectorNames[DetID])).Abs(); + GlobalResolution = ((m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(PositionResolution)) - (m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalOrigin))).Abs(); // cout << "Set the PositionResolution vector" << endl; From 043cf4ddac18a9d1577720a9875b49eadf475752 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 31 Mar 2025 15:15:33 -0700 Subject: [PATCH 23/90] CHG: Load splines and coefficients after determining detectors from geometry file. Make sure detector thickness matches between files --- include/MModuleDepthCalibration2024.h | 1 - src/MModuleDepthCalibration2024.cxx | 21 ++++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/MModuleDepthCalibration2024.h b/include/MModuleDepthCalibration2024.h index 78e9c325..9923efac 100644 --- a/include/MModuleDepthCalibration2024.h +++ b/include/MModuleDepthCalibration2024.h @@ -122,7 +122,6 @@ class MModuleDepthCalibration2024 : public MModule double m_Coeffs_Energy; MString m_CoeffsFile; MString m_SplinesFile; - unordered_map m_DetectorNames; unordered_map m_Thicknesses; unordered_map m_NXStrips; unordered_map m_NYStrips; diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index d61aec5b..12253a34 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -111,13 +111,6 @@ MModuleDepthCalibration2024::~MModuleDepthCalibration2024() bool MModuleDepthCalibration2024::Initialize() { - if( LoadCoeffsFile(m_CoeffsFile) == false ){ - return false; - } - if( LoadSplinesFile(m_SplinesFile) == false ){ - return false; - } - // The detectors need to be in the same order as DetIDs. // ie DetID=0 should be the 0th detector in m_Detectors, DetID=1 should the 1st, etc. vector DetList = m_Geometry->GetDetectorList(); @@ -163,6 +156,14 @@ bool MModuleDepthCalibration2024::Initialize() cout<<"No Strip3D detectors were found."<GetAvailableModuleByXmlTag("EnergyCalibrationUniversal"); if (m_EnergyCalibration == nullptr) { @@ -714,8 +715,10 @@ bool MModuleDepthCalibration2024::AddDepthCTD(vector depthvec, vector 0.0001) { + cout<<"MModuleDepthCalibration2024::AddDepthCTD: Warning, the thickness of detector "< Date: Mon, 31 Mar 2025 16:03:41 -0700 Subject: [PATCH 24/90] Cleanup: error handling and style conventions. --- src/MModuleDepthCalibration2024.cxx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 12253a34..4404363e 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -147,7 +147,11 @@ bool MModuleDepthCalibration2024::Initialize() cout << "Y strip pitch: " << m_YPitches[DetID] << endl; m_DetectorIDs.push_back(DetID); m_Detectors[DetID] = det; + } else { + cout<<"ERROR in MModuleDepthCalibration2024::Initialize: Found a duplicate detector: "<GetNSensitiveVolumes()<<" Sensitive Volumes."< depthvec, vector 0.0001) { cout<<"MModuleDepthCalibration2024::AddDepthCTD: Warning, the thickness of detector "< Date: Tue, 1 Apr 2025 13:20:27 -0700 Subject: [PATCH 25/90] Cleanup: for and if statement style conventions --- src/MModuleDepthCalibration2024.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 4404363e..ccccf157 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -710,8 +710,8 @@ bool MModuleDepthCalibration2024::AddDepthCTD(vector depthvec, vector 0) ){ + for (unsigned int i = 0; i < ctdarr.size(); ++i) { + if ((ctdarr[i].size() != depthvec.size()) && (ctdarr[i].size() > 0)) { cout << "MModuleDepthCalibration2024::AddDepthCTD: The number of values in the CTD list is not equal to the number of depth values." << endl; return false; } @@ -726,7 +726,7 @@ bool MModuleDepthCalibration2024::AddDepthCTD(vector depthvec, vector Date: Tue, 1 Apr 2025 13:22:04 -0700 Subject: [PATCH 26/90] CHG: Updated error handling and messages. If any depth-CTD spline fails, LoadSplinesFile returns false and so does Initialize. --- src/MModuleDepthCalibration2024.cxx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index ccccf157..64890753 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -161,10 +161,12 @@ bool MModuleDepthCalibration2024::Initialize() return false; } - if (LoadCoeffsFile(m_CoeffsFile) == false) { + m_CoeffsFileIsLoaded = LoadCoeffsFile(m_CoeffsFile); + if (m_CoeffsFileIsLoaded == false) { return false; } - if (LoadSplinesFile(m_SplinesFile) == false) { + m_SplinesFileIsLoaded = LoadSplinesFile(m_SplinesFile); + if (m_SplinesFileIsLoaded == false) { return false; } @@ -459,7 +461,7 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) // Pixel code (10000*det + 100*Xchannel + Ychannel), Stretch, Offset, Timing/CTD noise, Chi2 for the CTD fit (for diagnostics mainly) MFile F; if( F.Open(FName) == false ){ - cout << "MModuleDepthCalibration2024: failed to open coefficients file..." << endl; + cout << "ERROR in MModuleDepthCalibration2024::LoadCoeffsFile: failed to open coefficients file." << endl; return false; } else { MString Line; @@ -487,8 +489,6 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) F.Close(); } - m_CoeffsFileIsLoaded = true; - return true; } @@ -531,6 +531,7 @@ bool MModuleDepthCalibration2024::LoadSplinesFile(MString FName) // '' '' '' MFile F; if( F.Open(FName) == false ){ + cout << "ERROR in MModuleDepthCalibration2024::LoadSplinesFile: failed to open splines file." << endl; return false; } // vector depthvec, ctdvec, anovec, catvec; @@ -540,6 +541,7 @@ bool MModuleDepthCalibration2024::LoadSplinesFile(MString FName) vector temp_vec; ctdarr.push_back(temp_vec); } + bool Result = true; MString line; int DetID, NewDetID; while( F.ReadLine(line) ){ @@ -549,7 +551,7 @@ bool MModuleDepthCalibration2024::LoadSplinesFile(MString FName) vector tokens = line.Tokenize(" "); NewDetID = tokens[1].ToInt(); if( depthvec.size() > 0 ) { - AddDepthCTD(depthvec, ctdarr, DetID, m_DepthGrid, m_CTDMap); + Result &= AddDepthCTD(depthvec, ctdarr, DetID, m_DepthGrid, m_CTDMap); } depthvec.clear(); ctdarr.clear(); for( unsigned int i=0; i < 5; ++i ){ @@ -574,11 +576,10 @@ bool MModuleDepthCalibration2024::LoadSplinesFile(MString FName) } //make last spline if( depthvec.size() > 0 ){ - AddDepthCTD(depthvec, ctdarr, DetID, m_DepthGrid, m_CTDMap); + Result &= AddDepthCTD(depthvec, ctdarr, DetID, m_DepthGrid, m_CTDMap); } - m_SplinesFileIsLoaded = true; - return true; + return Result; } @@ -712,7 +713,7 @@ bool MModuleDepthCalibration2024::AddDepthCTD(vector depthvec, vector 0)) { - cout << "MModuleDepthCalibration2024::AddDepthCTD: The number of values in the CTD list is not equal to the number of depth values." << endl; + cout<<"ERROR in MModuleDepthCalibration2024::AddDepthCTD: The number of values in the CTD list is not equal to the number of depth values."< depthvec, vector 0.0001) { - cout<<"MModuleDepthCalibration2024::AddDepthCTD: Warning, the thickness of detector "< Date: Thu, 1 May 2025 14:44:16 -0700 Subject: [PATCH 27/90] ADD: copied TrappingCorrection into TrappingCorrectionAm241 as a template --- apps/TrappingCorrectionAm241.cxx | 759 +++++++++++++++++++++++++++++++ 1 file changed, 759 insertions(+) create mode 100644 apps/TrappingCorrectionAm241.cxx diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx new file mode 100644 index 00000000..9c8465aa --- /dev/null +++ b/apps/TrappingCorrectionAm241.cxx @@ -0,0 +1,759 @@ +/* + * TrappingCorrection.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + +// Standard +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +// ROOT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace ROOT::Minuit2; + +// MEGAlib +#include "MGlobal.h" +#include "MFile.h" +#include "MReadOutElementDoubleStrip.h" +#include "MFileReadOuts.h" +#include "MReadOutAssembly.h" +#include "MStripHit.h" +#include "MReadOutSequence.h" +#include "MSupervisor.h" +#include "MModuleLoaderMeasurementsROA.h" +#include "MModuleEnergyCalibrationUniversal.h" +#include "MModuleEventFilter.h" +#include "MModuleStripPairingGreedy.h" +#include "MModuleStripPairingChiSquare.h" +#include "MModuleTACcut.h" +#include "MAssembly.h" + + +int g_HistBins = 75; +double g_MinCTD = -250; +double g_MaxCTD = 250; +// double g_MinRatio = 0.94; +// double g_MaxRatio = 1.06; + + +//////////////////////////////////////////////////////////////////////////////// + + +class SymmetryFCN : public FCNBase +{ +public: + //! Operator which returns the symmetry of m_CTDHistogram given the parameters passed + double operator()(vector const &v) const override; + double Up() const override { return 1; } + + void AddCTD(double CTD){ m_CTD.push_back(CTD); } + void AddHVEnergy(double HVEnergy, double HVEnergyResolution){ m_HVEnergy.push_back(HVEnergy); m_HVEnergyResolution.push_back(HVEnergyResolution); } + void AddLVEnergy(double LVEnergy, double LVEnergyResolution){ m_LVEnergy.push_back(LVEnergy); m_LVEnergyResolution.push_back(LVEnergyResolution); } + + vector GetCTD(){ return m_CTD; } + vector GetHVEnergy(){ return m_HVEnergy; } + vector GetLVEnergy(){ return m_LVEnergy; } + vector GetHVEnergyResolution(){ return m_HVEnergyResolution; } + vector GetLVEnergyResolution(){ return m_LVEnergyResolution; } + + void SetCTD(vector CTD){ m_CTD = CTD; } + void SetHVEnergy(vector HVEnergy, vector HVEnergyResolution){ m_HVEnergy = HVEnergy; m_HVEnergyResolution = HVEnergyResolution; } + void SetLVEnergy(vector LVEnergy, vector LVEnergyResolution){ m_LVEnergy = LVEnergy; m_LVEnergyResolution = LVEnergyResolution; } + + //! The measured CTD and HV/LV energies + vector m_CTD; + vector m_HVEnergy; + vector m_LVEnergy; + vector m_HVEnergyResolution; + vector m_LVEnergyResolution; + +}; + + +//////////////////////////////////////////////////////////////////////////////// + + +class ChiSquaredFCN : public SymmetryFCN +{ +public: + //! Operator which returns the symmetry of m_CTDHistogram given the parameters passed + double operator()(vector const &v) const override; + double Up() const override { return 1; } + +}; + + +//////////////////////////////////////////////////////////////////////////////// + + + +//! A standalone program based on MEGAlib and ROOT +class TrappingCorrection +{ +public: + //! Default constructor + TrappingCorrection(); + //! Default destructor + ~TrappingCorrection(); + + //! Parse the command line + bool ParseCommandLine(int argc, char** argv); + //! Analyze what eveer needs to be analyzed... + bool Analyze(); + //!load cross talk correction + vector > > LoadCrossTalk(); + //! Interrupt the analysis + void Interrupt() { m_Interrupt = true; } + + void dummy_func() { return; } + + MStripHit* GetDominantStrip(vector& Strips, double& EnergyFraction); + +private: + //! True, if the analysis needs to be interrupted + bool m_Interrupt; + //! The input file name + MString m_FileName; + MString m_EcalFile; + MString m_TACFile; + //! output file names + MString m_OutFile; + //! energy E0 + // float m_E0; + //! option to correct charge loss or not + // bool m_CorrectCL; + //! option to do a pixel-by-pixel calibration (instead of detector-by-detector) + bool m_PixelCorrect; + bool m_GreedyPairing; + bool m_CardCageOverride; + + double m_MinEnergy; + double m_MaxEnergy; + +}; + +//////////////////////////////////////////////////////////////////////////////// + + +double SymmetryFCN::operator()(vector const &v) const +{ + double HVSlope = v[0]; + double HVIntercept = v[1]; + double LVSlope = v[2]; + double LVIntercept = v[3]; + + char name[64]; sprintf(name,"name"); + int HistBins = g_HistBins; + if (HistBins%2 == 0) { + HistBins += 1; + } + TH2D CorrectedHistogram(name, name, HistBins, g_MinCTD, g_MaxCTD, HistBins, g_MinRatio, g_MaxRatio); + + for (unsigned int i = 0; i < m_CTD.size(); ++i) { + double CTDHVShift = m_CTD[i] + g_MaxCTD; + double CTDLVShift = m_CTD[i] + g_MinCTD; + // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. + double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); + double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); + CorrectedHistogram.Fill(m_CTD[i], CorrectedHVEnergy/CorrectedLVEnergy); + } + + vector> BinValues; + vector> ReflectedBinValues; + double Asymmetry = 0; + + for (unsigned int y = 0; y < CorrectedHistogram.GetNbinsY(); ++y) { + + vector XValues; + + for (unsigned int x = 0; x < CorrectedHistogram.GetNbinsX(); ++x) { + XValues.push_back(CorrectedHistogram.GetBinContent(x,y)); + } + + // BinValues.push_back(XValues); + vector ReflectedXValues = XValues; + reverse(ReflectedXValues.begin(), ReflectedXValues.end()); + + for (unsigned int x = 0; x < XValues.size(); ++x) { + Asymmetry += pow(XValues[x] - ReflectedXValues[x], 2)/(XValues[x] + ReflectedXValues[x]); + } + } + + return Asymmetry; + +} + + +//////////////////////////////////////////////////////////////////////////////// + + +double ChiSquaredFCN::operator()(vector const &v) const +{ + double HVSlope = v[0]; + double HVIntercept = v[1]; + double LVSlope = v[2]; + double LVIntercept = v[3]; + + double ChiSquare = 0; + + for (unsigned int i = 0; i < m_CTD.size(); ++i) { + double CTDHVShift = m_CTD[i] + g_MaxCTD; + double CTDLVShift = m_CTD[i] + g_MinCTD; + // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. + double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); + double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); + + ChiSquare += pow(CorrectedHVEnergy - CorrectedLVEnergy, 2)/(m_HVEnergyResolution[i] + m_LVEnergyResolution[i]); + } + + // ChiSquare /= m_CTD.size(); + + return ChiSquare; + +} + + +//! Default constructor +TrappingCorrection::TrappingCorrection() : m_Interrupt(false) +{ + gStyle->SetPalette(1, 0); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Default destructor +TrappingCorrection::~TrappingCorrection() +{ + // Intentionally left blank +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Parse the command line +bool TrappingCorrection::ParseCommandLine(int argc, char** argv) +{ + ostringstream Usage; + Usage<"< i+1) && + (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ + cout<<"Error: Option "< i+2) && + (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0) && + (argv[i+2][0] != '-' || isalpha(argv[i+2][1]) == 0))){ + cout<<"Error: Option "<SetBinContent(i,j,c); + } + } + TCanvas *ctemp = new TCanvas(); + h2->Draw("colz"); + ctemp->Print("frac_map.pdf"); +*/ + //time code just to see + TStopwatch watch; + watch.Start(); + + if (m_Interrupt == true) return false; + + MSupervisor* S = MSupervisor::GetSupervisor(); + + MModuleLoaderMeasurementsROA* Loader; + MModuleTACcut* TACCalibrator; + MModuleEnergyCalibrationUniversal* EnergyCalibrator; + MModuleEventFilter* EventFilter; + + unsigned int MNumber = 0; + cout<<"Creating ROA loader"<SetFileName(m_FileName); + S->SetModule(Loader, MNumber); + ++MNumber; + + if (m_CardCageOverride==false) { + cout<<"Creating TAC calibrator"<SetTACCalFileName(m_TACFile); + S->SetModule(TACCalibrator, MNumber); + ++MNumber; + } + + cout<<"Creating energy calibrator"<SetFileName(m_EcalFile); + EnergyCalibrator->EnablePreampTempCorrection(false); + S->SetModule(EnergyCalibrator, MNumber); + ++MNumber; + + cout<<"Creating Event filter"<SetMinimumLVStrips(1); + EventFilter->SetMaximumLVStrips(1); + EventFilter->SetMinimumHVStrips(1); + EventFilter->SetMaximumHVStrips(1); + EventFilter->SetMinimumTotalEnergy(m_MinEnergy); + EventFilter->SetMaximumTotalEnergy(m_MaxEnergy); + S->SetModule(EventFilter, MNumber); + ++MNumber; + + cout<<"Creating strip pairing"<(Pairing); + Pairing = new MModuleStripPairingGreedy(); + } + else { + // Pairing = dynamic_cast(Pairing); + Pairing = new MModuleStripPairingChiSquare(); + } + S->SetModule(Pairing, MNumber); + + cout<<"Initializing Loader"<Initialize() == false) return false; + if (m_CardCageOverride==false) { + cout<<"Initializing TAC calibrator"<Initialize() == false) return false; + } + cout<<"Initializing Energy calibrator"<Initialize() == false) return false; + cout<<"Initializing Event filter"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; + + map Histograms; + map FCNs; + + bool IsFinished = false; + MReadOutAssembly* Event = new MReadOutAssembly(); + + cout<<"Analyzing..."<Clear(); + + if (Loader->IsReady() ){ + Loader->AnalyzeEvent(Event); + + if (m_CardCageOverride==false) { + TACCalibrator->AnalyzeEvent(Event); + } + + EnergyCalibrator->AnalyzeEvent(Event); + bool Unfiltered = EventFilter->AnalyzeEvent(Event); + Pairing->AnalyzeEvent(Event); + + if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true)) { + for (unsigned int h = 0; h < Event->GetNHits(); ++h) { + double HVEnergy = 0.0; + double LVEnergy = 0.0; + double HVEnergyResolution = 0.0; + double LVEnergyResolution = 0.0; + vector HVStrips; + vector LVStrips; + + MHit* H = Event->GetHit(h); + + int DetID = H->GetStripHit(0)->GetDetectorID(); + TH2D* Hist = Histograms[DetID]; + SymmetryFCN* FCN = FCNs[DetID]; + + if (Hist == nullptr) { + char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); + Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); + Hist->SetXTitle("CTD (ns)"); + Hist->SetYTitle("HV/LV Energy Ratio"); + Histograms[DetID] = Hist; + } + + if (FCN == nullptr) { + FCN = new SymmetryFCN(); + FCNs[DetID] = FCN; + } + + for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { + MStripHit* SH = H->GetStripHit(sh); + + if (SH->IsLowVoltageStrip()==true) { + LVEnergy += SH->GetEnergy(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } + } + + double HVEnergyFraction = 0; + double LVEnergyFraction = 0; + MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + double EnergyFraction = HVEnergy/LVEnergy; + double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + if (m_CardCageOverride == true) { + CTD *= -1; + } + Hist->Fill(CTD, EnergyFraction); + FCN->AddCTD(CTD); + FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); + FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); + } + } + } + IsFinished = Loader->IsFinished(); + } + + //setup output file + ofstream OutputCalFile; + OutputCalFile.open(m_OutFile+MString("_parameters.txt")); + OutputCalFile<<"Det"<<'\t'<<"HV Slope"<<'\t'<<"HV Intercept"<<'\t'<<"LV Slope"<<'\t'<<"LV Intercept"<SetLogz(); + C->cd(); + H.second->Draw("colz"); + + H.second->Write(); + f.Close(); + + } + + for (auto F: FCNs) { + + int DetID = F.first; + MnUserParameters* InitialStateSym = new MnUserParameters(); + InitialStateSym->Add("HVSlope", 1e-3, 1e-4, 0, 3e-1); + InitialStateSym->Add("HVIntercept", 0, 0.01, -2, 2); + InitialStateSym->Add("LVSlope", 0, 1e-4, -3e-2, 0); + InitialStateSym->Add("LVIntercept", 0, 0.01, -2, 2); + + InitialStateSym->Fix("LVSlope"); + InitialStateSym->Fix("LVIntercept"); + InitialStateSym->Fix("HVIntercept"); + + + MnMigrad migradSym(*F.second, *InitialStateSym); + // Minimize + FunctionMinimum MinimumSym = migradSym(); + + MnUserParameters ParametersSym = MinimumSym.UserParameters(); + // double HVSlope = ParametersSym.Value("HVSlope"); + // double HVIntercept = ParametersSym.Value("HVIntercept"); + // double LVSlope = ParametersSym.Value("LVSlope"); + // double LVIntercept = ParametersSym.Value("LVIntercept"); + + // output + cout<Add("HVSlope", ParametersSym.Value("HVSlope"), ParametersSym.Error("HVSlope")); + InitialStateChi->Add("HVIntercept", 0, 0.01, -2, 2); + InitialStateChi->Add("LVSlope", 0, 1e-4, -3e-2, 0); + InitialStateChi->Add("LVIntercept", 0, 0.01, -2, 2); + + InitialStateChi->Fix("LVSlope"); + InitialStateChi->Fix("LVIntercept"); + InitialStateChi->Fix("HVSlope"); + + + ChiSquaredFCN* ChiSquaredF = new ChiSquaredFCN(); + ChiSquaredF->SetCTD(F.second->GetCTD()); + ChiSquaredF->SetHVEnergy(F.second->GetHVEnergy(), F.second->GetHVEnergyResolution()); + ChiSquaredF->SetLVEnergy(F.second->GetLVEnergy(), F.second->GetLVEnergyResolution()); + MnMigrad migradChi(*ChiSquaredF, *InitialStateChi); + // Minimize + FunctionMinimum MinimumChi = migradChi(); + + MnUserParameters ParametersChi = MinimumChi.UserParameters(); + double HVSlope = ParametersChi.Value("HVSlope"); + double HVIntercept = ParametersChi.Value("HVIntercept"); + double LVSlope = ParametersChi.Value("LVSlope"); + double LVIntercept = ParametersChi.Value("LVIntercept"); + // output + cout<SetXTitle("CTD (ns)"); + Hist->SetYTitle("HV/LV Energy Ratio"); + + vector CTDList = F.second->GetCTD(); + vector HVEnergyList = F.second->GetHVEnergy(); + vector LVEnergyList = F.second->GetLVEnergy(); + for (unsigned int i=0; iFill(CTDList[i], CorrectedHVEnergy/CorrectedLVEnergy); + } + + TCanvas* C = new TCanvas(); + C->SetLogz(); + C->cd(); + Hist->Draw("colz"); + + TFile f(m_OutFile+MString("_Det")+DetID+MString("_Hist_Corr.root"),"recreate"); + Hist->Write(); + f.Close(); + + OutputCalFile<& Strips, double& EnergyFraction) +{ + double MaxEnergy = -numeric_limits::max(); // AZ: When both energies are zero (which shouldn't happen) we still pick one + double TotalEnergy = 0.0; + MStripHit* MaxStrip = nullptr; + + // Iterate through strip hits and get the strip with highest energy + for (const auto SH : Strips) { + double Energy = SH->GetEnergy(); + TotalEnergy += Energy; + if (Energy > MaxEnergy) { + MaxStrip = SH; + MaxEnergy = Energy; + } + } + if (TotalEnergy == 0) { + EnergyFraction = 0; + } else { + EnergyFraction = MaxEnergy/TotalEnergy; + } + return MaxStrip; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Called when an interrupt signal is flagged +//! All catched signals lead to a well defined exit of the program +void CatchSignal(int a) +{ + if (g_Prg != 0 && g_NInterruptCatches-- > 0) { + cout<<"Catched signal Ctrl-C (ID="<Interrupt(); + } else { + abort(); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Main program +int main(int argc, char** argv) +{ + // Catch a user interupt for graceful shutdown + signal(SIGINT, CatchSignal); + + // Initialize global MEGALIB variables, especially mgui, etc. + MGlobal::Initialize("Standalone", "a standalone example program"); + + TApplication TrappingCorrectionApp("TrappingCorrectionApp", 0, 0); + + g_Prg = new TrappingCorrection(); + + if (g_Prg->ParseCommandLine(argc, argv) == false) { + cerr<<"Error during parsing of command line!"<Analyze() == false) { + cerr<<"Error during analysis!"< Date: Fri, 2 May 2025 13:40:56 -0700 Subject: [PATCH 28/90] CHG: Load strip-by-strip shaping offset and coincidence window as a file --- include/MGUIOptionsTACcut.h | 10 ++-- include/MModuleTACcut.h | 34 ++++------- src/MGUIOptionsTACcut.cxx | 39 +++--------- src/MModuleTACcut.cxx | 116 +++++++++++++++++++++--------------- 4 files changed, 94 insertions(+), 105 deletions(-) diff --git a/include/MGUIOptionsTACcut.h b/include/MGUIOptionsTACcut.h index 3cbe8555..86575a41 100644 --- a/include/MGUIOptionsTACcut.h +++ b/include/MGUIOptionsTACcut.h @@ -72,20 +72,18 @@ class MGUIOptionsTACcut : public MGUIOptions //! The total TAC selection MGUIEMinMaxEntry* m_TAC; - //! The shaping offset: measured time between test pulse and pulse peak - MGUIEEntry* m_ShapingOffset; - //! FPGA setting of time between FLAG rising and ENABLE falling MGUIEEntry* m_DisableTime; //! internal FPGA delay between FLAG rising and FPGA reacting MGUIEEntry* m_FlagToEnDelay; - //! Coincidence window after strip hit with largest TAC (first strip hit) - MGUIEEntry* m_CoincidenceWindow; - //! Select TAC Calibration file to load, converts readout timing to nanoseconds MGUIEFileSelector* m_TACCalFileSelector; + + //! Select TAC Cut file to load, which specifies the parameters for removing strip hits + MGUIEFileSelector* m_TACCutFileSelector; + // private members: private: diff --git a/include/MModuleTACcut.h b/include/MModuleTACcut.h index 2ec787cb..5db18003 100644 --- a/include/MModuleTACcut.h +++ b/include/MModuleTACcut.h @@ -70,25 +70,15 @@ class MModuleTACcut : public MModule ///////////// Creating functions that will update and get the min/max TAC values ////////////////////////// - //! Set the minimum TAC value! - void SetMinimumTAC(unsigned int MinimumTAC) { m_MinimumTAC = MinimumTAC; } - //! Get the minimum TAC value! - unsigned int GetMinimumTAC() const { return m_MinimumTAC; } - - //! Set the maximum TAC value! - void SetMaximumTAC(unsigned int MaximumTAC) { m_MaximumTAC = MaximumTAC; } - //! Get the maximum TAC value! - unsigned int GetMaximumTAC() const { return m_MaximumTAC; } - //! Set filename for TAC Calibration void SetTACCalFileName( const MString& FileName) {m_TACCalFile = FileName;} //! Get filename for TAC Calibration MString GetTACCalFileName() const {return m_TACCalFile;} - //! Set the shaping offset - void SetShapingOffset(double ShapingOffset) { m_ShapingOffset = ShapingOffset; } - //! Get the shaping offset - unsigned int GetShapingOffset() const { return m_ShapingOffset; } + //! Set filename for TAC Cut + void SetTACCutFileName( const MString& FileName) {m_TACCutFile = FileName;} + //! Get filename for TAC Cut + MString GetTACCutFileName() const {return m_TACCutFile;} //! Set the disable time void SetDisableTime(double DisableTime) { m_DisableTime = DisableTime; } @@ -100,14 +90,12 @@ class MModuleTACcut : public MModule //! Get the shaping flag_to_en_delay unsigned int GetFlagToEnDelay() const { return m_FlagToEnDelay; } - //! Set the shaping coincidence window - void SetCoincidenceWindow(double CoincidenceWindow) { m_CoincidenceWindow = CoincidenceWindow; } - //! Get the shaping coincidence window - unsigned int GetCoincidenceWindow() const { return m_CoincidenceWindow; } - //! Load the TAC calibration file bool LoadTACCalFile(MString FName); + //! Load the TAC cut file + bool LoadTACCutFile(MString FName); + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -127,12 +115,14 @@ class MModuleTACcut : public MModule // private members: private: -// declare min and max TAC variables here -unsigned int m_MinimumTAC, m_MaximumTAC; -double m_ShapingOffset, m_DisableTime, m_FlagToEnDelay, m_CoincidenceWindow; +// declare TAC Cut and calibration variables here +double m_DisableTime, m_FlagToEnDelay; MString m_TACCalFile; +MString m_TACCutFile; unordered_map>> m_HVTACCal; unordered_map>> m_LVTACCal; +unordered_map>> m_HVTACCut; +unordered_map>> m_LVTACCut; vector m_DetectorIDs; diff --git a/src/MGUIOptionsTACcut.cxx b/src/MGUIOptionsTACcut.cxx index 419e1b52..2ea49d88 100644 --- a/src/MGUIOptionsTACcut.cxx +++ b/src/MGUIOptionsTACcut.cxx @@ -75,21 +75,15 @@ void MGUIOptionsTACcut::Create() { PreCreate(); - // Modify here - - // TGLayoutHints* TACLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); - // m_TAC = new MGUIEMinMaxEntry(m_OptionsFrame, "Choose the minimum and maximum TAC cut (in imaginary TAC units):", false, dynamic_cast(m_Module)->GetMinimumTAC(), dynamic_cast(m_Module)->GetMaximumTAC(), true, 0.0); - // m_OptionsFrame->AddFrame(m_TAC, TACLayout); - - m_TACCalFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Calibration file:", - dynamic_cast(m_Module)->GetTACCalFileName()); + m_TACCalFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Calibration file:", dynamic_cast(m_Module)->GetTACCalFileName()); m_TACCalFileSelector->SetFileType("TAC", "*.csv"); - TGLayoutHints* Label3Layout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); - m_OptionsFrame->AddFrame(m_TACCalFileSelector, Label3Layout); + TGLayoutHints* TACCalLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + m_OptionsFrame->AddFrame(m_TACCalFileSelector, TACCalLayout); - TGLayoutHints* ShapingOffsetLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); - m_ShapingOffset = new MGUIEEntry(m_OptionsFrame, "Shaping Offset [ns]:", false, dynamic_cast(m_Module)->GetShapingOffset(), false, -numeric_limits::max()/2, numeric_limits::max()/2); - m_OptionsFrame->AddFrame(m_ShapingOffset, ShapingOffsetLayout); + m_TACCutFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a TAC Cut file:", dynamic_cast(m_Module)->GetTACCutFileName()); + m_TACCutFileSelector->SetFileType("TAC", "*.csv"); + TGLayoutHints* TACCutLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + m_OptionsFrame->AddFrame(m_TACCutFileSelector, TACCutLayout); TGLayoutHints* DisableTimeLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); m_DisableTime = new MGUIEEntry(m_OptionsFrame, "Diable Time [ns]:", false, dynamic_cast(m_Module)->GetDisableTime(), false, -numeric_limits::max()/2, numeric_limits::max()/2); @@ -97,18 +91,7 @@ void MGUIOptionsTACcut::Create() TGLayoutHints* FlagToEnDelayLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); m_FlagToEnDelay = new MGUIEEntry(m_OptionsFrame, "FLAG to ENABLE delay [ns]:", false, dynamic_cast(m_Module)->GetFlagToEnDelay(), false, -numeric_limits::max()/2, numeric_limits::max()/2); - m_OptionsFrame->AddFrame(m_FlagToEnDelay, FlagToEnDelayLayout); - - TGLayoutHints* CoincidenceWindowLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); - m_CoincidenceWindow = new MGUIEEntry(m_OptionsFrame, "Coincidence Window [ns]:", false, dynamic_cast(m_Module)->GetCoincidenceWindow(), false, -numeric_limits::max()/2, numeric_limits::max()/2); - m_OptionsFrame->AddFrame(m_CoincidenceWindow, CoincidenceWindowLayout); - - - // TGLabel* TACLabel = new TGLabel(m_OptionsFrame, - // "This is a TAC cut and this text is here because.\n" - // "I'm not sure if I can remove it yet"); - // m_OptionsFrame->AddFrame(TACLabel, TACLayout); - + m_OptionsFrame->AddFrame(m_FlagToEnDelay, FlagToEnDelayLayout); PostCreate(); } @@ -151,14 +134,10 @@ bool MGUIOptionsTACcut::ProcessMessage(long Message, long Parameter1, long Param bool MGUIOptionsTACcut::OnApply() { // Store the data in the module - - // dynamic_cast(m_Module)->SetMinimumTAC(m_TAC->GetMinValue()); - // dynamic_cast(m_Module)->SetMaximumTAC(m_TAC->GetMaxValue()); dynamic_cast(m_Module)->SetTACCalFileName(m_TACCalFileSelector->GetFileName()); - dynamic_cast(m_Module)->SetShapingOffset(m_ShapingOffset->GetAsDouble()); + dynamic_cast(m_Module)->SetTACCutFileName(m_TACCutFileSelector->GetFileName()); dynamic_cast(m_Module)->SetDisableTime(m_DisableTime->GetAsDouble()); dynamic_cast(m_Module)->SetFlagToEnDelay(m_FlagToEnDelay->GetAsDouble()); - dynamic_cast(m_Module)->SetCoincidenceWindow(m_CoincidenceWindow->GetAsDouble()); return true; } diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 167f18c5..b1cfabfe 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -89,14 +89,10 @@ MModuleTACcut::MModuleTACcut() : MModule() // Can we use multiple instances of this class m_AllowMultipleInstances = false; - //initialize a min and max TAC value - m_MinimumTAC = 0; - m_MaximumTAC = 20000; - - m_ShapingOffset = 2255; + // m_ShapingOffset = 2255; m_DisableTime = 1396; m_FlagToEnDelay = 104; - m_CoincidenceWindow = 500; + // m_CoincidenceWindow = 500; } @@ -121,6 +117,11 @@ bool MModuleTACcut::Initialize() return false; } + if (LoadTACCutFile(m_TACCutFile) == false) { + cout << "TAC Calibration file could not be loaded." << endl; + return false; + } + return MModule::Initialize(); } @@ -147,24 +148,7 @@ void MModuleTACcut::CreateExpos() bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) { - // Main data analysis routine, which updates the event to a new level - - // // Apply cuts to the TAC values: - // for (unsigned int i = 0; i < Event->GetNStripHits();) { - // MStripHit* SH = Event->GetStripHit(i); - - // if (HasExpos()==true) { - // m_ExpoTACcut->AddTAC(SH->GetDetectorID(), SH->GetTiming()); - // } - // // takes inputted min and max TAC values from the GUI module to make cuts - // if (SH->GetTAC() < m_MinimumTAC || SH->GetTAC() > m_MaximumTAC) { - // Event->RemoveStripHit(i); - // delete SH; - // } else { - // ++i; - // } - // } - double TotalOffset = m_ShapingOffset + m_DisableTime + m_FlagToEnDelay; + double MaxTAC = -numeric_limits::max(); for (unsigned int i = 0; i < Event->GetNStripHits(); ++i) { MStripHit* SH = Event->GetStripHit(i); @@ -189,7 +173,19 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) for (unsigned int i = 0; i < Event->GetNStripHits();) { MStripHit* SH = Event->GetStripHit(i); double SHTiming = SH->GetTiming(); - if ((SHTiming < TotalOffset + m_CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - m_CoincidenceWindow)){ + int DetID = SH->GetDetectorID(); + int StripID = SH->GetStripID(); + double ShapingOffset; + double CoincidenceWindow; + if (SH->IsLowVoltageStrip() == true) { + ShapingOffset = m_LVTACCut[DetID][StripID][0]; + CoincidenceWindow = m_LVTACCut[DetID][StripID][1]; + } else { + ShapingOffset = m_HVTACCut[DetID][StripID][0]; + CoincidenceWindow = m_HVTACCut[DetID][StripID][1]; + } + double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; + if ((SHTiming < TotalOffset + CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - CoincidenceWindow)){ ++i; } else { Event->RemoveStripHit(i); @@ -237,18 +233,9 @@ bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) SetTACCalFileName(TACCalFileNameNode->GetValue()); } - MXmlNode* MinimumTACNode = Node->GetNode("MinimumTAC"); - if (MinimumTACNode != 0) { - m_MinimumTAC = MinimumTACNode->GetValueAsInt(); - } - MXmlNode* MaximumTACNode = Node->GetNode("MaximumTAC"); - if (MaximumTACNode != 0) { - m_MaximumTAC = MaximumTACNode->GetValueAsInt(); - } - - MXmlNode* ShapingOffsetNode = Node->GetNode("ShapingOffset"); - if (ShapingOffsetNode != 0) { - m_ShapingOffset = ShapingOffsetNode->GetValueAsDouble(); + MXmlNode* TACCutFileNameNode = Node->GetNode("TACCutFileName"); + if (TACCutFileNameNode != 0) { + SetTACCutFileName(TACCutFileNameNode->GetValue()); } MXmlNode* DisableTimeNode = Node->GetNode("DisableTime"); @@ -261,11 +248,6 @@ bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) m_FlagToEnDelay = FlagToEnDelayNode->GetValueAsDouble(); } - MXmlNode* CoincidenceWindowNode = Node->GetNode("CoincidenceWindow"); - if (CoincidenceWindowNode != 0) { - m_CoincidenceWindow = CoincidenceWindowNode->GetValueAsDouble(); - } - return true; } @@ -280,13 +262,9 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() MXmlNode* Node = new MXmlNode(0, m_XmlTag); new MXmlNode(Node, "TACCalFileName", m_TACCalFile); - new MXmlNode(Node, "MinimumTAC", m_MinimumTAC); - new MXmlNode(Node, "MaximumTAC", m_MaximumTAC); - new MXmlNode(Node, "ShapingOffset", m_ShapingOffset); + new MXmlNode(Node, "TACCutFileName", m_TACCutFile); new MXmlNode(Node, "DisableTime", m_DisableTime); new MXmlNode(Node, "FlagToEnDelay", m_FlagToEnDelay); - new MXmlNode(Node, "CoincidenceWindow", m_CoincidenceWindow); - return Node; } @@ -337,5 +315,49 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) } +bool MModuleTACcut::LoadTACCutFile(MString FName) +{ + // Read in the TAC Cut file, which should contain for each strip: + // DetID, h or l for high or low voltage, shaping offset, coincidence window + MFile F; + if (F.Open(FName) == false) { + cout << "MModuleTACcut: failed to open TAC Cut file." << endl; + return false; + } else { + MString Line; + while (F.ReadLine(Line)) { + if (!Line.BeginsWith("#")) { + std::vector Tokens = Line.Tokenize(","); + if (Tokens.size() == 5) { + int DetID = Tokens[0].ToInt(); + int StripID = Tokens[2].ToInt(); + double ShapingOffset = Tokens[3].ToDouble(); + double CoincidenceWindow = Tokens[4].ToDouble(); + vector CutParams; + CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); + + if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { + unordered_map> temp_map_HV; + m_HVTACCut[DetID] = temp_map_HV; + unordered_map> temp_map_LV; + m_LVTACCut[DetID] = temp_map_LV; + m_DetectorIDs.push_back(DetID); + } + + if (Tokens[1] == "l") { + m_LVTACCut[DetID][StripID] = CutParams; + } else if (Tokens[1] == "h") { + m_HVTACCut[DetID][StripID] = CutParams; + } + } + } + } + F.Close(); + sort(m_DetectorIDs.begin(), m_DetectorIDs.end()); + } + + return true; + +} // MModuleTACcut.cxx: the end... From f7d9274b0db880b0e457c995ec01fb1e17834518 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 2 May 2025 13:41:39 -0700 Subject: [PATCH 29/90] CHG: Only plot timing if not cut --- src/MModuleTACcut.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index b1cfabfe..5070cef2 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -162,9 +162,6 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) ns_timing = TAC_timing*m_HVTACCal[DetID][StripID][0] + m_HVTACCal[DetID][StripID][1]; } SH->SetTiming(ns_timing); - if (HasExpos()==true) { - m_ExpoTACcut->AddTAC(SH->GetDetectorID(), ns_timing); - } if (ns_timing > MaxTAC) { MaxTAC = ns_timing; } @@ -186,6 +183,9 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) } double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; if ((SHTiming < TotalOffset + CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - CoincidenceWindow)){ + if (HasExpos()==true) { + m_ExpoTACcut->AddTAC(DetID, SHTiming); + } ++i; } else { Event->RemoveStripHit(i); From 17bbc01c2e91083fba3996989df4646b49b293f2 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 2 May 2025 13:59:55 -0700 Subject: [PATCH 30/90] cleaning up comments --- src/MModuleTACcut.cxx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 5070cef2..08b1bd54 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -62,21 +62,15 @@ MModuleTACcut::MModuleTACcut() : MModule() // Set all modules, which have to be done before this module AddPreceedingModuleType(MAssembly::c_EventLoader); - //AddPreceedingModuleType(MAssembly::c_DetectorEffectsEngine); - AddPreceedingModuleType(MAssembly::c_EnergyCalibration); - // AddPreceedingModuleType(MAssembly::c_ChargeSharingCorrection); - // AddPreceedingModuleType(MAssembly::c_DepthCorrection); - // AddPreceedingModuleType(MAssembly::c_StripPairing); // Set all types this modules handles AddModuleType(MAssembly::c_TACcut); - // Set all modules, which can follow this module AddSucceedingModuleType(MAssembly::c_StripPairing); AddSucceedingModuleType(MAssembly::c_DepthCorrection); - // AddSucceedingModuleType(MAssembly::c_EnergyCalibration); + // Set if this module has an options GUI // Overwrite ShowOptionsGUI() with the call to the GUI! m_HasOptionsGUI = true; From 3021e412935ce61ce8c0613558c9727b776f7fbc Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 2 May 2025 14:15:48 -0700 Subject: [PATCH 31/90] comment cleanup --- src/MModuleTACcut.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 08b1bd54..15802c31 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -83,10 +83,8 @@ MModuleTACcut::MModuleTACcut() : MModule() // Can we use multiple instances of this class m_AllowMultipleInstances = false; - // m_ShapingOffset = 2255; m_DisableTime = 1396; m_FlagToEnDelay = 104; - // m_CoincidenceWindow = 500; } From 120c59b2158627858b4f7b70235d1688bb2b0d3f Mon Sep 17 00:00:00 2001 From: Andreas Zoglauer Date: Tue, 13 May 2025 14:27:11 -0700 Subject: [PATCH 32/90] Created new module, a HDF5 reader, which handles HDF hit data formats 1.0-1.2 --- Makefile | 27 +- include/MGUIOptionsLoaderMeasurements.h | 4 +- include/MGUIOptionsLoaderMeasurementsHDF.h | 93 ++++ include/MModuleLoaderMeasurements.h | 3 - include/MModuleLoaderMeasurementsHDF.h | 239 ++++++++ include/MModuleLoaderMeasurementsROA.h | 3 + include/MStripMap.h | 105 ++++ src/MAssembly.cxx | 2 + src/MGUIOptionsEnergyCalibrationUniversal.cxx | 13 +- src/MGUIOptionsLoaderMeasurements.cxx | 14 +- src/MGUIOptionsLoaderMeasurementsHDF.cxx | 141 +++++ src/MModuleLoaderMeasurements.cxx | 13 - src/MModuleLoaderMeasurementsBinary.cxx | 336 +++++------ src/MModuleLoaderMeasurementsHDF.cxx | 525 ++++++++++++++++++ src/MModuleLoaderMeasurementsROA.cxx | 15 + src/MStripMap.cxx | 162 ++++++ 16 files changed, 1493 insertions(+), 202 deletions(-) create mode 100644 include/MGUIOptionsLoaderMeasurementsHDF.h create mode 100644 include/MModuleLoaderMeasurementsHDF.h create mode 100644 include/MStripMap.h create mode 100644 src/MGUIOptionsLoaderMeasurementsHDF.cxx create mode 100644 src/MModuleLoaderMeasurementsHDF.cxx create mode 100644 src/MStripMap.cxx diff --git a/Makefile b/Makefile index 679c91c2..5dbb7ff4 100755 --- a/Makefile +++ b/Makefile @@ -38,15 +38,33 @@ MAKEFLAGS += --no-builtin-rules #.NOTPARALLEL: megalib .SILENT: + +#---------------------------------------------------------------- +# External libraries +# + +H5CXXFLAGS = +H5LIBS = +ifeq ("$(shell pkg-config --exists hdf5 1>&2 2> /dev/null; echo $$?)", "0") + H5CXXFLAGS += $(shell pkg-config --cflags hdf5) + H5LIBS += $(shell pkg-config --libs hdf5) + H5LIBS += -lhdf5_cpp +else + $(error "Unable to find HDF5 headers and libraries") +endif + + #---------------------------------------------------------------- # Definitions based on architecture and user options # CMD="" -CXXFLAGS += -I$(IN) -I$(MEGALIB)/include -I/opt/local/include +CXXFLAGS += -I$(IN) -I$(MEGALIB)/include -I/opt/local/include $(H5CXXFLAGS) # Comment this line out if you want to accept warnings #CXXFLAGS += -Werror -Wno-unused-variable +LIBS += $(H5LIBS) + # Names of the program NUCLEARIZER_PRG = $(BN)/nuclearizer NUCLEARIZER_CXX_MAIN = src/MNuclearizerMain.cxx @@ -62,6 +80,7 @@ $(LB)/MAspectReconstruction.o \ $(LB)/MHit.o \ $(LB)/MTimeAndCoordinate.o \ $(LB)/MStripHit.o \ +$(LB)/MStripMap.o \ $(LB)/MGuardringHit.o \ $(LB)/MDetectorEffectsEngineBalloon.o \ $(LB)/MModuleLoaderSimulationsBalloon.o \ @@ -71,6 +90,8 @@ $(LB)/MGUIOptionsLoaderSimulations.o \ $(LB)/MModuleLoaderMeasurements.o \ $(LB)/MModuleLoaderMeasurementsROA.o \ $(LB)/MGUIOptionsLoaderMeasurements.o \ +$(LB)/MModuleLoaderMeasurementsHDF.o \ +$(LB)/MGUIOptionsLoaderMeasurementsHDF.o \ $(LB)/MBinaryFlightDataParser.o \ $(LB)/MModuleReceiverBalloon.o \ $(LB)/MGUIOptionsReceiverBalloon.o \ @@ -194,6 +215,7 @@ $(FRETALON_DEP_FILES): $(LB)/%.d: $(FRETALON_DIR)/src/%.cxx $(FRETALON_LIBS): $(LB)/%.o: $(FRETALON_DIR)/src/%.cxx $(FRETALON_DIR)/inc/%.h $(LB)/%.d @echo "Compiling $(subst $(FRETALON_DIR)/src/,,$<) ..." @$(CXX) $(CXXFLAGS) -c $< -o $@ + @echo "$(CXX) $(CXXFLAGS) -c $< -o $@" $(NUCLEARIZER_DEP_FILES): $(LB)/%.d: src/%.cxx @echo "Creating dependencies for $(subst src/,,$<) ..." @@ -207,7 +229,7 @@ $(NUCLEARIZER_DICT): $(FRETALON_H_FILES) $(NUCLEARIZER_H_FILES) @echo "Generating LinkDef ..." @$(BN)/generatelinkdef -o $(NUCLEARIZER_LINKDEF) -i $(NUCLEARIZER_H_FILES) $(FRETALON_H_FILES) @echo "Generating dictionary ..." - @rootcling -f $@ -I$(IN) -I$(MEGALIB)/include -D___CLING___ -rmf $(NUCLEARIZER_ROOTMAP) -s libNuclearizer -c $(NUCLEARIZER_H_FILES) $(FRETALON_H_FILES) $(NUCLEARIZER_LINKDEF) + @rootcling -f $@ -I$(IN) -I$(MEGALIB)/include $(H5CXXFLAGS) -D___CLING___ -rmf $(NUCLEARIZER_ROOTMAP) -s libNuclearizer -c $(NUCLEARIZER_H_FILES) $(FRETALON_H_FILES) $(NUCLEARIZER_LINKDEF) @mv $(NUCLEARIZER_ROOTPCM) $(LB) $(NUCLEARIZER_DICT_LIB): $(NUCLEARIZER_DICT) @@ -222,6 +244,7 @@ $(NUCLEARIZER_PRG): $(NUCLEARIZER_SHARED_LIB) $(NUCLEARIZER_CXX_MAIN) @echo "Linking and compiling $(subst $(BN)/,,$(NUCLEARIZER_PRG)) ... Please stand by ... " @$(CXX) $(CXXFLAGS) $(LDFLAGS) $(NUCLEARIZER_CXX_MAIN) $(NUCLEARIZER_SHARED_LIB) $(ALLLIBS) $(GLIBS) $(LIBS) -o $(NUCLEARIZER_PRG) + ifneq ($(MAKECMDGOALS),clean) -include $(NUCLEARIZER_DEP_FILES) -include $(FRETALON_DEP_FILES) diff --git a/include/MGUIOptionsLoaderMeasurements.h b/include/MGUIOptionsLoaderMeasurements.h index 2e9082b4..bbcbd5e8 100644 --- a/include/MGUIOptionsLoaderMeasurements.h +++ b/include/MGUIOptionsLoaderMeasurements.h @@ -46,7 +46,7 @@ class MGUIOptionsLoaderMeasurements : public MGUIOptions // public Session: public: //! Default constructor - MGUIOptionsLoaderMeasurements(MModule* Module); + MGUIOptionsLoaderMeasurements(MModule* Module, MString FileType); //! Default destructor virtual ~MGUIOptionsLoaderMeasurements(); @@ -71,6 +71,8 @@ class MGUIOptionsLoaderMeasurements : public MGUIOptions //! Select which file to load MGUIEFileSelector* m_FileSelector; + //! The file type to load + MString m_FileType; #ifdef ___CLING___ public: diff --git a/include/MGUIOptionsLoaderMeasurementsHDF.h b/include/MGUIOptionsLoaderMeasurementsHDF.h new file mode 100644 index 00000000..b453cb2a --- /dev/null +++ b/include/MGUIOptionsLoaderMeasurementsHDF.h @@ -0,0 +1,93 @@ +/* + * MGUIOptionsLoaderMeasurementsHDF.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MGUIOptionsLoaderMeasurementsHDF__ +#define __MGUIOptionsLoaderMeasurementsHDF__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// ROOT libs: +#include +#include +#include +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MGlobal.h" +#include "MGUIEFileSelector.h" +#include "MGUIOptions.h" + +// Nuclearizer libs: +#include "MModule.h" + + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +//! UI settings for the HDF measurements loader +class MGUIOptionsLoaderMeasurementsHDF : public MGUIOptions +{ + // public Session: + public: + //! Default constructor + MGUIOptionsLoaderMeasurementsHDF(MModule* Module); + //! Default destructor + virtual ~MGUIOptionsLoaderMeasurementsHDF(); + + //! Process all button, etc. messages + virtual bool ProcessMessage(long Message, long Parameter1, long Parameter2); + + //! The creation part which gets overwritten + virtual void Create(); + + // protected methods: + protected: + + //! Actions after the Apply or OK button has been pressed + virtual bool OnApply(); + + + // protected members: + protected: + + // private members: + private: + //! Select which file to load + MGUIEFileSelector* m_FileSelectorHDF; + + //! Check button for switch between loading continuation files or not + TGCheckButton* m_LoadContinuationFiles; + + //! Select which file to load + MGUIEFileSelector* m_FileSelectorStripMap; + + + +#ifdef ___CLING___ + public: + ClassDef(MGUIOptionsLoaderMeasurementsHDF, 1) // basic class for dialog windows +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/include/MModuleLoaderMeasurements.h b/include/MModuleLoaderMeasurements.h index a1c31e39..bf9b59e0 100644 --- a/include/MModuleLoaderMeasurements.h +++ b/include/MModuleLoaderMeasurements.h @@ -51,9 +51,6 @@ class MModuleLoaderMeasurements : public MModule, public MFileEvents //! Main data analysis routine, which updates the event to a new level virtual bool AnalyzeEvent(MReadOutAssembly* Event); - //! Show the options GUI - virtual void ShowOptionsGUI(); - //! Read the configuration data from an XML node virtual bool ReadXmlConfiguration(MXmlNode* Node) = 0; //! Create an XML node tree from the configuration diff --git a/include/MModuleLoaderMeasurementsHDF.h b/include/MModuleLoaderMeasurementsHDF.h new file mode 100644 index 00000000..22b05841 --- /dev/null +++ b/include/MModuleLoaderMeasurementsHDF.h @@ -0,0 +1,239 @@ +/* + * MModuleLoaderMeasurementsHDF.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MModuleLoaderMeasurementsHDF__ +#define __MModuleLoaderMeasurementsHDF__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// Standard libs: + +// ROOT libs: + +// MEGAlib libs: +#include "MGlobal.h" +#include "MFileReadOuts.h" + +// Nuclearizer libs: +#include "MStripMap.h" +#include "MModuleLoaderMeasurements.h" + +// H5 libs +#include "H5Cpp.h" +using namespace H5; + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +//! The versions of the strip hits stored in the HDF file +enum class MHDFStripHitVersion { V1_0, V1_2 }; + +//! And a streamer for it +inline ostream& operator<<(ostream& os, MHDFStripHitVersion Version) { + switch (Version) { + case MHDFStripHitVersion::V1_0: return os<<"1.0"; + case MHDFStripHitVersion::V1_2: return os<<"1.2"; + default: return os<<"Unknown"; + } +} + +//! Version 1.0 & 1.1 of the HDF5 hit info +struct MHDFStripHit_V1_0 { + uint16_t m_EventID; + uint32_t m_TimeCode; + uint8_t m_HitType; + uint8_t m_TimingType; + uint16_t m_StripID; + uint8_t m_CrystalID; + uint8_t m_Gain; + uint8_t m_Overflow; + uint16_t m_CurrentMaximum; + uint16_t m_HighCurrentSamples; + uint16_t m_EnergyData; + uint16_t m_EnergyDataLowGain; + uint16_t m_EnergyDataHighGain; + uint16_t m_TimingData; + uint8_t m_Pad; + uint8_t m_Hits; + uint8_t m_EventType; + uint8_t m_CRC; +}; + +//! Version 1.2 of the HDF5 hit info +struct MHDFStripHit_V1_2 { + uint16_t m_EventID; + uint64_t m_TimeCode; + double m_GSETimeCode; + uint8_t m_HitType; + uint8_t m_TimingType; + uint16_t m_StripID; + uint8_t m_CrystalID; + uint8_t m_Gain; + uint8_t m_Overflow; + uint16_t m_CurrentMaximum; + uint16_t m_HighCurrentSamples; + uint16_t m_EnergyData; + uint16_t m_EnergyDataLowGain; + uint16_t m_EnergyDataHighGain; + uint16_t m_TimingData; + uint8_t m_Pad; + uint8_t m_Hits; + uint16_t m_Bytes; + uint8_t m_EventType; + uint8_t m_CRC; +}; + +//! The version string +struct MHDFStripHitVersionString { + char string_col[256]; +}; + +//////////////////////////////////////////////////////////////////////////////// + + +//! A module to load HDF5 data files +class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements +{ + // public interface: + public: + //! Default constructor + MModuleLoaderMeasurementsHDF(); + //! Default destructor + virtual ~MModuleLoaderMeasurementsHDF(); + + //! Create a new object of this class + virtual MModuleLoaderMeasurementsHDF* Clone() { return new MModuleLoaderMeasurementsHDF(); } + + //! Get the file name of the strip map + MString GetFileNameStripMap() const { return m_FileNameStripMap; } + //! Set the file name of the strip map + void SetFileNameStripMap(const MString& Name) { m_FileNameStripMap = Name; } + + + //! Enable/Disable loading continuation files + bool GetLoadContinuationFiles() const { return m_LoadContinuationFiles; } + //! Set loading continuation files + void SetLoadContinuationFiles(bool LoadContinuationFiles) { m_LoadContinuationFiles = LoadContinuationFiles; } + + //! Initialize the module + virtual bool Initialize(); + + //! Initialize the module + virtual void Finalize(); + + //! Main data analysis routine, which updates the event to a new level + virtual bool AnalyzeEvent(MReadOutAssembly* Event); + + //! Show the options GUI + virtual void ShowOptionsGUI(); + + //! Read the configuration data from an XML node + virtual bool ReadXmlConfiguration(MXmlNode* Node); + //! Create an XML node tree from the configuration + virtual MXmlNode* CreateXmlConfiguration(); + + + // protected methods: + protected: + //! Convert more data from raw to intermediate format - return false if no more data can be converted + bool OpenHDF5File(MString FileName); + //! Read a batch of hits using a hyperslab + bool ReadBatchHits(); + + // private methods: + private: + + + + // protected members: + protected: + + + // private members: + private: + /* + //! Start of the observation time + MTime m_StartObservationTime; + //! Clock time belonging to the start of the observation time + unsigned long m_StartClock; + //! End of the observation time + MTime m_EndObservationTime; + //! Clock time belonging to the end of the observation time + unsigned long m_EndClock; + */ + + //! The HDF5 file + H5File m_HDFFile; + + //! True, if we want to load continuation files + bool m_LoadContinuationFiles; + + //! The ID of the currently loaded continuation file + unsigned int m_ContinuationFileID; + + //! The HDF5 data set + DataSet m_HDFDataSet; + + //! The HDF5 compond data type + CompType m_HDFCompoundDataType; + + //! The version of the strip hit structure + MHDFStripHitVersion m_HDFStripHitVersion; + + //! The default batch size + static constexpr unsigned int m_DefaultBatchSize = 10000; + + //! The current batch size + unsigned int m_CurrentBatchSize; + + //! The current index in the batch + unsigned int m_CurrentBatchIndex; + + // The various batches: + //! The MHDFStripHit_V1_0 batch: + vector m_Buffer_1_0; + //! The MHDFStripHit_V1_2 batch: + vector m_Buffer_1_2; + + //! Total number of hits in a file + hsize_t m_TotalHits; + + //! Current hit number in the file + hsize_t m_CurrentHit; + + //! Number of event ID roll-overs: + unsigned int m_NumberOfEventIDRollOvers; + + //! The last handles event ID + unsigned int m_LastEventID; + + //! The file name of the strip map + MString m_FileNameStripMap; + + //! The strip map + MStripMap m_StripMap; + +#ifdef ___CLING___ + public: + ClassDef(MModuleLoaderMeasurementsHDF, 0) // no description +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/include/MModuleLoaderMeasurementsROA.h b/include/MModuleLoaderMeasurementsROA.h index 9db50119..3b302782 100644 --- a/include/MModuleLoaderMeasurementsROA.h +++ b/include/MModuleLoaderMeasurementsROA.h @@ -57,6 +57,9 @@ class MModuleLoaderMeasurementsROA : public MModuleLoaderMeasurements //! Main data analysis routine, which updates the event to a new level virtual bool AnalyzeEvent(MReadOutAssembly* Event); + //! Show the options GUI + virtual void ShowOptionsGUI(); + //! Read the configuration data from an XML node virtual bool ReadXmlConfiguration(MXmlNode* Node); //! Create an XML node tree from the configuration diff --git a/include/MStripMap.h b/include/MStripMap.h new file mode 100644 index 00000000..cce86254 --- /dev/null +++ b/include/MStripMap.h @@ -0,0 +1,105 @@ +/* + * MStripMap.h + * + * Copyright (C) by Andreas Zoglauer + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MStripMap__ +#define __MStripMap__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// Standard libs: +#include +#include +using namespace std; + +// ROOT libs: + +// MEGAlib libs: +#include "MGlobal.h" + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +//! This class represents the mapping from asic channels to detector, side, and strip ID +class MStripMap +{ + // public interface: + public: + //! Default constructor + MStripMap(); + //! Default destructor + virtual ~MStripMap(); + + //! Load a strip map - return false on error + bool Open(MString FileName); + + //! Check if we have a certain read-out ID + bool HasReadOutID(unsigned int ROI) const; + + //! Get detector by read out ID - check with HasReadOutID(ROI) first + unsigned int GetDetectorID(unsigned int ROI) const; + + //! Get detector side by read out ID - check with HasReadOutID(ROI) first + bool IsLowVoltage(unsigned int ROI) const; + + //! Get strip ID by read out ID - check with HasReadOutID(ROI) first + unsigned int GetStripNumber(unsigned int ROI) const; + + + // protected methods: + protected: + //! Return the index of the read-out ID or throw an exception + unsigned int GetReadOutIDIndex(unsigned int ROI) const; + + + // private methods: + private: + + + + // protected members: + protected: + + + // private members: + private: + //! The internal struct for the map + struct MSingleStripMapping { + unsigned int m_ReadOutID; + unsigned int m_RTB; + unsigned int m_DRM; + bool m_IsPrimary; + unsigned int m_ASICID; + unsigned int m_ChannelID; + unsigned int m_DetectorID; + bool m_IsLowVoltage; + unsigned int m_StripNumber; + }; + + //! The strip mapping data + vector m_StripMappings; + + +#ifdef ___CLING___ + public: + ClassDef(MStripMap, 0) // no description +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MAssembly.cxx b/src/MAssembly.cxx index f9d6c6bc..3202ee3e 100644 --- a/src/MAssembly.cxx +++ b/src/MAssembly.cxx @@ -60,6 +60,7 @@ using namespace std; #include "MModuleLoaderSimulationsBalloon.h" #include "MModuleLoaderSimulationsSMEX.h" #include "MModuleLoaderMeasurementsROA.h" +#include "MModuleLoaderMeasurementsHDF.h" #include "MModuleReceiverBalloon.h" #include "MModuleLoaderMeasurementsBinary.h" #include "MModuleEnergyCalibration.h" @@ -115,6 +116,7 @@ MAssembly::MAssembly() m_Supervisor->AddAvailableModule(new MModuleLoaderSimulationsBalloon()); m_Supervisor->AddAvailableModule(new MModuleLoaderSimulationsSMEX()); m_Supervisor->AddAvailableModule(new MModuleLoaderMeasurementsROA()); + m_Supervisor->AddAvailableModule(new MModuleLoaderMeasurementsHDF()); m_Supervisor->AddAvailableModule(new MModuleReceiverBalloon()); m_Supervisor->AddAvailableModule(new MModuleLoaderMeasurementsBinary()); diff --git a/src/MGUIOptionsEnergyCalibrationUniversal.cxx b/src/MGUIOptionsEnergyCalibrationUniversal.cxx index 6aafead3..d2ad6d72 100644 --- a/src/MGUIOptionsEnergyCalibrationUniversal.cxx +++ b/src/MGUIOptionsEnergyCalibrationUniversal.cxx @@ -105,8 +105,8 @@ bool MGUIOptionsEnergyCalibrationUniversal::ProcessMessage(long Message, long Pa { // Modify here if you have more buttons - bool Status = true; - + bool Status = true; + switch (GET_MSG(Message)) { case kC_COMMAND: switch (GET_SUBMSG(Message)) { @@ -123,7 +123,7 @@ bool MGUIOptionsEnergyCalibrationUniversal::ProcessMessage(long Message, long Pa m_TempFile->SetEnabled(false); } break; - } + } default: break; } @@ -146,17 +146,14 @@ bool MGUIOptionsEnergyCalibrationUniversal::ProcessMessage(long Message, long Pa bool MGUIOptionsEnergyCalibrationUniversal::OnApply() { - // Modify this to store the data in the module! + // Modify this to store the data in the module! dynamic_cast(m_Module)->SetFileName(m_FileSelector->GetFileName()); dynamic_cast(m_Module)->SetTempFileName(m_TempFile->GetFileName()); - if (dynamic_cast(m_Module)->GetPreampTempCorrection() != m_UseTempCal) dynamic_cast(m_Module)->EnablePreampTempCorrection(m_UseTempCal); - - - return true; + return true; } diff --git a/src/MGUIOptionsLoaderMeasurements.cxx b/src/MGUIOptionsLoaderMeasurements.cxx index c9dfe019..79f38dde 100644 --- a/src/MGUIOptionsLoaderMeasurements.cxx +++ b/src/MGUIOptionsLoaderMeasurements.cxx @@ -43,8 +43,8 @@ ClassImp(MGUIOptionsLoaderMeasurements) //////////////////////////////////////////////////////////////////////////////// -MGUIOptionsLoaderMeasurements::MGUIOptionsLoaderMeasurements(MModule* Module) - : MGUIOptions(Module) +MGUIOptionsLoaderMeasurements::MGUIOptionsLoaderMeasurements(MModule* Module, MString FileType) + : MGUIOptions(Module), m_FileType(FileType) { // standard constructor } @@ -66,12 +66,12 @@ void MGUIOptionsLoaderMeasurements::Create() { PreCreate(); - m_FileSelector = new MGUIEFileSelector(m_OptionsFrame, "Please select a data file:", + m_FileSelector = new MGUIEFileSelector(m_OptionsFrame, MString("Please select a ") + m_FileType + " file:", dynamic_cast(m_Module)->GetFileName()); - m_FileSelector->SetFileType("Roa file", "*.roa"); - m_FileSelector->SetFileType("Roa file", "*.roa.gz"); - m_FileSelector->SetFileType("Data file", "*.dat"); - m_FileSelector->SetFileType("Data file", "*.dat.gz"); + m_FileSelector->SetFileType(m_FileType + " file", MString("*.") + m_FileType); + if (m_FileType == "roa") { + m_FileSelector->SetFileType(m_FileType + " file", MString("*.") + m_FileType + ".gz"); + } TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); m_OptionsFrame->AddFrame(m_FileSelector, LabelLayout); diff --git a/src/MGUIOptionsLoaderMeasurementsHDF.cxx b/src/MGUIOptionsLoaderMeasurementsHDF.cxx new file mode 100644 index 00000000..5126b5b8 --- /dev/null +++ b/src/MGUIOptionsLoaderMeasurementsHDF.cxx @@ -0,0 +1,141 @@ +/* + * MGUIOptionsLoaderMeasurementsHDF.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +// Include the header: +#include "MGUIOptionsLoaderMeasurementsHDF.h" + +// Standard libs: + +// ROOT libs: +#include +#include +#include +#include + +// MEGAlib libs: +#include "MStreams.h" +#include "MModuleLoaderMeasurementsHDF.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MGUIOptionsLoaderMeasurementsHDF) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIOptionsLoaderMeasurementsHDF::MGUIOptionsLoaderMeasurementsHDF(MModule* Module) + : MGUIOptions(Module) +{ + // standard constructor +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIOptionsLoaderMeasurementsHDF::~MGUIOptionsLoaderMeasurementsHDF() +{ + // kDeepCleanup is activated +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIOptionsLoaderMeasurementsHDF::Create() +{ + PreCreate(); + + TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + + m_FileSelectorHDF = new MGUIEFileSelector(m_OptionsFrame, "Please select a HDF5 file:", + dynamic_cast(m_Module)->GetFileName()); + m_FileSelectorHDF->SetFileType("HDF5 file", "*.hdf5"); + m_FileSelectorHDF->SetFileType("HDF5 file", "*.hdf"); + m_OptionsFrame->AddFrame(m_FileSelectorHDF, LabelLayout); + + + m_LoadContinuationFiles = new TGCheckButton(m_OptionsFrame, "Enable loading continuation HDF5 files", 1); + m_LoadContinuationFiles->SetOn(dynamic_cast(m_Module)->GetLoadContinuationFiles()); + m_LoadContinuationFiles->Associate(this); + m_OptionsFrame->AddFrame(m_LoadContinuationFiles, LabelLayout); + + + m_FileSelectorStripMap = new MGUIEFileSelector(m_OptionsFrame, "Please select a strip map file:", + dynamic_cast(m_Module)->GetFileNameStripMap()); + m_FileSelectorStripMap->SetFileType("Strip map file", "*.map"); + m_OptionsFrame->AddFrame(m_FileSelectorStripMap, LabelLayout); + + + PostCreate(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MGUIOptionsLoaderMeasurementsHDF::ProcessMessage(long Message, long Parameter1, long Parameter2) +{ + // Modify here if you have more buttons + + bool Status = true; + + switch (GET_MSG(Message)) { + case kC_COMMAND: + switch (GET_SUBMSG(Message)) { + case kCM_BUTTON: + break; + default: + break; + } + break; + default: + break; + } + + if (Status == false) { + return false; + } + + // Call also base class + return MGUIOptions::ProcessMessage(Message, Parameter1, Parameter2); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MGUIOptionsLoaderMeasurementsHDF::OnApply() +{ + // Modify this to store the data in the module! + + dynamic_cast(m_Module)->SetFileName(m_FileSelectorHDF->GetFileName()); + dynamic_cast(m_Module)->SetLoadContinuationFiles(m_LoadContinuationFiles->IsOn()); + dynamic_cast(m_Module)->SetFileNameStripMap(m_FileSelectorStripMap->GetFileName()); + + return true; +} + + +// MGUIOptionsLoaderMeasurementsHDF: the end... +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MModuleLoaderMeasurements.cxx b/src/MModuleLoaderMeasurements.cxx index 5c6b890c..acc133bb 100644 --- a/src/MModuleLoaderMeasurements.cxx +++ b/src/MModuleLoaderMeasurements.cxx @@ -95,18 +95,5 @@ bool MModuleLoaderMeasurements::AnalyzeEvent(MReadOutAssembly* Event) } -/////////////////////////////////////////////////////////////////////////////// - - -void MModuleLoaderMeasurements::ShowOptionsGUI() -{ - //! Show the options GUI - - MGUIOptionsLoaderMeasurements* Options = new MGUIOptionsLoaderMeasurements(this); - Options->Create(); - gClient->WaitForUnmap(Options); -} - - // MModuleLoaderMeasurements.cxx: the end... //////////////////////////////////////////////////////////////////////////////// diff --git a/src/MModuleLoaderMeasurementsBinary.cxx b/src/MModuleLoaderMeasurementsBinary.cxx index af547b39..4d0e0343 100644 --- a/src/MModuleLoaderMeasurementsBinary.cxx +++ b/src/MModuleLoaderMeasurementsBinary.cxx @@ -1,19 +1,19 @@ /* - * MModuleLoaderMeasurementsBinary.cxx - * - * - * Copyright (C) by Alex Lowell & Andreas Zoglauer. - * All rights reserved. - * - * - * This code implementation is the intellectual property of - * Andreas Zoglauer. - * - * By copying, distributing or modifying the Program (or any work - * based on the Program) you indicate your acceptance of this statement, - * and all its terms. - * - */ +* MModuleLoaderMeasurementsBinary.cxx +* +* +* Copyright (C) by Alex Lowell & Andreas Zoglauer. +* All rights reserved. +* +* +* This code implementation is the intellectual property of +* Andreas Zoglauer. +* +* By copying, distributing or modifying the Program (or any work +* based on the Program) you indicate your acceptance of this statement, +* and all its terms. +* +*/ @@ -84,11 +84,11 @@ MModuleLoaderMeasurementsBinary::MModuleLoaderMeasurementsBinary() : MModule(), m_IgnoreAspect = false; //this was set to true and was causing events to be pushed through the pipeline before aspect info was available for them AWL Sep 20 2016 m_FileIsDone = false; - - m_IsZipped = false; + + m_IsZipped = false; m_ZipFile = NULL; - m_ExpoAspectViewer = nullptr; + m_ExpoAspectViewer = nullptr; } @@ -106,13 +106,13 @@ MModuleLoaderMeasurementsBinary::~MModuleLoaderMeasurementsBinary() void MModuleLoaderMeasurementsBinary::CreateExpos() { - // Create all expos - - if (HasExpos() == true) return; - - // Set the histogram display - m_ExpoAspectViewer = new MGUIExpoAspectViewer(this); - m_Expos.push_back(m_ExpoAspectViewer); + // Create all expos + + if (HasExpos() == true) return; + + // Set the histogram display + m_ExpoAspectViewer = new MGUIExpoAspectViewer(this); + m_Expos.push_back(m_ExpoAspectViewer); } @@ -122,35 +122,35 @@ FILE * f_TOnly; bool MModuleLoaderMeasurementsBinary::OpenNextFile() { - //! Open next file, return false on error - - ++m_OpenFileID; - if (m_OpenFileID >= (int) m_BinaryFileNames.size()) return false; - - m_IsZipped = m_BinaryFileNames[m_OpenFileID].EndsWith(".gz"); - - if (m_IsZipped == false) { - if (m_In.is_open()) m_In.close(); - m_In.clear(); - - m_In.open(m_BinaryFileNames[m_OpenFileID], ios::binary); - if (m_In.is_open() == false) { - if (g_Verbosity >= c_Error) cout<= c_Error) cout<= c_Info) cout<= (int) m_BinaryFileNames.size()) return false; + + m_IsZipped = m_BinaryFileNames[m_OpenFileID].EndsWith(".gz"); + + if (m_IsZipped == false) { + if (m_In.is_open()) m_In.close(); + m_In.clear(); + + m_In.open(m_BinaryFileNames[m_OpenFileID], ios::binary); + if (m_In.is_open() == false) { + if (g_Verbosity >= c_Error) cout<= c_Error) cout<= c_Info) cout<= c_Error) cout<= c_Error) cout<= c_Info) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Info) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout< Stream(Size); // Check if we reached the end of the file, if yes, truncate, and set the OK flag to false - // when the end of the file is reached, we want to + // when the end of the file is reached, we want to - //AWL restructured this so that we don't allocate/fill a 1MB array when there is nothing to read. + //AWL restructured this so that we don't allocate/fill a 1MB array when there is nothing to read. vector Stream; unsigned int Size = 1000000; @@ -261,55 +261,55 @@ bool MModuleLoaderMeasurementsBinary::IsReady() Read = 0; } else { Stream.reserve(Size); - if (m_IsZipped == false) { - m_In.read(&Stream[0], Size); - Read = m_In.gcount(); - } else { - Read = 0; - for (unsigned int i = 0; i < Size; ++i) { - int c = gzgetc(m_ZipFile); - if (c == -1) { - break; - } - Stream[i] = (char) c; - Read = i+1; - } - } + if (m_IsZipped == false) { + m_In.read(&Stream[0], Size); + Read = m_In.gcount(); + } else { + Read = 0; + for (unsigned int i = 0; i < Size; ++i) { + int c = gzgetc(m_ZipFile); + if (c == -1) { + break; + } + Stream[i] = (char) c; + Read = i+1; + } + } } // If we do not read anything, try again with the next file - if (Read == 0) { - if (OpenNextFile() == true) { - Stream.reserve(Size); - if (m_IsZipped == false) { - m_In.read(&Stream[0], Size); - Read = m_In.gcount(); - } else { - Read = 0; - for (unsigned int i = 0; i < Size; ++i) { - int c = gzgetc(m_ZipFile); - if (c == -1) { - break; - } - Stream[i] = (char) c; - Read = i+1; - } - } - } - } + if (Read == 0) { + if (OpenNextFile() == true) { + Stream.reserve(Size); + if (m_IsZipped == false) { + m_In.read(&Stream[0], Size); + Read = m_In.gcount(); + } else { + Read = 0; + for (unsigned int i = 0; i < Size; ++i) { + int c = gzgetc(m_ZipFile); + if (c == -1) { + break; + } + Stream[i] = (char) c; + Read = i+1; + } + } + } + } /* - if (Read < Size) { - m_IsOK = false; - } - */ + * i f (Read < Size) { * + * m_IsOK = false; +} +*/ /* - if (Read < Size) { - m_FileIsDone = true; - SetIsDone(true); - } - */ + * i f (Read < Size) { * + * m_FileIsDone = true; + * SetIsDone(true); +} +*/ if (Read == 0) { m_FileIsDone = true; @@ -330,7 +330,7 @@ bool MModuleLoaderMeasurementsBinary::IsReady() } //cout<<"Received: "<GetCL() < LastCL){ - cout << LastCL << "--->" << NewEvent->GetCL() << endl; - } - LastCL = NewEvent->GetCL(); - */ + * i f(NewEvent->GetCL() < LastCL){ * + * cout << LastCL << "--->" << NewEvent->GetCL() << endl; +} +LastCL = NewEvent->GetCL(); +*/ //print TOnly info for these events /* @@ -424,7 +424,7 @@ bool MModuleLoaderMeasurementsBinary::AnalyzeEvent(MReadOutAssembly* Event) } //cout<<"Adding: "<GetTime()<<":"<GetHeading()<AddHeading(NewEvent->GetTime(), A->GetHeading(), A->GetGPS_or_magnetometer(), A->GetBRMS(), A->GetAttFlag()); + m_ExpoAspectViewer->AddHeading(NewEvent->GetTime(), A->GetHeading(), A->GetGPS_or_magnetometer(), A->GetBRMS(), A->GetAttFlag()); } Event->SetAnalysisProgress(MAssembly::c_Aspect); } else { @@ -432,9 +432,9 @@ bool MModuleLoaderMeasurementsBinary::AnalyzeEvent(MReadOutAssembly* Event) Event->SetAspectIncomplete(true); } } - Event->SetAnalysisProgress(MAssembly::c_EventLoader | - MAssembly::c_EventLoaderMeasurement | - MAssembly::c_EventOrdering); + Event->SetAnalysisProgress(MAssembly::c_EventLoader | + MAssembly::c_EventLoaderMeasurement | + MAssembly::c_EventOrdering); if (Event->GetTime().GetAsSystemSeconds() == 0) { Event->SetTimeIncomplete(true); diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx new file mode 100644 index 00000000..408e5fa2 --- /dev/null +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -0,0 +1,525 @@ +/* + * MModuleLoaderMeasurementsHDF.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +//////////////////////////////////////////////////////////////////////////////// +// +// MModuleLoaderMeasurementsHDF +// +//////////////////////////////////////////////////////////////////////////////// + + +// Include the header: +#include "MModuleLoaderMeasurementsHDF.h" + +// Standard libs: +#include +using namespace std; + +// ROOT libs: +#include "TGClient.h" + +// MEGAlib libs: +#include "MGUIOptionsLoaderMeasurementsHDF.h" +#include "MReadOut.h" +#include "MReadOutSequence.h" +#include "MReadOutElementDoubleStrip.h" +#include "MReadOutDataADCValue.h" +#include "MReadOutDataTiming.h" +#include "MReadOutDataOrigins.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MModuleLoaderMeasurementsHDF) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleLoaderMeasurementsHDF::MModuleLoaderMeasurementsHDF() : MModuleLoaderMeasurements() +{ + // Construct an instance of MModuleLoaderMeasurementsHDF + + // Set all module relevant information + + // Set the module name --- has to be unique + m_Name = "Measurement loader for HDF files"; + + // Set the XML tag --- has to be unique --- no spaces allowed + m_XmlTag = "XmlTagMeasurementLoaderHDF"; + + // This is a special start module which can generate its own events + m_IsStartModule = true; + + // Allow the use of multiple threads and instances + m_AllowMultiThreading = true; + m_AllowMultipleInstances = false; + + m_LoadContinuationFiles = false; + m_FileNameStripMap = ""; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleLoaderMeasurementsHDF::~MModuleLoaderMeasurementsHDF() +{ + // Delete this instance of MModuleLoaderMeasurementsHDF +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleLoaderMeasurementsHDF::Initialize() +{ + // Initialize the module + + // Clean: + m_FileType = "Unknown"; + m_Detector = "Unknown"; + m_Version = -1; + /* + m_StartObservationTime = MTime(0); + m_EndObservationTime = MTime(0); + m_StartClock = numeric_limits::max(); + m_EndClock = numeric_limits::max(); + */ + + m_TotalHits = 0; + m_CurrentHit = 0; + + m_NumberOfEventIDRollOvers = 0; + m_LastEventID = 0; + + if (MFile::Exists(m_FileName) == false) { + if (g_Verbosity >= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout< 0) { + DataSet VersionDataset = m_HDFFile.openDataSet("/HDFVersion"); + + // Create compound type for version + CompType VersionType(sizeof(MHDFStripHitVersionString)); + StrType StringType(PredType::C_S1, 256); + VersionType.insertMember("string_col", HOFFSET(MHDFStripHitVersionString, string_col), StringType); + + MHDFStripHitVersionString VS; + VersionDataset.read(&VS, VersionType); + + if (string(VS.string_col) == "1.2") { + m_HDFStripHitVersion = MHDFStripHitVersion::V1_2; + } else { + if (g_Verbosity >= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout<= m_TotalHits) { + if (m_LoadContinuationFiles == true) { + // Check if we have more files to load: + MString FileName = m_FileName; + MString NextSuffix = MString("_") + (m_ContinuationFileID+1) + ".hdf5"; + FileName.ReplaceAllInPlace(".hdf5", NextSuffix); + if (MFile::Exists(FileName) == true) { + if (OpenHDF5File(FileName) == false) { + cout<= m_CurrentBatchSize) { + if (ReadBatchHits() == false) { + return false; + } + } + + // Extract the data we need + uint16_t EventID; + uint64_t TimeCode; + uint16_t StripID; + uint16_t ADCs; + uint16_t TACs; + uint8_t NumberOfHits; + + if (m_HDFStripHitVersion == MHDFStripHitVersion::V1_0) { + MHDFStripHit_V1_0& Hit = m_Buffer_1_0[m_CurrentBatchIndex]; + ++m_CurrentBatchIndex; + ++m_CurrentHit; + + EventID = Hit.m_EventID; + TimeCode = Hit.m_TimeCode; + StripID = Hit.m_StripID; + ADCs = Hit.m_EnergyData; + TACs = Hit.m_TimingData; + NumberOfHits = Hit.m_Hits; + } else if (m_HDFStripHitVersion == MHDFStripHitVersion::V1_2) { + MHDFStripHit_V1_2& Hit = m_Buffer_1_2[m_CurrentBatchIndex]; + ++m_CurrentBatchIndex; + ++m_CurrentHit; + + EventID = Hit.m_EventID; + TimeCode = Hit.m_TimeCode; + StripID = Hit.m_StripID; + ADCs = Hit.m_EnergyData; + TACs = Hit.m_TimingData; + NumberOfHits = Hit.m_Hits; + } else { + if (g_Verbosity >= c_Error) cout<= c_Info) { + cout<::max() + 1); + + Event->SetID(LongEventID); + if (m_HDFStripHitVersion == MHDFStripHitVersion::V1_0) { + Event->SetCL(TimeCode); + } else { + Event->SetTI(TimeCode); + } + + if (m_StripMap.HasReadOutID(StripID) == true) { + MStripHit* H = new MStripHit(); + H->SetDetectorID(m_StripMap.GetDetectorID(StripID)); + H->SetStripID(m_StripMap.GetStripNumber(StripID)); + H->IsLowVoltageStrip(m_StripMap.IsLowVoltage(StripID)); + H->SetADCUnits(ADCs); + H->SetTAC(TACs); + Event->AddStripHit(H); + } else { + if (g_Verbosity >= c_Error) cout<(NumberOfHits); + } + + Event->SetAnalysisProgress(MAssembly::c_EventLoader | MAssembly::c_EventLoaderMeasurement); + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MModuleLoaderMeasurementsHDF::Finalize() +{ + // Initialize the module + + MModule::Finalize(); + + cout<<"MModuleLoaderMeasurementsHDF: "<GetNode("FileNameHDF5"); + if (FileNameHDF5Node != nullptr) { + m_FileName = FileNameHDF5Node->GetValue(); + } + + MXmlNode* LoadContinuationFilesNode = Node->GetNode("LoadContinuationFiles"); + if (LoadContinuationFilesNode != nullptr) { + m_LoadContinuationFiles = LoadContinuationFilesNode->GetValueAsBoolean(); + } + + MXmlNode* FileNameStripMapNode = Node->GetNode("FileNameStripMap"); + if (FileNameStripMapNode != nullptr) { + m_FileNameStripMap = FileNameStripMapNode->GetValue(); + } + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MXmlNode* MModuleLoaderMeasurementsHDF::CreateXmlConfiguration() +{ + //! Create an XML node tree from the configuration + + MXmlNode* Node = new MXmlNode(0, m_XmlTag); + new MXmlNode(Node, "FileNameHDF5", m_FileName); + new MXmlNode(Node, "LoadContinuationFiles", m_LoadContinuationFiles); + new MXmlNode(Node, "FileNameStripMap", m_FileNameStripMap); + + return Node; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +void MModuleLoaderMeasurementsHDF::ShowOptionsGUI() +{ + //! Show the options GUI + + MGUIOptionsLoaderMeasurementsHDF* Options = new MGUIOptionsLoaderMeasurementsHDF(this); + Options->Create(); + gClient->WaitForUnmap(Options); +} + + +// MModuleLoaderMeasurementsHDF.cxx: the end... +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MModuleLoaderMeasurementsROA.cxx b/src/MModuleLoaderMeasurementsROA.cxx index cf19aedd..5d17749a 100644 --- a/src/MModuleLoaderMeasurementsROA.cxx +++ b/src/MModuleLoaderMeasurementsROA.cxx @@ -33,6 +33,7 @@ // MEGAlib libs: #include "MGUIOptionsTemplate.h" +#include "MGUIOptionsLoaderMeasurements.h" #include "MReadOut.h" #include "MReadOutSequence.h" #include "MReadOutElementDoubleStrip.h" @@ -40,6 +41,7 @@ #include "MReadOutDataTiming.h" #include "MReadOutDataOrigins.h" + //////////////////////////////////////////////////////////////////////////////// @@ -248,5 +250,18 @@ MXmlNode* MModuleLoaderMeasurementsROA::CreateXmlConfiguration() } +/////////////////////////////////////////////////////////////////////////////// + + +void MModuleLoaderMeasurementsROA::ShowOptionsGUI() +{ + //! Show the options GUI + + MGUIOptionsLoaderMeasurements* Options = new MGUIOptionsLoaderMeasurements(this, "roa"); + Options->Create(); + gClient->WaitForUnmap(Options); +} + + // MModuleLoaderMeasurementsROA.cxx: the end... //////////////////////////////////////////////////////////////////////////////// diff --git a/src/MStripMap.cxx b/src/MStripMap.cxx new file mode 100644 index 00000000..90fc6323 --- /dev/null +++ b/src/MStripMap.cxx @@ -0,0 +1,162 @@ +/* + * MStripMap.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +//////////////////////////////////////////////////////////////////////////////// +// +// MStripMap +// +//////////////////////////////////////////////////////////////////////////////// + + +// Include the header: +#include "MStripMap.h" + +// Standard libs: + +// ROOT libs: + +// MEGAlib libs: +#include "MStreams.h" +#include "MParser.h" +#include "MExceptions.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MStripMap) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MStripMap::MStripMap() +{ + // Construct an instance of MStripMap +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MStripMap::~MStripMap() +{ + // Delete this instance of MStripMap +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Load a strip map +bool MStripMap::Open(MString FileName) +{ + m_StripMappings.clear(); + + MParser Parser; + if (Parser.Open(FileName) == false) { + if (g_Verbosity >= c_Error) cout<<"MStripMap: Unable to load file: "<GetNTokens() == 0) continue; + if (Parser.GetTokenizerAt(i)->GetTokenAtAsString(0).BeginsWith("#") == true) continue; + if (Parser.GetTokenizerAt(i)->GetNTokens() == 9) { + MSingleStripMapping SM; + SM.m_ReadOutID = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(0); + SM.m_RTB = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(1); + SM.m_DRM = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(2); + SM.m_IsPrimary = Parser.GetTokenizerAt(i)->GetTokenAtAsBoolean(3); + SM.m_ASICID = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(4); + SM.m_ChannelID = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(5); + SM.m_DetectorID = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(6); + SM.m_IsLowVoltage = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(7) == 0 ? true : false; + SM.m_StripNumber = Parser.GetTokenizerAt(i)->GetTokenAtAsUnsignedInt(8); + m_StripMappings.push_back(SM); + } + } + + // Sort by m_ReadOutID: + sort(m_StripMappings.begin(), m_StripMappings.end(), [](const MSingleStripMapping& A, const MSingleStripMapping& B) { return A.m_ReadOutID < B.m_ReadOutID; }); + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Return true if the given read-out ID is on file +bool MStripMap::HasReadOutID(unsigned int ROI) const +{ + auto Iter = lower_bound(m_StripMappings.begin(), m_StripMappings.end(), ROI, [](const MSingleStripMapping& SSM, unsigned int ID) { return SSM.m_ReadOutID < ID; }); + return Iter != m_StripMappings.end() && Iter->m_ReadOutID == ROI; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Return the index of the ROI, throw an exception otherwise +unsigned int MStripMap::GetReadOutIDIndex(unsigned int ROI) const +{ + auto Iter = lower_bound(m_StripMappings.begin(), m_StripMappings.end(), ROI, [](const MSingleStripMapping& SSM, unsigned int ID) { return SSM.m_ReadOutID < ID; }); + + if (Iter != m_StripMappings.end() && Iter->m_ReadOutID == ROI) { + return distance(m_StripMappings.begin(), Iter); + } else { + throw MExceptionValueNotFound(ROI, "vector of read-out IDs"); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Get detector by read-out ID +unsigned int MStripMap::GetDetectorID(unsigned int ROI) const +{ + return m_StripMappings[GetReadOutIDIndex(ROI)].m_DetectorID; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Get detector side by read-out ID +bool MStripMap::IsLowVoltage(unsigned int ROI) const +{ + return m_StripMappings[GetReadOutIDIndex(ROI)].m_IsLowVoltage; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Get strip ID by read-out ID +unsigned int MStripMap::GetStripNumber(unsigned int ROI) const +{ + return m_StripMappings[GetReadOutIDIndex(ROI)].m_StripNumber; +} + + +// MStripMap.cxx: the end... +//////////////////////////////////////////////////////////////////////////////// From 913b1d764cf1dd44f91292a9a9c4a66c9407f999 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 22 May 2025 11:38:44 -0400 Subject: [PATCH 33/90] BUG: Initialize m_Coeffs_Energy and compare to double --- src/MModuleDepthCalibration2024.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 64890753..083c4a5e 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -83,6 +83,8 @@ MModuleDepthCalibration2024::MModuleDepthCalibration2024() : MModule() m_AllowMultiThreading = true; m_AllowMultipleInstances = false; + m_Coeffs_Energy = 0; + m_NoError = 0; m_Error1 = 0; m_Error2 = 0; @@ -441,7 +443,7 @@ double MModuleDepthCalibration2024::GetTimingNoiseFWHM(int pixel_code, double En // Should follow 1/E relation // TODO: Determine real energy dependence and implement it here. double noiseFWHM = 0.0; - if ( m_Coeffs_Energy != NULL ){ + if ( m_Coeffs_Energy != 0 ){ noiseFWHM = m_Coeffs[pixel_code][2] * m_Coeffs_Energy/Energy; if ( noiseFWHM < 3.0*2.355 ){ noiseFWHM = 3.0*2.355; From 9763e9ce172f994273cd6ede0b04a59fc7480e88 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 22 May 2025 11:39:04 -0400 Subject: [PATCH 34/90] BUG: removed unused DetID variable --- src/MModuleDepthCalibration2024.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 083c4a5e..edaa1270 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -117,7 +117,6 @@ bool MModuleDepthCalibration2024::Initialize() // ie DetID=0 should be the 0th detector in m_Detectors, DetID=1 should the 1st, etc. vector DetList = m_Geometry->GetDetectorList(); - unsigned int DetID = 0; // Look through the Geometry and get the names and thicknesses of all the detectors. for(unsigned int i = 0; i < DetList.size(); ++i){ // For now, DetID is in order of detectors, which puts contraints on how the geometry file should be written. From d678409ed74bb6c0660c9900dc5972176000f4c7 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 22 May 2025 11:39:27 -0400 Subject: [PATCH 35/90] BUG: Parentheses for explicit ordering of logic --- src/MModuleDepthCalibration2024.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index edaa1270..20128dd6 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -645,7 +645,7 @@ int MModuleDepthCalibration2024::GetHitGrade(MHit* H){ int return_value; // If 1 strip on each side, GRADE=0 // This represents the center of the pixel - if( (PStrips.size() == 1) && (NStrips.size() == 1) || (PStrips.size() == 3) && (NStrips.size() == 3) ){ + if( ((PStrips.size() == 1) && (NStrips.size() == 1)) || ((PStrips.size() == 3) && (NStrips.size() == 3)) ){ return_value = 0; } // If 2 hits on N side and 1 on P, GRADE=1 From 2364813e43091be1b9056c6b9687676a3fcaa8a0 Mon Sep 17 00:00:00 2001 From: Andreas Zoglauer Date: Tue, 27 May 2025 21:33:03 -0700 Subject: [PATCH 36/90] CHG: Added some error checks --- src/MModuleTACcut.cxx | 47 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 15802c31..b8c8ee56 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -62,7 +62,7 @@ MModuleTACcut::MModuleTACcut() : MModule() // Set all modules, which have to be done before this module AddPreceedingModuleType(MAssembly::c_EventLoader); - AddPreceedingModuleType(MAssembly::c_EnergyCalibration); + //AddPreceedingModuleType(MAssembly::c_EnergyCalibration); // Set all types this modules handles AddModuleType(MAssembly::c_TACcut); @@ -105,20 +105,40 @@ bool MModuleTACcut::Initialize() // Initialize the module if (LoadTACCalFile(m_TACCalFile) == false) { - cout << "TAC Calibration file could not be loaded." << endl; + cout<GetNode("TACCalFileName"); - if (TACCalFileNameNode != 0) { + if (TACCalFileNameNode != nullptr) { SetTACCalFileName(TACCalFileNameNode->GetValue()); } MXmlNode* TACCutFileNameNode = Node->GetNode("TACCutFileName"); - if (TACCutFileNameNode != 0) { + if (TACCutFileNameNode != nullptr) { SetTACCutFileName(TACCutFileNameNode->GetValue()); } MXmlNode* DisableTimeNode = Node->GetNode("DisableTime"); - if (DisableTimeNode != 0) { + if (DisableTimeNode != nullptr) { m_DisableTime = DisableTimeNode->GetValueAsDouble(); } MXmlNode* FlagToEnDelayNode = Node->GetNode("FlagToEnDelay"); - if (FlagToEnDelayNode != 0) { + if (FlagToEnDelayNode != nullptr) { m_FlagToEnDelay = FlagToEnDelayNode->GetValueAsDouble(); } @@ -257,9 +277,14 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() new MXmlNode(Node, "TACCutFileName", m_TACCutFile); new MXmlNode(Node, "DisableTime", m_DisableTime); new MXmlNode(Node, "FlagToEnDelay", m_FlagToEnDelay); + return Node; } + +//////////////////////////////////////////////////////////////////////////////// + + bool MModuleTACcut::LoadTACCalFile(MString FName) { // Read in the TAC Calibration file, which should contain for each strip: @@ -304,9 +329,12 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) } return true; - } + +//////////////////////////////////////////////////////////////////////////////// + + bool MModuleTACcut::LoadTACCutFile(MString FName) { // Read in the TAC Cut file, which should contain for each strip: @@ -353,3 +381,6 @@ bool MModuleTACcut::LoadTACCutFile(MString FName) } // MModuleTACcut.cxx: the end... +//////////////////////////////////////////////////////////////////////////////// + + From 6ea119020015fcc1eebaa8cb8062d063ade55bb4 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 29 May 2025 10:11:24 -0700 Subject: [PATCH 37/90] CHG: Parse new and old TAC calibration formats --- src/MModuleTACcut.cxx | 47 +++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index b8c8ee56..da188371 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -288,7 +288,9 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() bool MModuleTACcut::LoadTACCalFile(MString FName) { // Read in the TAC Calibration file, which should contain for each strip: - // DetID, h or l for high or low voltage, TAC cal, TAC cal error, TAC cal offset, TAC offset error + // DetID, Side (h or l for high or low voltage), TAC cal, TAC cal error, TAC cal offset, TAC offset error + // OR: + // ReadOutID, Detector, Side, Strip, TAC cal, TAC cal error, TAC offset, TAC offset error MFile F; if (F.Open(FName) == false) { cout << "MModuleTACcut: failed to open TAC Calibration file." << endl; @@ -298,28 +300,29 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) while (F.ReadLine(Line)) { if (!Line.BeginsWith("#")) { std::vector Tokens = Line.Tokenize(","); - if (Tokens.size() == 7) { - int DetID = Tokens[0].ToInt(); - int StripID = Tokens[2].ToInt(); - double taccal = Tokens[3].ToDouble(); - double taccal_err = Tokens[4].ToDouble(); - double offset = Tokens[5].ToDouble(); - double offset_err = Tokens[6].ToDouble(); - vector cal_vals; - cal_vals.push_back(taccal); cal_vals.push_back(offset); cal_vals.push_back(taccal_err); cal_vals.push_back(offset_err); + if ((Tokens.size() == 7) || (Tokens.size() == 8)) { + int IndexOffset = Tokens.size() % 7; + int DetID = Tokens[0+IndexOffset].ToInt(); + int StripID = Tokens[2+IndexOffset].ToInt(); + double TACCal = Tokens[3+IndexOffset].ToDouble(); + double TACCalError = Tokens[4+IndexOffset].ToDouble(); + double Offset = Tokens[5+IndexOffset].ToDouble(); + double OffsetError = Tokens[6+IndexOffset].ToDouble(); + vector CalValues; + CalValues.push_back(TACCal); CalValues.push_back(Offset); CalValues.push_back(TACCalError); CalValues.push_back(OffsetError); if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { - unordered_map> temp_map_HV; - m_HVTACCal[DetID] = temp_map_HV; - unordered_map> temp_map_LV; - m_LVTACCal[DetID] = temp_map_LV; + unordered_map> TempMapHV; + m_HVTACCal[DetID] = TempMapHV; + unordered_map> TempMapLV; + m_LVTACCal[DetID] = TempMapLV; m_DetectorIDs.push_back(DetID); } - if (Tokens[1] == "l") { - m_LVTACCal[DetID][StripID] = cal_vals; - } else if (Tokens[1] == "h") { - m_HVTACCal[DetID][StripID] = cal_vals; + if (Tokens[1+IndexOffset] == "l") { + m_LVTACCal[DetID][StripID] = CalValues; + } else if (Tokens[1+IndexOffset] == "h") { + m_HVTACCal[DetID][StripID] = CalValues; } } } @@ -357,10 +360,10 @@ bool MModuleTACcut::LoadTACCutFile(MString FName) CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { - unordered_map> temp_map_HV; - m_HVTACCut[DetID] = temp_map_HV; - unordered_map> temp_map_LV; - m_LVTACCut[DetID] = temp_map_LV; + unordered_map> TempMapHV; + m_HVTACCut[DetID] = TempMapHV; + unordered_map> TempMapLV; + m_LVTACCut[DetID] = TempMapLV; m_DetectorIDs.push_back(DetID); } From 483dd40152f068356fe5a44051e31d23a24893ee Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 29 May 2025 12:30:29 -0700 Subject: [PATCH 38/90] BUG: l=0 and h=1 when parsing new TAC calibration format --- src/MModuleTACcut.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index da188371..e1d1bc13 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -319,9 +319,9 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) m_DetectorIDs.push_back(DetID); } - if (Tokens[1+IndexOffset] == "l") { + if ((Tokens[1+IndexOffset] == "l") || (Tokens[1+IndexOffset] == "0")) { m_LVTACCal[DetID][StripID] = CalValues; - } else if (Tokens[1+IndexOffset] == "h") { + } else if ((Tokens[1+IndexOffset] == "h") || (Tokens[1+IndexOffset] == "1")) { m_HVTACCal[DetID][StripID] = CalValues; } } From 41cecff85f29cd90c9a42a78a5a9defd040560ea Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 3 Jun 2025 13:24:05 -0700 Subject: [PATCH 39/90] ADD: Flags indicating good timing and strip hit type (nearest neighbor and guard ring) --- include/MStripHit.h | 27 ++++++++++++++++++++- src/MStripHit.cxx | 57 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/include/MStripHit.h b/include/MStripHit.h index 7a1e3269..9f770f78 100644 --- a/include/MStripHit.h +++ b/include/MStripHit.h @@ -130,9 +130,27 @@ class MStripHit void AddOrigins(vector Origins); //! Get the origins from the simulation vector GetOrigins() const { return m_Origins; } + + //! Set the Guard Ring flag + void IsGuardRing(bool GuardRing) { m_IsGuardRing = GuardRing; } + //! Return a boolean indicating whether the strip is a Guard Ring + bool IsGuardRing() const { return m_IsGuardRing; } + //! Set the Nearest Neighbor flag + void IsNearestNeighbor(bool NearestNeighbor) { m_IsNearestNeighbor = NearestNeighbor; } + //! Return a boolean indicating whether the strip is a Nearest Neighbor + bool IsNearestNeighbor() const { return m_IsNearestNeighbor; } + + //! Set the Good Timing flag + void HasGoodTiming(bool GoodTiming) { m_HasGoodTiming = GoodTiming; } + //! Return a boolean indicating whether the strip timing is good; + bool HasGoodTiming() const { return m_HasGoodTiming; } - + //! Produce an unsigned int with bitwise values representing flags + unsigned int MakeFlags(); + //! Read in unsigned int with bitwise values representing flags and update boolean flags + void ParseFlags(unsigned int Flags); + //! Parse some content from a line bool Parse(MString& Line, int Version = 1); //! Dump the content into a file stream @@ -177,6 +195,13 @@ class MStripHit double m_TimingResolution; //! Temperature of Preamp double m_PreampTemp; + + //! Flags denoting the type of strip hit + bool m_IsGuardRing; + bool m_IsNearestNeighbor; + + //! Flag indicating whether the TAC/timing are reliable + bool m_HasGoodTiming; //! Origin IAs from simulations vector m_Origins; diff --git a/src/MStripHit.cxx b/src/MStripHit.cxx index e79350a4..4092fcf2 100644 --- a/src/MStripHit.cxx +++ b/src/MStripHit.cxx @@ -86,6 +86,9 @@ void MStripHit::Clear() m_Timing = 0; m_TimingResolution = 0; m_PreampTemp = 0; + m_IsGuardRing = false; + m_IsNearestNeighbor = false; + m_HasGoodTiming = false; m_Origins.clear(); } @@ -100,7 +103,8 @@ bool MStripHit::Parse(MString& Line, int Version) int det_id, strip_id, has_triggered, timing, un_adc, adc; float energy, energy_res; char pos_strip; - sscanf(&line[3],"%d %c %d %d %d %d %d %f %f",&det_id, + unsigned int flags; + sscanf(&line[3],"%d %c %d %d %d %d %d %f %f %u",&det_id, &pos_strip, &strip_id, &has_triggered, @@ -108,9 +112,10 @@ bool MStripHit::Parse(MString& Line, int Version) &un_adc, &adc, &energy, - &energy_res); + &energy_res, + &flags); SetDetectorID(det_id); - pos_strip == 'p' ? IsLowVoltageStrip(true) : IsLowVoltageStrip(false); + pos_strip == 'l' ? IsLowVoltageStrip(true) : IsLowVoltageStrip(false); SetStripID(strip_id); has_triggered == 0 ? HasTriggered(false) : HasTriggered(true); SetTiming((double)timing); @@ -118,6 +123,7 @@ bool MStripHit::Parse(MString& Line, int Version) SetADCUnits((double)adc); SetEnergy(energy); SetEnergyResolution(energy_res); + ParseFlags(flags); return true; } else { return false; @@ -173,7 +179,8 @@ bool MStripHit::StreamDat(ostream& S, int Version) <IsLowVoltageStrip() == true) ? "l" : "h")<<" " < Date: Fri, 6 Jun 2025 16:01:26 -0700 Subject: [PATCH 40/90] CHG: Handle nearest neighbor and guard ring strip hits, check that DetID and StripID are in the cal and cut files --- include/MModuleTACcut.h | 8 +-- src/MModuleTACcut.cxx | 130 +++++++++++++++++++++++++--------------- 2 files changed, 85 insertions(+), 53 deletions(-) diff --git a/include/MModuleTACcut.h b/include/MModuleTACcut.h index 5db18003..4739404e 100644 --- a/include/MModuleTACcut.h +++ b/include/MModuleTACcut.h @@ -119,10 +119,10 @@ class MModuleTACcut : public MModule double m_DisableTime, m_FlagToEnDelay; MString m_TACCalFile; MString m_TACCutFile; -unordered_map>> m_HVTACCal; -unordered_map>> m_LVTACCal; -unordered_map>> m_HVTACCut; -unordered_map>> m_LVTACCut; + +//! Map DetID -> Side (LV=0, HV=1) -> Strip ID -> TAC calibration/cut parameters +unordered_map>>> m_TACCal; +unordered_map>>> m_TACCut; vector m_DetectorIDs; diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index e1d1bc13..e1029fae 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -115,20 +115,12 @@ bool MModuleTACcut::Initialize() } // Some sanity checks: - if (m_LVTACCal.size() == 0) { - cout<GetNStripHits(); ++i) { MStripHit* SH = Event->GetStripHit(i); double TAC_timing = SH->GetTAC(); - double ns_timing; + double ns_timing = 0; int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); - if (SH->IsLowVoltageStrip() == true) { - ns_timing = TAC_timing*m_LVTACCal[DetID][StripID][0] + m_LVTACCal[DetID][StripID][1]; + int Side = SH->IsLowVoltageStrip() ? 0 : 1; + if ((TAC_timing == 0) || (SH->IsGuardRing() == true) || (SH->IsNearestNeighbor() == true)) { + SH->HasGoodTiming(false); } else { - ns_timing = TAC_timing*m_HVTACCal[DetID][StripID][0] + m_HVTACCal[DetID][StripID][1]; - } + if (m_TACCal.find(DetID) != m_TACCal.end()) { + if (m_TACCal[DetID][Side].find(StripID) != m_TACCal[DetID][Side].end()) { + ns_timing = TAC_timing*m_TACCal[DetID][Side][StripID][0] + m_TACCal[DetID][Side][StripID][1]; + SH->HasGoodTiming(true); + } else { + if (Side==0) { + cout<<"MModuleTACcut: Unable to find LV Strip ID "<HasGoodTiming(false); + } + } else { + cout<<"MModuleTACcut: Unable to find Det ID "<HasGoodTiming(false); + } + } SH->SetTiming(ns_timing); - if (ns_timing > MaxTAC) { + if ((SH->HasGoodTiming()==true) && (ns_timing > MaxTAC)) { MaxTAC = ns_timing; } } for (unsigned int i = 0; i < Event->GetNStripHits();) { MStripHit* SH = Event->GetStripHit(i); - double SHTiming = SH->GetTiming(); - int DetID = SH->GetDetectorID(); - int StripID = SH->GetStripID(); - double ShapingOffset; - double CoincidenceWindow; - if (SH->IsLowVoltageStrip() == true) { - ShapingOffset = m_LVTACCut[DetID][StripID][0]; - CoincidenceWindow = m_LVTACCut[DetID][StripID][1]; - } else { - ShapingOffset = m_HVTACCut[DetID][StripID][0]; - CoincidenceWindow = m_HVTACCut[DetID][StripID][1]; - } - double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; - if ((SHTiming < TotalOffset + CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - CoincidenceWindow)){ - if (HasExpos()==true) { - m_ExpoTACcut->AddTAC(DetID, SHTiming); + if ((SH->HasGoodTiming() == true) && (SH->IsNearestNeighbor()==false) && (SH->IsGuardRing()==false)) { + double SHTiming = SH->GetTiming(); + int DetID = SH->GetDetectorID(); + int StripID = SH->GetStripID(); + int Side = SH->IsLowVoltageStrip() ? 0 : 1; + if (m_TACCut.find(DetID) != m_TACCut.end()) { + if (m_TACCut[DetID][Side].find(StripID) != m_TACCut[DetID][Side].end()) { + double ShapingOffset = m_TACCut[DetID][Side][StripID][0]; + double CoincidenceWindow = m_TACCut[DetID][Side][StripID][1]; + double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; + if ((SHTiming < TotalOffset + CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - CoincidenceWindow)){ + if (HasExpos()==true) { + m_ExpoTACcut->AddTAC(DetID, SHTiming); + } + ++i; + } else { + Event->RemoveStripHit(i); + delete SH; + } + } else { + if (Side==0) { + cout<<"MModuleTACcut: Unable to find LV Strip ID "<HasGoodTiming(false); + ++i; + } + } else { + cout<<"MModuleTACcut: Unable to find Det ID "<HasGoodTiming(false); + ++i; } - ++i; } else { - Event->RemoveStripHit(i); - delete SH; + ++i; } } @@ -311,18 +333,23 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) vector CalValues; CalValues.push_back(TACCal); CalValues.push_back(Offset); CalValues.push_back(TACCalError); CalValues.push_back(OffsetError); - if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { - unordered_map> TempMapHV; - m_HVTACCal[DetID] = TempMapHV; + if (m_TACCal.find(DetID) == m_TACCal.end()) { + vector>> TempVector; unordered_map> TempMapLV; - m_LVTACCal[DetID] = TempMapLV; + unordered_map> TempMapHV; + m_TACCal[DetID] = TempVector; + m_TACCal[DetID].push_back(TempMapLV); + m_TACCal[DetID].push_back(TempMapHV); + } + + if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { m_DetectorIDs.push_back(DetID); } if ((Tokens[1+IndexOffset] == "l") || (Tokens[1+IndexOffset] == "0")) { - m_LVTACCal[DetID][StripID] = CalValues; + m_TACCal[DetID][0][StripID] = CalValues; } else if ((Tokens[1+IndexOffset] == "h") || (Tokens[1+IndexOffset] == "1")) { - m_HVTACCal[DetID][StripID] = CalValues; + m_TACCal[DetID][1][StripID] = CalValues; } } } @@ -359,18 +386,23 @@ bool MModuleTACcut::LoadTACCutFile(MString FName) vector CutParams; CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); - if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { - unordered_map> TempMapHV; - m_HVTACCut[DetID] = TempMapHV; + if (m_TACCut.find(DetID) == m_TACCut.end()) { + vector>> TempVector; unordered_map> TempMapLV; - m_LVTACCut[DetID] = TempMapLV; + unordered_map> TempMapHV; + m_TACCut[DetID] = TempVector; + m_TACCut[DetID].push_back(TempMapLV); + m_TACCut[DetID].push_back(TempMapHV); + } + + if (find(m_DetectorIDs.begin(), m_DetectorIDs.end(), DetID) == m_DetectorIDs.end()) { m_DetectorIDs.push_back(DetID); } if (Tokens[1] == "l") { - m_LVTACCut[DetID][StripID] = CutParams; + m_TACCut[DetID][0][StripID] = CutParams; } else if (Tokens[1] == "h") { - m_HVTACCut[DetID][StripID] = CutParams; + m_TACCut[DetID][1][StripID] = CutParams; } } } From 8afa53f85591eb3ce1faa8ab00f3fe9be4847b5c Mon Sep 17 00:00:00 2001 From: robin4730 Date: Tue, 10 Jun 2025 10:16:13 -0700 Subject: [PATCH 41/90] CHG: Updated event flags and storing options in roa files --- include/MGUIOptionsEventSaver.h | 4 ++++ include/MModuleEventSaver.h | 9 +++++++++ include/MStripHit.h | 8 ++++++++ src/MGUIOptionsEventSaver.cxx | 9 +++++++-- src/MModuleEventSaver.cxx | 29 ++++++++++++++++++++++++++++ src/MModuleLoaderMeasurementsHDF.cxx | 17 ++++++++++++++++ src/MStripHit.cxx | 1 + 7 files changed, 75 insertions(+), 2 deletions(-) diff --git a/include/MGUIOptionsEventSaver.h b/include/MGUIOptionsEventSaver.h index 9d2d405c..49d900a6 100644 --- a/include/MGUIOptionsEventSaver.h +++ b/include/MGUIOptionsEventSaver.h @@ -85,6 +85,10 @@ class MGUIOptionsEventSaver : public MGUIOptions TGCheckButton* m_SplitFile; //! Entry field for the time after which to split the file MGUIEEntry* m_SplitFileTime; + + // ------- ADDING!!! ------- + //! Checkbutton to include or exclude NN hits + TGCheckButton* m_IncludeNearestNeighborHits; #ifdef ___CLING___ public: diff --git a/include/MModuleEventSaver.h b/include/MModuleEventSaver.h index 28f1e5ad..47259dbe 100644 --- a/include/MModuleEventSaver.h +++ b/include/MModuleEventSaver.h @@ -77,6 +77,12 @@ class MModuleEventSaver : public MModule MTime GetSplitFileTime() const { return m_SplitFileTime; } //! Set the time after which the file should be split void SetSplitFileTime(MTime SplitFileTime) { m_SplitFileTime = SplitFileTime; } + + // --------- ADDING!!! ---------- + //! Return whether nearest neighbor hits should be included + bool GetIncludeNearestNeighborHits() const { return m_IncludeNearestNeighborHits; } + //! Set whether nearest neighbor hits should be included + void SetIncludeNearestNeighborHits(bool Include) { m_IncludeNearestNeighborHits = Include; } //! Set the start area of the far field simulation if there was any void SetStartAreaFarField(double Area) { m_StartAreaFarField = Area; } @@ -158,6 +164,9 @@ class MModuleEventSaver : public MModule bool m_SplitFile; //! If we split the file, this is the time in seconds after which we split MTime m_SplitFileTime; + + // ------- ADDING!!! ----------- + bool m_IncludeNearestNeighborHits = true; //! Main output stream for file MFile m_Out; diff --git a/include/MStripHit.h b/include/MStripHit.h index 9f770f78..17f02da1 100644 --- a/include/MStripHit.h +++ b/include/MStripHit.h @@ -144,6 +144,11 @@ class MStripHit void HasGoodTiming(bool GoodTiming) { m_HasGoodTiming = GoodTiming; } //! Return a boolean indicating whether the strip timing is good; bool HasGoodTiming() const { return m_HasGoodTiming; } + + //! Set the Fast Timing flag + void HasFastTiming(bool FastTiming) { m_HasFastTiming = FastTiming; } + //! Return a boolean indicating whether the strip timing is fast; + bool HasFastTiming() const { return m_HasFastTiming; } //! Produce an unsigned int with bitwise values representing flags @@ -202,6 +207,9 @@ class MStripHit //! Flag indicating whether the TAC/timing are reliable bool m_HasGoodTiming; + + //! Flag indicating whether the hit has fast timing + bool m_HasFastTiming; //! Origin IAs from simulations vector m_Origins; diff --git a/src/MGUIOptionsEventSaver.cxx b/src/MGUIOptionsEventSaver.cxx index 76020f67..4546fd82 100644 --- a/src/MGUIOptionsEventSaver.cxx +++ b/src/MGUIOptionsEventSaver.cxx @@ -103,7 +103,11 @@ void MGUIOptionsEventSaver::Create() dynamic_cast(m_Module)->GetSplitFileTime().GetAsSystemSeconds(), true, 0l); if (m_SplitFile->IsOn() == false) m_SplitFileTime->SetEnabled(false); m_OptionsFrame->AddFrame(m_SplitFileTime, SplitFileTimeLayout); - + + m_IncludeNearestNeighborHits = new TGCheckButton(m_OptionsFrame, "Include Nearest Neighbor Hits", 3); + m_IncludeNearestNeighborHits->Associate(this); + m_IncludeNearestNeighborHits->SetOn(dynamic_cast(m_Module)->GetIncludeNearestNeighborHits()); + m_OptionsFrame->AddFrame(m_IncludeNearestNeighborHits, LabelLayout); PostCreate(); } @@ -158,7 +162,8 @@ bool MGUIOptionsEventSaver::OnApply() dynamic_cast(m_Module)->SetAddTimeTag(m_AddTimeTag->IsOn()); dynamic_cast(m_Module)->SetSplitFile(m_SplitFile->IsOn()); dynamic_cast(m_Module)->SetSplitFileTime(MTime(m_SplitFileTime->GetAsInt())); - + dynamic_cast(m_Module)->SetIncludeNearestNeighborHits(m_IncludeNearestNeighborHits->IsOn()); + return true; } diff --git a/src/MModuleEventSaver.cxx b/src/MModuleEventSaver.cxx index 8bace658..f28f004e 100644 --- a/src/MModuleEventSaver.cxx +++ b/src/MModuleEventSaver.cxx @@ -76,6 +76,8 @@ MModuleEventSaver::MModuleEventSaver() : MModule() m_Zip = false; m_SaveBadEvents = true; m_AddTimeTag = false; + + m_IncludeNearestNeighborHits = true; m_SplitFile = true; m_SplitFileTime.Set(60*10); // seconds @@ -302,6 +304,27 @@ bool MModuleEventSaver::AnalyzeEvent(MReadOutAssembly* Event) } else { Choosen = &m_Out; } + + // I think I need to add something here about skipping NN events (if IncludeNearestNeighbors == False) + + if (!m_IncludeNearestNeighborHits) { + std::cout << "Before removal, hit count: " << Event->GetNStripHits() << std::endl; + + for (unsigned int i = 0; i < Event->GetNStripHits();) { + MStripHit* SH = Event->GetStripHit(i); + + // Debug output: check if it's tagged as nearest neighbor + std::cout << "Hit " << i << ": IsNearestNeighbor = " << SH->IsNearestNeighbor() << std::endl; + + if (SH->IsNearestNeighbor()) { + Event->RemoveStripHit(i); + delete SH; + } else { + ++i; + } + } + std::cout << "After removal, hit count: " << Event->GetNStripHits() << std::endl; + } ostringstream Out; if (m_Mode == c_EvtaFile) { @@ -363,6 +386,11 @@ bool MModuleEventSaver::ReadXmlConfiguration(MXmlNode* Node) if (SplitFileTimeNode != 0) { m_SplitFileTime.Set(SplitFileTimeNode->GetValueAsInt()); } + + MXmlNode* IncludeNearestNeighborNode = Node->GetNode("IncludeNearestNeighborHits"); + if (IncludeNearestNeighborNode != nullptr) { + m_IncludeNearestNeighborHits = IncludeNearestNeighborNode->GetValueAsBoolean(); + } return true; } @@ -382,6 +410,7 @@ MXmlNode* MModuleEventSaver::CreateXmlConfiguration() new MXmlNode(Node, "AddTimeTag", m_AddTimeTag); new MXmlNode(Node, "SplitFile", m_SplitFile); new MXmlNode(Node, "SplitFileTime", m_SplitFileTime.GetAsSystemSeconds()); + new MXmlNode(Node, "IncludeNearestNeighborHits", m_IncludeNearestNeighborHits ? "true" : "false"); return Node; } diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx index 408e5fa2..5a625196 100644 --- a/src/MModuleLoaderMeasurementsHDF.cxx +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -374,6 +374,8 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) uint16_t ADCs; uint16_t TACs; uint8_t NumberOfHits; + uint8_t HitType; + uint8_t TimingType; if (m_HDFStripHitVersion == MHDFStripHitVersion::V1_0) { MHDFStripHit_V1_0& Hit = m_Buffer_1_0[m_CurrentBatchIndex]; @@ -386,6 +388,9 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) ADCs = Hit.m_EnergyData; TACs = Hit.m_TimingData; NumberOfHits = Hit.m_Hits; + HitType = Hit.m_HitType; + TimingType = Hit.m_TimingType; + } else if (m_HDFStripHitVersion == MHDFStripHitVersion::V1_2) { MHDFStripHit_V1_2& Hit = m_Buffer_1_2[m_CurrentBatchIndex]; ++m_CurrentBatchIndex; @@ -397,6 +402,9 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) ADCs = Hit.m_EnergyData; TACs = Hit.m_TimingData; NumberOfHits = Hit.m_Hits; + HitType = Hit.m_HitType; + TimingType = Hit.m_TimingType; + } else { if (g_Verbosity >= c_Error) cout<IsLowVoltageStrip(m_StripMap.IsLowVoltage(StripID)); H->SetADCUnits(ADCs); H->SetTAC(TACs); + + // Set boolean flags based on HitType and TimingType + H->IsGuardRing(HitType == 2); + H->IsNearestNeighbor(HitType == 1); + H->HasFastTiming(TimingType == 1); + Event->AddStripHit(H); + } else { if (g_Verbosity >= c_Error) cout< Date: Tue, 10 Jun 2025 12:20:18 -0700 Subject: [PATCH 42/90] CHG: Upodates to roa event saving --- include/MGUIOptionsEventSaver.h | 20 +++++- include/MModuleEventSaver.h | 70 +++++++++++++++++--- include/MReadOutAssembly.h | 2 +- include/MStripHit.h | 2 +- src/MGUIOptionsEventSaver.cxx | 67 ++++++++++++++++--- src/MModuleEventSaver.cxx | 114 +++++++++++++++++++++++--------- src/MReadOutAssembly.cxx | 9 ++- src/MStripHit.cxx | 38 ++++++++--- 8 files changed, 253 insertions(+), 69 deletions(-) diff --git a/include/MGUIOptionsEventSaver.h b/include/MGUIOptionsEventSaver.h index 49d900a6..c6e07880 100644 --- a/include/MGUIOptionsEventSaver.h +++ b/include/MGUIOptionsEventSaver.h @@ -43,6 +43,7 @@ //////////////////////////////////////////////////////////////////////////////// +//! UI for the event saver class MGUIOptionsEventSaver : public MGUIOptions { // public Session: @@ -86,9 +87,22 @@ class MGUIOptionsEventSaver : public MGUIOptions //! Entry field for the time after which to split the file MGUIEEntry* m_SplitFileTime; - // ------- ADDING!!! ------- - //! Checkbutton to include or exclude NN hits - TGCheckButton* m_IncludeNearestNeighborHits; + //! Checkbutton to include or exclude ADCs in the roa file + TGCheckButton* m_RoaWithADCs; + //! Checkbutton to include or exclude TACs in the roa file + TGCheckButton* m_RoaWithTACs; + //! Checkbutton to include or exclude energies in the roa file + TGCheckButton* m_RoaWithEnergies; + //! Checkbutton to include or exclude timings in the roa file + TGCheckButton* m_RoaWithTimings; + //! Checkbutton to include or exclude temperatures in the roa file + TGCheckButton* m_RoaWithTemperatures; + //! Checkbutton to include or exclude flags in the roa file + TGCheckButton* m_RoaWithFlags; + //! Checkbutton to include or exclude origins in the roa file + TGCheckButton* m_RoaWithOrigins; + //! Checkbutton to include or exclude nearest neighbor hits in the roa file + TGCheckButton* m_RoaWithNearestNeighbors; #ifdef ___CLING___ public: diff --git a/include/MModuleEventSaver.h b/include/MModuleEventSaver.h index 47259dbe..81a6a7f6 100644 --- a/include/MModuleEventSaver.h +++ b/include/MModuleEventSaver.h @@ -77,13 +77,47 @@ class MModuleEventSaver : public MModule MTime GetSplitFileTime() const { return m_SplitFileTime; } //! Set the time after which the file should be split void SetSplitFileTime(MTime SplitFileTime) { m_SplitFileTime = SplitFileTime; } - - // --------- ADDING!!! ---------- - //! Return whether nearest neighbor hits should be included - bool GetIncludeNearestNeighborHits() const { return m_IncludeNearestNeighborHits; } - //! Set whether nearest neighbor hits should be included - void SetIncludeNearestNeighborHits(bool Include) { m_IncludeNearestNeighborHits = Include; } - + + //! Return whether ADCs should be included in the roa file + bool GetRoaWithADCs() const { return m_RoaWithADCs; } + //! Set whether ADCs should be included in the roa file + void SetRoaWithADCs(bool Flag) { m_RoaWithADCs = Flag; } + + //! Return whether TACs should be included in the roa file + bool GetRoaWithTACs() const { return m_RoaWithTACs; } + //! Set whether TACs should be included in the roa file + void SetRoaWithTACs(bool Flag) { m_RoaWithTACs = Flag; } + + //! Return whether energies should be included in the roa file + bool GetRoaWithEnergies() const { return m_RoaWithEnergies; } + //! Set whether energies should be included in the roa file + void SetRoaWithEnergies(bool Flag) { m_RoaWithEnergies = Flag; } + + //! Return whether timings should be included in the roa file + bool GetRoaWithTimings() const { return m_RoaWithTimings; } + //! Set whether timings should be included in the roa file + void SetRoaWithTimings(bool Flag) { m_RoaWithTimings = Flag; } + + //! Return whether temperatures should be included in the roa file + bool GetRoaWithTemperatures() const { return m_RoaWithTemperatures; } + //! Set whether temperatures should be included in the roa file + void SetRoaWithTemperatures(bool Flag) { m_RoaWithTemperatures = Flag; } + + //! Return whether flags should be included in the roa file + bool GetRoaWithFlags() const { return m_RoaWithFlags; } + //! Set whether flags should be included in the roa file + void SetRoaWithFlags(bool Flag) { m_RoaWithFlags = Flag; } + + //! Return whether origins should be included in the roa file + bool GetRoaWithOrigins() const { return m_RoaWithOrigins; } + //! Set whether origins should be included in the roa file + void SetRoaWithOrigins(bool Flag) { m_RoaWithOrigins = Flag; } + + //! Return whether nearest neighbors should be included in the roa file + bool GetRoaWithNearestNeighbors() const { return m_RoaWithNearestNeighbors; } + //! Set whether nearest neighbors should be included in the roa file + void SetRoaWithNearestNeighbors(bool Flag) { m_RoaWithNearestNeighbors = Flag; } + //! Set the start area of the far field simulation if there was any void SetStartAreaFarField(double Area) { m_StartAreaFarField = Area; } //! Set the number if simulated events @@ -164,9 +198,25 @@ class MModuleEventSaver : public MModule bool m_SplitFile; //! If we split the file, this is the time in seconds after which we split MTime m_SplitFileTime; - - // ------- ADDING!!! ----------- - bool m_IncludeNearestNeighborHits = true; + + // Roa options + + //! If true write ADC values to the roa file + bool m_RoaWithADCs; + //! If true write TAC values to the roa file + bool m_RoaWithTACs; + //! If true write energy values to the roa file + bool m_RoaWithEnergies; + //! If true write timing values to the roa file + bool m_RoaWithTimings; + //! If true write temperature values to the roa file + bool m_RoaWithTemperatures; + //! If true write flags to the roa file + bool m_RoaWithFlags; + //! If true write origins to the roa file + bool m_RoaWithOrigins; + //! True if we should include next neighbors in the data stream + bool m_RoaWithNearestNeighbors; //! Main output stream for file MFile m_Out; diff --git a/include/MReadOutAssembly.h b/include/MReadOutAssembly.h index 8f5e0fa3..23b408a4 100644 --- a/include/MReadOutAssembly.h +++ b/include/MReadOutAssembly.h @@ -276,7 +276,7 @@ class MReadOutAssembly : public MReadOutSequence //! Stream the content in MEGAlib's evta format void StreamEvta(ostream& S); //! Stream the content in MEGAlib's roa format - void StreamRoa(ostream& S, bool WithDescriptor = true); + 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); //! Build the next MReadoutAssemply from a .dat file bool GetNextFromDatFile(MFile &F); //! Use the info in m_Aspect to turn m_CL into an absolute UTC time diff --git a/include/MStripHit.h b/include/MStripHit.h index 17f02da1..49ec3dfa 100644 --- a/include/MStripHit.h +++ b/include/MStripHit.h @@ -161,7 +161,7 @@ class MStripHit //! Dump the content into a file stream bool StreamDat(ostream& S, int Version = 1); //! Stream the content in MEGAlib's roa format - void StreamRoa(ostream& S); + void StreamRoa(ostream& S, bool WithADC = true, bool WithTAC = true, bool WithEnergy = false, bool WithTiming = false, bool WithTemperature = false, bool WithFlags = false, bool WithOrigins = false); // protected methods: diff --git a/src/MGUIOptionsEventSaver.cxx b/src/MGUIOptionsEventSaver.cxx index 4546fd82..420bbc2d 100644 --- a/src/MGUIOptionsEventSaver.cxx +++ b/src/MGUIOptionsEventSaver.cxx @@ -66,8 +66,9 @@ void MGUIOptionsEventSaver::Create() { PreCreate(); - TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); - + TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 10, 10, 10, 10); + TGLayoutHints* RoaCheckButtonLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 10, 10, 2, 2); + m_Mode = new MGUIERBList(m_OptionsFrame, "Please select an output mode:"); m_Mode->Add("*.roa file to use with melinator"); m_Mode->Add("*.dat file containing all information"); @@ -103,12 +104,50 @@ void MGUIOptionsEventSaver::Create() dynamic_cast(m_Module)->GetSplitFileTime().GetAsSystemSeconds(), true, 0l); if (m_SplitFile->IsOn() == false) m_SplitFileTime->SetEnabled(false); m_OptionsFrame->AddFrame(m_SplitFileTime, SplitFileTimeLayout); - - m_IncludeNearestNeighborHits = new TGCheckButton(m_OptionsFrame, "Include Nearest Neighbor Hits", 3); - m_IncludeNearestNeighborHits->Associate(this); - m_IncludeNearestNeighborHits->SetOn(dynamic_cast(m_Module)->GetIncludeNearestNeighborHits()); - m_OptionsFrame->AddFrame(m_IncludeNearestNeighborHits, LabelLayout); - + + TGLabel* ROAOptionsLabel = new TGLabel(m_OptionsFrame, "Special options for roa files:"); + m_OptionsFrame->AddFrame(ROAOptionsLabel, LabelLayout); + + m_RoaWithADCs = new TGCheckButton(m_OptionsFrame, "Include ADCs (only this option is needed for melinator)", 3); + m_RoaWithADCs->Associate(this); + m_RoaWithADCs->SetOn(dynamic_cast(m_Module)->GetRoaWithADCs()); + m_OptionsFrame->AddFrame(m_RoaWithADCs, RoaCheckButtonLayout); + + m_RoaWithTACs = new TGCheckButton(m_OptionsFrame, "Include TACs", 3); + m_RoaWithTACs->Associate(this); + m_RoaWithTACs->SetOn(dynamic_cast(m_Module)->GetRoaWithTACs()); + m_OptionsFrame->AddFrame(m_RoaWithTACs, RoaCheckButtonLayout); + + m_RoaWithEnergies = new TGCheckButton(m_OptionsFrame, "Include energies", 3); + m_RoaWithEnergies->Associate(this); + m_RoaWithEnergies->SetOn(dynamic_cast(m_Module)->GetRoaWithEnergies()); + m_OptionsFrame->AddFrame(m_RoaWithEnergies, RoaCheckButtonLayout); + + m_RoaWithTimings = new TGCheckButton(m_OptionsFrame, "Include timings", 3); + m_RoaWithTimings->Associate(this); + m_RoaWithTimings->SetOn(dynamic_cast(m_Module)->GetRoaWithTimings()); + m_OptionsFrame->AddFrame(m_RoaWithTimings, RoaCheckButtonLayout); + + m_RoaWithTemperatures = new TGCheckButton(m_OptionsFrame, "Include temperatures", 3); + m_RoaWithTemperatures->Associate(this); + m_RoaWithTemperatures->SetOn(dynamic_cast(m_Module)->GetRoaWithTemperatures()); + m_OptionsFrame->AddFrame(m_RoaWithTemperatures, RoaCheckButtonLayout); + + m_RoaWithFlags = new TGCheckButton(m_OptionsFrame, "Include flags", 3); + m_RoaWithFlags->Associate(this); + m_RoaWithFlags->SetOn(dynamic_cast(m_Module)->GetRoaWithFlags()); + m_OptionsFrame->AddFrame(m_RoaWithFlags, RoaCheckButtonLayout); + + m_RoaWithOrigins = new TGCheckButton(m_OptionsFrame, "Include origins", 3); + m_RoaWithOrigins->Associate(this); + m_RoaWithOrigins->SetOn(dynamic_cast(m_Module)->GetRoaWithOrigins()); + m_OptionsFrame->AddFrame(m_RoaWithOrigins, RoaCheckButtonLayout); + + m_RoaWithNearestNeighbors = new TGCheckButton(m_OptionsFrame, "Include nearest neighbor Hits", 3); + m_RoaWithNearestNeighbors->Associate(this); + m_RoaWithNearestNeighbors->SetOn(dynamic_cast(m_Module)->GetRoaWithNearestNeighbors()); + m_OptionsFrame->AddFrame(m_RoaWithNearestNeighbors, RoaCheckButtonLayout); + PostCreate(); } @@ -157,12 +196,22 @@ bool MGUIOptionsEventSaver::OnApply() // Modify this to store the data in the module! dynamic_cast(m_Module)->SetMode(m_Mode->GetSelected()); + dynamic_cast(m_Module)->SetFileName(m_FileSelector->GetFileName()); + dynamic_cast(m_Module)->SetSaveBadEvents(m_SaveBadEvents->IsOn()); dynamic_cast(m_Module)->SetAddTimeTag(m_AddTimeTag->IsOn()); dynamic_cast(m_Module)->SetSplitFile(m_SplitFile->IsOn()); dynamic_cast(m_Module)->SetSplitFileTime(MTime(m_SplitFileTime->GetAsInt())); - dynamic_cast(m_Module)->SetIncludeNearestNeighborHits(m_IncludeNearestNeighborHits->IsOn()); + + dynamic_cast(m_Module)->SetRoaWithADCs(m_RoaWithADCs->IsOn()); + dynamic_cast(m_Module)->SetRoaWithTACs(m_RoaWithTACs->IsOn()); + dynamic_cast(m_Module)->SetRoaWithEnergies(m_RoaWithEnergies->IsOn()); + dynamic_cast(m_Module)->SetRoaWithTimings(m_RoaWithTimings->IsOn()); + dynamic_cast(m_Module)->SetRoaWithTemperatures(m_RoaWithTemperatures->IsOn()); + dynamic_cast(m_Module)->SetRoaWithFlags(m_RoaWithFlags->IsOn()); + dynamic_cast(m_Module)->SetRoaWithOrigins(m_RoaWithOrigins->IsOn()); + dynamic_cast(m_Module)->SetRoaWithNearestNeighbors(m_RoaWithNearestNeighbors->IsOn()); return true; } diff --git a/src/MModuleEventSaver.cxx b/src/MModuleEventSaver.cxx index f28f004e..ac9c6dd1 100644 --- a/src/MModuleEventSaver.cxx +++ b/src/MModuleEventSaver.cxx @@ -77,8 +77,15 @@ MModuleEventSaver::MModuleEventSaver() : MModule() m_SaveBadEvents = true; m_AddTimeTag = false; - m_IncludeNearestNeighborHits = true; - + m_RoaWithADCs = true; + m_RoaWithTACs = true; + m_RoaWithEnergies = false; + m_RoaWithTimings = false; + m_RoaWithTemperatures = false; + m_RoaWithFlags = false; + m_RoaWithOrigins = false; + m_RoaWithNearestNeighbors = true; + m_SplitFile = true; m_SplitFileTime.Set(60*10); // seconds m_SubFileStart.Set(0); @@ -165,14 +172,42 @@ bool MModuleEventSaver::Initialize() Header<= c_Error) cout<GetNStripHits() << std::endl; - - for (unsigned int i = 0; i < Event->GetNStripHits();) { - MStripHit* SH = Event->GetStripHit(i); - - // Debug output: check if it's tagged as nearest neighbor - std::cout << "Hit " << i << ": IsNearestNeighbor = " << SH->IsNearestNeighbor() << std::endl; - if (SH->IsNearestNeighbor()) { - Event->RemoveStripHit(i); - delete SH; - } else { - ++i; - } - } - std::cout << "After removal, hit count: " << Event->GetNStripHits() << std::endl; - } - ostringstream Out; if (m_Mode == c_EvtaFile) { Event->StreamEvta(Out); } else if (m_Mode == c_DatFile) { Event->StreamDat(Out, 1); } else if (m_Mode == c_RoaFile) { - Event->StreamRoa(Out); + Event->StreamRoa(Out, m_RoaWithADCs, m_RoaWithTACs, m_RoaWithEnergies, m_RoaWithTimings, m_RoaWithTemperatures, m_RoaWithFlags, m_RoaWithOrigins, m_RoaWithNearestNeighbors); } Choosen->Write(Out); @@ -386,10 +400,38 @@ bool MModuleEventSaver::ReadXmlConfiguration(MXmlNode* Node) if (SplitFileTimeNode != 0) { m_SplitFileTime.Set(SplitFileTimeNode->GetValueAsInt()); } - - MXmlNode* IncludeNearestNeighborNode = Node->GetNode("IncludeNearestNeighborHits"); - if (IncludeNearestNeighborNode != nullptr) { - m_IncludeNearestNeighborHits = IncludeNearestNeighborNode->GetValueAsBoolean(); + + MXmlNode* RoaWithADCsNode = Node->GetNode("RoaWithADCs"); + if (RoaWithADCsNode != nullptr) { + m_RoaWithADCs = RoaWithADCsNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithTACsNode = Node->GetNode("RoaWithTACs"); + if (RoaWithTACsNode != nullptr) { + m_RoaWithTACs = RoaWithTACsNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithEnergiesNode = Node->GetNode("RoaWithEnergies"); + if (RoaWithEnergiesNode != nullptr) { + m_RoaWithEnergies = RoaWithEnergiesNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithTimingsNode = Node->GetNode("RoaWithTimings"); + if (RoaWithTimingsNode != nullptr) { + m_RoaWithTimings = RoaWithTimingsNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithTemperaturesNode = Node->GetNode("RoaWithTemperatures"); + if (RoaWithTemperaturesNode != nullptr) { + m_RoaWithTemperatures = RoaWithTemperaturesNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithFlagsNode = Node->GetNode("RoaWithFlags"); + if (RoaWithFlagsNode != nullptr) { + m_RoaWithFlags = RoaWithFlagsNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithOriginsNode = Node->GetNode("RoaWithOrigins"); + if (RoaWithOriginsNode != nullptr) { + m_RoaWithOrigins = RoaWithOriginsNode->GetValueAsBoolean(); + } + MXmlNode* RoaWithNearestNeighborsNode = Node->GetNode("RoaWithNearestNeighbors"); + if (RoaWithNearestNeighborsNode != nullptr) { + m_RoaWithNearestNeighbors = RoaWithNearestNeighborsNode->GetValueAsBoolean(); } return true; @@ -410,7 +452,13 @@ MXmlNode* MModuleEventSaver::CreateXmlConfiguration() new MXmlNode(Node, "AddTimeTag", m_AddTimeTag); new MXmlNode(Node, "SplitFile", m_SplitFile); new MXmlNode(Node, "SplitFileTime", m_SplitFileTime.GetAsSystemSeconds()); - new MXmlNode(Node, "IncludeNearestNeighborHits", m_IncludeNearestNeighborHits ? "true" : "false"); + new MXmlNode(Node, "RoaWithADCs", m_RoaWithADCs); + new MXmlNode(Node, "RoaWithTACs", m_RoaWithTACs); + new MXmlNode(Node, "RoaWithEnergies", m_RoaWithEnergies); + new MXmlNode(Node, "RoaWithTimings", m_RoaWithTimings); + new MXmlNode(Node, "RoaWithFlags", m_RoaWithFlags); + new MXmlNode(Node, "RoaWithOrigins", m_RoaWithOrigins); + new MXmlNode(Node, "RoaWithNearestNeighbors", m_RoaWithNearestNeighbors); return Node; } diff --git a/src/MReadOutAssembly.cxx b/src/MReadOutAssembly.cxx index c9698418..09c9160e 100644 --- a/src/MReadOutAssembly.cxx +++ b/src/MReadOutAssembly.cxx @@ -623,7 +623,7 @@ void MReadOutAssembly::StreamEvta(ostream& S) //////////////////////////////////////////////////////////////////////////////// -void MReadOutAssembly::StreamRoa(ostream& S, bool) +void MReadOutAssembly::StreamRoa(ostream& S, bool WithADCs, bool WithTACs, bool WithEnergies, bool WithTimings, bool WithTemperatures, bool WithFlags, bool WithOrigins, bool WithNearestNeighbors) { //! Stream the content in MEGAlib's evta format @@ -632,7 +632,7 @@ void MReadOutAssembly::StreamRoa(ostream& S, bool) S<<"CL "<StreamEvta(S); } @@ -641,7 +641,10 @@ void MReadOutAssembly::StreamRoa(ostream& S, bool) } for (unsigned int h = 0; h < m_StripHits.size(); ++h) { - m_StripHits[h]->StreamRoa(S); + if (WithNearestNeighbors == false && m_StripHits[h]->IsNearestNeighbor() == true) { + continue; + } + m_StripHits[h]->StreamRoa(S, WithADCs, WithTACs, WithEnergies, WithTimings, WithTemperatures, WithFlags); } // Those are the only BD's relevant for the roa format diff --git a/src/MStripHit.cxx b/src/MStripHit.cxx index 9d5727e0..fc4860a8 100644 --- a/src/MStripHit.cxx +++ b/src/MStripHit.cxx @@ -192,21 +192,41 @@ bool MStripHit::StreamDat(ostream& S, int Version) //////////////////////////////////////////////////////////////////////////////// -void MStripHit::StreamRoa(ostream& S) +void MStripHit::StreamRoa(ostream& S, bool WithADC, bool WithTAC, bool WithEnergy, bool WithTiming, bool WithTemperature, bool WithFlags, bool WithOrigins) { //! Stream the content in MEGAlib's evta format S<<"UH " <GetDetectorID()<<" " <GetStripID()<<" " - <<((m_ReadOutElement->IsLowVoltageStrip() == true) ? "l" : "h")<<" " - <IsLowVoltageStrip() == true) ? "l" : "h")<<" "; + if (WithADC == true) { + S< Date: Tue, 10 Jun 2025 13:28:50 -0700 Subject: [PATCH 43/90] CHG: Merged Sean's pull request by hand and added more sanity check --- include/MStripHit.h | 20 +++---- src/MGUIOptionsEventSaver.cxx | 2 +- src/MModuleEventSaver.cxx | 21 ++++--- src/MModuleTACcut.cxx | 36 ++++++++++-- src/MReadOutAssembly.cxx | 5 ++ src/MStripHit.cxx | 100 ++++++++++++++-------------------- 6 files changed, 99 insertions(+), 85 deletions(-) diff --git a/include/MStripHit.h b/include/MStripHit.h index 49ec3dfa..bb72b792 100644 --- a/include/MStripHit.h +++ b/include/MStripHit.h @@ -139,18 +139,17 @@ class MStripHit void IsNearestNeighbor(bool NearestNeighbor) { m_IsNearestNeighbor = NearestNeighbor; } //! Return a boolean indicating whether the strip is a Nearest Neighbor bool IsNearestNeighbor() const { return m_IsNearestNeighbor; } - - //! Set the Good Timing flag - void HasGoodTiming(bool GoodTiming) { m_HasGoodTiming = GoodTiming; } - //! Return a boolean indicating whether the strip timing is good; - bool HasGoodTiming() const { return m_HasGoodTiming; } //! Set the Fast Timing flag void HasFastTiming(bool FastTiming) { m_HasFastTiming = FastTiming; } //! Return a boolean indicating whether the strip timing is fast; bool HasFastTiming() const { return m_HasFastTiming; } - - + + //! Set the Calibrated Timing flag + void HasCalibratedTiming(bool CalibratedTiming) { m_HasCalibratedTiming = CalibratedTiming; } + //! Return a boolean indicating whether the strip timing has been calibrated; + bool HasCalibratedTiming() const { return m_HasCalibratedTiming; } + //! Produce an unsigned int with bitwise values representing flags unsigned int MakeFlags(); //! Read in unsigned int with bitwise values representing flags and update boolean flags @@ -205,12 +204,11 @@ class MStripHit bool m_IsGuardRing; bool m_IsNearestNeighbor; - //! Flag indicating whether the TAC/timing are reliable - bool m_HasGoodTiming; - //! Flag indicating whether the hit has fast timing bool m_HasFastTiming; - + //! Flag indicating whether the hit has calibrated timing + bool m_HasCalibratedTiming; + //! Origin IAs from simulations vector m_Origins; diff --git a/src/MGUIOptionsEventSaver.cxx b/src/MGUIOptionsEventSaver.cxx index 420bbc2d..7cf81915 100644 --- a/src/MGUIOptionsEventSaver.cxx +++ b/src/MGUIOptionsEventSaver.cxx @@ -108,7 +108,7 @@ void MGUIOptionsEventSaver::Create() TGLabel* ROAOptionsLabel = new TGLabel(m_OptionsFrame, "Special options for roa files:"); m_OptionsFrame->AddFrame(ROAOptionsLabel, LabelLayout); - m_RoaWithADCs = new TGCheckButton(m_OptionsFrame, "Include ADCs (only this option is needed for melinator)", 3); + m_RoaWithADCs = new TGCheckButton(m_OptionsFrame, "Include ADCs", 3); m_RoaWithADCs->Associate(this); m_RoaWithADCs->SetOn(dynamic_cast(m_Module)->GetRoaWithADCs()); m_OptionsFrame->AddFrame(m_RoaWithADCs, RoaCheckButtonLayout); diff --git a/src/MModuleEventSaver.cxx b/src/MModuleEventSaver.cxx index ac9c6dd1..ed10bb0b 100644 --- a/src/MModuleEventSaver.cxx +++ b/src/MModuleEventSaver.cxx @@ -181,32 +181,39 @@ bool MModuleEventSaver::Initialize() Header<<"UF doublesidedstrip "; bool IsFirst = true; if (m_RoaWithADCs == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"adc"; + IsFirst = false; } if (m_RoaWithTACs == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"tac"; + IsFirst = false; } if (m_RoaWithEnergies == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"energy"; + IsFirst = false; } if (m_RoaWithTimings == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"timing"; + IsFirst = false; } if (m_RoaWithTemperatures == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"temperature"; + IsFirst = false; } if (m_RoaWithFlags == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"flags"; + IsFirst = false; } if (m_RoaWithOrigins == true) { - if (IsFirst) Header<<"_"; + if (IsFirst == false) Header<<"_"; Header<<"origins"; + IsFirst = false; } Header<GetNStripHits(); ++i) { + MStripHit* SH = Event->GetStripHit(i); + + int DetID = SH->GetDetectorID(); + int StripID = SH->GetStripID(); + + if (DetID >= m_LVTACCal.size()) { + cout<= m_LVTACCal[DetID].size()) { + cout<= m_HVTACCal.size()) { + cout<= m_HVTACCal[DetID].size()) { + cout<::max(); for (unsigned int i = 0; i < Event->GetNStripHits(); ++i) { diff --git a/src/MReadOutAssembly.cxx b/src/MReadOutAssembly.cxx index 09c9160e..69d5838e 100644 --- a/src/MReadOutAssembly.cxx +++ b/src/MReadOutAssembly.cxx @@ -640,11 +640,16 @@ void MReadOutAssembly::StreamRoa(ostream& S, bool WithADCs, bool WithTACs, bool S<IsNearestNeighbor() == true) { continue; } m_StripHits[h]->StreamRoa(S, WithADCs, WithTACs, WithEnergies, WithTimings, WithTemperatures, WithFlags); + ++Counter; + } + if (Counter == 0) { + S<<"BD No strip hits"< tokens = Line.Tokenize(" "); - if( tokens.size() >= 10 ){ - SetDetectorID(tokens.at(1).ToInt()); - tokens.at(2) == "p" ? IsLowVoltageStrip(true) : IsLowVoltageStrip(false); - SetStripID(tokens.at(3).ToInt()); - tokens.at(4) == "0" ? HasTriggered(false) : HasTriggered(true); - SetTiming( tokens.at(5).ToDouble() ); - SetUncorrectedADCUnits( tokens.at(6).ToDouble() ); - SetADCUnits( tokens.at(7).ToDouble() ); - SetEnergy( tokens.at(8).ToDouble() ); - SetEnergyResolution( tokens.at(9).ToDouble() ); - int det_id, pos_strip, strip_id - return true; + return true; } else { - return false; + return false; } - */ } @@ -239,16 +213,20 @@ unsigned int MStripHit::MakeFlags() { //! Return flags to indicate the type of strip hit //! Currently, 2 bits: - //! v = Is a nearest neighbor - //! v = Is a guard ring - //! 0b11u + //! v = Has fast timing + //! v = Is a nearest neighbor + //! v = Is a guard ring + //! 0b111u - unsigned int Flags = 0b00u; + unsigned int Flags = 0b000u; if (m_IsGuardRing == true) { - Flags = Flags | 0b01u; + Flags = Flags | 0b001u; } if (m_IsNearestNeighbor == true) { - Flags = Flags | 0b10u; + Flags = Flags | 0b010u; + } + if (m_HasFastTiming == true) { + Flags = Flags | 0b100u; } return Flags; @@ -261,13 +239,15 @@ unsigned int MStripHit::MakeFlags() void MStripHit::ParseFlags(unsigned int Flags) { //! Set internal booleans according to flag - //! Currently, 2 bits: - //! v = Is a nearest neighbor - //! v = Is a guard ring - //! 0b11u - - IsGuardRing(Flags & 0b01u); - IsNearestNeighbor(Flags & 0b10u); + //! Currently, 3 bits: + //! v = Has fast timing + //! v = Is a nearest neighbor + //! v = Is a guard ring + //! 0b111u + + IsGuardRing(Flags & 0b001u); + IsNearestNeighbor(Flags & 0b010u); + HasFastTiming(Flags & 0b100u); } From 69ae1d6144e14596768b31ada16c9754b44e2ac9 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 10 Jun 2025 13:44:23 -0700 Subject: [PATCH 44/90] CHG: Handle Side (LV and HV) more consistently by explicitly mapping characters to TAC Cal/Cut indices --- include/MModuleTACcut.h | 3 +++ src/MModuleTACcut.cxx | 57 ++++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/include/MModuleTACcut.h b/include/MModuleTACcut.h index 4739404e..b13415e4 100644 --- a/include/MModuleTACcut.h +++ b/include/MModuleTACcut.h @@ -124,6 +124,9 @@ MString m_TACCutFile; unordered_map>>> m_TACCal; unordered_map>>> m_TACCut; +//! Map characters representing sides of the detectors indices to avoid mistakes +unordered_map m_SideToIndex; + vector m_DetectorIDs; MGUIExpoTACcut* m_ExpoTACcut; diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index e1029fae..9c1f7c58 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -85,6 +85,7 @@ MModuleTACcut::MModuleTACcut() : MModule() m_DisableTime = 1396; m_FlagToEnDelay = 104; + m_SideToIndex = {{'l', 0}, {'h', 1}, {'0', 0}, {'1', 1}, {'p', 0}, {'n', 1}}; } @@ -160,16 +161,16 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) double ns_timing = 0; int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); - int Side = SH->IsLowVoltageStrip() ? 0 : 1; + char Side = SH->IsLowVoltageStrip() ? 'l' : 'h'; if ((TAC_timing == 0) || (SH->IsGuardRing() == true) || (SH->IsNearestNeighbor() == true)) { SH->HasGoodTiming(false); } else { if (m_TACCal.find(DetID) != m_TACCal.end()) { - if (m_TACCal[DetID][Side].find(StripID) != m_TACCal[DetID][Side].end()) { - ns_timing = TAC_timing*m_TACCal[DetID][Side][StripID][0] + m_TACCal[DetID][Side][StripID][1]; + if (m_TACCal[DetID][m_SideToIndex[Side]].find(StripID) != m_TACCal[DetID][m_SideToIndex[Side]].end()) { + ns_timing = TAC_timing*m_TACCal[DetID][m_SideToIndex[Side]][StripID][0] + m_TACCal[DetID][m_SideToIndex[Side]][StripID][1]; SH->HasGoodTiming(true); } else { - if (Side==0) { + if (Side=='l') { cout<<"MModuleTACcut: Unable to find LV Strip ID "<GetTiming(); int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); - int Side = SH->IsLowVoltageStrip() ? 0 : 1; + char Side = SH->IsLowVoltageStrip() ? 'l' : 'h'; if (m_TACCut.find(DetID) != m_TACCut.end()) { - if (m_TACCut[DetID][Side].find(StripID) != m_TACCut[DetID][Side].end()) { - double ShapingOffset = m_TACCut[DetID][Side][StripID][0]; - double CoincidenceWindow = m_TACCut[DetID][Side][StripID][1]; + if (m_TACCut[DetID][m_SideToIndex[Side]].find(StripID) != m_TACCut[DetID][m_SideToIndex[Side]].end()) { + double ShapingOffset = m_TACCut[DetID][m_SideToIndex[Side]][StripID][0]; + double CoincidenceWindow = m_TACCut[DetID][m_SideToIndex[Side]][StripID][1]; double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; if ((SHTiming < TotalOffset + CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - CoincidenceWindow)){ if (HasExpos()==true) { @@ -209,17 +210,15 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) delete SH; } } else { - if (Side==0) { + if (Side=='l') { cout<<"MModuleTACcut: Unable to find LV Strip ID "<HasGoodTiming(false); ++i; } } else { - cout<<"MModuleTACcut: Unable to find Det ID "<HasGoodTiming(false); + cout<<"MModuleTACcut: Unable to find Det ID "< Tokens = Line.Tokenize(","); if (Tokens.size() == 5) { int DetID = Tokens[0].ToInt(); + MString SideString = Tokens[1].Trim(); + char Side; + if (SideString.Length()!=1) { + cout<<"MModuleTACcut: Expected 1 character Side, got string: "< Date: Wed, 11 Jun 2025 15:52:51 -0700 Subject: [PATCH 45/90] CHG: Updated TAC cut and sanity checks --- src/MModuleTACcut.cxx | 102 +++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index d74e4df1..e578a906 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -159,21 +159,22 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); + char Side = SH->IsLowVoltageStrip() ? 'l' : 'h'; - if (DetID >= m_LVTACCal.size()) { - cout<= m_TACCal.size()) { + cout<= m_LVTACCal[DetID].size()) { - cout<= m_TACCal[DetID][m_SideToIndex[Side]].size()) { + cout<= m_HVTACCal.size()) { - cout<= m_TACCut.size()) { + cout<= m_HVTACCal[DetID].size()) { - cout<= m_TACCut[DetID][m_SideToIndex[Side]].size()) { + cout<GetDetectorID(); int StripID = SH->GetStripID(); char Side = SH->IsLowVoltageStrip() ? 'l' : 'h'; - if ((TAC_timing == 0) || (SH->IsGuardRing() == true) || (SH->IsNearestNeighbor() == true)) { - SH->HasGoodTiming(false); + if ((TAC_timing == 0) || (SH->IsGuardRing() == true)) { + SH->HasCalibratedTiming(false); } else { - if (m_TACCal.find(DetID) != m_TACCal.end()) { - if (m_TACCal[DetID][m_SideToIndex[Side]].find(StripID) != m_TACCal[DetID][m_SideToIndex[Side]].end()) { - ns_timing = TAC_timing*m_TACCal[DetID][m_SideToIndex[Side]][StripID][0] + m_TACCal[DetID][m_SideToIndex[Side]][StripID][1]; - SH->HasGoodTiming(true); - } else { - if (Side=='l') { - cout<<"MModuleTACcut: Unable to find LV Strip ID "<HasGoodTiming(false); - } - } else { - cout<<"MModuleTACcut: Unable to find Det ID "<HasGoodTiming(false); - } + ns_timing = TAC_timing*m_TACCal[DetID][m_SideToIndex[Side]][StripID][0] + m_TACCal[DetID][m_SideToIndex[Side]][StripID][1]; + SH->HasCalibratedTiming(true); } SH->SetTiming(ns_timing); - if ((SH->HasGoodTiming()==true) && (ns_timing > MaxTAC)) { + if ((SH->HasCalibratedTiming()==true) && (ns_timing > MaxTAC) && (SH->HasFastTiming()==true) && (SH->IsNearestNeighbor()==false)) { MaxTAC = ns_timing; } } for (unsigned int i = 0; i < Event->GetNStripHits();) { MStripHit* SH = Event->GetStripHit(i); - if ((SH->HasGoodTiming() == true) && (SH->IsNearestNeighbor()==false) && (SH->IsGuardRing()==false)) { + bool Passed = true; + if ((SH->HasCalibratedTiming() == true) && (SH->IsGuardRing()==false)) { double SHTiming = SH->GetTiming(); int DetID = SH->GetDetectorID(); int StripID = SH->GetStripID(); char Side = SH->IsLowVoltageStrip() ? 'l' : 'h'; - if (m_TACCut.find(DetID) != m_TACCut.end()) { - if (m_TACCut[DetID][m_SideToIndex[Side]].find(StripID) != m_TACCut[DetID][m_SideToIndex[Side]].end()) { - double ShapingOffset = m_TACCut[DetID][m_SideToIndex[Side]][StripID][0]; - double CoincidenceWindow = m_TACCut[DetID][m_SideToIndex[Side]][StripID][1]; - double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; - if ((SHTiming < TotalOffset + CoincidenceWindow) && (SHTiming > TotalOffset) && (SHTiming > MaxTAC - CoincidenceWindow)){ - if (HasExpos()==true) { - m_ExpoTACcut->AddTAC(DetID, SHTiming); - } - ++i; - } else { - Event->RemoveStripHit(i); - delete SH; - } - } else { - if (Side=='l') { - cout<<"MModuleTACcut: Unable to find LV Strip ID "<HasFastTiming()==true) { + double ShapingOffset = m_TACCut[DetID][m_SideToIndex[Side]][StripID][0]; + double CoincidenceWindow = m_TACCut[DetID][m_SideToIndex[Side]][StripID][1]; + double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; + if ((SHTiming > TotalOffset + CoincidenceWindow) || (SHTiming < TotalOffset) || (SHTiming < MaxTAC - CoincidenceWindow)) { + Passed = false; } - } else { - cout<<"MModuleTACcut: Unable to find Det ID "<AddTAC(DetID, SHTiming); + } + } + } + if (Passed == true) { ++i; + } else { + Event->RemoveStripHit(i); + delete SH; } } @@ -338,7 +320,7 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) // ReadOutID, Detector, Side, Strip, TAC cal, TAC cal error, TAC offset, TAC offset error MFile F; if (F.Open(FName) == false) { - cout << "MModuleTACcut: failed to open TAC Calibration file." << endl; + cout<<"MModuleTACcut: failed to open TAC Calibration file."< Tokens = Line.Tokenize(","); - if (Tokens.size() == 5) { + if ((Tokens.size() == 5) || (Tokens.size() == 6)) { int DetID = Tokens[0].ToInt(); MString SideString = Tokens[1].Trim(); char Side; @@ -424,8 +407,13 @@ bool MModuleTACcut::LoadTACCutFile(MString FName) int StripID = Tokens[2].ToInt(); double ShapingOffset = Tokens[3].ToDouble(); double CoincidenceWindow = Tokens[4].ToDouble(); + double FLNoiseCut = 100; // Old file format did not include a FLNoise Cut. Default to 100ns if not present in the file. + if (Tokens.size()==6) { + FLNoiseCut = Tokens[5].ToDouble(); + FLNoiseCutIncluded = true; + } vector CutParams; - CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); + CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); CutParams.push_back(FLNoiseCut); if (m_TACCut.find(DetID) == m_TACCut.end()) { vector>> TempVector; @@ -441,7 +429,7 @@ bool MModuleTACcut::LoadTACCutFile(MString FName) } if (m_SideToIndex.find(Side) != m_SideToIndex.end()) { - m_TACCut[DetID][m_SideToIndex[Side]][StripID] = CalValues; + m_TACCut[DetID][m_SideToIndex[Side]][StripID] = CutParams; } else { cout<<"MModuleTACcut: Unable to identify Side "< Date: Wed, 11 Jun 2025 16:06:49 -0700 Subject: [PATCH 46/90] typo in GUI --- src/MGUIOptionsTACcut.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MGUIOptionsTACcut.cxx b/src/MGUIOptionsTACcut.cxx index 2ea49d88..87b62590 100644 --- a/src/MGUIOptionsTACcut.cxx +++ b/src/MGUIOptionsTACcut.cxx @@ -86,7 +86,7 @@ void MGUIOptionsTACcut::Create() m_OptionsFrame->AddFrame(m_TACCutFileSelector, TACCutLayout); TGLayoutHints* DisableTimeLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); - m_DisableTime = new MGUIEEntry(m_OptionsFrame, "Diable Time [ns]:", false, dynamic_cast(m_Module)->GetDisableTime(), false, -numeric_limits::max()/2, numeric_limits::max()/2); + m_DisableTime = new MGUIEEntry(m_OptionsFrame, "Disable Time [ns]:", false, dynamic_cast(m_Module)->GetDisableTime(), false, -numeric_limits::max()/2, numeric_limits::max()/2); m_OptionsFrame->AddFrame(m_DisableTime, DisableTimeLayout); TGLayoutHints* FlagToEnDelayLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); From ecadce8e720147ddbb5d3a869365200949cf9fb9 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 11 Jun 2025 16:36:15 -0700 Subject: [PATCH 47/90] CHG: Don't skip events just because they contain guard ring strip hits --- src/MModuleTACcut.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index e578a906..71f5e6d6 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -165,7 +165,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) cout<= m_TACCal[DetID][m_SideToIndex[Side]].size()) { + if ((SH->IsGuardRing()==false) && (StripID >= m_TACCal[DetID][m_SideToIndex[Side]].size())) { cout<= m_TACCut[DetID][m_SideToIndex[Side]].size()) { + if ((SH->IsGuardRing()==false) && (StripID >= m_TACCut[DetID][m_SideToIndex[Side]].size())) { cout< Date: Wed, 11 Jun 2025 16:41:27 -0700 Subject: [PATCH 48/90] CHG: Removed nearest neighbor filter hack --- src/MModuleEnergyCalibrationUniversal.cxx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/MModuleEnergyCalibrationUniversal.cxx b/src/MModuleEnergyCalibrationUniversal.cxx index a0d3be0c..8d705851 100644 --- a/src/MModuleEnergyCalibrationUniversal.cxx +++ b/src/MModuleEnergyCalibrationUniversal.cxx @@ -395,17 +395,6 @@ bool MModuleEnergyCalibrationUniversal::AnalyzeEvent(MReadOutAssembly* Event) } } - for (unsigned int i = 0; i < Event->GetNStripHits(); ) { - MStripHit* SH = Event->GetStripHit(i); - if (SH->GetEnergy() < 8) { - Event->RemoveStripHit(i); - delete SH; - } else { - ++i; - } - } - - Event->SetAnalysisProgress(MAssembly::c_EnergyCalibration); return true; From f3a0014d8819c8056290293ef447910aac2138e3 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Thu, 12 Jun 2025 10:07:49 -0700 Subject: [PATCH 49/90] Revert "CHG: Don't skip events just because they contain guard ring strip hits" This reverts commit ecadce8e720147ddbb5d3a869365200949cf9fb9. --- src/MModuleTACcut.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 71f5e6d6..e578a906 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -165,7 +165,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) cout<IsGuardRing()==false) && (StripID >= m_TACCal[DetID][m_SideToIndex[Side]].size())) { + if (StripID >= m_TACCal[DetID][m_SideToIndex[Side]].size()) { cout<IsGuardRing()==false) && (StripID >= m_TACCut[DetID][m_SideToIndex[Side]].size())) { + if (StripID >= m_TACCut[DetID][m_SideToIndex[Side]].size()) { cout< Date: Fri, 13 Jun 2025 14:49:11 -0700 Subject: [PATCH 50/90] CHG: Don't plot slow timing --- src/MModuleTACcut.cxx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index e578a906..99fad923 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -216,10 +216,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; if ((SHTiming > TotalOffset + CoincidenceWindow) || (SHTiming < TotalOffset) || (SHTiming < MaxTAC - CoincidenceWindow)) { Passed = false; - } - } - if (Passed==true) { - if (HasExpos()==true) { + } else if (HasExpos()==true) { m_ExpoTACcut->AddTAC(DetID, SHTiming); } } From 9a838980ec7f0c8749b9fec020575dd4a7792856 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 17 Jun 2025 14:59:11 -0700 Subject: [PATCH 51/90] CHG: Moved all TAC cut parameters into the input file rather than having additional input boxes. --- include/MGUIOptionsTACcut.h | 8 ---- include/MModuleTACcut.h | 13 +----- src/MGUIOptionsTACcut.cxx | 10 ----- src/MModuleTACcut.cxx | 82 +++++++++++++++++++------------------ 4 files changed, 44 insertions(+), 69 deletions(-) diff --git a/include/MGUIOptionsTACcut.h b/include/MGUIOptionsTACcut.h index 86575a41..d83df4cd 100644 --- a/include/MGUIOptionsTACcut.h +++ b/include/MGUIOptionsTACcut.h @@ -69,14 +69,6 @@ class MGUIOptionsTACcut : public MGUIOptions protected: //! The detector IDs as a string TGTextEntry* m_Detectors; - //! The total TAC selection - MGUIEMinMaxEntry* m_TAC; - - //! FPGA setting of time between FLAG rising and ENABLE falling - MGUIEEntry* m_DisableTime; - - //! internal FPGA delay between FLAG rising and FPGA reacting - MGUIEEntry* m_FlagToEnDelay; //! Select TAC Calibration file to load, converts readout timing to nanoseconds MGUIEFileSelector* m_TACCalFileSelector; diff --git a/include/MModuleTACcut.h b/include/MModuleTACcut.h index b13415e4..7bf3836a 100644 --- a/include/MModuleTACcut.h +++ b/include/MModuleTACcut.h @@ -80,16 +80,6 @@ class MModuleTACcut : public MModule //! Get filename for TAC Cut MString GetTACCutFileName() const {return m_TACCutFile;} - //! Set the disable time - void SetDisableTime(double DisableTime) { m_DisableTime = DisableTime; } - //! Get the disable time - unsigned int GetDisableTime() const { return m_DisableTime; } - - //! Set the shaping flag_to_en_delay - void SetFlagToEnDelay(double FlagToEnDelay) { m_FlagToEnDelay = FlagToEnDelay; } - //! Get the shaping flag_to_en_delay - unsigned int GetFlagToEnDelay() const { return m_FlagToEnDelay; } - //! Load the TAC calibration file bool LoadTACCalFile(MString FName); @@ -115,8 +105,7 @@ class MModuleTACcut : public MModule // private members: private: -// declare TAC Cut and calibration variables here -double m_DisableTime, m_FlagToEnDelay; +//! TAC cut and TAC calibration parameter files MString m_TACCalFile; MString m_TACCutFile; diff --git a/src/MGUIOptionsTACcut.cxx b/src/MGUIOptionsTACcut.cxx index 87b62590..e410d65b 100644 --- a/src/MGUIOptionsTACcut.cxx +++ b/src/MGUIOptionsTACcut.cxx @@ -84,14 +84,6 @@ void MGUIOptionsTACcut::Create() m_TACCutFileSelector->SetFileType("TAC", "*.csv"); TGLayoutHints* TACCutLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); m_OptionsFrame->AddFrame(m_TACCutFileSelector, TACCutLayout); - - TGLayoutHints* DisableTimeLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); - m_DisableTime = new MGUIEEntry(m_OptionsFrame, "Disable Time [ns]:", false, dynamic_cast(m_Module)->GetDisableTime(), false, -numeric_limits::max()/2, numeric_limits::max()/2); - m_OptionsFrame->AddFrame(m_DisableTime, DisableTimeLayout); - - TGLayoutHints* FlagToEnDelayLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 30, 10, 0, 10); - m_FlagToEnDelay = new MGUIEEntry(m_OptionsFrame, "FLAG to ENABLE delay [ns]:", false, dynamic_cast(m_Module)->GetFlagToEnDelay(), false, -numeric_limits::max()/2, numeric_limits::max()/2); - m_OptionsFrame->AddFrame(m_FlagToEnDelay, FlagToEnDelayLayout); PostCreate(); } @@ -136,8 +128,6 @@ bool MGUIOptionsTACcut::OnApply() // Store the data in the module dynamic_cast(m_Module)->SetTACCalFileName(m_TACCalFileSelector->GetFileName()); dynamic_cast(m_Module)->SetTACCutFileName(m_TACCutFileSelector->GetFileName()); - dynamic_cast(m_Module)->SetDisableTime(m_DisableTime->GetAsDouble()); - dynamic_cast(m_Module)->SetFlagToEnDelay(m_FlagToEnDelay->GetAsDouble()); return true; } diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 99fad923..4046b350 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -83,8 +83,6 @@ MModuleTACcut::MModuleTACcut() : MModule() // Can we use multiple instances of this class m_AllowMultipleInstances = false; - m_DisableTime = 1396; - m_FlagToEnDelay = 104; m_SideToIndex = {{'l', 0}, {'h', 1}, {'0', 0}, {'1', 1}, {'p', 0}, {'n', 1}}; } @@ -111,7 +109,7 @@ bool MModuleTACcut::Initialize() } if (LoadTACCutFile(m_TACCutFile) == false) { - cout<SetTACHistogramArrangement(m_DetectorIDs); for (unsigned int i = 0; i < m_DetectorIDs.size(); ++i) { unsigned int DetID = m_DetectorIDs[i]; - m_ExpoTACcut->SetTACHistogramParameters(DetID, 120, 0, 7000); + m_ExpoTACcut->SetTACHistogramParameters(DetID, 200, 0, 6000); } m_Expos.push_back(m_ExpoTACcut); } @@ -166,7 +164,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) return false; } if (StripID >= m_TACCal[DetID][m_SideToIndex[Side]].size()) { - cout<= m_TACCut.size()) { @@ -174,7 +172,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) return false; } if (StripID >= m_TACCut[DetID][m_SideToIndex[Side]].size()) { - cout<GetDetectorID(); int StripID = SH->GetStripID(); char Side = SH->IsLowVoltageStrip() ? 'l' : 'h'; - double FLNoiseCut = m_TACCut[DetID][m_SideToIndex[Side]][StripID][2]; + double FLNoiseCut = m_TACCut[DetID][m_SideToIndex[Side]][StripID][4]; if ((SHTiming < FLNoiseCut)) { Passed = false; } else if (SH->HasFastTiming()==true) { double ShapingOffset = m_TACCut[DetID][m_SideToIndex[Side]][StripID][0]; double CoincidenceWindow = m_TACCut[DetID][m_SideToIndex[Side]][StripID][1]; - double TotalOffset = ShapingOffset + m_DisableTime + m_FlagToEnDelay; + double DisableTime = m_TACCut[DetID][m_SideToIndex[Side]][StripID][2]; + double FlagToEnDelay = m_TACCut[DetID][m_SideToIndex[Side]][StripID][3]; + double FlagDelay = m_TACCut[DetID][m_SideToIndex[Side]][StripID][5]; + double TotalOffset = ShapingOffset + DisableTime + FlagToEnDelay + FlagDelay; if ((SHTiming > TotalOffset + CoincidenceWindow) || (SHTiming < TotalOffset) || (SHTiming < MaxTAC - CoincidenceWindow)) { Passed = false; } else if (HasExpos()==true) { @@ -274,16 +275,6 @@ bool MModuleTACcut::ReadXmlConfiguration(MXmlNode* Node) SetTACCutFileName(TACCutFileNameNode->GetValue()); } - MXmlNode* DisableTimeNode = Node->GetNode("DisableTime"); - if (DisableTimeNode != nullptr) { - m_DisableTime = DisableTimeNode->GetValueAsDouble(); - } - - MXmlNode* FlagToEnDelayNode = Node->GetNode("FlagToEnDelay"); - if (FlagToEnDelayNode != nullptr) { - m_FlagToEnDelay = FlagToEnDelayNode->GetValueAsDouble(); - } - return true; } @@ -299,8 +290,6 @@ MXmlNode* MModuleTACcut::CreateXmlConfiguration() new MXmlNode(Node, "TACCalFileName", m_TACCalFile); new MXmlNode(Node, "TACCutFileName", m_TACCutFile); - new MXmlNode(Node, "DisableTime", m_DisableTime); - new MXmlNode(Node, "FlagToEnDelay", m_FlagToEnDelay); return Node; } @@ -317,7 +306,7 @@ bool MModuleTACcut::LoadTACCalFile(MString FName) // ReadOutID, Detector, Side, Strip, TAC cal, TAC cal error, TAC offset, TAC offset error MFile F; if (F.Open(FName) == false) { - cout<<"MModuleTACcut: failed to open TAC Calibration file."< Tokens = Line.Tokenize(","); - if ((Tokens.size() == 5) || (Tokens.size() == 6)) { + if (Tokens.size() >= 5) { int DetID = Tokens[0].ToInt(); - MString SideString = Tokens[1].Trim(); + MString SideString = Tokens[1]; char Side; if (SideString.Length()!=1) { - cout<<"MModuleTACcut: Expected 1 character Side, got string: "< CutParams; - CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); CutParams.push_back(FLNoiseCut); + CutParams.push_back(ShapingOffset); CutParams.push_back(CoincidenceWindow); CutParams.push_back(DisableTime); CutParams.push_back(FlagToEnDelay); CutParams.push_back(FLNoiseCut); CutParams.push_back(FlagDelay); if (m_TACCut.find(DetID) == m_TACCut.end()) { vector>> TempVector; @@ -428,7 +431,8 @@ bool MModuleTACcut::LoadTACCutFile(MString FName) if (m_SideToIndex.find(Side) != m_SideToIndex.end()) { m_TACCut[DetID][m_SideToIndex[Side]][StripID] = CutParams; } else { - cout<<"MModuleTACcut: Unable to identify Side "< Date: Fri, 20 Jun 2025 19:33:41 -0700 Subject: [PATCH 52/90] BUG: Repeated reading the same file if continuation was selected --- src/MModuleLoaderMeasurementsHDF.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx index 5a625196..88d4433e 100644 --- a/src/MModuleLoaderMeasurementsHDF.cxx +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -147,7 +147,7 @@ bool MModuleLoaderMeasurementsHDF::OpenHDF5File(MString FileName) { try { // HDF5 throws exceptions, thus need to encapsulate everything in try..catch - m_HDFFile = H5File(m_FileName, H5F_ACC_RDONLY); + m_HDFFile = H5File(FileName, H5F_ACC_RDONLY); // ToDo: Check for version. m_HDFStripHitVersion = MHDFStripHitVersion::V1_0; From db6ca23ae9dd351f6a4033eff02111a1572027ec Mon Sep 17 00:00:00 2001 From: ckierans Date: Wed, 25 Jun 2025 15:01:00 -0400 Subject: [PATCH 53/90] Updated guard ring and shield veto flag, added save option for events with veto --- include/MGUIOptionsEventSaver.h | 3 +++ include/MModuleEventSaver.h | 12 +++++++-- include/MReadOutAssembly.h | 34 +++++++++---------------- src/MBinaryFlightDataParser.cxx | 8 +++--- src/MGUIOptionsEventSaver.cxx | 5 ++++ src/MModuleEventSaver.cxx | 11 +++++++++ src/MModuleLoaderMeasurementsHDF.cxx | 7 ++++-- src/MModuleTACcut.cxx | 2 +- src/MReadOutAssembly.cxx | 37 ++++++++++++++++++++++++++-- 9 files changed, 86 insertions(+), 33 deletions(-) diff --git a/include/MGUIOptionsEventSaver.h b/include/MGUIOptionsEventSaver.h index c6e07880..47eff234 100644 --- a/include/MGUIOptionsEventSaver.h +++ b/include/MGUIOptionsEventSaver.h @@ -79,6 +79,9 @@ class MGUIOptionsEventSaver : public MGUIOptions //! Checkbutton to save or reject bad events TGCheckButton* m_SaveBadEvents; + //! Checkbutton to save veto events + TGCheckButton* m_SaveVetoEvents; + //! Checkbutton to add a time tag TGCheckButton* m_AddTimeTag; diff --git a/include/MModuleEventSaver.h b/include/MModuleEventSaver.h index 81a6a7f6..7211f27d 100644 --- a/include/MModuleEventSaver.h +++ b/include/MModuleEventSaver.h @@ -58,10 +58,15 @@ class MModuleEventSaver : public MModule //! Set the file name void SetFileName(const MString& Name) { m_FileName = Name; } - //! Get the file name + //! Return true if the Bad events should be saved bool GetSaveBadEvents() const { return m_SaveBadEvents; } - //! Set the file name + //! Set whether the Bad events should be saved void SetSaveBadEvents(bool SaveBadEvents) { m_SaveBadEvents = SaveBadEvents; } + + //! Return true if the Veto events should be saved + bool GetSaveVetoEvents() const { return m_SaveVetoEvents; } + //! Set whether the Veto events should be saved + void SetSaveVetoEvents(bool SaveVetoEvents) {m_SaveVetoEvents = SaveVetoEvents; } //! Get the add time tag flag bool GetAddTimeTag() const { return m_AddTimeTag; } @@ -188,6 +193,9 @@ class MModuleEventSaver : public MModule //! Save bad events bool m_SaveBadEvents; + //! Save Veto events + bool m_SaveVetoEvents; + //! Add a time tag to the file bool m_AddTimeTag; diff --git a/include/MReadOutAssembly.h b/include/MReadOutAssembly.h index 23b408a4..9c370673 100644 --- a/include/MReadOutAssembly.h +++ b/include/MReadOutAssembly.h @@ -109,25 +109,15 @@ class MReadOutAssembly : public MReadOutSequence //! Find out if the event contains strip hits in a given detector bool InDetector(int DetectorID); - //! Set the vetoed flag - void SetVeto(bool Veto = true) { m_Veto = Veto; } - //! Return the veto flag - bool GetVeto() const { return m_Veto; } - - //! Set the guard ring 0 veto flag - void SetGR0Veto(bool Veto = true) { m_VetoGR0 = Veto; } - //! Get the guard ring 0 veto flag - bool GetGR0Veto() const { return m_VetoGR0; } - - //! Set the guard ring 1 veto flag - void SetGR1Veto(bool Veto = true) { m_VetoGR1 = Veto; } - //! Get the guard ring 1 veto flag - bool GetGR1Veto() const { return m_VetoGR1; } + //! Set the guard ring veto flag + void SetGuardRingVeto(bool Veto = true) { m_GuardRingVeto = Veto; } + //! Get the guard ring veto flag + bool GetGuardRingVeto() const { return m_GuardRingVeto; } //! Set the shield veto flag - void SetShieldVeto(bool Veto = true) { m_VetoShield = Veto; } + void SetShieldVeto(bool Veto = true) { m_ShieldVeto = Veto; } //! Get the shield veto flag - bool GetShieldVeto() const { return m_VetoShield; } + bool GetShieldVeto() const { return m_ShieldVeto; } //! Set the triggered flag void SetTrigger(bool Trigger = true) { m_Trigger = Trigger; } @@ -254,6 +244,9 @@ class MReadOutAssembly : public MReadOutSequence //! Get the filgtered-out flag bool IsFilteredOut() const { return m_FilteredOut; } + //! Returns true if any of the "veto" flags have been set + bool IsVeto() const; + //! Returns true if none of the "bad" or "incomplete" flags has been set and the event has not been filtered out or rejected bool IsGood() const; //! Returns true if any of the "bad" or "incomplete" flags has been set @@ -338,14 +331,11 @@ class MReadOutAssembly : public MReadOutSequence //! Veto flag of this event bool m_Veto; - //! Guard ring 0 veto flag - bool m_VetoGR0; - - //! Guard ring 1 veto flag - bool m_VetoGR1; + //! Guard ring veto flag + bool m_GuardRingVeto; //! Shield veto flag - bool m_VetoShield; + bool m_ShieldVeto; //! Trigger flag of this event bool m_Trigger; diff --git a/src/MBinaryFlightDataParser.cxx b/src/MBinaryFlightDataParser.cxx index 4be64951..ddc86fac 100644 --- a/src/MBinaryFlightDataParser.cxx +++ b/src/MBinaryFlightDataParser.cxx @@ -1242,16 +1242,16 @@ bool MBinaryFlightDataParser::ConvertToMReadOutAssemblys( dataframe * DataIn, ve NewEvent->SetTime( NewTime ); if( E.TrigAndVetoInfo & 0x70 ){ - NewEvent->SetVeto(); + NewEvent->SetShieldVeto(); // Was ->SetVeto() } if( E.TrigAndVetoInfo & 0x10 ){ - //had a guard ring 0 veto - NewEvent->SetGR0Veto(true); + //had a guard ring veto + NewEvent->SetGuardRingVeto(true); } if( E.TrigAndVetoInfo & 0x20 ){ - NewEvent->SetGR1Veto(true); + NewEvent->SetGuardRingVeto(true); } if( E.TrigAndVetoInfo & 0x40 ){ diff --git a/src/MGUIOptionsEventSaver.cxx b/src/MGUIOptionsEventSaver.cxx index 7cf81915..dd821c0c 100644 --- a/src/MGUIOptionsEventSaver.cxx +++ b/src/MGUIOptionsEventSaver.cxx @@ -89,6 +89,10 @@ void MGUIOptionsEventSaver::Create() m_SaveBadEvents->SetOn(dynamic_cast(m_Module)->GetSaveBadEvents()); m_OptionsFrame->AddFrame(m_SaveBadEvents, LabelLayout); + m_SaveVetoEvents = new TGCheckButton(m_OptionsFrame, "Save guard ring and shield veto events (Veto)", 1); + m_SaveVetoEvents->SetOn(dynamic_cast(m_Module)->GetSaveVetoEvents()); + m_OptionsFrame->AddFrame(m_SaveVetoEvents, LabelLayout); + m_AddTimeTag = new TGCheckButton(m_OptionsFrame, "Add a unique time tag", 3); m_AddTimeTag->SetOn(dynamic_cast(m_Module)->GetAddTimeTag()); m_OptionsFrame->AddFrame(m_AddTimeTag, LabelLayout); @@ -200,6 +204,7 @@ bool MGUIOptionsEventSaver::OnApply() dynamic_cast(m_Module)->SetFileName(m_FileSelector->GetFileName()); dynamic_cast(m_Module)->SetSaveBadEvents(m_SaveBadEvents->IsOn()); + dynamic_cast(m_Module)->SetSaveVetoEvents(m_SaveVetoEvents->IsOn()); dynamic_cast(m_Module)->SetAddTimeTag(m_AddTimeTag->IsOn()); dynamic_cast(m_Module)->SetSplitFile(m_SplitFile->IsOn()); dynamic_cast(m_Module)->SetSplitFileTime(MTime(m_SplitFileTime->GetAsInt())); diff --git a/src/MModuleEventSaver.cxx b/src/MModuleEventSaver.cxx index ed10bb0b..b7070b7a 100644 --- a/src/MModuleEventSaver.cxx +++ b/src/MModuleEventSaver.cxx @@ -75,6 +75,7 @@ MModuleEventSaver::MModuleEventSaver() : MModule() m_InternalFileName = ""; m_Zip = false; m_SaveBadEvents = true; + m_SaveVetoEvents = true; m_AddTimeTag = false; m_RoaWithADCs = true; @@ -332,6 +333,11 @@ bool MModuleEventSaver::AnalyzeEvent(MReadOutAssembly* Event) if (Event->IsBad() == true) return true; } + if (m_SaveVetoEvents == false) { + if (Event->IsVeto() == true) return true; + } + + MFile* Choosen = 0; // Wish C++ would allow unassigned references... if (m_SplitFile == true) { MTime Current = Event->GetTime(); @@ -395,6 +401,10 @@ bool MModuleEventSaver::ReadXmlConfiguration(MXmlNode* Node) if (SaveBadEventsNode != 0) { m_SaveBadEvents = SaveBadEventsNode->GetValueAsBoolean(); } + MXmlNode* SaveVetoEventsNode = Node->GetNode("SaveVetoEvents"); + if (SaveVetoEventsNode != 0) { + m_SaveVetoEvents = SaveVetoEventsNode->GetValueAsBoolean(); + } MXmlNode* AddTimeTagNode = Node->GetNode("AddTimeTag"); if (AddTimeTagNode != 0) { m_AddTimeTag = AddTimeTagNode->GetValueAsBoolean(); @@ -456,6 +466,7 @@ MXmlNode* MModuleEventSaver::CreateXmlConfiguration() new MXmlNode(Node, "FileName", m_FileName); new MXmlNode(Node, "Mode", m_Mode); new MXmlNode(Node, "SaveBadEvents", m_SaveBadEvents); + new MXmlNode(Node, "SaveVetoEvents", m_SaveVetoEvents); new MXmlNode(Node, "AddTimeTag", m_AddTimeTag); new MXmlNode(Node, "SplitFile", m_SplitFile); new MXmlNode(Node, "SplitFileTime", m_SplitFileTime.GetAsSystemSeconds()); diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx index 88d4433e..fed76c3b 100644 --- a/src/MModuleLoaderMeasurementsHDF.cxx +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -444,14 +444,17 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) H->IsLowVoltageStrip(m_StripMap.IsLowVoltage(StripID)); H->SetADCUnits(ADCs); H->SetTAC(TACs); - + + // Set boolean flags based on HitType and TimingType H->IsGuardRing(HitType == 2); + if (H->IsGuardRing()) { + Event->SetGuardRingVeto(true); } H->IsNearestNeighbor(HitType == 1); H->HasFastTiming(TimingType == 1); Event->AddStripHit(H); - + } else { if (g_Verbosity >= c_Error) cout<= m_TACCal[DetID][m_SideToIndex[Side]].size()) { + if (StripID >= m_TACCal[DetID][m_SideToIndex[Side]].size() && SH->IsGuardRing()==false) { cout< Date: Wed, 25 Jun 2025 15:13:18 -0400 Subject: [PATCH 54/90] Removed extraneous m_Veto --- include/MReadOutAssembly.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/MReadOutAssembly.h b/include/MReadOutAssembly.h index 9c370673..a332f860 100644 --- a/include/MReadOutAssembly.h +++ b/include/MReadOutAssembly.h @@ -328,9 +328,6 @@ class MReadOutAssembly : public MReadOutSequence //! Quality of this event double m_EventQuality; - //! Veto flag of this event - bool m_Veto; - //! Guard ring veto flag bool m_GuardRingVeto; From 233543b9e510294e3480bfd8f523d30762d7bb16 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 25 Jun 2025 13:46:58 -0700 Subject: [PATCH 55/90] BUG: Fixed uninitialized DetID when no header line is included in the depth splines file. --- src/MModuleDepthCalibration2024.cxx | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 20128dd6..d9cec07f 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -544,39 +544,38 @@ bool MModuleDepthCalibration2024::LoadSplinesFile(MString FName) } bool Result = true; MString line; - int DetID, NewDetID; - while( F.ReadLine(line) ){ - if( line.Length() != 0 ){ - if( line.BeginsWith("#") ){ + int DetID = 0; + while (F.ReadLine(line)) { + if (line.Length() != 0) { + if (line.BeginsWith("#")) { // If we've reached a new ctd spline then record the previous one in the m_SplineMaps and start a new one. vector tokens = line.Tokenize(" "); - NewDetID = tokens[1].ToInt(); - if( depthvec.size() > 0 ) { + if (depthvec.size() > 0) { Result &= AddDepthCTD(depthvec, ctdarr, DetID, m_DepthGrid, m_CTDMap); } depthvec.clear(); ctdarr.clear(); - for( unsigned int i=0; i < 5; ++i ){ + for (unsigned int i=0; i < 5; ++i) { vector temp_vec; ctdarr.push_back(temp_vec); } - DetID = NewDetID; + DetID = tokens[1].ToInt(); } else { vector tokens = line.Tokenize(","); depthvec.push_back(tokens[0].ToDouble()); // Multiple CTDs allowed. - for( unsigned int i = 0; i < (tokens.size() - 1); ++i ){ + for (unsigned int i = 0; i < (tokens.size() - 1); ++i) { ctdarr[i].push_back(tokens[1+i].ToDouble()); } // Fill in the higher grades with the GRADE=0 CTD if there are none listed in the file. - for(unsigned int i=tokens.size()-1; i<5; ++i){ + for (unsigned int i=tokens.size()-1; i<5; ++i) { ctdarr[i].push_back(tokens[1].ToDouble()); } } } } //make last spline - if( depthvec.size() > 0 ){ + if (depthvec.size() > 0) { Result &= AddDepthCTD(depthvec, ctdarr, DetID, m_DepthGrid, m_CTDMap); } From b73b70871bd15e444773398a0637e563a7f5ecbd Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 27 Jun 2025 11:27:00 -0700 Subject: [PATCH 56/90] CHG: Increase tolerance for detector thickness mismatch --- src/MModuleDepthCalibration2024.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index d9cec07f..46dd66d6 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -720,7 +720,7 @@ bool MModuleDepthCalibration2024::AddDepthCTD(vector depthvec, vector 0.0001) { + if (fabs((maxdepth-mindepth) - m_Thicknesses[DetID]) > 0.01) { cout<<"ERROR in MModuleDepthCalibration2024::AddDepthCTD: The thickness of detector "< Date: Fri, 27 Jun 2025 11:53:08 -0700 Subject: [PATCH 57/90] CHG: Don't screen GR events based on tac cut file --- src/MModuleTACcut.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index 41a20987..ba7d4850 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -163,7 +163,7 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) cout<= m_TACCal[DetID][m_SideToIndex[Side]].size() && SH->IsGuardRing()==false) { + if ((StripID >= m_TACCal[DetID][m_SideToIndex[Side]].size()) && (SH->IsGuardRing()==false)) { cout<= m_TACCut[DetID][m_SideToIndex[Side]].size()) { + if ((StripID >= m_TACCut[DetID][m_SideToIndex[Side]].size()) && (SH->IsGuardRing()==false)) { cout< Date: Fri, 27 Jun 2025 11:53:51 -0700 Subject: [PATCH 58/90] CHG: Skip GR Veto events during depth calibration --- src/MModuleDepthCalibration2024.cxx | 336 ++++++++++++++-------------- 1 file changed, 172 insertions(+), 164 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 46dd66d6..6224b009 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -205,209 +205,217 @@ void MModuleDepthCalibration2024::CreateExpos() bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) { - for( unsigned int i = 0; i < Event->GetNHits(); ++i ){ - // Each event represents one photon. It contains Hits, representing interaction sites. - // H is a pointer to an instance of the MHit class. Each Hit has activated strips, represented by - // instances of the MStripHit class. - MHit* H = Event->GetHit(i); - - int Grade = GetHitGrade(H); - - // cout << "got a hit with grade " << Grade << endl; - - // Handle different grades differently - // GRADE=-1 is an error. Break from the loop and continue. - if ( Grade < 0 ){ - H->SetNoDepth(); - Event->SetDepthCalibrationIncomplete(); - if (Grade == -1) { - ++m_ErrorSH; - } else if (Grade == -2) { - ++m_ErrorNullSH; - } else if (Grade == -3) { - ++m_ErrorNoE; - } - } else if (Grade > 4) { // GRADE=5 is some complicated geometry with multiple hits on a single strip. GRADE=6 means not all strips are adjacent. - H->SetNoDepth(); - Event->SetDepthCalibrationIncomplete(); - if (Grade==5) { - ++m_Error5; - } else if (Grade==6) { - ++m_Error6; - } - } else { // If the Grade is 0-4, we can handle it. - - MVector LocalPosition, PositionResolution, GlobalPosition, GlobalResolution, LocalOrigin; - - // Calculate the position. If error is thrown, record and no depth. - // Take a Hit and separate its activated X- and Y-strips into separate vectors. - std::vector XStrips; - std::vector YStrips; - // cout << "looping over strip hits..." << endl; - for( unsigned int j = 0; j < H->GetNStripHits(); ++j){ - // cout << "strip hit " << j << endl; - MStripHit* SH = H->GetStripHit(j); - if( SH->IsLowVoltageStrip() ) XStrips.push_back(SH); else YStrips.push_back(SH); - } - - // cout << "finished looping over strip hits" << endl; - double XEnergyFraction; - double YEnergyFraction; - MStripHit* XSH = GetDominantStrip(XStrips, XEnergyFraction); - MStripHit* YSH = GetDominantStrip(YStrips, YEnergyFraction); + if (Event->GetGuardRingVeto()==true) { + + Event->SetDepthCalibrationIncomplete(); + return false; + + } else { + + for( unsigned int i = 0; i < Event->GetNHits(); ++i ){ + // Each event represents one photon. It contains Hits, representing interaction sites. + // H is a pointer to an instance of the MHit class. Each Hit has activated strips, represented by + // instances of the MStripHit class. + MHit* H = Event->GetHit(i); - // cout << "found the dominant strips" << endl; + int Grade = GetHitGrade(H); - double CTD_s = 0.0; + // cout << "got a hit with grade " << Grade << endl; - //now try and get z position - int DetID = XSH->GetDetectorID(); - int XStripID = XSH->GetStripID(); - int YStripID = YSH->GetStripID(); - int pixel_code = 10000*DetID + 100*XStripID + YStripID; + // Handle different grades differently + // GRADE=-1 is an error. Break from the loop and continue. + if ( Grade < 0 ){ + H->SetNoDepth(); + Event->SetDepthCalibrationIncomplete(); + if (Grade == -1) { + ++m_ErrorSH; + } else if (Grade == -2) { + ++m_ErrorNullSH; + } else if (Grade == -3) { + ++m_ErrorNoE; + } + } else if (Grade > 4) { // GRADE=5 is some complicated geometry with multiple hits on a single strip. GRADE=6 means not all strips are adjacent. + H->SetNoDepth(); + Event->SetDepthCalibrationIncomplete(); + if (Grade==5) { + ++m_Error5; + } else if (Grade==6) { + ++m_Error6; + } + } else { // If the Grade is 0-4, we can handle it. + + MVector LocalPosition, PositionResolution, GlobalPosition, GlobalResolution, LocalOrigin; + + // Calculate the position. If error is thrown, record and no depth. + // Take a Hit and separate its activated X- and Y-strips into separate vectors. + std::vector XStrips; + std::vector YStrips; + // cout << "looping over strip hits..." << endl; + for( unsigned int j = 0; j < H->GetNStripHits(); ++j){ + // cout << "strip hit " << j << endl; + MStripHit* SH = H->GetStripHit(j); + if( SH->IsLowVoltageStrip() ) XStrips.push_back(SH); else YStrips.push_back(SH); + } - // TODO: Calculate X and Y positions more rigorously using charge sharing. - // Somewhat confusing notation: XStrips run parallel to X-axis, so we calculate X position with YStrips. - double Xpos = m_YPitches[DetID]*((m_NYStrips[DetID]/2.0) - ((double)YStripID)); - double Ypos = m_XPitches[DetID]*((m_NXStrips[DetID]/2.0) - ((double)XStripID)); - // cout << "X position " << Xpos << endl; - // cout << "Y position " << Ypos << endl; - double Zpos = 0.0; + // cout << "finished looping over strip hits" << endl; + double XEnergyFraction; + double YEnergyFraction; + MStripHit* XSH = GetDominantStrip(XStrips, XEnergyFraction); + MStripHit* YSH = GetDominantStrip(YStrips, YEnergyFraction); - double Xsigma = m_YPitches[DetID]/sqrt(12.0); - double Ysigma = m_XPitches[DetID]/sqrt(12.0); - double Zsigma = m_Thicknesses[DetID]/sqrt(12.0); + // cout << "found the dominant strips" << endl; - // cout << "looking up the coefficients" << endl; - vector* Coeffs = GetPixelCoeffs(pixel_code); + double CTD_s = 0.0; - // TODO: For Card Cage, may need to add noise - double XTiming = XSH->GetTiming(); - double YTiming = YSH->GetTiming(); + //now try and get z position + int DetID = XSH->GetDetectorID(); + int XStripID = XSH->GetStripID(); + int YStripID = YSH->GetStripID(); + int pixel_code = 10000*DetID + 100*XStripID + YStripID; - // cout << "Got the coefficients: " << Coeffs << endl; + // TODO: Calculate X and Y positions more rigorously using charge sharing. + // Somewhat confusing notation: XStrips run parallel to X-axis, so we calculate X position with YStrips. + double Xpos = m_YPitches[DetID]*((m_NYStrips[DetID]/2.0) - ((double)YStripID)); + double Ypos = m_XPitches[DetID]*((m_NXStrips[DetID]/2.0) - ((double)XStripID)); + // cout << "X position " << Xpos << endl; + // cout << "Y position " << Ypos << endl; + double Zpos = 0.0; - // If there aren't coefficients loaded, then calibration is incomplete. - if( Coeffs == nullptr ){ - //set the bad flag for depth - H->SetNoDepth(); - Event->SetDepthCalibrationIncomplete(); - ++m_Error1; - } - // If there isn't timing information, set no depth. - // Alex's old comments suggest assigning the event to the middle of the detector and the position resolution to be large. - else if( (XTiming < 1.0E-6) || (YTiming < 1.0E-6) ){ - // cout << "no timing info" << endl; - ++m_Error3; - H->SetNoDepth(); - Event->SetDepthCalibrationIncomplete(); - } + double Xsigma = m_YPitches[DetID]/sqrt(12.0); + double Ysigma = m_XPitches[DetID]/sqrt(12.0); + double Zsigma = m_Thicknesses[DetID]/sqrt(12.0); - // If there are coefficients and timing information is loaded, try calculating the CTD and depth - else { + // cout << "looking up the coefficients" << endl; + vector* Coeffs = GetPixelCoeffs(pixel_code); - vector ctdvec = GetCTD(DetID, Grade); - vector depthvec = GetDepth(DetID); + // TODO: For Card Cage, may need to add noise + double XTiming = XSH->GetTiming(); + double YTiming = YSH->GetTiming(); - if ( ctdvec.size() == 0){ - cout << "Empty CTD vector" << endl; - H->SetNoDepth(); - Event->SetDepthCalibrationIncomplete(); - } + // cout << "Got the coefficients: " << Coeffs << endl; - double CTD; - if ( XSH->IsLowVoltageStrip() ){ - CTD = (YTiming - XTiming); + // If there aren't coefficients loaded, then calibration is incomplete. + if( Coeffs == nullptr ){ + //set the bad flag for depth + H->SetNoDepth(); + Event->SetDepthCalibrationIncomplete(); + ++m_Error1; } - else { - CTD = (XTiming - YTiming); + // If there isn't timing information, set no depth. + // Alex's old comments suggest assigning the event to the middle of the detector and the position resolution to be large. + else if( (XTiming < 1.0E-6) || (YTiming < 1.0E-6) ){ + // cout << "no timing info" << endl; + ++m_Error3; + H->SetNoDepth(); + Event->SetDepthCalibrationIncomplete(); } - // cout << "Got the CTD: " << CTD << endl; + // If there are coefficients and timing information is loaded, try calculating the CTD and depth + else { - // Confirmed that this matches SP's python code. - CTD_s = (CTD - Coeffs->at(1))/(Coeffs->at(0)); //apply inverse stretch and offset + vector ctdvec = GetCTD(DetID, Grade); + vector depthvec = GetDepth(DetID); - // cout << "Transformed CTD: " << CTD_s << endl; + if ( ctdvec.size() == 0){ + cout << "Empty CTD vector" << endl; + H->SetNoDepth(); + Event->SetDepthCalibrationIncomplete(); + } - double Xmin = * std::min_element(ctdvec.begin(), ctdvec.end()); - double Xmax = * std::max_element(ctdvec.begin(), ctdvec.end()); + double CTD; + if ( XSH->IsLowVoltageStrip() ){ + CTD = (YTiming - XTiming); + } + else { + CTD = (XTiming - YTiming); + } - // cout << "Got the min and max ctd values: " << Xmin << "; " << Xmax << endl; + // cout << "Got the CTD: " << CTD << endl; - double noise = GetTimingNoiseFWHM(pixel_code, H->GetEnergy()); + // Confirmed that this matches SP's python code. + CTD_s = (CTD - Coeffs->at(1))/(Coeffs->at(0)); //apply inverse stretch and offset - // cout << "Got the timing noise: " << noise << endl; + // cout << "Transformed CTD: " << CTD_s << endl; - //if the CTD is out of range, check if we should reject the event. - if( (CTD_s < (Xmin - 2.0*noise)) || (CTD_s > (Xmax + 2.0*noise)) ){ - H->SetNoDepth(); - Event->SetDepthCalibrationIncomplete(); - ++m_Error2; - } + double Xmin = * std::min_element(ctdvec.begin(), ctdvec.end()); + double Xmax = * std::max_element(ctdvec.begin(), ctdvec.end()); - // If the CTD is in range, calculate the depth - else { - // cout << "Calculating depth" << endl; - // Calculate the probability given timing noise of CTD_s corresponding to the values of depth in depthvec - // Utlize symmetry of the normal distribution. - vector prob_dist = norm_pdf(ctdvec, CTD_s, noise/2.355); - - // Weight the depth by probability - double prob_sum = 0.0; - for( unsigned int k=0; k < prob_dist.size(); ++k ){ - prob_sum += prob_dist[k]; - } - //double prob_sum = std::accumulate(prob_dist.begin(), prob_dist.end(), 0); - //cout << "summed probability: " << prob_sum << endl; - double weighted_depth = 0.0; - for( unsigned int k = 0; k < depthvec.size(); ++k ){ - weighted_depth += prob_dist[k]*depthvec[k]; - } - // Calculate the expectation value of the depth - double mean_depth = weighted_depth/prob_sum; + // cout << "Got the min and max ctd values: " << Xmin << "; " << Xmax << endl; - // Calculate the standard deviation of the depth - double depth_var = 0.0; - for( unsigned int k=0; kGetEnergy()); - Zsigma = sqrt(depth_var/prob_sum); - Zpos = mean_depth - (m_Thicknesses[DetID]/2.0); + // cout << "Got the timing noise: " << noise << endl; + + //if the CTD is out of range, check if we should reject the event. + if( (CTD_s < (Xmin - 2.0*noise)) || (CTD_s > (Xmax + 2.0*noise)) ){ + H->SetNoDepth(); + Event->SetDepthCalibrationIncomplete(); + ++m_Error2; + } - // Add the depth to the GUI histogram. - if (Event->IsStripPairingIncomplete()==false) { - m_ExpoDepthCalibration->AddDepth(DetID, Zpos); + // If the CTD is in range, calculate the depth + else { + // cout << "Calculating depth" << endl; + // Calculate the probability given timing noise of CTD_s corresponding to the values of depth in depthvec + // Utlize symmetry of the normal distribution. + vector prob_dist = norm_pdf(ctdvec, CTD_s, noise/2.355); + + // Weight the depth by probability + double prob_sum = 0.0; + for( unsigned int k=0; k < prob_dist.size(); ++k ){ + prob_sum += prob_dist[k]; + } + //double prob_sum = std::accumulate(prob_dist.begin(), prob_dist.end(), 0); + //cout << "summed probability: " << prob_sum << endl; + double weighted_depth = 0.0; + for( unsigned int k = 0; k < depthvec.size(); ++k ){ + weighted_depth += prob_dist[k]*depthvec[k]; + } + // Calculate the expectation value of the depth + double mean_depth = weighted_depth/prob_sum; + + // Calculate the standard deviation of the depth + double depth_var = 0.0; + for( unsigned int k=0; kIsStripPairingIncomplete()==false) { + m_ExpoDepthCalibration->AddDepth(DetID, Zpos); + } + m_NoError+=1; } - m_NoError+=1; } - } - LocalPosition.SetXYZ(Xpos, Ypos, Zpos); - LocalOrigin.SetXYZ(0.0,0.0,0.0); - // cout << m_DetectorNames[DetID] << endl; - GlobalPosition = m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalPosition); - // cout << "Found the GlobalPosition" << endl; + LocalPosition.SetXYZ(Xpos, Ypos, Zpos); + LocalOrigin.SetXYZ(0.0,0.0,0.0); + // cout << m_DetectorNames[DetID] << endl; + GlobalPosition = m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalPosition); + // cout << "Found the GlobalPosition" << endl; - // Make sure XYZ resolution are correctly mapped to the global coord system. - PositionResolution.SetXYZ(Xsigma, Ysigma, Zsigma); - GlobalResolution = ((m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(PositionResolution)) - (m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalOrigin))).Abs(); - - // cout << "Set the PositionResolution vector" << endl; + // Make sure XYZ resolution are correctly mapped to the global coord system. + PositionResolution.SetXYZ(Xsigma, Ysigma, Zsigma); + GlobalResolution = ((m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(PositionResolution)) - (m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalOrigin))).Abs(); + + // cout << "Set the PositionResolution vector" << endl; - H->SetPosition(GlobalPosition); + H->SetPosition(GlobalPosition); - // cout << "Set the global position for the strip hit" << endl; + // cout << "Set the global position for the strip hit" << endl; - H->SetPositionResolution(GlobalResolution); + H->SetPositionResolution(GlobalResolution); - // cout << "Set the position resolution for the strip hit" << endl; + // cout << "Set the position resolution for the strip hit" << endl; + } } } - + Event->SetAnalysisProgress(MAssembly::c_DepthCorrection | MAssembly::c_PositionDetermiation); return true; From 2a869793c4ce8cf86eeda8cbf43186eea86f9779 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 27 Jun 2025 15:25:52 -0700 Subject: [PATCH 59/90] CHG: Updated to work with updated TAC Calibration module. Also no longer does chi-squared step --- apps/TrappingCorrection.cxx | 436 +++++++++++++++++------------------- 1 file changed, 202 insertions(+), 234 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index 12963ec8..e685ad97 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -67,8 +67,8 @@ using namespace ROOT::Minuit2; int g_HistBins = 75; -double g_MinCTD = -200; -double g_MaxCTD = 200; +double g_MinCTD = -250; +double g_MaxCTD = 250; double g_MinRatio = 0.94; double g_MaxRatio = 1.06; @@ -135,10 +135,8 @@ class TrappingCorrection //! Parse the command line bool ParseCommandLine(int argc, char** argv); - //! Analyze what eveer needs to be analyzed... + //! Analyze what ever needs to be analyzed... bool Analyze(); - //!load cross talk correction - vector > > LoadCrossTalk(); //! Interrupt the analysis void Interrupt() { m_Interrupt = true; } @@ -152,17 +150,13 @@ class TrappingCorrection //! The input file name MString m_FileName; MString m_EcalFile; - MString m_TACFile; + MString m_TACCalFile; + MString m_TACCutFile; //! output file names MString m_OutFile; - //! energy E0 - // float m_E0; - //! option to correct charge loss or not - // bool m_CorrectCL; //! option to do a pixel-by-pixel calibration (instead of detector-by-detector) bool m_PixelCorrect; bool m_GreedyPairing; - bool m_CardCageOverride; double m_MinEnergy; double m_MaxEnergy; @@ -175,9 +169,7 @@ class TrappingCorrection double SymmetryFCN::operator()(vector const &v) const { double HVSlope = v[0]; - double HVIntercept = v[1]; - double LVSlope = v[2]; - double LVIntercept = v[3]; + double LVSlope = v[1]; char name[64]; sprintf(name,"name"); int HistBins = g_HistBins; @@ -190,8 +182,8 @@ double SymmetryFCN::operator()(vector const &v) const double CTDHVShift = m_CTD[i] + g_MaxCTD; double CTDLVShift = m_CTD[i] + g_MinCTD; // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. - double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); - double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); + double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift)/100); + double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift)/100); CorrectedHistogram.Fill(m_CTD[i], CorrectedHVEnergy/CorrectedLVEnergy); } @@ -216,7 +208,7 @@ double SymmetryFCN::operator()(vector const &v) const } } - return Asymmetry; + return Asymmetry*Asymmetry; } @@ -226,10 +218,9 @@ double SymmetryFCN::operator()(vector const &v) const double ChiSquaredFCN::operator()(vector const &v) const { - double HVSlope = v[0]; - double HVIntercept = v[1]; + double HVLVFactor = v[0]; + double HVSlope = v[1]; double LVSlope = v[2]; - double LVIntercept = v[3]; double ChiSquare = 0; @@ -237,8 +228,8 @@ double ChiSquaredFCN::operator()(vector const &v) const double CTDHVShift = m_CTD[i] + g_MaxCTD; double CTDLVShift = m_CTD[i] + g_MinCTD; // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. - double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); - double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); + double CorrectedHVEnergy = m_HVEnergy[i]/((1 - (HVSlope*CTDHVShift)/100)*HVLVFactor); + double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift)/100); ChiSquare += pow(CorrectedHVEnergy - CorrectedLVEnergy, 2)/(m_HVEnergyResolution[i] + m_LVEnergyResolution[i]); } @@ -277,14 +268,15 @@ bool TrappingCorrection::ParseCommandLine(int argc, char** argv) Usage<"< i+1) && - (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ + if ((Option == "-i") || (Option == "-o") || (Option == "--emin") || (Option == "--emax") || (Option == "--tcal") || (Option == "--tcut")) { + if (!((argc > i+1) && (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ cout<<"Error: Option "< i+2) && - (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0) && - (argv[i+2][0] != '-' || isalpha(argv[i+2][1]) == 0))){ - cout<<"Error: Option "<SetBinContent(i,j,c); - } - } - TCanvas *ctemp = new TCanvas(); - h2->Draw("colz"); - ctemp->Print("frac_map.pdf"); -*/ //time code just to see TStopwatch watch; watch.Start(); if (m_Interrupt == true) return false; - MSupervisor* S = MSupervisor::GetSupervisor(); - - MModuleLoaderMeasurementsROA* Loader; - MModuleTACcut* TACCalibrator; - MModuleEnergyCalibrationUniversal* EnergyCalibrator; - MModuleEventFilter* EventFilter; - - unsigned int MNumber = 0; - cout<<"Creating ROA loader"<SetFileName(m_FileName); - S->SetModule(Loader, MNumber); - ++MNumber; - - if (m_CardCageOverride==false) { - cout<<"Creating TAC calibrator"<SetTACCalFileName(m_TACFile); - S->SetModule(TACCalibrator, MNumber); - ++MNumber; - } - - cout<<"Creating energy calibrator"<SetFileName(m_EcalFile); - EnergyCalibrator->EnablePreampTempCorrection(false); - S->SetModule(EnergyCalibrator, MNumber); - ++MNumber; - - cout<<"Creating Event filter"<SetMinimumLVStrips(1); - EventFilter->SetMaximumLVStrips(1); - EventFilter->SetMinimumHVStrips(1); - EventFilter->SetMaximumHVStrips(1); - EventFilter->SetMinimumTotalEnergy(m_MinEnergy); - EventFilter->SetMaximumTotalEnergy(m_MaxEnergy); - S->SetModule(EventFilter, MNumber); - ++MNumber; - - cout<<"Creating strip pairing"<(Pairing); - Pairing = new MModuleStripPairingGreedy(); - } - else { - // Pairing = dynamic_cast(Pairing); - Pairing = new MModuleStripPairingChiSquare(); - } - S->SetModule(Pairing, MNumber); - - cout<<"Initializing Loader"<Initialize() == false) return false; - if (m_CardCageOverride==false) { - cout<<"Initializing TAC calibrator"<Initialize() == false) return false; + vector FileNames; + + if ((m_FileName.GetSubString(m_FileName.Length() - 3)) == "roa"){ + FileNames.push_back(m_FileName); + } else if ((m_FileName.GetSubString(m_FileName.Length() - 3)) == "txt") { + MFile F; + if (F.Open(m_FileName)==false) { + cout<<"Error: Failed to open input file."<Initialize() == false) return false; - cout<<"Initializing Event filter"<Initialize() == false) return false; - cout<<"Initializing Pairing"<Initialize() == false) return false; - map Histograms; - map FCNs; + map Histograms; + map FCNs; - bool IsFinished = false; - MReadOutAssembly* Event = new MReadOutAssembly(); + for (unsigned int f = 0; fClear(); + MString ROAFile = FileNames[f]; - if (Loader->IsReady() ){ - Loader->AnalyzeEvent(Event); + cout<<"Beginning analysis of file "<AnalyzeEvent(Event); - } - - EnergyCalibrator->AnalyzeEvent(Event); - bool Unfiltered = EventFilter->AnalyzeEvent(Event); - Pairing->AnalyzeEvent(Event); - - if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true)) { - for (unsigned int h = 0; h < Event->GetNHits(); ++h) { - double HVEnergy = 0.0; - double LVEnergy = 0.0; - double HVEnergyResolution = 0.0; - double LVEnergyResolution = 0.0; - vector HVStrips; - vector LVStrips; - - MHit* H = Event->GetHit(h); - - int DetID = H->GetStripHit(0)->GetDetectorID(); - TH2D* Hist = Histograms[DetID]; - SymmetryFCN* FCN = FCNs[DetID]; - - if (Hist == nullptr) { - char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); - Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); - Hist->SetXTitle("CTD (ns)"); - Hist->SetYTitle("HV/LV Energy Ratio"); - Histograms[DetID] = Hist; - } + MSupervisor* S = MSupervisor::GetSupervisor(); + + MModuleLoaderMeasurementsROA* Loader; + MModuleTACcut* TACCalibrator; + MModuleEnergyCalibrationUniversal* EnergyCalibrator; + MModuleEventFilter* EventFilter; + + unsigned int MNumber = 0; + cout<<"Creating ROA loader"<SetFileName(ROAFile); + S->SetModule(Loader, MNumber); + ++MNumber; + + cout<<"Creating TAC calibrator"<SetTACCalFileName(m_TACCalFile); + TACCalibrator->SetTACCutFileName(m_TACCutFile); + S->SetModule(TACCalibrator, MNumber); + ++MNumber; + + cout<<"Creating energy calibrator"<SetFileName(m_EcalFile); + EnergyCalibrator->EnablePreampTempCorrection(false); + S->SetModule(EnergyCalibrator, MNumber); + ++MNumber; + + cout<<"Creating Event filter"<SetMinimumLVStrips(1); + EventFilter->SetMaximumLVStrips(1); + EventFilter->SetMinimumHVStrips(1); + EventFilter->SetMaximumHVStrips(1); + EventFilter->SetMinimumHits(0); + EventFilter->SetMaximumHits(3); + EventFilter->SetMinimumTotalEnergy(m_MinEnergy); + EventFilter->SetMaximumTotalEnergy(m_MaxEnergy); + S->SetModule(EventFilter, MNumber); + ++MNumber; + + cout<<"Creating strip pairing"<SetModule(Pairing, MNumber); + + cout<<"Initializing Loader"<Initialize() == false) return false; + cout<<"Initializing TAC calibrator"<Initialize() == false) return false; + cout<<"Initializing Energy calibrator"<Initialize() == false) return false; + cout<<"Initializing Event filter"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; + + bool IsFinished = false; + MReadOutAssembly* Event = new MReadOutAssembly(); + + cout<<"Analyzing..."<Clear(); + + if (Loader->IsReady()){ + + Loader->AnalyzeEvent(Event); + TACCalibrator->AnalyzeEvent(Event); + EnergyCalibrator->AnalyzeEvent(Event); + bool Unfiltered = EventFilter->AnalyzeEvent(Event); + Pairing->AnalyzeEvent(Event); + + if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true)) { + for (unsigned int h = 0; h < Event->GetNHits(); ++h) { + double HVEnergy = 0.0; + double LVEnergy = 0.0; + double HVEnergyResolution = 0.0; + double LVEnergyResolution = 0.0; + vector HVStrips; + vector LVStrips; + + MHit* H = Event->GetHit(h); + + int DetID = H->GetStripHit(0)->GetDetectorID(); + TH2D* Hist = Histograms[DetID]; + SymmetryFCN* FCN = FCNs[DetID]; + + if (Hist == nullptr) { + char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); + Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); + Hist->SetXTitle("CTD (ns)"); + Hist->SetYTitle("HV/LV Energy Ratio"); + Histograms[DetID] = Hist; + } - if (FCN == nullptr) { - FCN = new SymmetryFCN(); - FCNs[DetID] = FCN; - } + if (FCN == nullptr) { + FCN = new SymmetryFCN(); + FCNs[DetID] = FCN; + } - for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { - MStripHit* SH = H->GetStripHit(sh); - - if (SH->IsLowVoltageStrip()==true) { - LVEnergy += SH->GetEnergy(); - LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - LVStrips.push_back(SH); - } else { - HVEnergy += SH->GetEnergy(); - HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - HVStrips.push_back(SH); + for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { + MStripHit* SH = H->GetStripHit(sh); + + if (SH->IsLowVoltageStrip()==true) { + LVEnergy += SH->GetEnergy(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } } - } - double HVEnergyFraction = 0; - double LVEnergyFraction = 0; - MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); - MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); - double EnergyFraction = HVEnergy/LVEnergy; - double CTD = LVSH->GetTiming() - HVSH->GetTiming(); - if (m_CardCageOverride == true) { - CTD *= -1; + double HVEnergyFraction = 0; + double LVEnergyFraction = 0; + MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + double EnergyFraction = HVEnergy/LVEnergy; + double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + Hist->Fill(CTD, EnergyFraction); + FCN->AddCTD(CTD); + FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); + FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); } - Hist->Fill(CTD, EnergyFraction); - FCN->AddCTD(CTD); - FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); - FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); } } + IsFinished = Loader->IsFinished(); } - IsFinished = Loader->IsFinished(); } //setup output file ofstream OutputCalFile; OutputCalFile.open(m_OutFile+MString("_parameters.txt")); - OutputCalFile<<"Det"<<'\t'<<"HV Slope"<<'\t'<<"HV Intercept"<<'\t'<<"LV Slope"<<'\t'<<"LV Intercept"<Add("HVSlope", 1e-3, 1e-4, 0, 3e-1); - InitialStateSym->Add("HVIntercept", 0, 0.01, -2, 2); + InitialStateSym->Add("HVSlope", 2e-3, 1e-4, 0, 3e-1); InitialStateSym->Add("LVSlope", 0, 1e-4, -3e-2, 0); - InitialStateSym->Add("LVIntercept", 0, 0.01, -2, 2); InitialStateSym->Fix("LVSlope"); - InitialStateSym->Fix("LVIntercept"); - InitialStateSym->Fix("HVIntercept"); - MnMigrad migradSym(*F.second, *InitialStateSym); // Minimize FunctionMinimum MinimumSym = migradSym(); MnUserParameters ParametersSym = MinimumSym.UserParameters(); - // double HVSlope = ParametersSym.Value("HVSlope"); - // double HVIntercept = ParametersSym.Value("HVIntercept"); - // double LVSlope = ParametersSym.Value("LVSlope"); - // double LVIntercept = ParametersSym.Value("LVIntercept"); + double HVSlope = ParametersSym.Value("HVSlope"); + double LVSlope = ParametersSym.Value("LVSlope"); // output cout<Add("HVSlope", ParametersSym.Value("HVSlope"), ParametersSym.Error("HVSlope")); - InitialStateChi->Add("HVIntercept", 0, 0.01, -2, 2); - InitialStateChi->Add("LVSlope", 0, 1e-4, -3e-2, 0); - InitialStateChi->Add("LVIntercept", 0, 0.01, -2, 2); + // MnUserParameters* InitialStateChi = new MnUserParameters(); + // InitialStateChi->Add("HVLVFactor", 1.0, 0.01, 0.95, 1.05); + // InitialStateChi->Add("HVSlope", ParametersSym.Value("HVSlope"), ParametersSym.Error("HVSlope")); + // InitialStateChi->Add("LVSlope", ParametersSym.Value("LVSlope"), ParametersSym.Error("LVSlope")); - InitialStateChi->Fix("LVSlope"); - InitialStateChi->Fix("LVIntercept"); - InitialStateChi->Fix("HVSlope"); + // InitialStateChi->Fix("HVSlope"); + // InitialStateChi->Fix("LVSlope"); - ChiSquaredFCN* ChiSquaredF = new ChiSquaredFCN(); - ChiSquaredF->SetCTD(F.second->GetCTD()); - ChiSquaredF->SetHVEnergy(F.second->GetHVEnergy(), F.second->GetHVEnergyResolution()); - ChiSquaredF->SetLVEnergy(F.second->GetLVEnergy(), F.second->GetLVEnergyResolution()); - MnMigrad migradChi(*ChiSquaredF, *InitialStateChi); - // Minimize - FunctionMinimum MinimumChi = migradChi(); + // ChiSquaredFCN* ChiSquaredF = new ChiSquaredFCN(); + // ChiSquaredF->SetCTD(F.second->GetCTD()); + // ChiSquaredF->SetHVEnergy(F.second->GetHVEnergy(), F.second->GetHVEnergyResolution()); + // ChiSquaredF->SetLVEnergy(F.second->GetLVEnergy(), F.second->GetLVEnergyResolution()); + // MnMigrad migradChi(*ChiSquaredF, *InitialStateChi); + // // Minimize + // FunctionMinimum MinimumChi = migradChi(); - MnUserParameters ParametersChi = MinimumChi.UserParameters(); - double HVSlope = ParametersChi.Value("HVSlope"); - double HVIntercept = ParametersChi.Value("HVIntercept"); - double LVSlope = ParametersChi.Value("LVSlope"); - double LVIntercept = ParametersChi.Value("LVIntercept"); - // output - cout<Fill(CTDList[i], CorrectedHVEnergy/CorrectedLVEnergy); } @@ -665,7 +633,7 @@ bool TrappingCorrection::Analyze() Hist->Write(); f.Close(); - OutputCalFile< Date: Sun, 29 Jun 2025 01:18:27 -0700 Subject: [PATCH 60/90] CHG: Enable multi-threaded processing --- src/MModuleTACcut.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index ba7d4850..f29748c5 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -81,7 +81,7 @@ MModuleTACcut::MModuleTACcut() : MModule() m_AllowMultiThreading = true; // Can we use multiple instances of this class - m_AllowMultipleInstances = false; + m_AllowMultipleInstances = true; m_SideToIndex = {{'l', 0}, {'h', 1}, {'0', 0}, {'1', 1}, {'p', 0}, {'n', 1}}; } From 822e1da101968f516b6cabf3be2e80e68648eb62 Mon Sep 17 00:00:00 2001 From: Andreas Zoglauer Date: Sun, 29 Jun 2025 01:18:47 -0700 Subject: [PATCH 61/90] ADD: Protections against zero-data-bug --- include/MModuleLoaderMeasurementsHDF.h | 2 +- src/MModuleLoaderMeasurementsHDF.cxx | 31 ++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/include/MModuleLoaderMeasurementsHDF.h b/include/MModuleLoaderMeasurementsHDF.h index 22b05841..a926e449 100644 --- a/include/MModuleLoaderMeasurementsHDF.h +++ b/include/MModuleLoaderMeasurementsHDF.h @@ -217,7 +217,7 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! Number of event ID roll-overs: unsigned int m_NumberOfEventIDRollOvers; - //! The last handles event ID + //! The last handled event ID unsigned int m_LastEventID; //! The file name of the strip map diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx index fed76c3b..24f1f918 100644 --- a/src/MModuleLoaderMeasurementsHDF.cxx +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -147,6 +147,7 @@ bool MModuleLoaderMeasurementsHDF::OpenHDF5File(MString FileName) { try { // HDF5 throws exceptions, thus need to encapsulate everything in try..catch + MFile::ExpandFileName(FileName); m_HDFFile = H5File(FileName, H5F_ACC_RDONLY); // ToDo: Check for version. @@ -329,8 +330,11 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) // Main data analysis routine, which updates the event to a new level: // Here: Just read it. + bool IsZeroDataBug = false; + unsigned int NStripHits = 1; - for (unsigned int s = 0; s < NStripHits; ++s) { + unsigned int StripHitIndex = 0; + while (StripHitIndex < NStripHits) { // First step is to check if we have events left in the file: if (m_CurrentHit >= m_TotalHits) { @@ -360,7 +364,7 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) } } - // Second step is to check is we have events left in the batch + // Second step is to check if we have events left in the batch if (m_CurrentBatchIndex >= m_CurrentBatchSize) { if (ReadBatchHits() == false) { return false; @@ -423,6 +427,23 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) cout<<" TimingType: "<= c_Error) cout<GetNStripHits() > 0) { + MStripHit* H = Event->GetStripHit(0); + delete H; + Event->RemoveStripHit(0); + } + } + IsZeroDataBug = false; + } + if (EventID < m_LastEventID) { m_NumberOfEventIDRollOvers++; } @@ -448,8 +469,9 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) // Set boolean flags based on HitType and TimingType H->IsGuardRing(HitType == 2); - if (H->IsGuardRing()) { - Event->SetGuardRingVeto(true); } + if (H->IsGuardRing() == true) { + Event->SetGuardRingVeto(true); + } H->IsNearestNeighbor(HitType == 1); H->HasFastTiming(TimingType == 1); @@ -461,6 +483,7 @@ bool MModuleLoaderMeasurementsHDF::AnalyzeEvent(MReadOutAssembly* Event) } NStripHits = static_cast(NumberOfHits); + StripHitIndex++; } Event->SetAnalysisProgress(MAssembly::c_EventLoader | MAssembly::c_EventLoaderMeasurement); From b9398e436b1a431764ceb6ed54105d32b2e6049f Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 1 Jul 2025 13:40:14 -0700 Subject: [PATCH 62/90] CHG: Read HDF5 files instead ROAs --- apps/TrappingCorrection.cxx | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index e685ad97..a0bcbe68 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -57,7 +57,9 @@ using namespace ROOT::Minuit2; #include "MStripHit.h" #include "MReadOutSequence.h" #include "MSupervisor.h" +#include "MModuleLoaderMeasurements.h" #include "MModuleLoaderMeasurementsROA.h" +#include "MModuleLoaderMeasurementsHDF.h" #include "MModuleEnergyCalibrationUniversal.h" #include "MModuleEventFilter.h" #include "MModuleStripPairingGreedy.h" @@ -152,6 +154,7 @@ class TrappingCorrection MString m_EcalFile; MString m_TACCalFile; MString m_TACCutFile; + MString m_StripMapFile; //! output file names MString m_OutFile; //! option to do a pixel-by-pixel calibration (instead of detector-by-detector) @@ -268,13 +271,14 @@ bool TrappingCorrection::ParseCommandLine(int argc, char** argv) Usage<"< i+1) && (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ cout<<"Error: Option "< FileNames; - if ((m_FileName.GetSubString(m_FileName.Length() - 3)) == "roa"){ + if ((m_FileName.GetSubString(m_FileName.Length() - 4)) == "hdf5") { FileNames.push_back(m_FileName); } else if ((m_FileName.GetSubString(m_FileName.Length() - 3)) == "txt") { MFile F; @@ -401,21 +410,30 @@ bool TrappingCorrection::Analyze() for (unsigned int f = 0; fSetFileName(ROAFile); + + if ((InFile.GetSubString(InFile.Length() - 4)) == "hdf5") { + cout<<"Creating HDF5 loader"<SetFileNameStripMap(m_StripMapFile); + Loader->SetFileName(InFile); S->SetModule(Loader, MNumber); ++MNumber; From 68816a32d33305e3b51a5ca0ff2b94ae7eca7a25 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 1 Jul 2025 13:41:48 -0700 Subject: [PATCH 63/90] CHG: Expand criteria up to 3x3 pixels to include nearest neighbors. Do filtering before pairing to save time --- apps/TrappingCorrection.cxx | 122 +++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 57 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index a0bcbe68..3c6be1f6 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -71,8 +71,8 @@ using namespace ROOT::Minuit2; int g_HistBins = 75; double g_MinCTD = -250; double g_MaxCTD = 250; -double g_MinRatio = 0.94; -double g_MaxRatio = 1.06; +double g_MinRatio = 0.96; +double g_MaxRatio = 1.04; //////////////////////////////////////////////////////////////////////////////// @@ -297,7 +297,7 @@ bool TrappingCorrection::ParseCommandLine(int argc, char** argv) m_PixelCorrect = false; m_GreedyPairing = false; - m_MinEnergy = 30; + m_MinEnergy = 40; m_MaxEnergy = 5000; time_t rawtime; @@ -455,11 +455,11 @@ bool TrappingCorrection::Analyze() //! Only use events with 1 Strip Hit on each side to avoid strip pairing complications EventFilter = new MModuleEventFilter(); EventFilter->SetMinimumLVStrips(1); - EventFilter->SetMaximumLVStrips(1); + EventFilter->SetMaximumLVStrips(3); EventFilter->SetMinimumHVStrips(1); - EventFilter->SetMaximumHVStrips(1); + EventFilter->SetMaximumHVStrips(3); EventFilter->SetMinimumHits(0); - EventFilter->SetMaximumHits(3); + EventFilter->SetMaximumHits(100); EventFilter->SetMinimumTotalEnergy(m_MinEnergy); EventFilter->SetMaximumTotalEnergy(m_MaxEnergy); S->SetModule(EventFilter, MNumber); @@ -481,9 +481,9 @@ bool TrappingCorrection::Analyze() if (TACCalibrator->Initialize() == false) return false; cout<<"Initializing Energy calibrator"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; - cout<<"Initializing Pairing"<Initialize() == false) return false; bool IsFinished = false; @@ -499,60 +499,68 @@ bool TrappingCorrection::Analyze() TACCalibrator->AnalyzeEvent(Event); EnergyCalibrator->AnalyzeEvent(Event); bool Unfiltered = EventFilter->AnalyzeEvent(Event); - Pairing->AnalyzeEvent(Event); - - if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true)) { - for (unsigned int h = 0; h < Event->GetNHits(); ++h) { - double HVEnergy = 0.0; - double LVEnergy = 0.0; - double HVEnergyResolution = 0.0; - double LVEnergyResolution = 0.0; - vector HVStrips; - vector LVStrips; - - MHit* H = Event->GetHit(h); - - int DetID = H->GetStripHit(0)->GetDetectorID(); - TH2D* Hist = Histograms[DetID]; - SymmetryFCN* FCN = FCNs[DetID]; - - if (Hist == nullptr) { - char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); - Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); - Hist->SetXTitle("CTD (ns)"); - Hist->SetYTitle("HV/LV Energy Ratio"); - Histograms[DetID] = Hist; - } - if (FCN == nullptr) { - FCN = new SymmetryFCN(); - FCNs[DetID] = FCN; - } + if (Unfiltered == true) { + + Pairing->AnalyzeEvent(Event); + + if (Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) { + for (unsigned int h = 0; h < Event->GetNHits(); ++h) { + double HVEnergy = 0.0; + double LVEnergy = 0.0; + double HVEnergyResolution = 0.0; + double LVEnergyResolution = 0.0; + vector HVStrips; + vector LVStrips; + + MHit* H = Event->GetHit(h); + + int DetID = H->GetStripHit(0)->GetDetectorID(); + TH2D* Hist = Histograms[DetID]; + SymmetryFCN* FCN = FCNs[DetID]; + + if (Hist == nullptr) { + char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); + Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); + Hist->SetXTitle("CTD (ns)"); + Hist->SetYTitle("HV/LV Energy Ratio"); + Histograms[DetID] = Hist; + } - for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { - MStripHit* SH = H->GetStripHit(sh); - - if (SH->IsLowVoltageStrip()==true) { - LVEnergy += SH->GetEnergy(); - LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - LVStrips.push_back(SH); - } else { - HVEnergy += SH->GetEnergy(); - HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - HVStrips.push_back(SH); + if (FCN == nullptr) { + FCN = new SymmetryFCN(); + FCNs[DetID] = FCN; + } + + for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { + MStripHit* SH = H->GetStripHit(sh); + + if (SH->IsLowVoltageStrip()==true) { + LVEnergy += SH->GetEnergy(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } } - } - double HVEnergyFraction = 0; - double LVEnergyFraction = 0; - MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); - MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); - double EnergyFraction = HVEnergy/LVEnergy; - double CTD = LVSH->GetTiming() - HVSH->GetTiming(); - Hist->Fill(CTD, EnergyFraction); - FCN->AddCTD(CTD); - FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); - FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); + if ((HVStrips.size()>0) && (LVStrips.size()>0)) { + double HVEnergyFraction = 0; + double LVEnergyFraction = 0; + MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + double EnergyFraction = HVEnergy/LVEnergy; + if ((LVSH->HasCalibratedTiming()==true) && (HVSH->HasCalibratedTiming()==true)) { + double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + Hist->Fill(CTD, EnergyFraction); + FCN->AddCTD(CTD); + FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); + FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); + } + } + } } } } From d659b2746d651a01ca5e717e07a54aed4726d936 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 1 Jul 2025 14:58:45 -0700 Subject: [PATCH 64/90] BUG: return true when passing -h, fix order of initializing messages --- apps/TrappingCorrection.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index 3c6be1f6..7253b466 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -291,7 +291,7 @@ bool TrappingCorrection::ParseCommandLine(int argc, char** argv) Option = argv[i]; if (Option == "-h" || Option == "--help" || Option == "?" || Option == "-?") { cout<Initialize() == false) return false; cout<<"Initializing Energy calibrator"<Initialize() == false) return false; - cout<<"Initializing Pairing"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; bool IsFinished = false; From 70412c82cb6187d32816b2df7453a279fc85ffef Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 1 Jul 2025 15:00:05 -0700 Subject: [PATCH 65/90] Revert "BUG: return true when passing -h, fix order of initializing messages" This reverts commit d659b2746d651a01ca5e717e07a54aed4726d936. --- apps/TrappingCorrection.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index 7253b466..3c6be1f6 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -291,7 +291,7 @@ bool TrappingCorrection::ParseCommandLine(int argc, char** argv) Option = argv[i]; if (Option == "-h" || Option == "--help" || Option == "?" || Option == "-?") { cout<Initialize() == false) return false; cout<<"Initializing Energy calibrator"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; - cout<<"Initializing Pairing"<Initialize() == false) return false; bool IsFinished = false; From c2a5fa3447bd82ee4804e49f4b44f4d990bc6891 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Tue, 1 Jul 2025 15:01:13 -0700 Subject: [PATCH 66/90] BUG: fixed order of initialization messages --- apps/TrappingCorrection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index 3c6be1f6..8f0bfbdf 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -481,9 +481,9 @@ bool TrappingCorrection::Analyze() if (TACCalibrator->Initialize() == false) return false; cout<<"Initializing Energy calibrator"<Initialize() == false) return false; - cout<<"Initializing Pairing"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; bool IsFinished = false; From 2c2ca13ef13cdf91659cdf3c5cbfb5b9cb20935b Mon Sep 17 00:00:00 2001 From: Andreas Zoglauer Date: Wed, 2 Jul 2025 07:17:23 -0700 Subject: [PATCH 67/90] ADD: Nearest neighbot module - which currently just cuts NN events out --- Makefile | 1 + include/MAssembly.h | 37 +++--- include/MModuleNearestNeighbor.h | 90 +++++++++++++++ src/MAssembly.cxx | 5 +- src/MModuleNearestNeighbor.cxx | 189 +++++++++++++++++++++++++++++++ 5 files changed, 301 insertions(+), 21 deletions(-) create mode 100644 include/MModuleNearestNeighbor.h create mode 100644 src/MModuleNearestNeighbor.cxx diff --git a/Makefile b/Makefile index 5dbb7ff4..a260b9c0 100755 --- a/Makefile +++ b/Makefile @@ -140,6 +140,7 @@ $(LB)/MGUIExpoDiagnostics.o \ $(LB)/MModuleTACcut.o \ $(LB)/MGUIExpoTACcut.o \ $(LB)/MGUIOptionsTACcut.o \ +$(LB)/MModuleNearestNeighbor.o \ diff --git a/include/MAssembly.h b/include/MAssembly.h index 7f0aa339..396f5b13 100644 --- a/include/MAssembly.h +++ b/include/MAssembly.h @@ -54,24 +54,25 @@ class MAssembly static const uint64_t c_EventOrdering = (1 << 3); // = 8 static const uint64_t c_Coincidence = (1 << 4); // = 16 static const uint64_t c_TACcut = (1 << 5); // = 32 - static const uint64_t c_DetectorEffectsEngine = (1 << 6); - static const uint64_t c_EventFilter = (1 << 7); // = 64 - static const uint64_t c_EnergyCalibration = (1 << 8); // = 128 - static const uint64_t c_ChargeSharingCorrection = (1 << 9); // = 256 - static const uint64_t c_DepthCorrection = (1 << 10); // = 512 - static const uint64_t c_StripPairing = (1 << 11); // = 1024 - static const uint64_t c_Aspect = (1 << 12); // = 2048 - static const uint64_t c_CrosstalkCorrection = (1 << 13); // = 4096 - static const uint64_t c_EventReconstruction = (1 << 14); // = 8196 - static const uint64_t c_Else = (1 << 15); - static const uint64_t c_NoRestriction = (1 << 16); - static const uint64_t c_EventSaver = (1 << 17); - static const uint64_t c_EventTransmitter = (1 << 18); - static const uint64_t c_PositionDetermiation = (1 << 19); - static const uint64_t c_Statistics = (1 << 20); - static const uint64_t c_FlagHits = (1 << 21); - static const uint64_t c_Diagnostics = (1 << 22); - static const uint64_t c_ResponseGeneration = (1 << 23); + static const uint64_t c_NearestNeighbor = (1 << 6); // = 32 + static const uint64_t c_DetectorEffectsEngine = (1 << 7); + static const uint64_t c_EventFilter = (1 << 8); + static const uint64_t c_EnergyCalibration = (1 << 9); + static const uint64_t c_ChargeSharingCorrection = (1 << 10); + static const uint64_t c_DepthCorrection = (1 << 11); + static const uint64_t c_StripPairing = (1 << 12); + static const uint64_t c_Aspect = (1 << 13); + static const uint64_t c_CrosstalkCorrection = (1 << 14); + static const uint64_t c_EventReconstruction = (1 << 15); + static const uint64_t c_Else = (1 << 16); + static const uint64_t c_NoRestriction = (1 << 17); + static const uint64_t c_EventSaver = (1 << 18); + static const uint64_t c_EventTransmitter = (1 << 19); + static const uint64_t c_PositionDetermiation = (1 << 20); + static const uint64_t c_Statistics = (1 << 21); + static const uint64_t c_FlagHits = (1 << 22); + static const uint64_t c_Diagnostics = (1 << 23); + static const uint64_t c_ResponseGeneration = (1 << 24); // IMPORTANT: diff --git a/include/MModuleNearestNeighbor.h b/include/MModuleNearestNeighbor.h new file mode 100644 index 00000000..c46f05c5 --- /dev/null +++ b/include/MModuleNearestNeighbor.h @@ -0,0 +1,90 @@ +/* + * MModuleNearestNeighbor.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MModuleNearestNeighbor__ +#define __MModuleNearestNeighbor__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// Standard libs: + +// ROOT libs: + +// MEGAlib libs: +#include "MGlobal.h" +#include "MModule.h" + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +class MModuleNearestNeighbor : public MModule +{ + // public interface: + public: + //! Default constructor + MModuleNearestNeighbor(); + //! Default destructor + virtual ~MModuleNearestNeighbor(); + + //! Create a new object of this class + virtual MModuleNearestNeighbor* Clone() { return new MModuleNearestNeighbor(); } + + //! Initialize the module + virtual bool Initialize(); + + //! Finalize the module + virtual void Finalize(); + + //! Main data analysis routine, which updates the event to a new level + virtual bool AnalyzeEvent(MReadOutAssembly* Event); + + //! Show the options GUI + virtual void ShowOptionsGUI(); + + //! Read the configuration data from an XML node + virtual bool ReadXmlConfiguration(MXmlNode* Node); + //! Create an XML node tree from the configuration + virtual MXmlNode* CreateXmlConfiguration(); + + // protected methods: + protected: + + // private methods: + private: + + + + // protected members: + protected: + + + // private members: + private: + + + + +#ifdef ___CLING___ + public: + ClassDef(MModuleNearestNeighbor, 0) // no description +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MAssembly.cxx b/src/MAssembly.cxx index 3202ee3e..2c91b546 100644 --- a/src/MAssembly.cxx +++ b/src/MAssembly.cxx @@ -56,7 +56,6 @@ using namespace std; #include "MModule.h" #include "MGUIExpoCombinedViewer.h" #include "MModuleTransmitterRealta.h" - #include "MModuleLoaderSimulationsBalloon.h" #include "MModuleLoaderSimulationsSMEX.h" #include "MModuleLoaderMeasurementsROA.h" @@ -75,9 +74,8 @@ using namespace std; #include "MModuleEventFilter.h" #include "MModuleEventSaver.h" #include "MModuleResponseGenerator.h" - #include "MModuleTACcut.h" - +#include "MModuleNearestNeighbor.h" #include "MModuleDiagnostics.h" #include "MModuleDiagnosticsEnergyPerStrip.h" @@ -136,6 +134,7 @@ MAssembly::MAssembly() m_Supervisor->AddAvailableModule(new MModuleTransmitterRealta()); m_Supervisor->AddAvailableModule(new MModuleResponseGenerator()); m_Supervisor->AddAvailableModule(new MModuleTACcut()); + m_Supervisor->AddAvailableModule(new MModuleNearestNeighbor()); m_Supervisor->AddAvailableModule(new MModuleDiagnostics()); m_Supervisor->AddAvailableModule(new MModuleDiagnosticsEnergyPerStrip()); diff --git a/src/MModuleNearestNeighbor.cxx b/src/MModuleNearestNeighbor.cxx new file mode 100644 index 00000000..6d79b7ee --- /dev/null +++ b/src/MModuleNearestNeighbor.cxx @@ -0,0 +1,189 @@ +/* + * MModuleNearestNeighbor.cxx + * + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Andreas Zoglauer. + * + * By copying, distributing or modifying the Program (or any work + * based on the Program) you indicate your acceptance of this statement, + * and all its terms. + * + */ + + +//////////////////////////////////////////////////////////////////////////////// +// +// MModuleNearestNeighbor +// +//////////////////////////////////////////////////////////////////////////////// + + +// Include the header: +#include "MModuleNearestNeighbor.h" + +// Standard libs: + +// ROOT libs: +#include "TGClient.h" + +// MEGAlib libs: +#include "MModule.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MModuleNearestNeighbor) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleNearestNeighbor::MModuleNearestNeighbor() : MModule() +{ + // Construct an instance of MModuleNearestNeighbor + + // Set all module relevant information + + // Set the module name --- has to be unique + m_Name = "NearestNeighbor"; + + // Set the XML tag --- has to be unique --- no spaces allowed + m_XmlTag = "XmlTagNearestNeighbor"; + + // Set all modules, which have to be done before this module + AddPreceedingModuleType(MAssembly::c_EventLoader); + + // Set all types this modules handles + AddModuleType(MAssembly::c_NearestNeighbor); + + // Set all modules, which can follow this module + AddSucceedingModuleType(MAssembly::c_NoRestriction); + + // Set if this module has an options GUI + // Overwrite ShowOptionsGUI() with the call to the GUI! + m_HasOptionsGUI = false; + // If true, you have to derive a class from MGUIOptions (use MGUIOptionsNearestNeighbor) + // and implement all your GUI options + + // Can the program be run multi-threaded + m_AllowMultiThreading = true; + + // Can we use multiple instances of this class + m_AllowMultipleInstances = true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleNearestNeighbor::~MModuleNearestNeighbor() +{ + // Delete this instance of MModuleNearestNeighbor +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleNearestNeighbor::Initialize() +{ + // Initialize the module + + return MModule::Initialize(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleNearestNeighbor::AnalyzeEvent(MReadOutAssembly* Event) +{ + // For the time being remove all next neighbor hits + + for (unsigned int i = 0; i < Event->GetNStripHits();) { + MStripHit* SH = Event->GetStripHit(i); + if (SH->IsNearestNeighbor() == true) { + Event->RemoveStripHit(i); + delete SH; + } else { + ++i; + } + } + + Event->SetAnalysisProgress(MAssembly::c_NearestNeighbor); + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MModuleNearestNeighbor::Finalize() +{ + // Finalize the analysis - do all cleanup, i.e., undo Initialize() + + MModule::Finalize(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MModuleNearestNeighbor::ShowOptionsGUI() +{ + //! Show the options GUI --- has to be overwritten! + + /* + MGUIOptionsNearestNeighbor* Options = new MGUIOptionsNearestNeighbor(this); + Options->Create(); + gClient->WaitForUnmap(Options); + */ +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleNearestNeighbor::ReadXmlConfiguration(MXmlNode* Node) +{ + //! Read the configuration data from an XML node + + /* + MXmlNode* SomeTagNode = Node->GetNode("SomeTag"); + if (SomeTagNode != 0) { + m_SomeTagValue = SomeTagNode->GetValue(); + } + */ + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MXmlNode* MModuleNearestNeighbor::CreateXmlConfiguration() +{ + //! Create an XML node tree from the configuration + + MXmlNode* Node = new MXmlNode(0, m_XmlTag); + + /* + MXmlNode* SomeTagNode = new MXmlNode(Node, "SomeTag", "SomeValue"); + */ + + return Node; +} + + +// MModuleNearestNeighbor.cxx: the end... +//////////////////////////////////////////////////////////////////////////////// From 83d4d91e8e5f5a345710990cc63f7606ce691ffa Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 2 Jul 2025 10:11:58 -0700 Subject: [PATCH 68/90] CHG: Add option to exclude nearest neighbors --- apps/TrappingCorrection.cxx | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index 8f0bfbdf..d562b86b 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -160,6 +160,7 @@ class TrappingCorrection //! option to do a pixel-by-pixel calibration (instead of detector-by-detector) bool m_PixelCorrect; bool m_GreedyPairing; + bool m_ExcludeNN; double m_MinEnergy; double m_MaxEnergy; @@ -280,6 +281,7 @@ bool TrappingCorrection::ParseCommandLine(int argc, char** argv) Usage<<" -p: do pixel-by-pixel correction"<GetNStripHits(); ++sh) { MStripHit* SH = H->GetStripHit(sh); - if (SH->IsLowVoltageStrip()==true) { - LVEnergy += SH->GetEnergy(); - LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - LVStrips.push_back(SH); - } else { - HVEnergy += SH->GetEnergy(); - HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - HVStrips.push_back(SH); + if ((m_ExcludeNN==false) || ((m_ExcludeNN==true) && (SH->IsNearestNeighbor()==false))) { + if (SH->IsLowVoltageStrip()==true) { + LVEnergy += SH->GetEnergy(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } } } From 08c5df56c89f9fe816e0e75fff7c6dda23ca4368 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 2 Jul 2025 15:21:10 -0700 Subject: [PATCH 69/90] ADD: Am241 Trapping correction app. Parameter saving not yet implemented --- apps/TrappingCorrectionAm241.cxx | 742 ++++++++++++------------------- 1 file changed, 296 insertions(+), 446 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 9c8465aa..11b4c32a 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -1,13 +1,13 @@ /* - * TrappingCorrection.cxx + * TrappingCorrectionAm241.cxx * * - * Copyright (C) by Andreas Zoglauer. + * Copyright (C) by Sean Pike. * All rights reserved. * * * This code implementation is the intellectual property of - * Andreas Zoglauer. + * Sean Pike. * * By copying, distributing or modifying the Program (or any work * based on the Program) you indicate your acceptance of this statement, @@ -37,16 +37,10 @@ using namespace std; #include #include #include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -using namespace ROOT::Minuit2; // MEGAlib #include "MGlobal.h" @@ -57,7 +51,7 @@ using namespace ROOT::Minuit2; #include "MStripHit.h" #include "MReadOutSequence.h" #include "MSupervisor.h" -#include "MModuleLoaderMeasurementsROA.h" +#include "MModuleLoaderMeasurementsHDF.h" #include "MModuleEnergyCalibrationUniversal.h" #include "MModuleEventFilter.h" #include "MModuleStripPairingGreedy.h" @@ -66,103 +60,46 @@ using namespace ROOT::Minuit2; #include "MAssembly.h" -int g_HistBins = 75; -double g_MinCTD = -250; -double g_MaxCTD = 250; -// double g_MinRatio = 0.94; -// double g_MaxRatio = 1.06; - - -//////////////////////////////////////////////////////////////////////////////// - - -class SymmetryFCN : public FCNBase -{ -public: - //! Operator which returns the symmetry of m_CTDHistogram given the parameters passed - double operator()(vector const &v) const override; - double Up() const override { return 1; } - - void AddCTD(double CTD){ m_CTD.push_back(CTD); } - void AddHVEnergy(double HVEnergy, double HVEnergyResolution){ m_HVEnergy.push_back(HVEnergy); m_HVEnergyResolution.push_back(HVEnergyResolution); } - void AddLVEnergy(double LVEnergy, double LVEnergyResolution){ m_LVEnergy.push_back(LVEnergy); m_LVEnergyResolution.push_back(LVEnergyResolution); } - - vector GetCTD(){ return m_CTD; } - vector GetHVEnergy(){ return m_HVEnergy; } - vector GetLVEnergy(){ return m_LVEnergy; } - vector GetHVEnergyResolution(){ return m_HVEnergyResolution; } - vector GetLVEnergyResolution(){ return m_LVEnergyResolution; } - - void SetCTD(vector CTD){ m_CTD = CTD; } - void SetHVEnergy(vector HVEnergy, vector HVEnergyResolution){ m_HVEnergy = HVEnergy; m_HVEnergyResolution = HVEnergyResolution; } - void SetLVEnergy(vector LVEnergy, vector LVEnergyResolution){ m_LVEnergy = LVEnergy; m_LVEnergyResolution = LVEnergyResolution; } - - //! The measured CTD and HV/LV energies - vector m_CTD; - vector m_HVEnergy; - vector m_LVEnergy; - vector m_HVEnergyResolution; - vector m_LVEnergyResolution; - -}; - - -//////////////////////////////////////////////////////////////////////////////// - - -class ChiSquaredFCN : public SymmetryFCN -{ -public: - //! Operator which returns the symmetry of m_CTDHistogram given the parameters passed - double operator()(vector const &v) const override; - double Up() const override { return 1; } - -}; - +double g_MinCTD = -300; +double g_MaxCTD = 300; //////////////////////////////////////////////////////////////////////////////// - //! A standalone program based on MEGAlib and ROOT -class TrappingCorrection +class TrappingCorrectionAm241 { public: //! Default constructor - TrappingCorrection(); + TrappingCorrectionAm241(); //! Default destructor - ~TrappingCorrection(); + ~TrappingCorrectionAm241(); //! Parse the command line bool ParseCommandLine(int argc, char** argv); - //! Analyze what eveer needs to be analyzed... + //! Analyze what ever needs to be analyzed... bool Analyze(); - //!load cross talk correction - vector > > LoadCrossTalk(); //! Interrupt the analysis void Interrupt() { m_Interrupt = true; } - void dummy_func() { return; } - MStripHit* GetDominantStrip(vector& Strips, double& EnergyFraction); private: //! True, if the analysis needs to be interrupted bool m_Interrupt; //! The input file name - MString m_FileName; + MString m_HVFileName; + MString m_LVFileName; MString m_EcalFile; - MString m_TACFile; + MString m_TACCalFile; + MString m_TACCutFile; + MString m_StripMapFile; //! output file names MString m_OutFile; - //! energy E0 - // float m_E0; - //! option to correct charge loss or not - // bool m_CorrectCL; //! option to do a pixel-by-pixel calibration (instead of detector-by-detector) bool m_PixelCorrect; bool m_GreedyPairing; - bool m_CardCageOverride; + bool m_ExcludeNN; double m_MinEnergy; double m_MaxEnergy; @@ -172,86 +109,8 @@ class TrappingCorrection //////////////////////////////////////////////////////////////////////////////// -double SymmetryFCN::operator()(vector const &v) const -{ - double HVSlope = v[0]; - double HVIntercept = v[1]; - double LVSlope = v[2]; - double LVIntercept = v[3]; - - char name[64]; sprintf(name,"name"); - int HistBins = g_HistBins; - if (HistBins%2 == 0) { - HistBins += 1; - } - TH2D CorrectedHistogram(name, name, HistBins, g_MinCTD, g_MaxCTD, HistBins, g_MinRatio, g_MaxRatio); - - for (unsigned int i = 0; i < m_CTD.size(); ++i) { - double CTDHVShift = m_CTD[i] + g_MaxCTD; - double CTDLVShift = m_CTD[i] + g_MinCTD; - // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. - double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); - double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); - CorrectedHistogram.Fill(m_CTD[i], CorrectedHVEnergy/CorrectedLVEnergy); - } - - vector> BinValues; - vector> ReflectedBinValues; - double Asymmetry = 0; - - for (unsigned int y = 0; y < CorrectedHistogram.GetNbinsY(); ++y) { - - vector XValues; - - for (unsigned int x = 0; x < CorrectedHistogram.GetNbinsX(); ++x) { - XValues.push_back(CorrectedHistogram.GetBinContent(x,y)); - } - - // BinValues.push_back(XValues); - vector ReflectedXValues = XValues; - reverse(ReflectedXValues.begin(), ReflectedXValues.end()); - - for (unsigned int x = 0; x < XValues.size(); ++x) { - Asymmetry += pow(XValues[x] - ReflectedXValues[x], 2)/(XValues[x] + ReflectedXValues[x]); - } - } - - return Asymmetry; - -} - - -//////////////////////////////////////////////////////////////////////////////// - - -double ChiSquaredFCN::operator()(vector const &v) const -{ - double HVSlope = v[0]; - double HVIntercept = v[1]; - double LVSlope = v[2]; - double LVIntercept = v[3]; - - double ChiSquare = 0; - - for (unsigned int i = 0; i < m_CTD.size(); ++i) { - double CTDHVShift = m_CTD[i] + g_MaxCTD; - double CTDLVShift = m_CTD[i] + g_MinCTD; - // Correct the HV and LV energies by dividing by the CCE. DeltaCCE is defined as a linear function with units percentage energy lost. - double CorrectedHVEnergy = m_HVEnergy[i]/(1 - (HVSlope*CTDHVShift + HVIntercept)/100); - double CorrectedLVEnergy = m_LVEnergy[i]/(1 - (LVSlope*CTDLVShift + LVIntercept)/100); - - ChiSquare += pow(CorrectedHVEnergy - CorrectedLVEnergy, 2)/(m_HVEnergyResolution[i] + m_LVEnergyResolution[i]); - } - - // ChiSquare /= m_CTD.size(); - - return ChiSquare; - -} - - //! Default constructor -TrappingCorrection::TrappingCorrection() : m_Interrupt(false) +TrappingCorrectionAm241::TrappingCorrectionAm241() : m_Interrupt(false) { gStyle->SetPalette(1, 0); } @@ -261,7 +120,7 @@ TrappingCorrection::TrappingCorrection() : m_Interrupt(false) //! Default destructor -TrappingCorrection::~TrappingCorrection() +TrappingCorrectionAm241::~TrappingCorrectionAm241() { // Intentionally left blank } @@ -271,20 +130,24 @@ TrappingCorrection::~TrappingCorrection() //! Parse the command line -bool TrappingCorrection::ParseCommandLine(int argc, char** argv) +bool TrappingCorrectionAm241::ParseCommandLine(int argc, char** argv) { ostringstream Usage; Usage<"<"< i+1) && - (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ + if ((Option == "--HVfile") || (Option == "--LVfile") || (Option == "-o") || (Option == "--emin") || (Option == "--emax") || (Option == "--tcal") || (Option == "--tcut") || (Option == "-m")) { + if (!((argc > i+1) && (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ cout<<"Error: Option "< i+2) && - (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0) && - (argv[i+2][0] != '-' || isalpha(argv[i+2][1]) == 0))){ - cout<<"Error: Option "<SetBinContent(i,j,c); - } - } - TCanvas *ctemp = new TCanvas(); - h2->Draw("colz"); - ctemp->Print("frac_map.pdf"); -*/ //time code just to see TStopwatch watch; watch.Start(); if (m_Interrupt == true) return false; - MSupervisor* S = MSupervisor::GetSupervisor(); - - MModuleLoaderMeasurementsROA* Loader; - MModuleTACcut* TACCalibrator; - MModuleEnergyCalibrationUniversal* EnergyCalibrator; - MModuleEventFilter* EventFilter; - - unsigned int MNumber = 0; - cout<<"Creating ROA loader"<SetFileName(m_FileName); - S->SetModule(Loader, MNumber); - ++MNumber; - - if (m_CardCageOverride==false) { - cout<<"Creating TAC calibrator"<SetTACCalFileName(m_TACFile); - S->SetModule(TACCalibrator, MNumber); - ++MNumber; - } - - cout<<"Creating energy calibrator"<SetFileName(m_EcalFile); - EnergyCalibrator->EnablePreampTempCorrection(false); - S->SetModule(EnergyCalibrator, MNumber); - ++MNumber; - - cout<<"Creating Event filter"<SetMinimumLVStrips(1); - EventFilter->SetMaximumLVStrips(1); - EventFilter->SetMinimumHVStrips(1); - EventFilter->SetMaximumHVStrips(1); - EventFilter->SetMinimumTotalEnergy(m_MinEnergy); - EventFilter->SetMaximumTotalEnergy(m_MaxEnergy); - S->SetModule(EventFilter, MNumber); - ++MNumber; - - cout<<"Creating strip pairing"<(Pairing); - Pairing = new MModuleStripPairingGreedy(); - } - else { - // Pairing = dynamic_cast(Pairing); - Pairing = new MModuleStripPairingChiSquare(); - } - S->SetModule(Pairing, MNumber); - - cout<<"Initializing Loader"<Initialize() == false) return false; - if (m_CardCageOverride==false) { - cout<<"Initializing TAC calibrator"<Initialize() == false) return false; - } - cout<<"Initializing Energy calibrator"<Initialize() == false) return false; - cout<<"Initializing Event filter"<Initialize() == false) return false; - cout<<"Initializing Pairing"<Initialize() == false) return false; - - map Histograms; - map FCNs; + // [HV Illum. CTD, HV Illum. Energy, LV Illum. CTD, LV Illum. Energy] + vector HVEndpoints; + vector LVEndpoints; + + vector FileNames; + FileNames.push_back(m_HVFileName); + FileNames.push_back(m_LVFileName); + + vector IllumSide; + IllumSide.push_back(MString("HV")); + IllumSide.push_back(MString("LV")); + + for (unsigned int s=0; s<2; ++s) { + + MString InputFile = FileNames[s]; + vector HDFNames; + + if ((InputFile.GetSubString(InputFile.Length() - 4)) == "hdf5") { + HDFNames.push_back(InputFile); + } else if ((InputFile.GetSubString(InputFile.Length() - 3)) == "txt") { + MFile F; + if (F.Open(InputFile)==false) { + cout<<"Error: Failed to open input file."< CTDHistograms; + map HVEnergyHistograms; + map LVEnergyHistograms; - cout<<"Analyzing..."<Clear(); + for (unsigned int f = 0; fIsReady() ){ - Loader->AnalyzeEvent(Event); + MString File = HDFNames[f]; + cout<<"Beginning analysis of file "<AnalyzeEvent(Event); + MSupervisor* S = MSupervisor::GetSupervisor(); + + MModuleLoaderMeasurementsHDF* Loader; + MModuleTACcut* TACCalibrator; + MModuleEnergyCalibrationUniversal* EnergyCalibrator; + MModuleEventFilter* EventFilter; + + unsigned int MNumber = 0; + cout<<"Creating HDF5 loader"<SetFileNameStripMap(m_StripMapFile); + Loader->SetFileName(File); + Loader->SetLoadContinuationFiles(true); + S->SetModule(Loader, MNumber); + ++MNumber; + + cout<<"Creating TAC calibrator"<SetTACCalFileName(m_TACCalFile); + TACCalibrator->SetTACCutFileName(m_TACCutFile); + S->SetModule(TACCalibrator, MNumber); + ++MNumber; + + cout<<"Creating energy calibrator"<SetFileName(m_EcalFile); + EnergyCalibrator->EnablePreampTempCorrection(false); + S->SetModule(EnergyCalibrator, MNumber); + ++MNumber; + + cout<<"Creating Event filter"<SetMinimumLVStrips(1); + EventFilter->SetMaximumLVStrips(3); + EventFilter->SetMinimumHVStrips(1); + EventFilter->SetMaximumHVStrips(3); + EventFilter->SetMinimumHits(0); + EventFilter->SetMaximumHits(100); + EventFilter->SetMinimumTotalEnergy(m_MinEnergy); + EventFilter->SetMaximumTotalEnergy(m_MaxEnergy*2); + S->SetModule(EventFilter, MNumber); + ++MNumber; + + cout<<"Creating strip pairing"<AnalyzeEvent(Event); - bool Unfiltered = EventFilter->AnalyzeEvent(Event); - Pairing->AnalyzeEvent(Event); - - if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true)) { - for (unsigned int h = 0; h < Event->GetNHits(); ++h) { - double HVEnergy = 0.0; - double LVEnergy = 0.0; - double HVEnergyResolution = 0.0; - double LVEnergyResolution = 0.0; - vector HVStrips; - vector LVStrips; - - MHit* H = Event->GetHit(h); - - int DetID = H->GetStripHit(0)->GetDetectorID(); - TH2D* Hist = Histograms[DetID]; - SymmetryFCN* FCN = FCNs[DetID]; - - if (Hist == nullptr) { - char name[64]; sprintf(name,"Detector %d (Uncorrected)",DetID); - Hist = new TH2D(name, name, g_HistBins, g_MinCTD, g_MaxCTD, g_HistBins, g_MinRatio, g_MaxRatio); - Hist->SetXTitle("CTD (ns)"); - Hist->SetYTitle("HV/LV Energy Ratio"); - Histograms[DetID] = Hist; - } - - if (FCN == nullptr) { - FCN = new SymmetryFCN(); - FCNs[DetID] = FCN; - } - - for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { - MStripHit* SH = H->GetStripHit(sh); - - if (SH->IsLowVoltageStrip()==true) { - LVEnergy += SH->GetEnergy(); - LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - LVStrips.push_back(SH); - } else { - HVEnergy += SH->GetEnergy(); - HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); - HVStrips.push_back(SH); + else { + Pairing = new MModuleStripPairingChiSquare(); + } + S->SetModule(Pairing, MNumber); + + cout<<"Initializing Loader"<Initialize() == false) return false; + cout<<"Initializing TAC calibrator"<Initialize() == false) return false; + cout<<"Initializing Energy calibrator"<Initialize() == false) return false; + cout<<"Initializing Event filter"<Initialize() == false) return false; + cout<<"Initializing Pairing"<Initialize() == false) return false; + + bool IsFinished = false; + MReadOutAssembly* Event = new MReadOutAssembly(); + + cout<<"Analyzing..."<Clear(); + + if (Loader->IsReady()) { + + Loader->AnalyzeEvent(Event); + TACCalibrator->AnalyzeEvent(Event); + EnergyCalibrator->AnalyzeEvent(Event); + bool Unfiltered = EventFilter->AnalyzeEvent(Event); + + if (Unfiltered == true) { + + Pairing->AnalyzeEvent(Event); + + if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true) && (Event->GetNHits()==1)) { + for (unsigned int h = 0; h < Event->GetNHits(); ++h) { + double HVEnergy = 0.0; + double LVEnergy = 0.0; + double HVEnergyResolution = 0.0; + double LVEnergyResolution = 0.0; + vector HVStrips; + vector LVStrips; + + MHit* H = Event->GetHit(h); + + int DetID = H->GetStripHit(0)->GetDetectorID(); + TH1D* CTDHist = CTDHistograms[DetID]; + TH1D* HVHist = HVEnergyHistograms[DetID]; + TH1D* LVHist = LVEnergyHistograms[DetID]; + + if (CTDHist == nullptr) { + char name[64]; sprintf(name,"CTD: Detector %d %s Illumination",DetID,IllumSide[s].Data()); + CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + CTDHist->SetXTitle("CTD (ns)"); + CTDHist->SetYTitle("Hits"); + CTDHistograms[DetID] = CTDHist; + } + + if (HVHist == nullptr) { + char name[64]; sprintf(name,"HV energy: Detector %d %s Illumination",DetID,IllumSide[s].Data()); + HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + HVHist->SetXTitle("HV Energy (keV)"); + HVHist->SetYTitle("Hits"); + HVEnergyHistograms[DetID] = HVHist; + } + + if (LVHist == nullptr) { + char name[64]; sprintf(name,"LV energy: Detector %d %s Illumination",DetID,IllumSide[s].Data()); + LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + LVHist->SetXTitle("LV Energy (keV)"); + LVHist->SetYTitle("Hits"); + LVEnergyHistograms[DetID] = LVHist; + } + + for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { + MStripHit* SH = H->GetStripHit(sh); + + if ((m_ExcludeNN==false) || ((m_ExcludeNN==true) && (SH->IsNearestNeighbor()==false))) { + if (SH->IsLowVoltageStrip()==true) { + LVEnergy += SH->GetEnergy(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } + } + } + + if ((HVStrips.size()>0) && (LVStrips.size()>0)) { + double HVEnergyFraction = 0; + double LVEnergyFraction = 0; + MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + if ((LVSH->HasCalibratedTiming()==true) && (HVSH->HasCalibratedTiming()==true)) { + double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + CTDHist->Fill(CTD); + HVHist->Fill(HVEnergy); + LVHist->Fill(LVEnergy); + } + } + } } } - - double HVEnergyFraction = 0; - double LVEnergyFraction = 0; - MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); - MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); - double EnergyFraction = HVEnergy/LVEnergy; - double CTD = LVSH->GetTiming() - HVSH->GetTiming(); - if (m_CardCageOverride == true) { - CTD *= -1; - } - Hist->Fill(CTD, EnergyFraction); - FCN->AddCTD(CTD); - FCN->AddHVEnergy(HVEnergy, HVEnergyResolution); - FCN->AddLVEnergy(LVEnergy, LVEnergyResolution); } + IsFinished = Loader->IsFinished(); } } - IsFinished = Loader->IsFinished(); - } - //setup output file - ofstream OutputCalFile; - OutputCalFile.open(m_OutFile+MString("_parameters.txt")); - OutputCalFile<<"Det"<<'\t'<<"HV Slope"<<'\t'<<"HV Intercept"<<'\t'<<"LV Slope"<<'\t'<<"LV Intercept"<Fit("gaus", "S"); + TFitResultPtr HVFit = HVEnergyHistograms[DetID]->Fit("gaus", "S"); + TFitResultPtr LVFit = LVEnergyHistograms[DetID]->Fit("gaus", "S"); - for (auto H: Histograms) { - - int DetID = H.first; - TFile f(m_OutFile+MString("_Det")+DetID+MString("_Hist_Uncorr.root"),"recreate"); + cout<<"Results of CTD fit:"<Print(); + cout<<"Results of HV energy fit:"<Print(); + cout<<"Results of LV energy fit:"<Print(); + + TFile CTDFile(m_OutFile+MString("_Det")+DetID+MString("_CTDHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - TCanvas* C = new TCanvas(); - C->SetLogz(); - C->cd(); - H.second->Draw("colz"); + TCanvas* CTDCanvas = new TCanvas(); + CTDCanvas->SetLogz(); + CTDCanvas->cd(); + H.second->Draw("colz"); - H.second->Write(); - f.Close(); + H.second->Write(); + CTDFile.Close(); - } - for (auto F: FCNs) { - - int DetID = F.first; - MnUserParameters* InitialStateSym = new MnUserParameters(); - InitialStateSym->Add("HVSlope", 1e-3, 1e-4, 0, 3e-1); - InitialStateSym->Add("HVIntercept", 0, 0.01, -2, 2); - InitialStateSym->Add("LVSlope", 0, 1e-4, -3e-2, 0); - InitialStateSym->Add("LVIntercept", 0, 0.01, -2, 2); - - InitialStateSym->Fix("LVSlope"); - InitialStateSym->Fix("LVIntercept"); - InitialStateSym->Fix("HVIntercept"); - - - MnMigrad migradSym(*F.second, *InitialStateSym); - // Minimize - FunctionMinimum MinimumSym = migradSym(); - - MnUserParameters ParametersSym = MinimumSym.UserParameters(); - // double HVSlope = ParametersSym.Value("HVSlope"); - // double HVIntercept = ParametersSym.Value("HVIntercept"); - // double LVSlope = ParametersSym.Value("LVSlope"); - // double LVIntercept = ParametersSym.Value("LVIntercept"); - - // output - cout<Add("HVSlope", ParametersSym.Value("HVSlope"), ParametersSym.Error("HVSlope")); - InitialStateChi->Add("HVIntercept", 0, 0.01, -2, 2); - InitialStateChi->Add("LVSlope", 0, 1e-4, -3e-2, 0); - InitialStateChi->Add("LVIntercept", 0, 0.01, -2, 2); - - InitialStateChi->Fix("LVSlope"); - InitialStateChi->Fix("LVIntercept"); - InitialStateChi->Fix("HVSlope"); - - - ChiSquaredFCN* ChiSquaredF = new ChiSquaredFCN(); - ChiSquaredF->SetCTD(F.second->GetCTD()); - ChiSquaredF->SetHVEnergy(F.second->GetHVEnergy(), F.second->GetHVEnergyResolution()); - ChiSquaredF->SetLVEnergy(F.second->GetLVEnergy(), F.second->GetLVEnergyResolution()); - MnMigrad migradChi(*ChiSquaredF, *InitialStateChi); - // Minimize - FunctionMinimum MinimumChi = migradChi(); - - MnUserParameters ParametersChi = MinimumChi.UserParameters(); - double HVSlope = ParametersChi.Value("HVSlope"); - double HVIntercept = ParametersChi.Value("HVIntercept"); - double LVSlope = ParametersChi.Value("LVSlope"); - double LVIntercept = ParametersChi.Value("LVIntercept"); - // output - cout<SetXTitle("CTD (ns)"); - Hist->SetYTitle("HV/LV Energy Ratio"); - - vector CTDList = F.second->GetCTD(); - vector HVEnergyList = F.second->GetHVEnergy(); - vector LVEnergyList = F.second->GetLVEnergy(); - for (unsigned int i=0; iFill(CTDList[i], CorrectedHVEnergy/CorrectedLVEnergy); - } + TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + + TCanvas* HVHistCanvas = new TCanvas(); + HVHistCanvas->SetLogz(); + HVHistCanvas->cd(); + HVEnergyHistograms[DetID]->Draw("colz"); - TCanvas* C = new TCanvas(); - C->SetLogz(); - C->cd(); - Hist->Draw("colz"); + HVEnergyHistograms[DetID]->Write(); + HVHistFile.Close(); - TFile f(m_OutFile+MString("_Det")+DetID+MString("_Hist_Corr.root"),"recreate"); - Hist->Write(); - f.Close(); + TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - OutputCalFile<SetLogz(); + LVHistCanvas->cd(); + LVEnergyHistograms[DetID]->Draw("colz"); + LVEnergyHistograms[DetID]->Write(); + LVHistFile.Close(); + + } } - OutputCalFile.close(); + + //setup output file + // ofstream OutputCalFile; + // OutputCalFile.open(m_OutFile+MString("_parameters.txt")); + // OutputCalFile<<"Det"<<'\t'<<"HV Slope"<<'\t'<<"HV Intercept"<<'\t'<<"LV Slope"<<'\t'<<"LV Intercept"<& Strips, double& EnergyFraction) +MStripHit* TrappingCorrectionAm241::GetDominantStrip(vector& Strips, double& EnergyFraction) { double MaxEnergy = -numeric_limits::max(); // AZ: When both energies are zero (which shouldn't happen) we still pick one double TotalEnergy = 0.0; @@ -737,7 +587,7 @@ int main(int argc, char** argv) TApplication TrappingCorrectionApp("TrappingCorrectionApp", 0, 0); - g_Prg = new TrappingCorrection(); + g_Prg = new TrappingCorrectionAm241(); if (g_Prg->ParseCommandLine(argc, argv) == false) { cerr<<"Error during parsing of command line!"< Date: Wed, 2 Jul 2025 21:55:18 -0700 Subject: [PATCH 70/90] BUG: Need to protect access to all expos in case we are in batch mode and they don't exist --- src/MModuleDepthCalibration2024.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index 6224b009..e9881af5 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -385,7 +385,9 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) // Add the depth to the GUI histogram. if (Event->IsStripPairingIncomplete()==false) { - m_ExpoDepthCalibration->AddDepth(DetID, Zpos); + if (HasExpos() == true) { + m_ExpoDepthCalibration->AddDepth(DetID, Zpos); + } } m_NoError+=1; } From d49bd60b53a08a70e19b682fc9ffb43a503e7d4d Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 7 Jul 2025 11:40:00 -0700 Subject: [PATCH 71/90] CHG: Calculate and save HV and LV slopes (energy loss per CTD) --- apps/TrappingCorrectionAm241.cxx | 279 ++++++++++++++++++++++--------- 1 file changed, 199 insertions(+), 80 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 11b4c32a..30c178e8 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -37,6 +37,7 @@ using namespace std; #include #include #include +#include #include #include #include @@ -62,6 +63,7 @@ using namespace std; double g_MinCTD = -300; double g_MaxCTD = 300; +int g_MinCounts = 1000; //////////////////////////////////////////////////////////////////////////////// @@ -265,9 +267,8 @@ bool TrappingCorrectionAm241::Analyze() if (m_Interrupt == true) return false; - // [HV Illum. CTD, HV Illum. Energy, LV Illum. CTD, LV Illum. Energy] - vector HVEndpoints; - vector LVEndpoints; + // [CTD, HV Energy, LV Energy] for HV illumination and LV illumination + map>> Endpoints; vector FileNames; FileNames.push_back(m_HVFileName); @@ -277,6 +278,25 @@ bool TrappingCorrectionAm241::Analyze() IllumSide.push_back(MString("HV")); IllumSide.push_back(MString("LV")); + vector> CTDHistograms; + map tempCTDHistHV; + map tempCTDHistLV; + CTDHistograms.push_back(tempCTDHistHV); + CTDHistograms.push_back(tempCTDHistLV); + + vector> HVEnergyHistograms; + map tempHVHistHV; + map tempHVHistLV; + HVEnergyHistograms.push_back(tempHVHistHV); + HVEnergyHistograms.push_back(tempHVHistLV); + + vector> LVEnergyHistograms; + map tempLVHistHV; + map tempLVHistLV; + LVEnergyHistograms.push_back(tempLVHistHV); + LVEnergyHistograms.push_back(tempLVHistLV); + + for (unsigned int s=0; s<2; ++s) { MString InputFile = FileNames[s]; @@ -296,10 +316,6 @@ bool TrappingCorrectionAm241::Analyze() } } - map CTDHistograms; - map HVEnergyHistograms; - map LVEnergyHistograms; - for (unsigned int f = 0; fSetModule(Pairing, MNumber); @@ -389,6 +404,7 @@ bool TrappingCorrectionAm241::Analyze() Pairing->AnalyzeEvent(Event); if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true) && (Event->GetNHits()==1)) { + for (unsigned int h = 0; h < Event->GetNHits(); ++h) { double HVEnergy = 0.0; double LVEnergy = 0.0; @@ -400,33 +416,6 @@ bool TrappingCorrectionAm241::Analyze() MHit* H = Event->GetHit(h); int DetID = H->GetStripHit(0)->GetDetectorID(); - TH1D* CTDHist = CTDHistograms[DetID]; - TH1D* HVHist = HVEnergyHistograms[DetID]; - TH1D* LVHist = LVEnergyHistograms[DetID]; - - if (CTDHist == nullptr) { - char name[64]; sprintf(name,"CTD: Detector %d %s Illumination",DetID,IllumSide[s].Data()); - CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); - CTDHist->SetXTitle("CTD (ns)"); - CTDHist->SetYTitle("Hits"); - CTDHistograms[DetID] = CTDHist; - } - - if (HVHist == nullptr) { - char name[64]; sprintf(name,"HV energy: Detector %d %s Illumination",DetID,IllumSide[s].Data()); - HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - HVHist->SetXTitle("HV Energy (keV)"); - HVHist->SetYTitle("Hits"); - HVEnergyHistograms[DetID] = HVHist; - } - - if (LVHist == nullptr) { - char name[64]; sprintf(name,"LV energy: Detector %d %s Illumination",DetID,IllumSide[s].Data()); - LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - LVHist->SetXTitle("LV Energy (keV)"); - LVHist->SetYTitle("Hits"); - LVEnergyHistograms[DetID] = LVHist; - } for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { MStripHit* SH = H->GetStripHit(sh); @@ -445,12 +434,58 @@ bool TrappingCorrectionAm241::Analyze() } if ((HVStrips.size()>0) && (LVStrips.size()>0)) { + double HVEnergyFraction = 0; double LVEnergyFraction = 0; MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); - MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + if ((LVSH->HasCalibratedTiming()==true) && (HVSH->HasCalibratedTiming()==true)) { + double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + + int ID = DetID; + if (m_PixelCorrect==true) { + ID = (10000*DetID) + (100*LVSH->GetStripID()) + (HVSH->GetStripID()); + } + + if (Endpoints.find(ID)==Endpoints.end()) { + vector tempHVvec; + vector tempLVvec; + vector> tempvec; + Endpoints[ID] = tempvec; + Endpoints[ID].push_back(tempHVvec); + Endpoints[ID].push_back(tempLVvec); + } + + TH1D* CTDHist = CTDHistograms[s][ID]; + TH1D* HVHist = HVEnergyHistograms[s][ID]; + TH1D* LVHist = LVEnergyHistograms[s][ID]; + + if (CTDHist == nullptr) { + char name[64]; sprintf(name,"CTD: ID %d %s Illumination",ID,IllumSide[s].Data()); + CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + CTDHist->SetXTitle("CTD (ns)"); + CTDHist->SetYTitle("Hits"); + CTDHistograms[s][ID] = CTDHist; + } + + if (HVHist == nullptr) { + char name[64]; sprintf(name,"HV energy: ID %d %s Illumination",ID,IllumSide[s].Data()); + HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + HVHist->SetXTitle("HV Energy (keV)"); + HVHist->SetYTitle("Hits"); + HVEnergyHistograms[s][ID] = HVHist; + } + + if (LVHist == nullptr) { + char name[64]; sprintf(name,"LV energy: ID %d %s Illumination",ID,IllumSide[s].Data()); + LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + LVHist->SetXTitle("LV Energy (keV)"); + LVHist->SetYTitle("Hits"); + LVEnergyHistograms[s][ID] = LVHist; + } + CTDHist->Fill(CTD); HVHist->Fill(HVEnergy); LVHist->Fill(LVEnergy); @@ -463,62 +498,146 @@ bool TrappingCorrectionAm241::Analyze() IsFinished = Loader->IsFinished(); } } + } - for (auto H: CTDHistograms) { - - int DetID = H.first; - cout<<"Fitting detector with ID "<Fit("gaus", "S"); - TFitResultPtr HVFit = HVEnergyHistograms[DetID]->Fit("gaus", "S"); - TFitResultPtr LVFit = LVEnergyHistograms[DetID]->Fit("gaus", "S"); - - cout<<"Results of CTD fit:"<Print(); - cout<<"Results of HV energy fit:"<Print(); - cout<<"Results of LV energy fit:"<Print(); - - TFile CTDFile(m_OutFile+MString("_Det")+DetID+MString("_CTDHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - - TCanvas* CTDCanvas = new TCanvas(); - CTDCanvas->SetLogz(); - CTDCanvas->cd(); - H.second->Draw("colz"); + int ID = H.first; + if (H.second->Integral() > g_MinCounts) { - H.second->Write(); - CTDFile.Close(); + TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); + TFitResultPtr HVFit = HVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); + TFitResultPtr LVFit = LVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); + if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { + Endpoints[ID][s].push_back(CTDFit->Parameter(1)); + Endpoints[ID][s].push_back(HVFit->Parameter(1)); + Endpoints[ID][s].push_back(LVFit->Parameter(1)); - TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + if (m_PixelCorrect==false) { + cout<<"Results of CTD fit:"<Print(); + cout<<"Results of HV energy fit:"<Print(); + cout<<"Results of LV energy fit:"<Print(); + + TFile CTDFile(m_OutFile+MString("_Det")+ID+MString("_CTDHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - TCanvas* HVHistCanvas = new TCanvas(); - HVHistCanvas->SetLogz(); - HVHistCanvas->cd(); - HVEnergyHistograms[DetID]->Draw("colz"); + TCanvas* CTDCanvas = new TCanvas(); + CTDCanvas->SetLogz(); + CTDCanvas->cd(); + H.second->Draw("colz"); - HVEnergyHistograms[DetID]->Write(); - HVHistFile.Close(); + H.second->Write(); + CTDFile.Close(); - TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - TCanvas* LVHistCanvas = new TCanvas(); - LVHistCanvas->SetLogz(); - LVHistCanvas->cd(); - LVEnergyHistograms[DetID]->Draw("colz"); + TFile HVHistFile(m_OutFile+MString("_Det")+ID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - LVEnergyHistograms[DetID]->Write(); - LVHistFile.Close(); - + TCanvas* HVHistCanvas = new TCanvas(); + HVHistCanvas->SetLogz(); + HVHistCanvas->cd(); + HVEnergyHistograms[s][ID]->Draw("colz"); + + HVEnergyHistograms[s][ID]->Write(); + HVHistFile.Close(); + + TFile LVHistFile(m_OutFile+MString("_Det")+ID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + + TCanvas* LVHistCanvas = new TCanvas(); + LVHistCanvas->SetLogz(); + LVHistCanvas->cd(); + LVEnergyHistograms[s][ID]->Draw("colz"); + + LVEnergyHistograms[s][ID]->Write(); + LVHistFile.Close(); + } + } else { + cout<<"Fits failed for "< DeltaHV; + map DeltaLV; + + for (auto E: Endpoints) { + int ID = E.first; + if ((E.second[0].size() > 0) && (E.second[1].size() > 0)) { + double HVSlope = (E.second[0][1] - E.second[1][1])/(E.second[0][0] - E.second[1][0]); + double LVSlope = (E.second[0][2] - E.second[1][2])/(E.second[0][0] - E.second[1][0]); + if (m_PixelCorrect==true) { + int DetID = (ID-(ID%10000))/10000; + int LVSHID = (ID-(DetID*10000) - (ID%100))/100; + int HVSHID = (ID-(DetID*10000) - (LVSHID *100)); + OutputCalFile<SetXTitle("HV Strip"); + TempHV->SetYTitle("LV Strip"); + TempHV->SetZTitle("Delta HV Energy"); + + char LVname[64]; sprintf(LVname,"Delta LV Map: Det %d",DetID); + TempLV = new TH2D(LVname, LVname, 64, 0, 64, 64, 0, 64); + TempLV->SetXTitle("HV Strip"); + TempLV->SetYTitle("LV Strip"); + TempLV->SetZTitle("Delta LV Energy"); + + DeltaHV[DetID] = TempHV; + DeltaLV[DetID] = TempLV; + } + + DeltaHV[DetID]->SetBinContent(HVSHID, LVSHID, E.second[0][1] - E.second[1][1]); + DeltaLV[DetID]->SetBinContent(HVSHID, LVSHID, E.second[0][2] - E.second[1][2]); + + } else { + for (int hv=0; hv<64; ++hv) { + for (int lv=0; lv<64; ++lv) { + OutputCalFile<cd(); + H.second->Draw("colz"); + H.second->Write(); + HVFile.Close(); + + TFile LVFile(m_OutFile+MString("_Det")+DetID+MString("_DeltaLVMap.root"),"recreate"); + TCanvas* LVCanvas = new TCanvas(); + LVCanvas->cd(); + DeltaLV[DetID]->Draw("colz"); + DeltaLV[DetID]->Write(); + LVFile.Close(); + } + } watch.Stop(); cout<<"total time (s): "< Date: Wed, 9 Jul 2025 15:38:40 -0700 Subject: [PATCH 72/90] BUG: Check to make sure all histograms have enough counts --- apps/TrappingCorrectionAm241.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 30c178e8..a15aa278 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -505,7 +505,7 @@ bool TrappingCorrectionAm241::Analyze() for (auto H: CTDHistograms[s]) { int ID = H.first; - if (H.second->Integral() > g_MinCounts) { + if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[s][ID]->Integral() > g_MinCounts) && (LVEnergyHistograms[s][ID]->Integral() > g_MinCounts)) { TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); TFitResultPtr HVFit = HVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); From 6eb4d9d4055e1d095e26ad133b5994e136948a6a Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Wed, 9 Jul 2025 16:23:18 -0700 Subject: [PATCH 73/90] CHG: Sum up pixel histograms to get detector histograms --- apps/TrappingCorrectionAm241.cxx | 201 ++++++++++++++++++++++--------- 1 file changed, 143 insertions(+), 58 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index a15aa278..8a3c3216 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -444,46 +444,43 @@ bool TrappingCorrectionAm241::Analyze() double CTD = LVSH->GetTiming() - HVSH->GetTiming(); - int ID = DetID; - if (m_PixelCorrect==true) { - ID = (10000*DetID) + (100*LVSH->GetStripID()) + (HVSH->GetStripID()); - } - - if (Endpoints.find(ID)==Endpoints.end()) { + int PixelID = (10000*DetID) + (100*LVSH->GetStripID()) + (HVSH->GetStripID()); + + if (Endpoints.find(PixelID)==Endpoints.end()) { vector tempHVvec; vector tempLVvec; vector> tempvec; - Endpoints[ID] = tempvec; - Endpoints[ID].push_back(tempHVvec); - Endpoints[ID].push_back(tempLVvec); + Endpoints[PixelID] = tempvec; + Endpoints[PixelID].push_back(tempHVvec); + Endpoints[PixelID].push_back(tempLVvec); } - TH1D* CTDHist = CTDHistograms[s][ID]; - TH1D* HVHist = HVEnergyHistograms[s][ID]; - TH1D* LVHist = LVEnergyHistograms[s][ID]; + TH1D* CTDHist = CTDHistograms[s][PixelID]; + TH1D* HVHist = HVEnergyHistograms[s][PixelID]; + TH1D* LVHist = LVEnergyHistograms[s][PixelID]; if (CTDHist == nullptr) { - char name[64]; sprintf(name,"CTD: ID %d %s Illumination",ID,IllumSide[s].Data()); + char name[64]; sprintf(name,"CTD: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); CTDHist->SetXTitle("CTD (ns)"); CTDHist->SetYTitle("Hits"); - CTDHistograms[s][ID] = CTDHist; + CTDHistograms[s][PixelID] = CTDHist; } if (HVHist == nullptr) { - char name[64]; sprintf(name,"HV energy: ID %d %s Illumination",ID,IllumSide[s].Data()); + char name[64]; sprintf(name,"HV energy: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); HVHist->SetXTitle("HV Energy (keV)"); HVHist->SetYTitle("Hits"); - HVEnergyHistograms[s][ID] = HVHist; + HVEnergyHistograms[s][PixelID] = HVHist; } if (LVHist == nullptr) { - char name[64]; sprintf(name,"LV energy: ID %d %s Illumination",ID,IllumSide[s].Data()); + char name[64]; sprintf(name,"LV energy: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); LVHist->SetXTitle("LV Energy (keV)"); LVHist->SetYTitle("Hits"); - LVEnergyHistograms[s][ID] = LVHist; + LVEnergyHistograms[s][PixelID] = LVHist; } CTDHist->Fill(CTD); @@ -500,66 +497,154 @@ bool TrappingCorrectionAm241::Analyze() } } + map>> FullDetEndpoints; + + vector> FullDetCTDHistograms; + map FullDettempCTDHistHV; + map FullDettempCTDHistLV; + FullDetCTDHistograms.push_back(FullDettempCTDHistHV); + FullDetCTDHistograms.push_back(FullDettempCTDHistLV); + + vector> FullDetHVEnergyHistograms; + map FullDettempHVHistHV; + map FullDettempHVHistLV; + FullDetHVEnergyHistograms.push_back(FullDettempHVHistHV); + FullDetHVEnergyHistograms.push_back(FullDettempHVHistLV); + + vector> FullDetLVEnergyHistograms; + map FullDettempLVHistHV; + map FullDettempLVHistLV; + FullDetLVEnergyHistograms.push_back(FullDettempLVHistHV); + FullDetLVEnergyHistograms.push_back(FullDettempLVHistLV); + + for (unsigned int s=0; s<2; ++s) { for (auto H: CTDHistograms[s]) { - int ID = H.first; - if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[s][ID]->Integral() > g_MinCounts) && (LVEnergyHistograms[s][ID]->Integral() > g_MinCounts)) { + int PixelID = H.first; + int DetID = (PixelID-(PixelID%10000))/10000; + int LVSHID = (PixelID-(DetID*10000) - (PixelID%100))/100; + int HVSHID = (PixelID-(DetID*10000) - (LVSHID *100)); + + if (FullDetEndpoints.find(DetID)==FullDetEndpoints.end()) { + vector tempHVvec; + vector tempLVvec; + vector> tempvec; + FullDetEndpoints[DetID] = tempvec; + FullDetEndpoints[DetID].push_back(tempHVvec); + FullDetEndpoints[DetID].push_back(tempLVvec); + } + + TH1D* CTDHist = FullDetCTDHistograms[s][DetID]; + TH1D* HVHist = FullDetHVEnergyHistograms[s][DetID]; + TH1D* LVHist = FullDetLVEnergyHistograms[s][DetID]; + + if (CTDHist == nullptr) { + char name[64]; sprintf(name,"CTD: DetID %d %s Illumination",DetID,IllumSide[s].Data()); + CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + CTDHist->SetXTitle("CTD (ns)"); + CTDHist->SetYTitle("Hits"); + FullDetCTDHistograms[s][DetID] = CTDHist; + } + + if (HVHist == nullptr) { + char name[64]; sprintf(name,"HV energy: DetID %d %s Illumination",DetID,IllumSide[s].Data()); + HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + HVHist->SetXTitle("HV Energy (keV)"); + HVHist->SetYTitle("Hits"); + FullDetHVEnergyHistograms[s][DetID] = HVHist; + } + + if (LVHist == nullptr) { + char name[64]; sprintf(name,"LV energy: DetID %d %s Illumination",DetID,IllumSide[s].Data()); + LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + LVHist->SetXTitle("LV Energy (keV)"); + LVHist->SetYTitle("Hits"); + FullDetLVEnergyHistograms[s][DetID] = LVHist; + } + + CTDHist->Add(CTDHist, H.second); + HVHist->Add(HVHist, HVEnergyHistograms[s][ID]); + LVHist->Add(LVHist, LVEnergyHistograms[s][ID]); + + if (m_PixelCorrect==true) { + if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[s][ID]->Integral() > g_MinCounts) && (LVEnergyHistograms[s][ID]->Integral() > g_MinCounts)) { + + TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); + TFitResultPtr HVFit = HVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); + TFitResultPtr LVFit = LVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); + + if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { + Endpoints[ID][s].push_back(CTDFit->Parameter(1)); + Endpoints[ID][s].push_back(HVFit->Parameter(1)); + Endpoints[ID][s].push_back(LVFit->Parameter(1)); + } else { + cout<<"Fits failed for Pixel "<Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[s][DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[s][DetID]->Integral() > g_MinCounts)) { TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); - TFitResultPtr HVFit = HVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); - TFitResultPtr LVFit = LVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); + TFitResultPtr HVFit = FullDetHVEnergyHistograms[s][DetID]->Fit("gaus", "SQ"); + TFitResultPtr LVFit = FullDetLVEnergyHistograms[s][DetID]->Fit("gaus", "SQ"); if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { - Endpoints[ID][s].push_back(CTDFit->Parameter(1)); - Endpoints[ID][s].push_back(HVFit->Parameter(1)); - Endpoints[ID][s].push_back(LVFit->Parameter(1)); - - if (m_PixelCorrect==false) { - cout<<"Results of CTD fit:"<Print(); - cout<<"Results of HV energy fit:"<Print(); - cout<<"Results of LV energy fit:"<Print(); - - TFile CTDFile(m_OutFile+MString("_Det")+ID+MString("_CTDHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + FullDetEndpoints[DetID][s].push_back(CTDFit->Parameter(1)); + FullDetEndpoints[DetID][s].push_back(HVFit->Parameter(1)); + FullDetEndpoints[DetID][s].push_back(LVFit->Parameter(1)); - TCanvas* CTDCanvas = new TCanvas(); - CTDCanvas->SetLogz(); - CTDCanvas->cd(); - H.second->Draw("colz"); + cout<<"Results of Det "<Print(); + cout<<"Results of Det "<Print(); + cout<<"Results of Det "<Print(); - H.second->Write(); - CTDFile.Close(); + TFile CTDFile(m_OutFile+MString("_Det")+DetID+MString("_CTDHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + TCanvas* CTDCanvas = new TCanvas(); + CTDCanvas->SetLogz(); + CTDCanvas->cd(); + H.second->Draw("colz"); - TFile HVHistFile(m_OutFile+MString("_Det")+ID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + H.second->Write(); + CTDFile.Close(); - TCanvas* HVHistCanvas = new TCanvas(); - HVHistCanvas->SetLogz(); - HVHistCanvas->cd(); - HVEnergyHistograms[s][ID]->Draw("colz"); + TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); - HVEnergyHistograms[s][ID]->Write(); - HVHistFile.Close(); + TCanvas* HVHistCanvas = new TCanvas(); + HVHistCanvas->SetLogz(); + HVHistCanvas->cd(); + FullDetHVEnergyHistograms[s][DetID]->Draw("colz"); - TFile LVHistFile(m_OutFile+MString("_Det")+ID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + FullDetHVEnergyHistograms[s][DetID]->Write(); + HVHistFile.Close(); - TCanvas* LVHistCanvas = new TCanvas(); - LVHistCanvas->SetLogz(); - LVHistCanvas->cd(); - LVEnergyHistograms[s][ID]->Draw("colz"); + TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + + TCanvas* LVHistCanvas = new TCanvas(); + LVHistCanvas->SetLogz(); + LVHistCanvas->cd(); + FullDetLVEnergyHistograms[s][DetID]->Draw("colz"); + + FullDetLVEnergyHistograms[s][DetID]->Write(); + LVHistFile.Close(); - LVEnergyHistograms[s][ID]->Write(); - LVHistFile.Close(); - } } else { - cout<<"Fits failed for "< Date: Wed, 9 Jul 2025 17:32:45 -0700 Subject: [PATCH 74/90] CHG: rearrange loops, default to full detector parameters when pixel parameters unavailable --- apps/TrappingCorrectionAm241.cxx | 203 ++++++++++++++----------------- 1 file changed, 90 insertions(+), 113 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 8a3c3216..bfaa2625 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -65,6 +65,9 @@ double g_MinCTD = -300; double g_MaxCTD = 300; int g_MinCounts = 1000; +int g_HVStrips = 64; +int g_LVStrips = 64; + //////////////////////////////////////////////////////////////////////////////// @@ -269,6 +272,7 @@ bool TrappingCorrectionAm241::Analyze() // [CTD, HV Energy, LV Energy] for HV illumination and LV illumination map>> Endpoints; + map>> FullDetEndpoints; vector FileNames; FileNames.push_back(m_HVFileName); @@ -278,30 +282,15 @@ bool TrappingCorrectionAm241::Analyze() IllumSide.push_back(MString("HV")); IllumSide.push_back(MString("LV")); - vector> CTDHistograms; - map tempCTDHistHV; - map tempCTDHistLV; - CTDHistograms.push_back(tempCTDHistHV); - CTDHistograms.push_back(tempCTDHistLV); - - vector> HVEnergyHistograms; - map tempHVHistHV; - map tempHVHistLV; - HVEnergyHistograms.push_back(tempHVHistHV); - HVEnergyHistograms.push_back(tempHVHistLV); - - vector> LVEnergyHistograms; - map tempLVHistHV; - map tempLVHistLV; - LVEnergyHistograms.push_back(tempLVHistHV); - LVEnergyHistograms.push_back(tempLVHistLV); - - for (unsigned int s=0; s<2; ++s) { MString InputFile = FileNames[s]; vector HDFNames; + map CTDHistograms; + map HVEnergyHistograms; + map LVEnergyHistograms; + if ((InputFile.GetSubString(InputFile.Length() - 4)) == "hdf5") { HDFNames.push_back(InputFile); } else if ((InputFile.GetSubString(InputFile.Length() - 3)) == "txt") { @@ -455,16 +444,16 @@ bool TrappingCorrectionAm241::Analyze() Endpoints[PixelID].push_back(tempLVvec); } - TH1D* CTDHist = CTDHistograms[s][PixelID]; - TH1D* HVHist = HVEnergyHistograms[s][PixelID]; - TH1D* LVHist = LVEnergyHistograms[s][PixelID]; + TH1D* CTDHist = CTDHistograms[PixelID]; + TH1D* HVHist = HVEnergyHistograms[PixelID]; + TH1D* LVHist = LVEnergyHistograms[PixelID]; if (CTDHist == nullptr) { char name[64]; sprintf(name,"CTD: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); CTDHist->SetXTitle("CTD (ns)"); CTDHist->SetYTitle("Hits"); - CTDHistograms[s][PixelID] = CTDHist; + CTDHistograms[PixelID] = CTDHist; } if (HVHist == nullptr) { @@ -472,7 +461,7 @@ bool TrappingCorrectionAm241::Analyze() HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); HVHist->SetXTitle("HV Energy (keV)"); HVHist->SetYTitle("Hits"); - HVEnergyHistograms[s][PixelID] = HVHist; + HVEnergyHistograms[PixelID] = HVHist; } if (LVHist == nullptr) { @@ -480,7 +469,7 @@ bool TrappingCorrectionAm241::Analyze() LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); LVHist->SetXTitle("LV Energy (keV)"); LVHist->SetYTitle("Hits"); - LVEnergyHistograms[s][PixelID] = LVHist; + LVEnergyHistograms[PixelID] = LVHist; } CTDHist->Fill(CTD); @@ -495,37 +484,15 @@ bool TrappingCorrectionAm241::Analyze() IsFinished = Loader->IsFinished(); } } - } - - map>> FullDetEndpoints; - - vector> FullDetCTDHistograms; - map FullDettempCTDHistHV; - map FullDettempCTDHistLV; - FullDetCTDHistograms.push_back(FullDettempCTDHistHV); - FullDetCTDHistograms.push_back(FullDettempCTDHistLV); - - vector> FullDetHVEnergyHistograms; - map FullDettempHVHistHV; - map FullDettempHVHistLV; - FullDetHVEnergyHistograms.push_back(FullDettempHVHistHV); - FullDetHVEnergyHistograms.push_back(FullDettempHVHistLV); - - vector> FullDetLVEnergyHistograms; - map FullDettempLVHistHV; - map FullDettempLVHistLV; - FullDetLVEnergyHistograms.push_back(FullDettempLVHistHV); - FullDetLVEnergyHistograms.push_back(FullDettempLVHistLV); - - - for (unsigned int s=0; s<2; ++s) { - - for (auto H: CTDHistograms[s]) { + + map FullDetCTDHistograms; + map FullDetHVEnergyHistograms; + map FullDetLVEnergyHistograms; + + for (auto H: CTDHistograms) { int PixelID = H.first; int DetID = (PixelID-(PixelID%10000))/10000; - int LVSHID = (PixelID-(DetID*10000) - (PixelID%100))/100; - int HVSHID = (PixelID-(DetID*10000) - (LVSHID *100)); if (FullDetEndpoints.find(DetID)==FullDetEndpoints.end()) { vector tempHVvec; @@ -536,16 +503,16 @@ bool TrappingCorrectionAm241::Analyze() FullDetEndpoints[DetID].push_back(tempLVvec); } - TH1D* CTDHist = FullDetCTDHistograms[s][DetID]; - TH1D* HVHist = FullDetHVEnergyHistograms[s][DetID]; - TH1D* LVHist = FullDetLVEnergyHistograms[s][DetID]; + TH1D* CTDHist = FullDetCTDHistograms[DetID]; + TH1D* HVHist = FullDetHVEnergyHistograms[DetID]; + TH1D* LVHist = FullDetLVEnergyHistograms[DetID]; if (CTDHist == nullptr) { char name[64]; sprintf(name,"CTD: DetID %d %s Illumination",DetID,IllumSide[s].Data()); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); CTDHist->SetXTitle("CTD (ns)"); CTDHist->SetYTitle("Hits"); - FullDetCTDHistograms[s][DetID] = CTDHist; + FullDetCTDHistograms[DetID] = CTDHist; } if (HVHist == nullptr) { @@ -553,7 +520,7 @@ bool TrappingCorrectionAm241::Analyze() HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); HVHist->SetXTitle("HV Energy (keV)"); HVHist->SetYTitle("Hits"); - FullDetHVEnergyHistograms[s][DetID] = HVHist; + FullDetHVEnergyHistograms[DetID] = HVHist; } if (LVHist == nullptr) { @@ -561,42 +528,42 @@ bool TrappingCorrectionAm241::Analyze() LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); LVHist->SetXTitle("LV Energy (keV)"); LVHist->SetYTitle("Hits"); - FullDetLVEnergyHistograms[s][DetID] = LVHist; + FullDetLVEnergyHistograms[DetID] = LVHist; } CTDHist->Add(CTDHist, H.second); - HVHist->Add(HVHist, HVEnergyHistograms[s][ID]); - LVHist->Add(LVHist, LVEnergyHistograms[s][ID]); + HVHist->Add(HVHist, HVEnergyHistograms[PixelID]); + LVHist->Add(LVHist, LVEnergyHistograms[PixelID]); if (m_PixelCorrect==true) { - if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[s][ID]->Integral() > g_MinCounts) && (LVEnergyHistograms[s][ID]->Integral() > g_MinCounts)) { + if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[PixelID]->Integral() > g_MinCounts) && (LVEnergyHistograms[PixelID]->Integral() > g_MinCounts)) { TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); - TFitResultPtr HVFit = HVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); - TFitResultPtr LVFit = LVEnergyHistograms[s][ID]->Fit("gaus", "SQ"); + TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit("gaus", "SQ"); + TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit("gaus", "SQ"); if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { - Endpoints[ID][s].push_back(CTDFit->Parameter(1)); - Endpoints[ID][s].push_back(HVFit->Parameter(1)); - Endpoints[ID][s].push_back(LVFit->Parameter(1)); + Endpoints[PixelID][s].push_back(CTDFit->Parameter(1)); + Endpoints[PixelID][s].push_back(HVFit->Parameter(1)); + Endpoints[PixelID][s].push_back(LVFit->Parameter(1)); } else { - cout<<"Fits failed for Pixel "<Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[s][DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[s][DetID]->Integral() > g_MinCounts)) { + if ((H.second->Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[DetID]->Integral() > g_MinCounts)) { TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); - TFitResultPtr HVFit = FullDetHVEnergyHistograms[s][DetID]->Fit("gaus", "SQ"); - TFitResultPtr LVFit = FullDetLVEnergyHistograms[s][DetID]->Fit("gaus", "SQ"); + TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit("gaus", "SQ"); + TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit("gaus", "SQ"); if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { FullDetEndpoints[DetID][s].push_back(CTDFit->Parameter(1)); @@ -625,9 +592,9 @@ bool TrappingCorrectionAm241::Analyze() TCanvas* HVHistCanvas = new TCanvas(); HVHistCanvas->SetLogz(); HVHistCanvas->cd(); - FullDetHVEnergyHistograms[s][DetID]->Draw("colz"); + FullDetHVEnergyHistograms[DetID]->Draw("colz"); - FullDetHVEnergyHistograms[s][DetID]->Write(); + FullDetHVEnergyHistograms[DetID]->Write(); HVHistFile.Close(); TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); @@ -635,16 +602,16 @@ bool TrappingCorrectionAm241::Analyze() TCanvas* LVHistCanvas = new TCanvas(); LVHistCanvas->SetLogz(); LVHistCanvas->cd(); - FullDetLVEnergyHistograms[s][DetID]->Draw("colz"); + FullDetLVEnergyHistograms[DetID]->Draw("colz"); - FullDetLVEnergyHistograms[s][DetID]->Write(); + FullDetLVEnergyHistograms[DetID]->Write(); LVHistFile.Close(); } else { cout<<"Fits failed for Det "< DeltaHV; map DeltaLV; - for (auto E: Endpoints) { - int ID = E.first; + for (auto E: FullDetEndpoints) { + + int DetID = E.first; + + double HVSlope = 0; + double LVSlope = 0; + if ((E.second[0].size() > 0) && (E.second[1].size() > 0)) { - double HVSlope = (E.second[0][1] - E.second[1][1])/(E.second[0][0] - E.second[1][0]); - double LVSlope = (E.second[0][2] - E.second[1][2])/(E.second[0][0] - E.second[1][0]); - if (m_PixelCorrect==true) { - int DetID = (ID-(ID%10000))/10000; - int LVSHID = (ID-(DetID*10000) - (ID%100))/100; - int HVSHID = (ID-(DetID*10000) - (LVSHID *100)); - OutputCalFile<SetXTitle("HV Strip"); - TempHV->SetYTitle("LV Strip"); - TempHV->SetZTitle("Delta HV Energy"); - - char LVname[64]; sprintf(LVname,"Delta LV Map: Det %d",DetID); - TempLV = new TH2D(LVname, LVname, 64, 0, 64, 64, 0, 64); - TempLV->SetXTitle("HV Strip"); - TempLV->SetYTitle("LV Strip"); - TempLV->SetZTitle("Delta LV Energy"); - - DeltaHV[DetID] = TempHV; - DeltaLV[DetID] = TempLV; - } + HVSlope = (E.second[0][1] - E.second[1][1])/(E.second[0][0] - E.second[1][0]); + LVSlope = (E.second[0][2] - E.second[1][2])/(E.second[0][0] - E.second[1][0]); + } - DeltaHV[DetID]->SetBinContent(HVSHID, LVSHID, E.second[0][1] - E.second[1][1]); - DeltaLV[DetID]->SetBinContent(HVSHID, LVSHID, E.second[0][2] - E.second[1][2]); + for (int hv=0; hv 0) && (Endpoints[PixelID][1].size() > 0)) { + + HVSlope = (Endpoints[PixelID][0][1] - Endpoints[PixelID][1][1])/(Endpoints[PixelID][0][0] - Endpoints[PixelID][1][0]); + LVSlope = (Endpoints[PixelID][0][2] - Endpoints[PixelID][1][2])/(Endpoints[PixelID][0][0] - Endpoints[PixelID][1][0]); + + TH2D* TempHV = DeltaHV[DetID]; + TH2D* TempLV = DeltaLV[DetID]; + + if (TempHV == nullptr) { + + char HVname[64]; sprintf(HVname,"Delta HV Map: Det %d",DetID); + TempHV = new TH2D(HVname, HVname, g_HVStrips, 0, g_HVStrips, g_LVStrips, 0, g_LVStrips); + TempHV->SetXTitle("HV Strip"); + TempHV->SetYTitle("LV Strip"); + TempHV->SetZTitle("Delta HV Energy"); + + char LVname[64]; sprintf(LVname,"Delta LV Map: Det %d",DetID); + TempLV = new TH2D(LVname, LVname, g_HVStrips, 0, g_HVStrips, g_LVStrips, 0, g_LVStrips); + TempLV->SetXTitle("HV Strip"); + TempLV->SetYTitle("LV Strip"); + TempLV->SetZTitle("Delta LV Energy"); + + DeltaHV[DetID] = TempHV; + DeltaLV[DetID] = TempLV; + } + DeltaHV[DetID]->SetBinContent(hv, lv, Endpoints[PixelID][0][1] - Endpoints[PixelID][1][1]); + DeltaLV[DetID]->SetBinContent(hv, lv, Endpoints[PixelID][0][2] - Endpoints[PixelID][1][2]); + } } } + OutputCalFile< Date: Fri, 11 Jul 2025 14:54:52 -0700 Subject: [PATCH 75/90] CHG: Updated CTD and photopeak models --- apps/TrappingCorrectionAm241.cxx | 101 +++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index bfaa2625..4527b052 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -37,6 +37,8 @@ using namespace std; #include #include #include +#include +#include #include #include #include @@ -61,8 +63,8 @@ using namespace std; #include "MAssembly.h" -double g_MinCTD = -300; -double g_MaxCTD = 300; +double g_MinCTD = -400; +double g_MaxCTD = 400; int g_MinCounts = 1000; int g_HVStrips = 64; @@ -87,6 +89,10 @@ class TrappingCorrectionAm241 //! Interrupt the analysis void Interrupt() { m_Interrupt = true; } + //! Produce functions for fitting + TF1* GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess, double FlipSwitch); + TF1* GeneratePhotopeakFunction(); + MStripHit* GetDominantStrip(vector& Strips, double& EnergyFraction); private: @@ -284,6 +290,19 @@ bool TrappingCorrectionAm241::Analyze() for (unsigned int s=0; s<2; ++s) { + double CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch; + if (IllumSide[s]=="HV") { + FlipSwitch = 1; + CTDFitMin = g_MinCTD; + CTDFitMax = 0; + CTDGuess = -300; + } else { + FlipSwitch = -1; + CTDFitMin = 0; + CTDFitMax = g_MaxCTD; + CTDGuess = 300; + } + MString InputFile = FileNames[s]; vector HDFNames; @@ -537,13 +556,18 @@ bool TrappingCorrectionAm241::Analyze() if (m_PixelCorrect==true) { if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[PixelID]->Integral() > g_MinCounts) && (LVEnergyHistograms[PixelID]->Integral() > g_MinCounts)) { + + TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch); + TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); - TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); - TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit("gaus", "SQ"); - TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit("gaus", "SQ"); + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 55, 70); + + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 55, 70); if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { - Endpoints[PixelID][s].push_back(CTDFit->Parameter(1)); + Endpoints[PixelID][s].push_back(CTDFit->Parameter(2)); Endpoints[PixelID][s].push_back(HVFit->Parameter(1)); Endpoints[PixelID][s].push_back(LVFit->Parameter(1)); } else { @@ -561,12 +585,17 @@ bool TrappingCorrectionAm241::Analyze() if ((H.second->Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[DetID]->Integral() > g_MinCounts)) { - TFitResultPtr CTDFit = H.second->Fit("gaus", "SQ"); - TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit("gaus", "SQ"); - TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit("gaus", "SQ"); + TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch); + TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 55, 70); + + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 55, 70); if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { - FullDetEndpoints[DetID][s].push_back(CTDFit->Parameter(1)); + FullDetEndpoints[DetID][s].push_back(CTDFit->Parameter(2)); FullDetEndpoints[DetID][s].push_back(HVFit->Parameter(1)); FullDetEndpoints[DetID][s].push_back(LVFit->Parameter(1)); @@ -619,7 +648,7 @@ bool TrappingCorrectionAm241::Analyze() //setup output file ofstream OutputCalFile; OutputCalFile.open(m_OutFile+MString("_parameters.txt")); - OutputCalFile<<"Det ID"<<"HV Strip ID"<<"LV Strip ID"<<'\t'<<"HV Slope"<<'\t'<<"LV Slope"< DeltaHV; map DeltaLV; @@ -711,6 +740,56 @@ bool TrappingCorrectionAm241::Analyze() //////////////////////////////////////////////////////////////////////////////// +TF1* TrappingCorrectionAm241::GeneratePhotopeakFunction() +{ + // Gaussian with a low-E shelf + TF1* PhotopeakFunction = new TF1("PhotopeakFunction", "gaus(0) + [0]*[3]*(1 - erf((x-[1])/(sqrt(2)*[2])))", 55, 70); + + PhotopeakFunction->SetParName(0, "Gauss norm"); + PhotopeakFunction->SetParName(1, "Mu"); + PhotopeakFunction->SetParName(2, "Sigma"); + PhotopeakFunction->SetParName(3, "Shelf norm"); + + PhotopeakFunction->SetParameter("Gauss norm", 1000); + PhotopeakFunction->SetParameter("Mu", 60); + PhotopeakFunction->SetParameter("Sigma", 2); + PhotopeakFunction->SetParameter("Shelf norm", 0.05); + + PhotopeakFunction->SetParLimits(1, 55, 65); + PhotopeakFunction->SetParLimits(3, 0, 0.1); + + return PhotopeakFunction; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +TF1* TrappingCorrectionAm241::GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess, double FlipSwitch) +{ + // Exponentially modified gaussian + TF1* CTDFunction = new TF1("CTDFunction", "[0]*([1]/2)*exp(([1]/2)*(([1]*[3]*[3]) - 2*[4]*(x-[2])))*erfc((([1]*[3]*[3]) - [4]*(x-[2]))/([3]*sqrt(2)))", g_MinCTD, g_MaxCTD); + + CTDFunction->SetParName(0, "Norm"); + CTDFunction->SetParName(1, "Lambda"); + CTDFunction->SetParName(2, "Mu"); + CTDFunction->SetParName(3, "Sigma"); + CTDFunction->SetParName(4, "Flip"); + + CTDFunction->SetParameter("Norm", 1000); + CTDFunction->SetParameter("Lambda", 0.05); + CTDFunction->SetParameter("Sigma", 16); + CTDFunction->SetParameter("Mu", CTDGuess); + CTDFunction->FixParameter(4, FlipSwitch); + CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); + + return CTDFunction; +} + + +//////////////////////////////////////////////////////////////////////////////// + + TrappingCorrectionAm241* g_Prg = 0; int g_NInterruptCatches = 1; From e6ce0631ad92328ef35fa94e4a30dcbf9b5ed075 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 11 Jul 2025 15:55:38 -0700 Subject: [PATCH 76/90] CHG: Place limits on parameters to avoid unreasonable fits --- apps/TrappingCorrectionAm241.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 4527b052..496aaabf 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -755,7 +755,9 @@ TF1* TrappingCorrectionAm241::GeneratePhotopeakFunction() PhotopeakFunction->SetParameter("Sigma", 2); PhotopeakFunction->SetParameter("Shelf norm", 0.05); + PhotopeakFunction->SetParLimits(0, 10, 1e8); PhotopeakFunction->SetParLimits(1, 55, 65); + PhotopeakFunction->SetParLimits(2, 0.1, 10); PhotopeakFunction->SetParLimits(3, 0, 0.1); return PhotopeakFunction; @@ -781,7 +783,11 @@ TF1* TrappingCorrectionAm241::GenerateCTDFunction(double CTDFitMin, double CTDFi CTDFunction->SetParameter("Sigma", 16); CTDFunction->SetParameter("Mu", CTDGuess); CTDFunction->FixParameter(4, FlipSwitch); + + CTDFunction->SetParLimits(0, 0, 1e8); + CTDFunction->SetParLimits(1, 0, 1); CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); + CTDFunction->SetParLimits(3, 0, 100); return CTDFunction; } From c85f83cdace65c8da5f4ec83b08fd235a5f0e685 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 18 Jul 2025 13:26:17 -0700 Subject: [PATCH 77/90] CHG: Changed naming conventions so that strips are referred to using HV and LV throughout --- src/MModuleDepthCalibration2024.cxx | 138 ++++++++++------------------ 1 file changed, 51 insertions(+), 87 deletions(-) diff --git a/src/MModuleDepthCalibration2024.cxx b/src/MModuleDepthCalibration2024.cxx index e9881af5..135db6dc 100644 --- a/src/MModuleDepthCalibration2024.cxx +++ b/src/MModuleDepthCalibration2024.cxx @@ -220,8 +220,6 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) int Grade = GetHitGrade(H); - // cout << "got a hit with grade " << Grade << endl; - // Handle different grades differently // GRADE=-1 is an error. Break from the loop and continue. if ( Grade < 0 ){ @@ -248,51 +246,41 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) // Calculate the position. If error is thrown, record and no depth. // Take a Hit and separate its activated X- and Y-strips into separate vectors. - std::vector XStrips; - std::vector YStrips; - // cout << "looping over strip hits..." << endl; + std::vector LVStrips; + std::vector HVStrips; for( unsigned int j = 0; j < H->GetNStripHits(); ++j){ - // cout << "strip hit " << j << endl; MStripHit* SH = H->GetStripHit(j); - if( SH->IsLowVoltageStrip() ) XStrips.push_back(SH); else YStrips.push_back(SH); + if( SH->IsLowVoltageStrip() ) LVStrips.push_back(SH); else HVStrips.push_back(SH); } - // cout << "finished looping over strip hits" << endl; - double XEnergyFraction; - double YEnergyFraction; - MStripHit* XSH = GetDominantStrip(XStrips, XEnergyFraction); - MStripHit* YSH = GetDominantStrip(YStrips, YEnergyFraction); - - // cout << "found the dominant strips" << endl; + double LVEnergyFraction; + double HVEnergyFraction; + MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); + MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); double CTD_s = 0.0; //now try and get z position - int DetID = XSH->GetDetectorID(); - int XStripID = XSH->GetStripID(); - int YStripID = YSH->GetStripID(); - int pixel_code = 10000*DetID + 100*XStripID + YStripID; + int DetID = LVSH->GetDetectorID(); + int LVStripID = LVSH->GetStripID(); + int HVStripID = HVSH->GetStripID(); + int PixelCode = 10000*DetID + 100*LVStripID + HVStripID; // TODO: Calculate X and Y positions more rigorously using charge sharing. - // Somewhat confusing notation: XStrips run parallel to X-axis, so we calculate X position with YStrips. - double Xpos = m_YPitches[DetID]*((m_NYStrips[DetID]/2.0) - ((double)YStripID)); - double Ypos = m_XPitches[DetID]*((m_NXStrips[DetID]/2.0) - ((double)XStripID)); - // cout << "X position " << Xpos << endl; - // cout << "Y position " << Ypos << endl; + // Somewhat confusing notation: HVStrips run parallel to X-axis, so we calculate X position with LVStrips. + double Xpos = m_YPitches[DetID]*((m_NYStrips[DetID]/2.0) - ((double)LVStripID)); + double Ypos = m_XPitches[DetID]*((m_NXStrips[DetID]/2.0) - ((double)HVStripID)); double Zpos = 0.0; double Xsigma = m_YPitches[DetID]/sqrt(12.0); double Ysigma = m_XPitches[DetID]/sqrt(12.0); double Zsigma = m_Thicknesses[DetID]/sqrt(12.0); - // cout << "looking up the coefficients" << endl; - vector* Coeffs = GetPixelCoeffs(pixel_code); + vector* Coeffs = GetPixelCoeffs(PixelCode); // TODO: For Card Cage, may need to add noise - double XTiming = XSH->GetTiming(); - double YTiming = YSH->GetTiming(); - - // cout << "Got the coefficients: " << Coeffs << endl; + double LVTiming = LVSH->GetTiming(); + double HVTiming = HVSH->GetTiming(); // If there aren't coefficients loaded, then calibration is incomplete. if( Coeffs == nullptr ){ @@ -303,8 +291,7 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) } // If there isn't timing information, set no depth. // Alex's old comments suggest assigning the event to the middle of the detector and the position resolution to be large. - else if( (XTiming < 1.0E-6) || (YTiming < 1.0E-6) ){ - // cout << "no timing info" << endl; + else if( (LVTiming < 1.0E-6) || (HVTiming < 1.0E-6) ){ ++m_Error3; H->SetNoDepth(); Event->SetDepthCalibrationIncomplete(); @@ -322,29 +309,15 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) Event->SetDepthCalibrationIncomplete(); } - double CTD; - if ( XSH->IsLowVoltageStrip() ){ - CTD = (YTiming - XTiming); - } - else { - CTD = (XTiming - YTiming); - } - - // cout << "Got the CTD: " << CTD << endl; + double CTD = (HVTiming - LVTiming); // Confirmed that this matches SP's python code. CTD_s = (CTD - Coeffs->at(1))/(Coeffs->at(0)); //apply inverse stretch and offset - // cout << "Transformed CTD: " << CTD_s << endl; - double Xmin = * std::min_element(ctdvec.begin(), ctdvec.end()); double Xmax = * std::max_element(ctdvec.begin(), ctdvec.end()); - // cout << "Got the min and max ctd values: " << Xmin << "; " << Xmax << endl; - - double noise = GetTimingNoiseFWHM(pixel_code, H->GetEnergy()); - - // cout << "Got the timing noise: " << noise << endl; + double noise = GetTimingNoiseFWHM(PixelCode, H->GetEnergy()); //if the CTD is out of range, check if we should reject the event. if( (CTD_s < (Xmin - 2.0*noise)) || (CTD_s > (Xmax + 2.0*noise)) ){ @@ -355,7 +328,6 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) // If the CTD is in range, calculate the depth else { - // cout << "Calculating depth" << endl; // Calculate the probability given timing noise of CTD_s corresponding to the values of depth in depthvec // Utlize symmetry of the normal distribution. vector prob_dist = norm_pdf(ctdvec, CTD_s, noise/2.355); @@ -366,7 +338,6 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) prob_sum += prob_dist[k]; } //double prob_sum = std::accumulate(prob_dist.begin(), prob_dist.end(), 0); - //cout << "summed probability: " << prob_sum << endl; double weighted_depth = 0.0; for( unsigned int k = 0; k < depthvec.size(); ++k ){ weighted_depth += prob_dist[k]*depthvec[k]; @@ -395,23 +366,16 @@ bool MModuleDepthCalibration2024::AnalyzeEvent(MReadOutAssembly* Event) LocalPosition.SetXYZ(Xpos, Ypos, Zpos); LocalOrigin.SetXYZ(0.0,0.0,0.0); - // cout << m_DetectorNames[DetID] << endl; GlobalPosition = m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalPosition); - // cout << "Found the GlobalPosition" << endl; // Make sure XYZ resolution are correctly mapped to the global coord system. PositionResolution.SetXYZ(Xsigma, Ysigma, Zsigma); GlobalResolution = ((m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(PositionResolution)) - (m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalOrigin))).Abs(); - // cout << "Set the PositionResolution vector" << endl; - H->SetPosition(GlobalPosition); - // cout << "Set the global position for the strip hit" << endl; - H->SetPositionResolution(GlobalResolution); - // cout << "Set the position resolution for the strip hit" << endl; } @@ -446,14 +410,14 @@ MStripHit* MModuleDepthCalibration2024::GetDominantStrip(vector& Str return MaxStrip; } -double MModuleDepthCalibration2024::GetTimingNoiseFWHM(int pixel_code, double Energy) +double MModuleDepthCalibration2024::GetTimingNoiseFWHM(int PixelCode, double Energy) { // Placeholder for determining the timing noise with energy, and possibly even on a pixel-by-pixel basis. // Should follow 1/E relation // TODO: Determine real energy dependence and implement it here. double noiseFWHM = 0.0; if ( m_Coeffs_Energy != 0 ){ - noiseFWHM = m_Coeffs[pixel_code][2] * m_Coeffs_Energy/Energy; + noiseFWHM = m_Coeffs[PixelCode][2] * m_Coeffs_Energy/Energy; if ( noiseFWHM < 3.0*2.355 ){ noiseFWHM = 3.0*2.355; } @@ -469,7 +433,7 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) // Read in the stretch and offset file, which should have a header line with information on the measurements: // ### 800 V 80 K 59.5 keV // And which should contain for each pixel: - // Pixel code (10000*det + 100*Xchannel + Ychannel), Stretch, Offset, Timing/CTD noise, Chi2 for the CTD fit (for diagnostics mainly) + // Pixel code (10000*det + 100*LVStrip + HVStrip), Stretch, Offset, Timing/CTD noise, Chi2 for the CTD fit (for diagnostics mainly) MFile F; if( F.Open(FName) == false ){ cout << "ERROR in MModuleDepthCalibration2024::LoadCoeffsFile: failed to open coefficients file." << endl; @@ -485,7 +449,7 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) else { std::vector Tokens = Line.Tokenize(","); if( Tokens.size() == 5 ){ - int pixel_code = Tokens[0].ToInt(); + int PixelCode = Tokens[0].ToInt(); double Stretch = Tokens[1].ToDouble(); double Offset = Tokens[2].ToDouble(); double CTD_FWHM = Tokens[3].ToDouble() * 2.355; @@ -493,7 +457,7 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) // Previous iteration of depth calibration read in "Scale" instead of ctd resolution. vector coeffs; coeffs.push_back(Stretch); coeffs.push_back(Offset); coeffs.push_back(CTD_FWHM); coeffs.push_back(Chi2); - m_Coeffs[pixel_code] = coeffs; + m_Coeffs[PixelCode] = coeffs; } } } @@ -504,14 +468,14 @@ bool MModuleDepthCalibration2024::LoadCoeffsFile(MString FName) } -std::vector* MModuleDepthCalibration2024::GetPixelCoeffs(int pixel_code) +std::vector* MModuleDepthCalibration2024::GetPixelCoeffs(int PixelCode) { // Check to see if the stretch and offset have been loaded. If so, try to get the coefficients for the specified pixel. if( m_CoeffsFileIsLoaded ){ - if( m_Coeffs.count(pixel_code) > 0 ){ - return &m_Coeffs[pixel_code]; + if( m_Coeffs.count(PixelCode) > 0 ){ + return &m_Coeffs[PixelCode]; } else { - cout << "MModuleDepthCalibration2024::GetPixelCoeffs: cannot get stretch and offset; pixel code " << pixel_code << " not found." << endl; + cout << "MModuleDepthCalibration2024::GetPixelCoeffs: cannot get stretch and offset; pixel code " << PixelCode << " not found." << endl; return nullptr; } } else { @@ -609,21 +573,21 @@ int MModuleDepthCalibration2024::GetHitGrade(MHit* H){ } // Take a Hit and separate its activated p and n strips into separate vectors. - std::vector PStrips; - std::vector NStrips; - vector PStripIDs; - vector NStripIDs; + std::vector LVStrips; + std::vector HVStrips; + vector LVStripIDs; + vector HVStripIDs; for( unsigned int j = 0; j < H->GetNStripHits(); ++j){ MStripHit* SH = H->GetStripHit(j); if( SH == NULL ) { cout << "ERROR in MModuleDepthCalibration2024: Depth Calibration: got NULL strip hit :( " << endl; return -1;} if( SH->GetEnergy() == 0 ) { cout << "ERROR in MModuleDepthCalibration2024: Depth Calibration: got strip without energy :( " << endl; return -1;} if( SH->IsLowVoltageStrip() ){ - PStrips.push_back(SH); - PStripIDs.push_back(SH->GetStripID()); + LVStrips.push_back(SH); + LVStripIDs.push_back(SH->GetStripID()); } else { - NStrips.push_back(SH); - NStripIDs.push_back(SH->GetStripID()); + HVStrips.push_back(SH); + HVStripIDs.push_back(SH->GetStripID()); } } @@ -634,15 +598,15 @@ int MModuleDepthCalibration2024::GetHitGrade(MHit* H){ return 5; } - if( PStrips.size()>0 && NStrips.size()>0 ){ - int Nmin = * std::min_element(NStripIDs.begin(), NStripIDs.end()); - int Nmax = * std::max_element(NStripIDs.begin(), NStripIDs.end()); + if( LVStrips.size()>0 && HVStrips.size()>0 ){ + int HVmin = * std::min_element(HVStripIDs.begin(), HVStripIDs.end()); + int HVmax = * std::max_element(HVStripIDs.begin(), HVStripIDs.end()); - int Pmin = * std::min_element(PStripIDs.begin(), PStripIDs.end()); - int Pmax = * std::max_element(PStripIDs.begin(), PStripIDs.end()); + int LVmin = * std::min_element(LVStripIDs.begin(), LVStripIDs.end()); + int LVmax = * std::max_element(LVStripIDs.begin(), LVStripIDs.end()); // If the strip hits are not all adjacent, it's a bad grade. - if ( ((Nmax - Nmin) >= (NStrips.size())) || ((Pmax - Pmin) >= (PStrips.size())) ){ + if ( ((HVmax - HVmin) >= (HVStrips.size())) || ((LVmax - LVmin) >= (LVStrips.size())) ){ return 6; } } @@ -654,48 +618,48 @@ int MModuleDepthCalibration2024::GetHitGrade(MHit* H){ int return_value; // If 1 strip on each side, GRADE=0 // This represents the center of the pixel - if( ((PStrips.size() == 1) && (NStrips.size() == 1)) || ((PStrips.size() == 3) && (NStrips.size() == 3)) ){ + if( ((LVStrips.size() == 1) && (HVStrips.size() == 1)) || ((LVStrips.size() == 3) && (HVStrips.size() == 3)) ){ return_value = 0; } // If 2 hits on N side and 1 on P, GRADE=1 // This represents the middle of the edges of the pixel - else if( (PStrips.size() == 1) && (NStrips.size() == 2) ){ + else if( (LVStrips.size() == 1) && (HVStrips.size() == 2) ){ return_value = 1; } // If 2 hits on P and 1 on N, GRADE=2 // This represents the middle of the edges of the pixel - else if( (PStrips.size() == 2) && (NStrips.size() == 1) ){ + else if( (LVStrips.size() == 2) && (HVStrips.size() == 1) ){ return_value = 2; } // If 2 strip hits on both sides, GRADE=3 // This represents the corners the pixel - else if( (PStrips.size() == 2) && (NStrips.size() == 2) ){ + else if( (LVStrips.size() == 2) && (HVStrips.size() == 2) ){ return_value = 3; } // If 3 hits on N side and 1 on P, GRADE=0 // This represents the middle of the pixel, near the p (LV) side of the detector. - else if( (PStrips.size() == 1) && (NStrips.size() == 3) ){ + else if( (LVStrips.size() == 1) && (HVStrips.size() == 3) ){ return_value = 0; } // If 3 hits on P and 1 on N, GRADE=0 // This represents the middle of the pixel, near the n (HV) side of the detector. - else if( (PStrips.size() == 3) && (NStrips.size() == 1) ){ + else if( (LVStrips.size() == 3) && (HVStrips.size() == 1) ){ return_value = 0; } // If 3 hits on N side and 2 on P, GRADE=0 // This represents the middle of the edge of the pixel, near the p (LV) side of the detector. - else if( (PStrips.size() == 2) && (NStrips.size() == 3) ){ + else if( (LVStrips.size() == 2) && (HVStrips.size() == 3) ){ return_value = 2; } // If 3 hits on P and 2 on N, GRADE=0 // This represents the middle of the edge of the pixel, near the n (HV) side of the detector. - else if( (PStrips.size() == 3) && (NStrips.size() == 2) ){ + else if( (LVStrips.size() == 3) && (HVStrips.size() == 2) ){ return_value = 1; } From 325fad2b4cb7ad2e6afed983078477169a85d829 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Fri, 18 Jul 2025 13:40:49 -0700 Subject: [PATCH 78/90] CHG: update header to make function arguments match source file --- include/MModuleDepthCalibration2024.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/MModuleDepthCalibration2024.h b/include/MModuleDepthCalibration2024.h index 9923efac..21f48291 100644 --- a/include/MModuleDepthCalibration2024.h +++ b/include/MModuleDepthCalibration2024.h @@ -104,11 +104,11 @@ class MModuleDepthCalibration2024 : public MModule //! Load in the specified coefficients file bool LoadCoeffsFile(MString FName); //! Return the coefficients for a pixel - vector* GetPixelCoeffs(int pixel_code); + vector* GetPixelCoeffs(int PixelCode); //! Load the splines file bool LoadSplinesFile(MString FName); //! Get the timing FWHM noise for the specified pixel and Energy - double GetTimingNoiseFWHM(int pixel_code, double Energy); + double GetTimingNoiseFWHM(int PixelCode, double Energy); // private methods From 0069237292a95f5a1bad706ccb3c9e883e81df43 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 11:55:05 -0700 Subject: [PATCH 79/90] CHG: Create and fill a directory for pixel-by-pixel results and plots --- apps/TrappingCorrectionAm241.cxx | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 496aaabf..ed8e3fa6 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -17,6 +17,7 @@ // Standard #include +#include #include #include #include @@ -288,6 +289,13 @@ bool TrappingCorrectionAm241::Analyze() IllumSide.push_back(MString("HV")); IllumSide.push_back(MString("LV")); + MString PixelDir = m_OutFile + MString("_pixeldata"); + if (m_PixelCorrect==true) { + if (std::filesystem::create_directories(PixelDir.Data())==false) { + cout<<"Directory '"<Add(LVHist, LVEnergyHistograms[PixelID]); if (m_PixelCorrect==true) { + + // Write each of the histograms to a root file if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[PixelID]->Integral() > g_MinCounts) && (LVEnergyHistograms[PixelID]->Integral() > g_MinCounts)) { + double CTDGuess = H.second->GetBinCenter(H.second->GetMaximumBin()); TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch); TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + ofstream CTDFitFile(PixelDir +MString("/") + PixelID+MString("_CTDFitResult_")+IllumSide[s]+ MString("Illum.txt")); + streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(CTDFitFile.rdbuf()); + if (CTDFit.Get()) { + CTDFit->Print(); + } + cout.rdbuf(coutbuf); + CTDFitFile.close(); + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 55, 70); + ofstream HVFitFile(PixelDir +MString("/") + PixelID+MString("_HVEnergyFitResult_")+IllumSide[s]+ MString("Illum.txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(HVFitFile.rdbuf()); + if (HVFit.Get()) { + HVFit->Print(); + } + cout.rdbuf(coutbuf); + HVFitFile.close(); + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 55, 70); + + ofstream LVFitFile(PixelDir +MString("/") + PixelID+MString("_LVEnergyFitResult_")+IllumSide[s]+ MString("Illum.txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit.Get()) { + LVFit->Print(); + } + cout.rdbuf(coutbuf); + LVFitFile.close(); if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { Endpoints[PixelID][s].push_back(CTDFit->Parameter(2)); @@ -576,6 +614,18 @@ bool TrappingCorrectionAm241::Analyze() } else { cout<<"Fewer than "<Write(); + CTDHistFile.Close(); + + TFile HVHistFile(PixelDir+MString("/")+PixelID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + HVEnergyHistograms[PixelID]->Write(); + HVHistFile.Close(); + + TFile LVHistFile(PixelDir+MString("/")+PixelID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); + LVEnergyHistograms[PixelID]->Write(); + LVHistFile.Close(); } } From 39d520413d86a933327ea93c1f11c4a6f7557ed5 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 11:56:18 -0700 Subject: [PATCH 80/90] CHG: better parameter initialization and bounds for fits --- apps/TrappingCorrectionAm241.cxx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index ed8e3fa6..a39b483e 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -298,22 +298,22 @@ bool TrappingCorrectionAm241::Analyze() for (unsigned int s=0; s<2; ++s) { - double CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch; + double CTDFitMin, CTDFitMax, FlipSwitch; if (IllumSide[s]=="HV") { FlipSwitch = 1; CTDFitMin = g_MinCTD; CTDFitMax = 0; - CTDGuess = -300; } else { FlipSwitch = -1; CTDFitMin = 0; CTDFitMax = g_MaxCTD; - CTDGuess = 300; } MString InputFile = FileNames[s]; vector HDFNames; + TH1::SetDefaultSumw2(); + map CTDHistograms; map HVEnergyHistograms; map LVEnergyHistograms; @@ -635,6 +635,7 @@ bool TrappingCorrectionAm241::Analyze() if ((H.second->Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[DetID]->Integral() > g_MinCounts)) { + double CTDGuess = H.second->GetBinCenter(H.second->GetMaximumBin()); TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch); TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); @@ -807,7 +808,7 @@ TF1* TrappingCorrectionAm241::GeneratePhotopeakFunction() PhotopeakFunction->SetParLimits(0, 10, 1e8); PhotopeakFunction->SetParLimits(1, 55, 65); - PhotopeakFunction->SetParLimits(2, 0.1, 10); + PhotopeakFunction->SetParLimits(2, 1.0, 10); PhotopeakFunction->SetParLimits(3, 0, 0.1); return PhotopeakFunction; @@ -820,7 +821,7 @@ TF1* TrappingCorrectionAm241::GeneratePhotopeakFunction() TF1* TrappingCorrectionAm241::GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess, double FlipSwitch) { // Exponentially modified gaussian - TF1* CTDFunction = new TF1("CTDFunction", "[0]*([1]/2)*exp(([1]/2)*(([1]*[3]*[3]) - 2*[4]*(x-[2])))*erfc((([1]*[3]*[3]) - [4]*(x-[2]))/([3]*sqrt(2)))", g_MinCTD, g_MaxCTD); + TF1* CTDFunction = new TF1("CTDFunction", "[0]*([1]/2)*exp(([1]/2)*(([1]*[3]*[3]) - 2*[4]*(x-[2])))*erfc((([1]*[3]*[3]) - [4]*(x-[2]))/([3]*sqrt(2)))", CTDFitMin, CTDFitMax); CTDFunction->SetParName(0, "Norm"); CTDFunction->SetParName(1, "Lambda"); @@ -830,14 +831,14 @@ TF1* TrappingCorrectionAm241::GenerateCTDFunction(double CTDFitMin, double CTDFi CTDFunction->SetParameter("Norm", 1000); CTDFunction->SetParameter("Lambda", 0.05); - CTDFunction->SetParameter("Sigma", 16); + CTDFunction->SetParameter("Sigma", 12); CTDFunction->SetParameter("Mu", CTDGuess); CTDFunction->FixParameter(4, FlipSwitch); CTDFunction->SetParLimits(0, 0, 1e8); - CTDFunction->SetParLimits(1, 0, 1); + CTDFunction->SetParLimits(1, 0.01, 1); CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); - CTDFunction->SetParLimits(3, 0, 100); + CTDFunction->SetParLimits(3, 6, 30); return CTDFunction; } From 3ebc9a668731187559b7b93d24f993fcadf7c176 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 11:58:03 -0700 Subject: [PATCH 81/90] CHG: Write detailed fit results to files. Plot deltaE maps and histograms --- apps/TrappingCorrectionAm241.cxx | 177 ++++++++++++++++++++++--------- 1 file changed, 129 insertions(+), 48 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index a39b483e..8171c013 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -650,19 +650,39 @@ bool TrappingCorrectionAm241::Analyze() FullDetEndpoints[DetID][s].push_back(HVFit->Parameter(1)); FullDetEndpoints[DetID][s].push_back(LVFit->Parameter(1)); - cout<<"Results of Det "<Print(); - cout<<"Results of Det "<Print(); - cout<<"Results of Det "<Print(); + ofstream CTDFitFile(DetID+MString("_CTDFitResult_")+IllumSide[s]+ MString("Illum.txt")); + streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(CTDFitFile.rdbuf()); + if (CTDFit.Get()) { + CTDFit->Print(); + } + cout.rdbuf(coutbuf); + CTDFitFile.close(); + + ofstream HVFitFile(DetID+MString("_HVEnergyFitResult_")+IllumSide[s]+ MString("Illum.txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(HVFitFile.rdbuf()); + if (HVFit.Get()) { + HVFit->Print(); + } + cout.rdbuf(coutbuf); + HVFitFile.close(); + + ofstream LVFitFile(DetID+MString("_LVEnergyFitResult_")+IllumSide[s]+ MString("Illum.txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit.Get()) { + LVFit->Print(); + } + cout.rdbuf(coutbuf); + LVFitFile.close(); TFile CTDFile(m_OutFile+MString("_Det")+DetID+MString("_CTDHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); TCanvas* CTDCanvas = new TCanvas(); - CTDCanvas->SetLogz(); CTDCanvas->cd(); - H.second->Draw("colz"); + H.second->Draw("hist"); + CTDFunction->Draw("same"); H.second->Write(); CTDFile.Close(); @@ -670,9 +690,9 @@ bool TrappingCorrectionAm241::Analyze() TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_HVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); TCanvas* HVHistCanvas = new TCanvas(); - HVHistCanvas->SetLogz(); HVHistCanvas->cd(); - FullDetHVEnergyHistograms[DetID]->Draw("colz"); + FullDetHVEnergyHistograms[DetID]->Draw("hist"); + PhotopeakFunctionHV->Draw("same"); FullDetHVEnergyHistograms[DetID]->Write(); HVHistFile.Close(); @@ -680,9 +700,9 @@ bool TrappingCorrectionAm241::Analyze() TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + IllumSide[s]+ MString("Illum.root"),"recreate"); TCanvas* LVHistCanvas = new TCanvas(); - LVHistCanvas->SetLogz(); LVHistCanvas->cd(); - FullDetLVEnergyHistograms[DetID]->Draw("colz"); + FullDetLVEnergyHistograms[DetID]->Draw("hist"); + PhotopeakFunctionLV->Draw("same"); FullDetLVEnergyHistograms[DetID]->Write(); LVHistFile.Close(); @@ -699,21 +719,32 @@ bool TrappingCorrectionAm241::Analyze() //setup output file ofstream OutputCalFile; OutputCalFile.open(m_OutFile+MString("_parameters.txt")); - OutputCalFile<<"# Det ID"<<'\t'<<"HV Strip ID"<<'\t'<<"LV Strip ID"<<'\t'<<"HV Slope"<<'\t'<<"LV Slope"< DeltaHVMap; + map DeltaLVMap; - map DeltaHV; - map DeltaLV; + map DeltaHVHist; + map DeltaLVHist; for (auto E: FullDetEndpoints) { int DetID = E.first; - double HVSlope = 0; - double LVSlope = 0; + double HVIllumCTD = 0; + double LVIllumCTD = 0; + double HVIllumHVCentroid = 0; + double LVIllumHVCentroid = 0; + double HVIllumLVCentroid = 0; + double LVIllumLVCentroid = 0; if ((E.second[0].size() > 0) && (E.second[1].size() > 0)) { - HVSlope = (E.second[0][1] - E.second[1][1])/(E.second[0][0] - E.second[1][0]); - LVSlope = (E.second[0][2] - E.second[1][2])/(E.second[0][0] - E.second[1][0]); + HVIllumCTD = E.second[0][0]; + LVIllumCTD = E.second[1][0]; + HVIllumHVCentroid = E.second[0][1]; + LVIllumHVCentroid = E.second[1][1]; + HVIllumLVCentroid = E.second[0][2]; + LVIllumLVCentroid = E.second[1][2]; } for (int hv=0; hvSetXTitle("HV Strip"); + TempHVMap->SetYTitle("LV Strip"); + TempHVMap->SetZTitle("Delta HV Energy"); + + char LVname[64]; sprintf(LVname,"Delta LV Map: Det %d",DetID); + TempLVMap = new TH2D(LVname, LVname, g_HVStrips, -0.5, g_HVStrips-0.5, g_LVStrips, -0.5, g_LVStrips-0.5); + TempLVMap->SetXTitle("HV Strip"); + TempLVMap->SetYTitle("LV Strip"); + TempLVMap->SetZTitle("Delta LV Energy"); + + DeltaHVMap[DetID] = TempHVMap; + DeltaLVMap[DetID] = TempLVMap; + } + + if (TempHVHist == nullptr) { + + char HVname[64]; sprintf(HVname,"Delta HV Hist: Det %d",DetID); + TempHVHist = new TH1D(HVname, HVname, 50, -3.0, 3.0); + TempHVHist->SetXTitle("Delta HV Energy (keV)"); + TempHVHist->SetYTitle("Number of pixels"); + + char LVname[64]; sprintf(LVname,"Delta LV Hist: Det %d",DetID); + TempLVHist = new TH1D(LVname, LVname, 50, -3.0, 3.0); + TempLVHist->SetXTitle("Delta LV Energy (keV)"); + TempLVHist->SetYTitle("Number of pixels"); + + DeltaHVHist[DetID] = TempHVHist; + DeltaLVHist[DetID] = TempLVHist; + } + + DeltaHVMap[DetID]->SetBinContent(hv+1, lv+1, -100); + DeltaLVMap[DetID]->SetBinContent(hv+1, lv+1, -100); + if (Endpoints.find(PixelID)!=Endpoints.end()) { if ((Endpoints[PixelID][0].size() > 0) && (Endpoints[PixelID][1].size() > 0)) { - HVSlope = (Endpoints[PixelID][0][1] - Endpoints[PixelID][1][1])/(Endpoints[PixelID][0][0] - Endpoints[PixelID][1][0]); - LVSlope = (Endpoints[PixelID][0][2] - Endpoints[PixelID][1][2])/(Endpoints[PixelID][0][0] - Endpoints[PixelID][1][0]); - - TH2D* TempHV = DeltaHV[DetID]; - TH2D* TempLV = DeltaLV[DetID]; - - if (TempHV == nullptr) { - - char HVname[64]; sprintf(HVname,"Delta HV Map: Det %d",DetID); - TempHV = new TH2D(HVname, HVname, g_HVStrips, 0, g_HVStrips, g_LVStrips, 0, g_LVStrips); - TempHV->SetXTitle("HV Strip"); - TempHV->SetYTitle("LV Strip"); - TempHV->SetZTitle("Delta HV Energy"); - - char LVname[64]; sprintf(LVname,"Delta LV Map: Det %d",DetID); - TempLV = new TH2D(LVname, LVname, g_HVStrips, 0, g_HVStrips, g_LVStrips, 0, g_LVStrips); - TempLV->SetXTitle("HV Strip"); - TempLV->SetYTitle("LV Strip"); - TempLV->SetZTitle("Delta LV Energy"); - - DeltaHV[DetID] = TempHV; - DeltaLV[DetID] = TempLV; - } - DeltaHV[DetID]->SetBinContent(hv, lv, Endpoints[PixelID][0][1] - Endpoints[PixelID][1][1]); - DeltaLV[DetID]->SetBinContent(hv, lv, Endpoints[PixelID][0][2] - Endpoints[PixelID][1][2]); + HVIllumCTD = Endpoints[PixelID][0][0]; + LVIllumCTD = Endpoints[PixelID][1][0]; + HVIllumHVCentroid = Endpoints[PixelID][0][1]; + LVIllumHVCentroid = Endpoints[PixelID][1][1]; + HVIllumLVCentroid = Endpoints[PixelID][0][2]; + LVIllumLVCentroid = Endpoints[PixelID][1][2]; + + double HVDiff = (HVIllumHVCentroid - LVIllumHVCentroid)*(g_AmPhotopeak/HVIllumHVCentroid); + double LVDiff = (HVIllumLVCentroid - LVIllumLVCentroid)*(g_AmPhotopeak/HVIllumLVCentroid); + + DeltaHVMap[DetID]->SetBinContent(hv+1, lv+1, HVDiff); + DeltaLVMap[DetID]->SetBinContent(hv+1, lv+1, LVDiff); + + // Normalize the differences in Energy to account for calibration differences + DeltaHVHist[DetID]->Fill(HVDiff); + DeltaLVHist[DetID]->Fill(LVDiff); } } } - OutputCalFile<cd(); + H.second->SetMinimum(-5.); H.second->Draw("colz"); H.second->Write(); HVFile.Close(); @@ -775,9 +841,24 @@ bool TrappingCorrectionAm241::Analyze() TFile LVFile(m_OutFile+MString("_Det")+DetID+MString("_DeltaLVMap.root"),"recreate"); TCanvas* LVCanvas = new TCanvas(); LVCanvas->cd(); - DeltaLV[DetID]->Draw("colz"); - DeltaLV[DetID]->Write(); + DeltaLVMap[DetID]->SetMinimum(-5.); + DeltaLVMap[DetID]->Draw("colz"); + DeltaLVMap[DetID]->Write(); LVFile.Close(); + + TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_DeltaHVHist.root"),"recreate"); + TCanvas* HVHistCanvas = new TCanvas(); + HVHistCanvas->cd(); + DeltaHVHist[DetID]->Draw("hist"); + DeltaHVHist[DetID]->Write(); + HVHistFile.Close(); + + TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_DeltaLVHist.root"),"recreate"); + TCanvas* LVHistCanvas = new TCanvas(); + LVHistCanvas->cd(); + DeltaLVHist[DetID]->Draw("hist"); + DeltaLVHist[DetID]->Write(); + LVHistFile.Close(); } } From cd28137e6bcefb8c0bd2c5930afca259abd35f95 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 11:59:45 -0700 Subject: [PATCH 82/90] CHG: Chi-square cut for saving parameters. --- apps/TrappingCorrectionAm241.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 8171c013..cb83d7b5 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -604,7 +604,7 @@ bool TrappingCorrectionAm241::Analyze() cout.rdbuf(coutbuf); LVFitFile.close(); - if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty()))) { + if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty())) && ((CTDFit->Chi2()/CTDFit->Ndf()) < 5) && ((HVFit->Chi2()/HVFit->Ndf()) < 5) && ((LVFit->Chi2()/LVFit->Ndf()) < 5)) { Endpoints[PixelID][s].push_back(CTDFit->Parameter(2)); Endpoints[PixelID][s].push_back(HVFit->Parameter(1)); Endpoints[PixelID][s].push_back(LVFit->Parameter(1)); From 1be613b081cb040c1033b402214a08f2745b9268 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 12:01:07 -0700 Subject: [PATCH 83/90] CHG: Comments and changes to global variables --- apps/TrappingCorrectionAm241.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index cb83d7b5..be705f75 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -66,11 +66,13 @@ using namespace std; double g_MinCTD = -400; double g_MaxCTD = 400; -int g_MinCounts = 1000; +int g_MinCounts = 250; int g_HVStrips = 64; int g_LVStrips = 64; +double g_AmPhotopeak = 59.54; + //////////////////////////////////////////////////////////////////////////////// @@ -332,6 +334,7 @@ bool TrappingCorrectionAm241::Analyze() } } + // Analyze all the data and fill in the histograms for (unsigned int f = 0; f FullDetHVEnergyHistograms; map FullDetLVEnergyHistograms; + // Add up the pixel-level histograms to get full detector histograms + // Fit to the pixel-level histograms and record the results for (auto H: CTDHistograms) { int PixelID = H.first; From b6154ca2b7e733b8f52ab4778ad5371ff53fb704 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 12:15:33 -0700 Subject: [PATCH 84/90] CHG: Updated comments --- apps/TrappingCorrectionAm241.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index be705f75..5d7a5b04 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -371,7 +371,7 @@ bool TrappingCorrectionAm241::Analyze() ++MNumber; cout<<"Creating Event filter"<SetMinimumLVStrips(1); EventFilter->SetMaximumLVStrips(3); @@ -422,6 +422,7 @@ bool TrappingCorrectionAm241::Analyze() Pairing->AnalyzeEvent(Event); + // Only look at events with 1 Hit since we're interested in the 60keV photopeak. if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true) && (Event->GetNHits()==1)) { for (unsigned int h = 0; h < Event->GetNHits(); ++h) { @@ -634,6 +635,7 @@ bool TrappingCorrectionAm241::Analyze() } } + // Fit and plot the detector-level histograms for (auto H: FullDetCTDHistograms) { int DetID = H.first; @@ -732,6 +734,8 @@ bool TrappingCorrectionAm241::Analyze() map DeltaHVHist; map DeltaLVHist; + // Write the results of good fits to the output file and produce summary plots. + // If an individual pixel did not produce a good fit, default to the detector-level parameters. for (auto E: FullDetEndpoints) { int DetID = E.first; @@ -830,6 +834,7 @@ bool TrappingCorrectionAm241::Analyze() OutputCalFile.close(); + // Save and plot the summary figures. if (m_PixelCorrect==true) { for (auto H: DeltaHVMap) { From 211ac51aafb52241c2f5ef8df6d76cdef9a75c17 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 12:18:42 -0700 Subject: [PATCH 85/90] minor comment update --- apps/TrappingCorrection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index d562b86b..dfc369ae 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -459,7 +459,7 @@ bool TrappingCorrection::Analyze() ++MNumber; cout<<"Creating Event filter"<SetMinimumLVStrips(1); EventFilter->SetMaximumLVStrips(3); From adbc021b281135cfcb58714261a91a061f163386 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 4 Aug 2025 12:19:43 -0700 Subject: [PATCH 86/90] Update copyright --- apps/TrappingCorrection.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/TrappingCorrection.cxx b/apps/TrappingCorrection.cxx index dfc369ae..306a4c04 100644 --- a/apps/TrappingCorrection.cxx +++ b/apps/TrappingCorrection.cxx @@ -2,12 +2,12 @@ * TrappingCorrection.cxx * * - * Copyright (C) by Andreas Zoglauer. + * Copyright (C) by Sean Pike. * All rights reserved. * * * This code implementation is the intellectual property of - * Andreas Zoglauer. + * Sean Pike. * * By copying, distributing or modifying the Program (or any work * based on the Program) you indicate your acceptance of this statement, From d06858f0735360622749136a24b040d604a7e2b8 Mon Sep 17 00:00:00 2001 From: Andreas Zoglauer Date: Mon, 8 Sep 2025 12:57:18 -0700 Subject: [PATCH 87/90] CHG: Added protection against empty TAC calibration/caut entries. --- src/MModuleTACcut.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/MModuleTACcut.cxx b/src/MModuleTACcut.cxx index f29748c5..07b2de7f 100644 --- a/src/MModuleTACcut.cxx +++ b/src/MModuleTACcut.cxx @@ -163,6 +163,10 @@ bool MModuleTACcut::AnalyzeEvent(MReadOutAssembly* Event) cout<IsGuardRing() == false) { + cout<= m_TACCal[DetID][m_SideToIndex[Side]].size()) && (SH->IsGuardRing()==false)) { cout<IsGuardRing()==false) { + cout<= m_TACCut[DetID][m_SideToIndex[Side]].size()) && (SH->IsGuardRing()==false)) { cout< Date: Mon, 22 Sep 2025 16:54:08 -0700 Subject: [PATCH 88/90] CHG: New option to suppress HDF5 continuous file reading. --- apps/TrappingCorrectionAm241.cxx | 58 +++++++++++++------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index 5d7a5b04..b6e24f26 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -114,6 +114,7 @@ class TrappingCorrectionAm241 bool m_PixelCorrect; bool m_GreedyPairing; bool m_ExcludeNN; + bool m_ContinueHDF5; double m_MinEnergy; double m_MaxEnergy; @@ -162,6 +163,7 @@ bool TrappingCorrectionAm241::ParseCommandLine(int argc, char** argv) Usage<<" -g: greedy strip pairing (default is chi-square)"<SetFileNameStripMap(m_StripMapFile); Loader->SetFileName(File); - Loader->SetLoadContinuationFiles(true); + Loader->SetLoadContinuationFiles(m_ContinueHDF5); S->SetModule(Loader, MNumber); ++MNumber; From f827da289e0e201d0191886bdde4b26abcb07618 Mon Sep 17 00:00:00 2001 From: Sean Pike Date: Mon, 22 Sep 2025 16:54:22 -0700 Subject: [PATCH 89/90] CHG: Better checks on input files --- apps/TrappingCorrectionAm241.cxx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index b6e24f26..d688e79b 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -317,9 +317,18 @@ bool TrappingCorrectionAm241::Analyze() } else { MString Line; while (F.ReadLine(Line)) { - HDFNames.push_back(Line.Trim()); + MString Trimmed = Line.Trim(); + if ((Trimmed != "")) { + if (F.Exists(Trimmed)==true) { + HDFNames.push_back(Trimmed); + } else { + cout<<"Error: Could not find file "< Date: Tue, 23 Sep 2025 17:42:28 -0700 Subject: [PATCH 90/90] Improved comments and additional details in help message --- apps/TrappingCorrectionAm241.cxx | 62 +++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index d688e79b..eccecde0 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -149,6 +149,8 @@ bool TrappingCorrectionAm241::ParseCommandLine(int argc, char** argv) { ostringstream Usage; Usage<"<>> Endpoints; map>> FullDetEndpoints; + // Store the HV and LV input files vector FileNames; FileNames.push_back(m_HVFileName); FileNames.push_back(m_LVFileName); + // Map the side integer to HV and LV labels + // i.e. 0=HV, 1=LV vector IllumSide; IllumSide.push_back(MString("HV")); IllumSide.push_back(MString("LV")); + // Make a directory in which to store the pixel-level data MString PixelDir = m_OutFile + MString("_pixeldata"); if (m_PixelCorrect==true) { if (std::filesystem::create_directories(PixelDir.Data())==false) { @@ -284,8 +290,10 @@ bool TrappingCorrectionAm241::Analyze() } } + // For each side (HV and LV) calibrate the input data, construct histograms, and fit models for (unsigned int s=0; s<2; ++s) { + // Prep CTD model parameters. Mirror the model about the x-axis depending which side is being analyzed. double CTDFitMin, CTDFitMax, FlipSwitch; if (IllumSide[s]=="HV") { FlipSwitch = 1; @@ -306,6 +314,7 @@ bool TrappingCorrectionAm241::Analyze() map HVEnergyHistograms; map LVEnergyHistograms; + // Read in the input files and make a list of hdf5 files to calibrate if ((InputFile.GetSubString(InputFile.Length() - 4)) == "hdf5") { HDFNames.push_back(InputFile); } else if ((InputFile.GetSubString(InputFile.Length() - 3)) == "txt") { @@ -337,6 +346,7 @@ bool TrappingCorrectionAm241::Analyze() MString File = HDFNames[f]; cout<<"Beginning analysis of file "<SetMinimumLVStrips(1); EventFilter->SetMaximumLVStrips(3); @@ -377,7 +388,7 @@ bool TrappingCorrectionAm241::Analyze() EventFilter->SetMinimumHits(0); EventFilter->SetMaximumHits(100); EventFilter->SetMinimumTotalEnergy(m_MinEnergy); - EventFilter->SetMaximumTotalEnergy(m_MaxEnergy*2); + EventFilter->SetMaximumTotalEnergy(m_MaxEnergy*2); // Multiply by 2 because this is the event-level energy, i.e. sum over both sides S->SetModule(EventFilter, MNumber); ++MNumber; @@ -404,12 +415,14 @@ bool TrappingCorrectionAm241::Analyze() bool IsFinished = false; MReadOutAssembly* Event = new MReadOutAssembly(); + // Pass Events through each module. Once calibrated, add the Event to the histograms cout<<"Analyzing..."<Clear(); if (Loader->IsReady()) { + // Load Event from HDF5 file, then do TAC cut/calibration, energy calibration, and filtering Loader->AnalyzeEvent(Event); TACCalibrator->AnalyzeEvent(Event); EnergyCalibrator->AnalyzeEvent(Event); @@ -417,11 +430,13 @@ bool TrappingCorrectionAm241::Analyze() if (Unfiltered == true) { + // Pair strips Pairing->AnalyzeEvent(Event); // Only look at events with 1 Hit since we're interested in the 60keV photopeak. if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true) && (Event->GetNHits()==1)) { + // for each Hit for (unsigned int h = 0; h < Event->GetNHits(); ++h) { double HVEnergy = 0.0; double LVEnergy = 0.0; @@ -434,9 +449,11 @@ bool TrappingCorrectionAm241::Analyze() int DetID = H->GetStripHit(0)->GetDetectorID(); + // for each Strip Hit in the Hit for (unsigned int sh = 0; sh < H->GetNStripHits(); ++sh) { MStripHit* SH = H->GetStripHit(sh); + // Sum up the HV and LV energies, excluding nearest neighbors if m_ExcludeNN==true if ((m_ExcludeNN==false) || ((m_ExcludeNN==true) && (SH->IsNearestNeighbor()==false))) { if (SH->IsLowVoltageStrip()==true) { LVEnergy += SH->GetEnergy(); @@ -450,6 +467,7 @@ bool TrappingCorrectionAm241::Analyze() } } + // As long as there are Strip Hits remaining on each side, add the energies and CTDs to histograms if ((HVStrips.size()>0) && (LVStrips.size()>0)) { double HVEnergyFraction = 0; @@ -463,6 +481,7 @@ bool TrappingCorrectionAm241::Analyze() int PixelID = (10000*DetID) + (100*LVSH->GetStripID()) + (HVSH->GetStripID()); + // If this PixelID hasn't been encountered yet, make an entry for it in Endpoints if (Endpoints.find(PixelID)==Endpoints.end()) { vector tempHVvec; vector tempLVvec; @@ -476,6 +495,7 @@ bool TrappingCorrectionAm241::Analyze() TH1D* HVHist = HVEnergyHistograms[PixelID]; TH1D* LVHist = LVEnergyHistograms[PixelID]; + // If we didnt find an entry for the CTD and energy histograms, make new ones if (CTDHist == nullptr) { char name[64]; sprintf(name,"CTD: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); @@ -483,7 +503,6 @@ bool TrappingCorrectionAm241::Analyze() CTDHist->SetYTitle("Hits"); CTDHistograms[PixelID] = CTDHist; } - if (HVHist == nullptr) { char name[64]; sprintf(name,"HV energy: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); @@ -491,7 +510,6 @@ bool TrappingCorrectionAm241::Analyze() HVHist->SetYTitle("Hits"); HVEnergyHistograms[PixelID] = HVHist; } - if (LVHist == nullptr) { char name[64]; sprintf(name,"LV energy: PixelID %d %s Illumination",PixelID,IllumSide[s].Data()); LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); @@ -500,6 +518,7 @@ bool TrappingCorrectionAm241::Analyze() LVEnergyHistograms[PixelID] = LVHist; } + // Add the data to the histograms CTDHist->Fill(CTD); HVHist->Fill(HVEnergy); LVHist->Fill(LVEnergy); @@ -517,13 +536,14 @@ bool TrappingCorrectionAm241::Analyze() map FullDetHVEnergyHistograms; map FullDetLVEnergyHistograms; - // Add up the pixel-level histograms to get full detector histograms + // Loop over all pixels for which there are pixel-level histograms and sum to get full detector histograms // Fit to the pixel-level histograms and record the results for (auto H: CTDHistograms) { int PixelID = H.first; int DetID = (PixelID-(PixelID%10000))/10000; + // If this DetID hasn't been encountered yet, make an entry for it in Endpoints if (FullDetEndpoints.find(DetID)==FullDetEndpoints.end()) { vector tempHVvec; vector tempLVvec; @@ -537,6 +557,7 @@ bool TrappingCorrectionAm241::Analyze() TH1D* HVHist = FullDetHVEnergyHistograms[DetID]; TH1D* LVHist = FullDetLVEnergyHistograms[DetID]; + // If we didnt find an entry for the CTD and energy histograms, make new ones if (CTDHist == nullptr) { char name[64]; sprintf(name,"CTD: DetID %d %s Illumination",DetID,IllumSide[s].Data()); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); @@ -544,7 +565,6 @@ bool TrappingCorrectionAm241::Analyze() CTDHist->SetYTitle("Hits"); FullDetCTDHistograms[DetID] = CTDHist; } - if (HVHist == nullptr) { char name[64]; sprintf(name,"HV energy: DetID %d %s Illumination",DetID,IllumSide[s].Data()); HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); @@ -552,7 +572,6 @@ bool TrappingCorrectionAm241::Analyze() HVHist->SetYTitle("Hits"); FullDetHVEnergyHistograms[DetID] = HVHist; } - if (LVHist == nullptr) { char name[64]; sprintf(name,"LV energy: DetID %d %s Illumination",DetID,IllumSide[s].Data()); LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); @@ -567,13 +586,16 @@ bool TrappingCorrectionAm241::Analyze() if (m_PixelCorrect==true) { - // Write each of the histograms to a root file + // Fit histograms and save the results + // Only perform fits if the total counts in each is above the threshold given by g_MinCounts if ((H.second->Integral() > g_MinCounts) && (HVEnergyHistograms[PixelID]->Integral() > g_MinCounts) && (LVEnergyHistograms[PixelID]->Integral() > g_MinCounts)) { + // Initialize and run the CTD fit double CTDGuess = H.second->GetBinCenter(H.second->GetMaximumBin()); TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess, FlipSwitch); TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + // Save the results of the CTD fit ofstream CTDFitFile(PixelDir +MString("/") + PixelID+MString("_CTDFitResult_")+IllumSide[s]+ MString("Illum.txt")); streambuf* coutbuf = cout.rdbuf(); cout.rdbuf(CTDFitFile.rdbuf()); @@ -582,10 +604,12 @@ bool TrappingCorrectionAm241::Analyze() } cout.rdbuf(coutbuf); CTDFitFile.close(); - + + // Initialize and run the HV photopeak fit TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 55, 70); + // Save the results of the HV photopeak fit ofstream HVFitFile(PixelDir +MString("/") + PixelID+MString("_HVEnergyFitResult_")+IllumSide[s]+ MString("Illum.txt")); coutbuf = cout.rdbuf(); cout.rdbuf(HVFitFile.rdbuf()); @@ -595,9 +619,11 @@ bool TrappingCorrectionAm241::Analyze() cout.rdbuf(coutbuf); HVFitFile.close(); + // Initialize and run the LV photopeak fit TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 55, 70); + // Save the results of the LV photopeak fit ofstream LVFitFile(PixelDir +MString("/") + PixelID+MString("_LVEnergyFitResult_")+IllumSide[s]+ MString("Illum.txt")); coutbuf = cout.rdbuf(); cout.rdbuf(LVFitFile.rdbuf()); @@ -607,6 +633,8 @@ bool TrappingCorrectionAm241::Analyze() cout.rdbuf(coutbuf); LVFitFile.close(); + // Save the resulting HV and LV photopeak centroids and CTD centroids to the Endpoints map. + // Only save these values if the fits ran successfully and if their reduced chi-square is less than 5 if ((!(CTDFit->IsEmpty())) && (!(HVFit->IsEmpty())) && (!(LVFit->IsEmpty())) && ((CTDFit->Chi2()/CTDFit->Ndf()) < 5) && ((HVFit->Chi2()/HVFit->Ndf()) < 5) && ((LVFit->Chi2()/LVFit->Ndf()) < 5)) { Endpoints[PixelID][s].push_back(CTDFit->Parameter(2)); Endpoints[PixelID][s].push_back(HVFit->Parameter(1)); @@ -632,7 +660,7 @@ bool TrappingCorrectionAm241::Analyze() } } - // Fit and plot the detector-level histograms + // Do the same function fitting and recording as above, but for the full detectors rather than pixel-by-pixel for (auto H: FullDetCTDHistograms) { int DetID = H.first; @@ -720,7 +748,7 @@ bool TrappingCorrectionAm241::Analyze() } } - //setup output file + //setup parameter file ofstream OutputCalFile; OutputCalFile.open(m_OutFile+MString("_parameters.txt")); OutputCalFile<<"# Det ID"<<'\t'<<"HV Strip ID"<<'\t'<<"LV Strip ID"<<'\t'<<"HV Illum CTD"<<'\t'<<"LV Illum CTD"<<'\t'<<"HV Illum. HV Centroid"<<'\t'<<"LV Illum. HV Centroid"<<'\t'<<"HV Illum. LV Centroid"<<'\t'<<"LV Illum. LV Centroid"< DeltaHVHist; map DeltaLVHist; - // Write the results of good fits to the output file and produce summary plots. + // Write the results of good fits to the parameter file and produce summary plots. // If an individual pixel did not produce a good fit, default to the detector-level parameters. + // Loop over each detector for (auto E: FullDetEndpoints) { int DetID = E.first; @@ -753,6 +782,7 @@ bool TrappingCorrectionAm241::Analyze() LVIllumLVCentroid = E.second[1][2]; } + // Loop over each pixel for (int hv=0; hvSetBinContent(hv+1, lv+1, -100); DeltaLVMap[DetID]->SetBinContent(hv+1, lv+1, -100); + // Retrieve the stored HV and LV energies and CTDs + // Plot the energy shifts in the HV and LV Maps, and fill in the histograms if (Endpoints.find(PixelID)!=Endpoints.end()) { if ((Endpoints[PixelID][0].size() > 0) && (Endpoints[PixelID][1].size() > 0)) { @@ -812,18 +845,21 @@ bool TrappingCorrectionAm241::Analyze() HVIllumLVCentroid = Endpoints[PixelID][0][2]; LVIllumLVCentroid = Endpoints[PixelID][1][2]; + // Normalize the differences in Energy to account for calibration differences double HVDiff = (HVIllumHVCentroid - LVIllumHVCentroid)*(g_AmPhotopeak/HVIllumHVCentroid); double LVDiff = (HVIllumLVCentroid - LVIllumLVCentroid)*(g_AmPhotopeak/HVIllumLVCentroid); DeltaHVMap[DetID]->SetBinContent(hv+1, lv+1, HVDiff); DeltaLVMap[DetID]->SetBinContent(hv+1, lv+1, LVDiff); - // Normalize the differences in Energy to account for calibration differences DeltaHVHist[DetID]->Fill(HVDiff); DeltaLVHist[DetID]->Fill(LVDiff); } } } + + // Record the Energies and CTDs in the parameter file + // Note that we default to the detector value if the pixel value isn't available and to 0 if the detector value isn't available. OutputCalFile<