From 3aee0c306b02d42ad2e1dee193b71c28bacba501 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:33:01 -0700 Subject: [PATCH 01/61] troubleshooting trapping app --- apps/TrappingCorrectionAm241.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index dadf4894..e650d358 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -274,13 +274,16 @@ bool TrappingCorrectionAm241::Analyze() // Store the HV and LV input files vector FileNames; FileNames.push_back(m_HVFileName); + cout<<"HV file names stored"< IllumSide; IllumSide.push_back(MString("HV")); IllumSide.push_back(MString("LV")); + cout<<"HV and LV integers mapped"< Date: Fri, 3 Apr 2026 15:24:47 -0700 Subject: [PATCH 02/61] adapted trapping app to intake Cs-137 data and output lineshifts From c2bc846e6f5f4872255ccb80e3cc2ab7adb6b3f8 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:53:47 -0700 Subject: [PATCH 03/61] changed fitting range around Cs line --- apps/TrappingCorrectionCs137.cxx | 1076 ++++++++++++++++++++++++++++++ 1 file changed, 1076 insertions(+) create mode 100644 apps/TrappingCorrectionCs137.cxx diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx new file mode 100644 index 00000000..b4fbe87e --- /dev/null +++ b/apps/TrappingCorrectionCs137.cxx @@ -0,0 +1,1076 @@ +/* + * TrappingCorrectionCs137.cxx + * + * + * Copyright (C) by Sean Pike. + * All rights reserved. + * + * + * This code implementation is the intellectual property of + * Sean Pike. + * + * 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 +#include +#include +using namespace std; + +// ROOT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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 "MModuleLoaderMeasurementsHDF.h" +#include "MModuleEnergyCalibration.h" +#include "MModuleEventFilter.h" +#include "MModuleStripPairingMultiRoundChiSquare.h" +#include "MModuleStripPairingChiSquare.h" +#include "MModuleTACcut.h" +#include "MAssembly.h" + + +double g_MinCTD = -400; +double g_MaxCTD = 400; +int g_MinCounts = 100; + +int g_HVStrips = 64; +int g_LVStrips = 64; + +double g_CsPhotopeak = 661.7; + +//////////////////////////////////////////////////////////////////////////////// + + +//! A standalone program based on MEGAlib and ROOT +class TrappingCorrectionCs137 +{ +public: + //! Default constructor + TrappingCorrectionCs137(); + //! Default destructor + ~TrappingCorrectionCs137(); + + //! Parse the command line + bool ParseCommandLine(int argc, char** argv); + //! Analyze what ever needs to be analyzed... + bool Analyze(); + //! Interrupt the analysis + void Interrupt() { m_Interrupt = true; } + + //! Produce functions for fitting + TF1* GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess); + TF1* GeneratePhotopeakFunction(); + + 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_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) + bool m_PixelCorrect; + bool m_MultiRoundStripPairing; + bool m_ExcludeNN; + bool m_ContinueHDF5; + + double m_MinEnergy; + double m_MaxEnergy; + +}; + +//////////////////////////////////////////////////////////////////////////////// + + +//! Default constructor +TrappingCorrectionCs137::TrappingCorrectionCs137() : m_Interrupt(false) +{ + gStyle->SetPalette(1, 0); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Default destructor +TrappingCorrectionCs137::~TrappingCorrectionCs137() +{ + // Intentionally left blank +} + + +//////////////////////////////////////////////////////////////////////////////// + + +//! Parse the command line +bool TrappingCorrectionCs137::ParseCommandLine(int argc, char** argv) +{ + ostringstream Usage; + Usage<"< i+1) && (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ + cout<<"Error: Option "<>> Endpoints; + map>> FullDetEndpoints; + + // Store the HV and LV input files + vector FileNames; + FileNames.push_back(m_FileName); + cout<<"file name stored"< IllumSide; + // IllumSide.push_back(MString("HV")); + // IllumSide.push_back(MString("LV")); + // cout<<"HV and LV integers mapped"< HDFNames; + + TH1::SetDefaultSumw2(); + + map CTDHistograms; + 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); + cout<<"hdf names loaded correctly"<SetFileNameStripMap(m_StripMapFile); + Loader->SetFileName(File); + Loader->SetLoadContinuationFiles(m_ContinueHDF5); + 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); // Multiply by 2 because this is the event-level energy, i.e. sum over both sides + 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(); + + // Pass Events through each module. Once calibrated, add the Event to the histograms + cout<<"Analyzing..."<Clear(); + cout<<"event is clear??"<IsReady()) { + cout<<"loader is ready"<AnalyzeEvent(Event); + cout<<"event loaded"<AnalyzeEvent(Event); + cout<<"TAc cal loaded"<AnalyzeEvent(Event); + cout<<"ecal loaded"<AnalyzeEvent(Event); + + if (Unfiltered == true) { + + // Pair strips + Pairing->AnalyzeEvent(Event); + cout<<"pairing events"<HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true) ) { + + // for each Hit + 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(); + + // 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(); + LVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + LVStrips.push_back(SH); + } else { + HVEnergy += SH->GetEnergy(); + HVEnergyResolution += (SH->GetEnergyResolution())*(SH->GetEnergyResolution()); + HVStrips.push_back(SH); + } + } + } + + // 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; + 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(); + + 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; + vector> tempvec; + Endpoints[PixelID] = tempvec; + Endpoints[PixelID].push_back(tempHVvec); + Endpoints[PixelID].push_back(tempLVvec); + } + + TH1D* CTDHist = CTDHistograms[PixelID]; + 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 ",PixelID,PixelDir.Data()); + CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + CTDHist->SetXTitle("CTD (ns)"); + CTDHist->SetYTitle("Hits"); + CTDHistograms[PixelID] = CTDHist; + } + if (HVHist == nullptr) { + char name[64]; sprintf(name,"HV energy: PixelID %d ",PixelID,PixelDir.Data()); + HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + HVHist->SetXTitle("HV Energy (keV)"); + HVHist->SetYTitle("Hits"); + HVEnergyHistograms[PixelID] = HVHist; + } + if (LVHist == nullptr) { + char name[64]; sprintf(name,"LV energy: PixelID %d ",PixelID,PixelDir.Data()); + LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + LVHist->SetXTitle("LV Energy (keV)"); + LVHist->SetYTitle("Hits"); + LVEnergyHistograms[PixelID] = LVHist; + } + + // Add the data to the histograms + CTDHist->Fill(CTD); + HVHist->Fill(HVEnergy); + LVHist->Fill(LVEnergy); + } + } + } + } + } + } + IsFinished = Loader->IsFinished(); + } + } + + map FullDetCTDHistograms; + map FullDetHVEnergyHistograms; + map FullDetLVEnergyHistograms; + + // 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; + vector> tempvec; + FullDetEndpoints[DetID] = tempvec; + FullDetEndpoints[DetID].push_back(tempHVvec); + FullDetEndpoints[DetID].push_back(tempLVvec); + } + + TH1D* CTDHist = FullDetCTDHistograms[DetID]; + 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 ",DetID,PixelDir.Data()); + CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + CTDHist->SetXTitle("CTD (ns)"); + CTDHist->SetYTitle("Hits"); + FullDetCTDHistograms[DetID] = CTDHist; + } + if (HVHist == nullptr) { + char name[64]; sprintf(name,"HV energy: DetID %d ",DetID,PixelDir.Data()); + HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + HVHist->SetXTitle("HV Energy (keV)"); + HVHist->SetYTitle("Hits"); + FullDetHVEnergyHistograms[DetID] = HVHist; + } + if (LVHist == nullptr) { + char name[64]; sprintf(name,"LV energy: DetID %d ",DetID,PixelDir.Data()); + LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + LVHist->SetXTitle("LV Energy (keV)"); + LVHist->SetYTitle("Hits"); + FullDetLVEnergyHistograms[DetID] = LVHist; + } + + CTDHist->Add(CTDHist, H.second); + HVHist->Add(HVHist, HVEnergyHistograms[PixelID]); + LVHist->Add(LVHist, LVEnergyHistograms[PixelID]); + + if (m_PixelCorrect==true) { + + // Fit histograms and save the results + // Only perform fits if the total counts in each is above the threshold given by g_MinCounts + cout<Integral()<<" counts in CTD histogram for Pixel ID "<Integral()<<" counts in HV energy histogram for Pixel ID "<Integral()<<" counts in LV energy histogram for Pixel ID "<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); + TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + + // Save the results of the CTD fit + ofstream CTDFitFile(PixelDir +MString("/") + PixelID+MString("_CTDFitResult_")+ MString(".txt")); + streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(CTDFitFile.rdbuf()); + if (CTDFit >= 0) { + CTDFit->Print(); + } + cout.rdbuf(coutbuf); + CTDFitFile.close(); + + // Initialize and run the HV photopeak fit + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + + // Save the results of the HV photopeak fit + ofstream HVFitFile(PixelDir +MString("/") + PixelID+MString("_HVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(HVFitFile.rdbuf()); + if (HVFit >= 0) { + HVFit->Print(); + } + cout.rdbuf(coutbuf); + HVFitFile.close(); + + // Initialize and run the LV photopeak fit + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + + // Save the results of the LV photopeak fit + ofstream LVFitFile(PixelDir +MString("/") + PixelID+MString("_LVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit >= 0) { + LVFit->Print(); + } + 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 >= 0) && (HVFit >= 0) && (LVFit >= 0)) { + if (((CTDFit->Chi2()/CTDFit->Ndf()) < 25) && ((HVFit->Chi2()/HVFit->Ndf()) < 25) && ((LVFit->Chi2()/LVFit->Ndf()) < 25)) { + Endpoints[PixelID][0].push_back(CTDFit->Parameter(2)); + Endpoints[PixelID][0].push_back(HVFit->Parameter(1)); + Endpoints[PixelID][0].push_back(LVFit->Parameter(1)); + } else { + cout<<"Fits for Pixel "<Write(); + CTDHistFile.Close(); + + TFile HVHistFile(PixelDir+MString("/")+PixelID+MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); + HVEnergyHistograms[PixelID]->Write(); + HVHistFile.Close(); + + TFile LVHistFile(PixelDir+MString("/")+PixelID+MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); + LVEnergyHistograms[PixelID]->Write(); + LVHistFile.Close(); + + } + } + + // Do the same function fitting and recording as above, but for the full detectors rather than pixel-by-pixel + for (auto H: FullDetCTDHistograms) { + + cout<<"Analyzing Full Detector Histograms"<Integral()<Integral()<Integral()<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); + TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + + if ((CTDFit >= 0) && (HVFit >= 0) && (LVFit >= 0)) { + FullDetEndpoints[DetID][0].push_back(CTDFit->Parameter(2)); + FullDetEndpoints[DetID][0].push_back(HVFit->Parameter(1)); + FullDetEndpoints[DetID][0].push_back(LVFit->Parameter(1)); + + ofstream CTDFitFile(DetID+MString("_CTDFitResult_")+ MString(".txt")); + streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(CTDFitFile.rdbuf()); + if (CTDFit >= 0) { + CTDFit->Print(); + } + cout.rdbuf(coutbuf); + CTDFitFile.close(); + + ofstream HVFitFile(DetID+MString("_HVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(HVFitFile.rdbuf()); + if (HVFit >= 0) { + HVFit->Print(); + } + cout.rdbuf(coutbuf); + HVFitFile.close(); + + ofstream LVFitFile(DetID+MString("_LVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit >= 0) { + LVFit->Print(); + } + cout.rdbuf(coutbuf); + LVFitFile.close(); + + TFile CTDFile(m_OutFile+MString("_Det")+DetID+MString("_CTDHist_") + MString("Illum.root"),"recreate"); + + TCanvas* CTDCanvas = new TCanvas(); + CTDCanvas->cd(); + H.second->Draw("hist"); + CTDFunction->Draw("same"); + + H.second->Write(); + CTDFile.Close(); + + TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); + + TCanvas* HVHistCanvas = new TCanvas(); + HVHistCanvas->cd(); + FullDetHVEnergyHistograms[DetID]->Draw("hist"); + PhotopeakFunctionHV->Draw("same"); + + FullDetHVEnergyHistograms[DetID]->Write(); + HVHistFile.Close(); + + TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); + + TCanvas* LVHistCanvas = new TCanvas(); + LVHistCanvas->cd(); + FullDetLVEnergyHistograms[DetID]->Draw("hist"); + PhotopeakFunctionLV->Draw("same"); + + FullDetLVEnergyHistograms[DetID]->Write(); + LVHistFile.Close(); + + } else { + cout<<"Fits failed for Det "< DeltaHVMap; + // map DeltaLVMap; + + // map DeltaHVHist; + // map DeltaLVHist; + + // 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; + + double CTD = 0; + double HVCentroid = 0; + double LVCentroid = 0; + + if ((E.second[0].size() > 0) && (E.second[1].size() > 0)) { + CTD = E.second[0][0]; + HVCentroid = E.second[1][0]; + LVCentroid = E.second[0][1]; + } + + // Loop over each pixel + 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); + + // // 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)) { + + // 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]; + + // // Normalize the differences in Energy to account for calibration differences + // double HVDiff = (HVIllumHVCentroid - LVIllumHVCentroid)*(g_CsPhotopeak/HVIllumHVCentroid); + // double LVDiff = (HVIllumLVCentroid - LVIllumLVCentroid)*(g_CsPhotopeak/HVIllumLVCentroid); + + // DeltaHVMap[DetID]->SetBinContent(hv+1, lv+1, HVDiff); + // DeltaLVMap[DetID]->SetBinContent(hv+1, lv+1, LVDiff); + + // 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<cd(); + // H.second->SetMinimum(-5.); + // 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(); + // 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(); + // } + // } + +// watch.Stop(); +// cout<<"total time (s): "<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", 662); + PhotopeakFunction->SetParameter("Sigma", 2); + PhotopeakFunction->SetParameter("Shelf norm", 0.05); + + PhotopeakFunction->SetParLimits(0, 10, 1e8); + PhotopeakFunction->SetParLimits(1, 650, 670); + PhotopeakFunction->SetParLimits(2, 1.0, 10); + PhotopeakFunction->SetParLimits(3, 0, 0.1); + + return PhotopeakFunction; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +TF1* TrappingCorrectionCs137::GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess) +{ + // 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)))", CTDFitMin, CTDFitMax); + + 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", 12); + CTDFunction->SetParameter("Mu", CTDGuess); + + CTDFunction->SetParLimits(0, 0, 1e8); + CTDFunction->SetParLimits(1, 0.01, 1); + CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); + CTDFunction->SetParLimits(3, 6, 30); + + return CTDFunction; +} + + +//////////////////////////////////////////////////////////////////////////////// + + +TrappingCorrectionCs137* g_Prg = 0; +int g_NInterruptCatches = 1; + +MStripHit* TrappingCorrectionCs137::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; + 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 TrappingCorrectionCs137(); + + if (g_Prg->ParseCommandLine(argc, argv) == false) { + cerr<<"Error during parsing of command line!"<Analyze() == false) { + cerr<<"Error during analysis!"< Date: Mon, 4 May 2026 15:52:33 -0700 Subject: [PATCH 04/61] added depth binning on pixel and detector level --- apps/TrappingCorrectionCs137.cxx | 430 ++++++++++++++++--------------- 1 file changed, 223 insertions(+), 207 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index b4fbe87e..07814280 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -74,6 +74,14 @@ int g_LVStrips = 64; double g_CsPhotopeak = 661.7; +const int NCTDBins = 10; +double CTDBinWidth = (CTDmax - CTDmin) / NCTDBins; + +int GetCTDBin(double CTD) { + if (CTD < CTDmin || CTD >= CTDmax) return -1; + return int((CTD - CTDmin) / CTDBinWidth); +} + //////////////////////////////////////////////////////////////////////////////// @@ -315,9 +323,9 @@ bool TrappingCorrectionCs137::Analyze() TH1::SetDefaultSumw2(); - map CTDHistograms; - map HVEnergyHistograms; - map LVEnergyHistograms; + map> CTDHistograms; + 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") { @@ -425,24 +433,18 @@ bool TrappingCorrectionCs137::Analyze() cout<<"Analyzing..."<Clear(); - cout<<"event is clear??"<IsReady()) { - cout<<"loader is ready"<AnalyzeEvent(Event); - cout<<"event loaded"<AnalyzeEvent(Event); - cout<<"TAc cal loaded"<AnalyzeEvent(Event); - cout<<"ecal loaded"<AnalyzeEvent(Event); if (Unfiltered == true) { // Pair strips Pairing->AnalyzeEvent(Event); - cout<<"pairing events"<HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered==true) ) { @@ -489,6 +491,8 @@ bool TrappingCorrectionCs137::Analyze() if ((LVSH->HasCalibratedTiming()==true) && (HVSH->HasCalibratedTiming()==true)) { double CTD = LVSH->GetTiming() - HVSH->GetTiming(); + int CTDBin = GetCTDBin(CTD); + if (CTDBin < 0) continue; int PixelID = (10000*DetID) + (100*LVSH->GetStripID()) + (HVSH->GetStripID()); @@ -502,31 +506,31 @@ bool TrappingCorrectionCs137::Analyze() Endpoints[PixelID].push_back(tempLVvec); } - TH1D* CTDHist = CTDHistograms[PixelID]; - TH1D* HVHist = HVEnergyHistograms[PixelID]; - TH1D* LVHist = LVEnergyHistograms[PixelID]; + TH1D* CTDHist = CTDHistograms[CTDBin][PixelID]; + TH1D* HVHist = HVEnergyHistograms[CTDBin][PixelID]; + TH1D* LVHist = LVEnergyHistograms[CTDBin][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 ",PixelID,PixelDir.Data()); + char name[128]; sprintf(name,"CTD: PixelID %d CTDbin %d", PixelID,CTDBin); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); CTDHist->SetXTitle("CTD (ns)"); CTDHist->SetYTitle("Hits"); - CTDHistograms[PixelID] = CTDHist; + CTDHistograms[CTDBin][PixelID] = CTDHist; } if (HVHist == nullptr) { - char name[64]; sprintf(name,"HV energy: PixelID %d ",PixelID,PixelDir.Data()); + char name[128]; sprintf(name,"HV energy: PixelID %d ",PixelID,CTDBin); HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); HVHist->SetXTitle("HV Energy (keV)"); HVHist->SetYTitle("Hits"); - HVEnergyHistograms[PixelID] = HVHist; + HVEnergyHistograms[CTDBin][PixelID] = HVHist; } if (LVHist == nullptr) { - char name[64]; sprintf(name,"LV energy: PixelID %d ",PixelID,PixelDir.Data()); + char name[128]; sprintf(name,"LV energy: PixelID %d ",PixelID,CTDBin); LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); LVHist->SetXTitle("LV Energy (keV)"); LVHist->SetYTitle("Hits"); - LVEnergyHistograms[PixelID] = LVHist; + LVEnergyHistograms[CTDBin][PixelID] = LVHist; } // Add the data to the histograms @@ -543,234 +547,246 @@ bool TrappingCorrectionCs137::Analyze() } } - map FullDetCTDHistograms; - map FullDetHVEnergyHistograms; - map FullDetLVEnergyHistograms; + map> FullDetCTDHistograms; + map> FullDetHVEnergyHistograms; + map> FullDetLVEnergyHistograms; // 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; - vector> tempvec; - FullDetEndpoints[DetID] = tempvec; - FullDetEndpoints[DetID].push_back(tempHVvec); - FullDetEndpoints[DetID].push_back(tempLVvec); - } - - TH1D* CTDHist = FullDetCTDHistograms[DetID]; - TH1D* HVHist = FullDetHVEnergyHistograms[DetID]; - TH1D* LVHist = FullDetLVEnergyHistograms[DetID]; + for (int c = 0; c < NCTDBins; ++c) { + cout << "Processing CTD bin " << c << endl; + + for (auto H : CTDHistograms[c]) { + + int PixelID = H.first; + TH1D* CTDHist = H.second; + TH1D* HVHist = HVEnergyHistograms[c][PixelID]; + TH1D* LVHist = LVEnergyHistograms[c][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: DetID %d ",DetID,PixelDir.Data()); - CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); - CTDHist->SetXTitle("CTD (ns)"); - CTDHist->SetYTitle("Hits"); - FullDetCTDHistograms[DetID] = CTDHist; - } - if (HVHist == nullptr) { - char name[64]; sprintf(name,"HV energy: DetID %d ",DetID,PixelDir.Data()); - HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - HVHist->SetXTitle("HV Energy (keV)"); - HVHist->SetYTitle("Hits"); - FullDetHVEnergyHistograms[DetID] = HVHist; - } - if (LVHist == nullptr) { - char name[64]; sprintf(name,"LV energy: DetID %d ",DetID,PixelDir.Data()); - LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - LVHist->SetXTitle("LV Energy (keV)"); - LVHist->SetYTitle("Hits"); - FullDetLVEnergyHistograms[DetID] = LVHist; - } + 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; + vector> tempvec; + FullDetEndpoints[DetID] = tempvec; + FullDetEndpoints[DetID].push_back(tempHVvec); + FullDetEndpoints[DetID].push_back(tempLVvec); + } - CTDHist->Add(CTDHist, H.second); - HVHist->Add(HVHist, HVEnergyHistograms[PixelID]); - LVHist->Add(LVHist, LVEnergyHistograms[PixelID]); + TH1D* CTDHist = FullDetCTDHistograms[DetID]; + 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 ",DetID,PixelDir.Data()); + CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + CTDHist->SetXTitle("CTD (ns)"); + CTDHist->SetYTitle("Hits"); + FullDetCTDHistograms[DetID] = CTDHist; + } + if (HVHist == nullptr) { + char name[64]; sprintf(name,"HV energy: DetID %d ",DetID,PixelDir.Data()); + HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + HVHist->SetXTitle("HV Energy (keV)"); + HVHist->SetYTitle("Hits"); + FullDetHVEnergyHistograms[DetID] = HVHist; + } + if (LVHist == nullptr) { + char name[64]; sprintf(name,"LV energy: DetID %d ",DetID,PixelDir.Data()); + LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + LVHist->SetXTitle("LV Energy (keV)"); + LVHist->SetYTitle("Hits"); + FullDetLVEnergyHistograms[DetID] = LVHist; + } - if (m_PixelCorrect==true) { + CTDHist->Add(CTDHist, H.second); + HVHist->Add(HVHist, HVEnergyHistograms[PixelID]); + LVHist->Add(LVHist, LVEnergyHistograms[PixelID]); - // Fit histograms and save the results - // Only perform fits if the total counts in each is above the threshold given by g_MinCounts - cout<Integral()<<" counts in CTD histogram for Pixel ID "<Integral()<<" counts in HV energy histogram for Pixel ID "<Integral()<<" counts in LV energy histogram for Pixel ID "<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); - TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + // Fit histograms and save the results + // Only perform fits if the total counts in each is above the threshold given by g_MinCounts + cout<Integral()<<" counts in CTD histogram for Pixel ID "<Integral()<<" counts in HV energy histogram for Pixel ID "<Integral()<<" counts in LV energy histogram for Pixel ID "<= 0) { - CTDFit->Print(); - } - cout.rdbuf(coutbuf); - CTDFitFile.close(); - - // Initialize and run the HV photopeak fit - TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); - - // Save the results of the HV photopeak fit - ofstream HVFitFile(PixelDir +MString("/") + PixelID+MString("_HVEnergyFitResult_")+ MString(".txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(HVFitFile.rdbuf()); - if (HVFit >= 0) { - HVFit->Print(); - } - cout.rdbuf(coutbuf); - HVFitFile.close(); + 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); + TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + + // Save the results of the CTD fit + ofstream CTDFitFile(PixelDir + MString("/") + PixelID + MString("_CTDbin_") + c + MString("_CTDFitResult.txt")); + streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(CTDFitFile.rdbuf()); + if (CTDFit >= 0) { + CTDFit->Print(); + } + cout.rdbuf(coutbuf); + CTDFitFile.close(); + + // Initialize and run the HV photopeak fit + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + + // Save the results of the HV photopeak fit + ofstream HVFitFile(PixelDir +MString("/") + PixelID+ + MString("_CTDbin_") + c + MString("_HVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(HVFitFile.rdbuf()); + if (HVFit >= 0) { + HVFit->Print(); + } + cout.rdbuf(coutbuf); + HVFitFile.close(); - // Initialize and run the LV photopeak fit - TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); - - // Save the results of the LV photopeak fit - ofstream LVFitFile(PixelDir +MString("/") + PixelID+MString("_LVEnergyFitResult_")+ MString(".txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(LVFitFile.rdbuf()); - if (LVFit >= 0) { - LVFit->Print(); - } - 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 >= 0) && (HVFit >= 0) && (LVFit >= 0)) { - if (((CTDFit->Chi2()/CTDFit->Ndf()) < 25) && ((HVFit->Chi2()/HVFit->Ndf()) < 25) && ((LVFit->Chi2()/LVFit->Ndf()) < 25)) { - Endpoints[PixelID][0].push_back(CTDFit->Parameter(2)); - Endpoints[PixelID][0].push_back(HVFit->Parameter(1)); - Endpoints[PixelID][0].push_back(LVFit->Parameter(1)); + // Initialize and run the LV photopeak fit + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + + // Save the results of the LV photopeak fit + ofstream LVFitFile(PixelDir +MString("/") + PixelID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit >= 0) { + LVFit->Print(); + } + 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 >= 0) && (HVFit >= 0) && (LVFit >= 0)) { + if (((CTDFit->Chi2()/CTDFit->Ndf()) < 25) && ((HVFit->Chi2()/HVFit->Ndf()) < 25) && ((LVFit->Chi2()/LVFit->Ndf()) < 25)) { + Endpoints[PixelID][0].push_back(CTDFit->Parameter(2)); + Endpoints[PixelID][0].push_back(HVFit->Parameter(1)); + Endpoints[PixelID][0].push_back(LVFit->Parameter(1)); + } else { + cout<<"Fits for Pixel "<Write(); - CTDHistFile.Close(); + TFile CTDHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c +MString("_CTDHist_") + MString("Illum.root"),"recreate"); + H.second->Write(); + CTDHistFile.Close(); - TFile HVHistFile(PixelDir+MString("/")+PixelID+MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); - HVEnergyHistograms[PixelID]->Write(); - HVHistFile.Close(); + TFile HVHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c +MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); + HVEnergyHistograms[PixelID]->Write(); + HVHistFile.Close(); - TFile LVHistFile(PixelDir+MString("/")+PixelID+MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); - LVEnergyHistograms[PixelID]->Write(); - LVHistFile.Close(); + TFile LVHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c + MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); + LVEnergyHistograms[PixelID]->Write(); + LVHistFile.Close(); + } } } // Do the same function fitting and recording as above, but for the full detectors rather than pixel-by-pixel - for (auto H: FullDetCTDHistograms) { + for (int c = 0; c < NCTDBins; ++c) { + for (auto H : FullDetCTDHistograms[c]) { - cout<<"Analyzing Full Detector Histograms"<Integral()<Integral()<Integral()<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); - TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); - - TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + cout<<"full detector HV counts"<Integral()<Integral()<Integral()<Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[DetID]->Integral() > g_MinCounts)) { - TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + double CTDGuess = H.second->GetBinCenter(H.second->GetMaximumBin()); + TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); + TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); - if ((CTDFit >= 0) && (HVFit >= 0) && (LVFit >= 0)) { - FullDetEndpoints[DetID][0].push_back(CTDFit->Parameter(2)); - FullDetEndpoints[DetID][0].push_back(HVFit->Parameter(1)); - FullDetEndpoints[DetID][0].push_back(LVFit->Parameter(1)); + TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); - ofstream CTDFitFile(DetID+MString("_CTDFitResult_")+ MString(".txt")); - streambuf* coutbuf = cout.rdbuf(); - cout.rdbuf(CTDFitFile.rdbuf()); - if (CTDFit >= 0) { - CTDFit->Print(); - } - cout.rdbuf(coutbuf); - CTDFitFile.close(); - - ofstream HVFitFile(DetID+MString("_HVEnergyFitResult_")+ MString(".txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(HVFitFile.rdbuf()); - if (HVFit >= 0) { - HVFit->Print(); - } - cout.rdbuf(coutbuf); - HVFitFile.close(); - - ofstream LVFitFile(DetID+MString("_LVEnergyFitResult_")+ MString(".txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(LVFitFile.rdbuf()); - if (LVFit >= 0) { - LVFit->Print(); - } - cout.rdbuf(coutbuf); - LVFitFile.close(); + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + + if ((CTDFit >= 0) && (HVFit >= 0) && (LVFit >= 0)) { + FullDetEndpoints[DetID][0].push_back(CTDFit->Parameter(2)); + FullDetEndpoints[DetID][0].push_back(HVFit->Parameter(1)); + FullDetEndpoints[DetID][0].push_back(LVFit->Parameter(1)); + + ofstream CTDFitFile(DetID+MString("_CTDFitResult_")+ MString(".txt")); + streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(CTDFitFile.rdbuf()); + if (CTDFit >= 0) { + CTDFit->Print(); + } + cout.rdbuf(coutbuf); + CTDFitFile.close(); + + ofstream HVFitFile(DetID + MString("_CTDbin_") + c +MString("_HVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(HVFitFile.rdbuf()); + if (HVFit >= 0) { + HVFit->Print(); + } + cout.rdbuf(coutbuf); + HVFitFile.close(); + + ofstream LVFitFile(DetID+ MString("_CTDbin_") + c +MString("_LVEnergyFitResult_")+ MString(".txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit >= 0) { + LVFit->Print(); + } + cout.rdbuf(coutbuf); + LVFitFile.close(); - TFile CTDFile(m_OutFile+MString("_Det")+DetID+MString("_CTDHist_") + MString("Illum.root"),"recreate"); + TFile CTDFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_CTDHist_") + MString("Illum.root"),"recreate"); - TCanvas* CTDCanvas = new TCanvas(); - CTDCanvas->cd(); - H.second->Draw("hist"); - CTDFunction->Draw("same"); + TCanvas* CTDCanvas = new TCanvas(); + CTDCanvas->cd(); + H.second->Draw("hist"); + CTDFunction->Draw("same"); - H.second->Write(); - CTDFile.Close(); + H.second->Write(); + CTDFile.Close(); - TFile HVHistFile(m_OutFile+MString("_Det")+DetID+MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); + TFile HVHistFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); - TCanvas* HVHistCanvas = new TCanvas(); - HVHistCanvas->cd(); - FullDetHVEnergyHistograms[DetID]->Draw("hist"); - PhotopeakFunctionHV->Draw("same"); + TCanvas* HVHistCanvas = new TCanvas(); + HVHistCanvas->cd(); + FullDetHVEnergyHistograms[DetID]->Draw("hist"); + PhotopeakFunctionHV->Draw("same"); - FullDetHVEnergyHistograms[DetID]->Write(); - HVHistFile.Close(); + FullDetHVEnergyHistograms[DetID]->Write(); + HVHistFile.Close(); - TFile LVHistFile(m_OutFile+MString("_Det")+DetID+MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); + TFile LVHistFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); - TCanvas* LVHistCanvas = new TCanvas(); - LVHistCanvas->cd(); - FullDetLVEnergyHistograms[DetID]->Draw("hist"); - PhotopeakFunctionLV->Draw("same"); + TCanvas* LVHistCanvas = new TCanvas(); + LVHistCanvas->cd(); + FullDetLVEnergyHistograms[DetID]->Draw("hist"); + PhotopeakFunctionLV->Draw("same"); - FullDetLVEnergyHistograms[DetID]->Write(); - LVHistFile.Close(); + FullDetLVEnergyHistograms[DetID]->Write(); + LVHistFile.Close(); + } else { + cout<<"Fits failed for Det "< DeltaHVMap; // map DeltaLVMap; @@ -945,7 +961,7 @@ bool TrappingCorrectionCs137::Analyze() TF1* TrappingCorrectionCs137::GeneratePhotopeakFunction() { // Gaussian with a low-E shelf - TF1* PhotopeakFunction = new TF1("PhotopeakFunction", "gaus(0) + [0]*[3]*(1 - erf((x-[1])/(sqrt(2)*[2])))", 650, 670); + TF1* PhotopeakFunction = new TF1("PhotopeakFunction", "gaus(0) + [0]*[3]*(1 - erf((x-[1])/(sqrt(2)*[2])))", 635, 675); PhotopeakFunction->SetParName(0, "Gauss norm"); PhotopeakFunction->SetParName(1, "Mu"); From e2b1c0af20d089b62c436041ad9a8b57483f647f Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 19 May 2026 15:35:10 -0400 Subject: [PATCH 05/61] added depth binning but need to remove pixel by pixel fitting --- apps/TrappingCorrectionCs137.cxx | 196 +++++++++++++++++++------------ 1 file changed, 120 insertions(+), 76 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 07814280..93302348 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -65,8 +65,8 @@ using namespace std; #include "MAssembly.h" -double g_MinCTD = -400; -double g_MaxCTD = 400; +double g_MinCTD = -350; +double g_MaxCTD = 350; int g_MinCounts = 100; int g_HVStrips = 64; @@ -74,12 +74,12 @@ int g_LVStrips = 64; double g_CsPhotopeak = 661.7; -const int NCTDBins = 10; -double CTDBinWidth = (CTDmax - CTDmin) / NCTDBins; +const int NCTDBins = 5; +double CTDBinWidth = (g_MaxCTD - g_MinCTD) / NCTDBins; int GetCTDBin(double CTD) { - if (CTD < CTDmin || CTD >= CTDmax) return -1; - return int((CTD - CTDmin) / CTDBinWidth); + if (CTD < g_MinCTD || CTD >= g_MaxCTD) return -1; + return int((CTD - g_MinCTD) / CTDBinWidth); } //////////////////////////////////////////////////////////////////////////////// @@ -312,6 +312,20 @@ bool TrappingCorrectionCs137::Analyze() } } + vector CTDBinDirs; + + for (int c = 0; c < NCTDBins; ++c) { + + MString CTDDir = PixelDir + MString("/CTDbin_") + c; + CTDBinDirs.push_back(CTDDir); + + if (m_PixelCorrect == true) { + if (std::filesystem::create_directories(CTDDir.Data()) == false) { + cout << "Directory '" << CTDDir << "' already exists or could not be created." << endl; + } + } + } + // Prep CTD model parameters. Mirror the model about the x-axis depending which side is being analyzed. @@ -512,21 +526,21 @@ bool TrappingCorrectionCs137::Analyze() // If we didnt find an entry for the CTD and energy histograms, make new ones if (CTDHist == nullptr) { - char name[128]; sprintf(name,"CTD: PixelID %d CTDbin %d", PixelID,CTDBin); + char name[128]; sprintf(name,"CTD_Pixel%d_bin%d", PixelID, CTDBin); CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); CTDHist->SetXTitle("CTD (ns)"); CTDHist->SetYTitle("Hits"); CTDHistograms[CTDBin][PixelID] = CTDHist; } if (HVHist == nullptr) { - char name[128]; sprintf(name,"HV energy: PixelID %d ",PixelID,CTDBin); + char name[128]; sprintf(name,"HV_Pixel%d_bin%d", PixelID, CTDBin); HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); HVHist->SetXTitle("HV Energy (keV)"); HVHist->SetYTitle("Hits"); HVEnergyHistograms[CTDBin][PixelID] = HVHist; } if (LVHist == nullptr) { - char name[128]; sprintf(name,"LV energy: PixelID %d ",PixelID,CTDBin); + char name[128]; sprintf(name,"LV_Pixel%d_bin%d", PixelID, CTDBin); LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); LVHist->SetXTitle("LV Energy (keV)"); LVHist->SetYTitle("Hits"); @@ -558,66 +572,64 @@ bool TrappingCorrectionCs137::Analyze() cout << "Processing CTD bin " << c << endl; for (auto H : CTDHistograms[c]) { - + int PixelID = H.first; + int DetID = (PixelID - (PixelID % 10000)) / 10000; + TH1D* CTDHist = H.second; TH1D* HVHist = HVEnergyHistograms[c][PixelID]; TH1D* LVHist = LVEnergyHistograms[c][PixelID]; - - 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; - vector> tempvec; - FullDetEndpoints[DetID] = tempvec; - FullDetEndpoints[DetID].push_back(tempHVvec); - FullDetEndpoints[DetID].push_back(tempLVvec); - } - - TH1D* CTDHist = FullDetCTDHistograms[DetID]; - 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 ",DetID,PixelDir.Data()); - CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); - CTDHist->SetXTitle("CTD (ns)"); - CTDHist->SetYTitle("Hits"); - FullDetCTDHistograms[DetID] = CTDHist; + if (HVHist == nullptr || LVHist == nullptr) continue; + + TH1D* FullCTDHist = FullDetCTDHistograms[c][DetID]; + TH1D* FullHVHist = FullDetHVEnergyHistograms[c][DetID]; + TH1D* FullLVHist = FullDetLVEnergyHistograms[c][DetID]; + + if (FullCTDHist == nullptr) { + char name[128]; + sprintf(name,"CTD_Detector%d_bin%d", DetID, c); + FullCTDHist = new TH1D(name, name, + (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); + FullDetCTDHistograms[c][DetID] = FullCTDHist; } - if (HVHist == nullptr) { - char name[64]; sprintf(name,"HV energy: DetID %d ",DetID,PixelDir.Data()); - HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - HVHist->SetXTitle("HV Energy (keV)"); - HVHist->SetYTitle("Hits"); - FullDetHVEnergyHistograms[DetID] = HVHist; + + if (FullHVHist == nullptr) { + char name[128]; + sprintf(name,"HV_Detector%d_bin%d", DetID, c); + FullHVHist = new TH1D(name, name, + (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + FullDetHVEnergyHistograms[c][DetID] = FullHVHist; } - if (LVHist == nullptr) { - char name[64]; sprintf(name,"LV energy: DetID %d ",DetID,PixelDir.Data()); - LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - LVHist->SetXTitle("LV Energy (keV)"); - LVHist->SetYTitle("Hits"); - FullDetLVEnergyHistograms[DetID] = LVHist; + + if (FullLVHist == nullptr) { + char name[128]; + sprintf(name,"LV_Detector%d_bin%d", DetID, c); + FullLVHist = new TH1D(name, name, + (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); + FullDetLVEnergyHistograms[c][DetID] = FullLVHist; } - CTDHist->Add(CTDHist, H.second); - HVHist->Add(HVHist, HVEnergyHistograms[PixelID]); - LVHist->Add(LVHist, LVEnergyHistograms[PixelID]); + // Add pixel histograms into full detector histograms + FullCTDHist->Add(CTDHist); + FullHVHist->Add(HVHist); + FullLVHist->Add(LVHist); if (m_PixelCorrect==true) { + int PixelID = H.first; + + TH1D* CTDHist = H.second; + TH1D* HVHist = HVEnergyHistograms[c][PixelID]; + TH1D* LVHist = LVEnergyHistograms[c][PixelID]; + // Fit histograms and save the results // Only perform fits if the total counts in each is above the threshold given by g_MinCounts - cout<Integral()<<" counts in CTD histogram for Pixel ID "<Integral()<<" counts in HV energy histogram for Pixel ID "<Integral()<<" counts in LV energy histogram for Pixel ID "<Integral()<<" counts in CTD histogram for Pixel ID "<Integral()<<" counts in HV energy histogram for Pixel ID "<Integral()<<" counts in LV energy histogram for Pixel ID "<Integral() > g_MinCounts) && (HVEnergyHistograms[PixelID]->Integral() > g_MinCounts) && (LVEnergyHistograms[PixelID]->Integral() > g_MinCounts)) { + if ((CTDHist->Integral() > g_MinCounts) && (HVHist->Integral() > g_MinCounts) && (LVHist->Integral() > g_MinCounts)) { // Initialize and run the CTD fit double CTDGuess = H.second->GetBinCenter(H.second->GetMaximumBin()); @@ -636,10 +648,10 @@ bool TrappingCorrectionCs137::Analyze() // Initialize and run the HV photopeak fit TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - TFitResultPtr HVFit = HVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); // Save the results of the HV photopeak fit - ofstream HVFitFile(PixelDir +MString("/") + PixelID+ + MString("_CTDbin_") + c + MString("_HVEnergyFitResult_")+ MString(".txt")); + ofstream HVFitFile(PixelDir +MString("/") + PixelID + MString("_CTDbin_") + c + MString("_HVEnergyFitResult_")+ MString(".txt")); coutbuf = cout.rdbuf(); cout.rdbuf(HVFitFile.rdbuf()); if (HVFit >= 0) { @@ -650,7 +662,7 @@ bool TrappingCorrectionCs137::Analyze() // Initialize and run the LV photopeak fit TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = LVEnergyHistograms[PixelID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + TFitResultPtr LVFit = LVHist->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); // Save the results of the LV photopeak fit ofstream LVFitFile(PixelDir +MString("/") + PixelID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_")+ MString(".txt")); @@ -680,15 +692,15 @@ bool TrappingCorrectionCs137::Analyze() } TFile CTDHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c +MString("_CTDHist_") + MString("Illum.root"),"recreate"); - H.second->Write(); + CTDHist->Write(); CTDHistFile.Close(); TFile HVHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c +MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); - HVEnergyHistograms[PixelID]->Write(); + HVHist->Write(); HVHistFile.Close(); TFile LVHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c + MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); - LVEnergyHistograms[PixelID]->Write(); + LVHist->Write(); LVHistFile.Close(); } @@ -697,29 +709,53 @@ bool TrappingCorrectionCs137::Analyze() // Do the same function fitting and recording as above, but for the full detectors rather than pixel-by-pixel for (int c = 0; c < NCTDBins; ++c) { - for (auto H : FullDetCTDHistograms[c]) { - cout<<"Analyzing Full Detector Histograms"<Integral()<Integral()<Integral()<Integral()<<" bin "<Integral()<<" bin "<Integral()<<" bin "<Integral()<<" and CTD counts are: "<Integral()<Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[DetID]->Integral() > g_MinCounts)) { + if ((FullDetCTDHistograms[c][DetID]->Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[c][DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[c][DetID]->Integral() > g_MinCounts)) { + + // cout<<"enough counts in the histograms"<GetBinCenter(H.second->GetMaximumBin()); TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - TFitResultPtr HVFit = FullDetHVEnergyHistograms[DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + TFitResultPtr HVFit = FullDetHVEnergyHistograms[c][DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = FullDetLVEnergyHistograms[DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + TFitResultPtr LVFit = FullDetLVEnergyHistograms[c][DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); + + // cout<<"generated photopeak functions"<= 0) && (HVFit >= 0) && (LVFit >= 0)) { + // cout << "Hist fits are positive" << endl; + + // Check if the entry for this DetID exists; if not, initialize the inner vectors + if (FullDetEndpoints.find(DetID) == FullDetEndpoints.end()) { + FullDetEndpoints[DetID] = vector>(2); // Creates index [0] and [1] + } + FullDetEndpoints[DetID][0].push_back(CTDFit->Parameter(2)); FullDetEndpoints[DetID][0].push_back(HVFit->Parameter(1)); FullDetEndpoints[DetID][0].push_back(LVFit->Parameter(1)); @@ -727,7 +763,9 @@ bool TrappingCorrectionCs137::Analyze() ofstream CTDFitFile(DetID+MString("_CTDFitResult_")+ MString(".txt")); streambuf* coutbuf = cout.rdbuf(); cout.rdbuf(CTDFitFile.rdbuf()); + cout<<"CTD Fit Results for Detector "<= 0) { + // cout<<"CTD fit positive"<Print(); } cout.rdbuf(coutbuf); @@ -737,6 +775,7 @@ bool TrappingCorrectionCs137::Analyze() coutbuf = cout.rdbuf(); cout.rdbuf(HVFitFile.rdbuf()); if (HVFit >= 0) { + // cout<<"HV fit positive"<Print(); } cout.rdbuf(coutbuf); @@ -746,6 +785,7 @@ bool TrappingCorrectionCs137::Analyze() coutbuf = cout.rdbuf(); cout.rdbuf(LVFitFile.rdbuf()); if (LVFit >= 0) { + // cout<<"LV fit positive"<Print(); } cout.rdbuf(coutbuf); @@ -757,6 +797,7 @@ bool TrappingCorrectionCs137::Analyze() CTDCanvas->cd(); H.second->Draw("hist"); CTDFunction->Draw("same"); + cout<<"CTD histogram drawn"<Write(); CTDFile.Close(); @@ -765,27 +806,29 @@ bool TrappingCorrectionCs137::Analyze() TCanvas* HVHistCanvas = new TCanvas(); HVHistCanvas->cd(); - FullDetHVEnergyHistograms[DetID]->Draw("hist"); + FullDetHVEnergyHistograms[c][DetID]->Draw("hist"); PhotopeakFunctionHV->Draw("same"); + cout<<"HV histogram drawn"<Write(); + FullDetHVEnergyHistograms[c][DetID]->Write(); HVHistFile.Close(); TFile LVHistFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); TCanvas* LVHistCanvas = new TCanvas(); LVHistCanvas->cd(); - FullDetLVEnergyHistograms[DetID]->Draw("hist"); + FullDetLVEnergyHistograms[c][DetID]->Draw("hist"); PhotopeakFunctionLV->Draw("same"); + cout<<"LV histogram drawn"<Write(); + FullDetLVEnergyHistograms[c][DetID]->Write(); LVHistFile.Close(); } else { - cout<<"Fits failed for Det "< DeltaHVMap; // map DeltaLVMap; @@ -806,6 +849,7 @@ bool TrappingCorrectionCs137::Analyze() // If an individual pixel did not produce a good fit, default to the detector-level parameters. // Loop over each detector for (auto E: FullDetEndpoints) { + cout<<"Analyzing at Detector levle for detector: "< Date: Tue, 2 Jun 2026 09:24:10 -0400 Subject: [PATCH 06/61] added CTD binning and photopeak fits to LV and HV data --- include/MModuleLoaderMeasurementsHDF.h | 80 +--- src/MGUIOptionsLoaderMeasurementsHDF.cxx | 7 - src/MModuleLoaderMeasurementsHDF.cxx | 509 +++++------------------ 3 files changed, 101 insertions(+), 495 deletions(-) diff --git a/include/MModuleLoaderMeasurementsHDF.h b/include/MModuleLoaderMeasurementsHDF.h index 28da33ab..a926e449 100644 --- a/include/MModuleLoaderMeasurementsHDF.h +++ b/include/MModuleLoaderMeasurementsHDF.h @@ -1,7 +1,7 @@ /* * MModuleLoaderMeasurementsHDF.h * - * Copyright (C) by Andreas Zoglauer, Felix Hagemann. + * Copyright (C) by Andreas Zoglauer. * All rights reserved. * * Please see the source-file for the copyright-notice. @@ -39,15 +39,13 @@ using namespace H5; //! The versions of the strip hits stored in the HDF file -enum class MHDFStripHitVersion { V1_0, V1_2, V2_0, V2_2 }; +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"; - case MHDFStripHitVersion::V2_0: return os<<"2.0"; - case MHDFStripHitVersion::V2_2: return os<<"2.2"; default: return os<<"Unknown"; } } @@ -98,53 +96,6 @@ struct MHDFStripHit_V1_2 { uint8_t m_CRC; }; -//! Version 2 of the HDF5 hit info -struct MHDFStripHit_V2 { - uint32_t m_EventIndex; - uint8_t m_HitType; - uint8_t m_TimingType; - uint16_t m_StripID; - uint16_t m_EnergyData; - uint16_t m_TimingData; -}; - -//! Version 2.0 of the HDF5 event info -struct MHDFEvent_V2_0 { - uint16_t m_EventID; - uint64_t m_TimeCode; - // Nanoseconds since epoch - uint64_t m_GSETimeCode; - uint8_t m_Hits; - uint16_t m_Bytes; - uint8_t m_EventType; - uint8_t m_CRC; -}; - -//! Version 2.2 of the HDF5 event info (adding SPWTimeCode) -struct MHDFEvent_V2_2 { - uint16_t m_EventID; - uint64_t m_TimeCode; - // Nanoseconds since epoch - uint64_t m_GSETimeCode; - // Nanoseconds since start of acquisition - uint64_t m_SPWTimeCode; - uint8_t m_Hits; - uint16_t m_Bytes; - uint8_t m_EventType; - uint8_t m_CRC; -}; - -//! HDF5 EventIndices (for HDF5v2 data) -struct MHDFEventIndices_V2 { - uint32_t m_FEEHits[2]; - uint32_t m_ACSHits[2]; - uint32_t m_HS[2]; - uint32_t m_SinglesCounts[2]; - uint32_t m_DIBCoincidence[2]; - uint32_t m_DetectorHits[2]; - uint32_t m_DetectorLiveTime[2]; -}; - //! The version string struct MHDFStripHitVersionString { char string_col[256]; @@ -193,11 +144,6 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements virtual bool ReadXmlConfiguration(MXmlNode* Node); //! Create an XML node tree from the configuration virtual MXmlNode* CreateXmlConfiguration(); - - //! Enable/Disable including nearest neighbors - bool GetIncludeNearestNeighbor() const { return m_IncludeNearestNeighbor; } - //! Set nearest neighbor variable - void SetIncludeNearestNeighbor(bool Include) { m_IncludeNearestNeighbor = Include; } // protected methods: @@ -240,18 +186,10 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! The HDF5 data set DataSet m_HDFDataSet; - DataSet m_EventDataSet; - DataSet m_EventIndicesDataSet; - //! The HDF5 compound data type (v1) + //! The HDF5 compond data type CompType m_HDFCompoundDataType; - //! The HDF5 compound data types (v2) - CompType m_EventCompoundDataType; - CompType m_EventIndicesCompoundDataType; - CompType m_HDFFEECompoundDataType; - - //! The version of the strip hit structure MHDFStripHitVersion m_HDFStripHitVersion; @@ -263,18 +201,12 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! The current index in the batch unsigned int m_CurrentBatchIndex; - unsigned int m_MinHitIndex; // The various batches: //! The MHDFStripHit_V1_0 batch: vector m_Buffer_1_0; //! The MHDFStripHit_V1_2 batch: vector m_Buffer_1_2; - //! The MHDFStripHit_V2 batch: - vector m_Buffer_2; - vector m_EventIndices_2; - vector m_EventData_2_0; - vector m_EventData_2_2; //! Total number of hits in a file hsize_t m_TotalHits; @@ -291,14 +223,8 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! The file name of the strip map MString m_FileNameStripMap; - //! The map which ASICs are HV/LV for HDFv2 - vector>> m_ASICPolarities; - //! The strip map MStripMap m_StripMap; - - //! Variable that deteremines if the user wants to include Nearest Neighbors - bool m_IncludeNearestNeighbor; #ifdef ___CLING___ public: diff --git a/src/MGUIOptionsLoaderMeasurementsHDF.cxx b/src/MGUIOptionsLoaderMeasurementsHDF.cxx index a763f1bc..5126b5b8 100644 --- a/src/MGUIOptionsLoaderMeasurementsHDF.cxx +++ b/src/MGUIOptionsLoaderMeasurementsHDF.cxx @@ -85,12 +85,6 @@ void MGUIOptionsLoaderMeasurementsHDF::Create() dynamic_cast(m_Module)->GetFileNameStripMap()); m_FileSelectorStripMap->SetFileType("Strip map file", "*.map"); m_OptionsFrame->AddFrame(m_FileSelectorStripMap, LabelLayout); - - // Nearest neighbor checkbox - m_IncludeNearestNeighbor = new TGCheckButton(m_OptionsFrame, "Include Nearest Neighbors"); - m_IncludeNearestNeighbor->SetOn(dynamic_cast(m_Module)->GetIncludeNearestNeighbor()); - m_IncludeNearestNeighbor->Associate(this); - m_OptionsFrame->AddFrame(m_IncludeNearestNeighbor, LabelLayout); PostCreate(); @@ -138,7 +132,6 @@ bool MGUIOptionsLoaderMeasurementsHDF::OnApply() dynamic_cast(m_Module)->SetFileName(m_FileSelectorHDF->GetFileName()); dynamic_cast(m_Module)->SetLoadContinuationFiles(m_LoadContinuationFiles->IsOn()); dynamic_cast(m_Module)->SetFileNameStripMap(m_FileSelectorStripMap->GetFileName()); - dynamic_cast(m_Module)->SetIncludeNearestNeighbor(m_IncludeNearestNeighbor->IsOn()); return true; } diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx index 95f58949..24f1f918 100644 --- a/src/MModuleLoaderMeasurementsHDF.cxx +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -2,7 +2,7 @@ * MModuleLoaderMeasurementsHDF.cxx * * - * Copyright (C) by Andreas Zoglauer, Felix Hagemann. + * Copyright (C) by Andreas Zoglauer. * All rights reserved. * * @@ -28,7 +28,6 @@ // Standard libs: #include -#include using namespace std; // ROOT libs: @@ -76,8 +75,6 @@ MModuleLoaderMeasurementsHDF::MModuleLoaderMeasurementsHDF() : MModuleLoaderMeas m_LoadContinuationFiles = false; m_FileNameStripMap = ""; - - m_IncludeNearestNeighbor = true; } @@ -114,20 +111,6 @@ bool MModuleLoaderMeasurementsHDF::Initialize() m_NumberOfEventIDRollOvers = 0; m_LastEventID = 0; - // Clear all data buffers and related variables - m_Buffer_1_0.clear(); - m_Buffer_1_2.clear(); - m_Buffer_2.clear(); - m_EventIndices_2.clear(); - m_EventData_2_0.clear(); - m_EventData_2_2.clear(); - m_CurrentBatchSize = 0; - m_CurrentBatchIndex = 0; - m_MinHitIndex = 0; - - // Clear ASIC polarities (relevant in HDFv2) - m_ASICPolarities.clear(); - if (MFile::Exists(m_FileName) == false) { if (g_Verbosity >= c_Error) cout<= MHDFStripHitVersion::V2_0) { - if (m_StripMap.UpdateASICPolarities(m_ASICPolarities) == false) { - if (g_Verbosity >= c_Error) cout<= c_Error) cout< 0 && H5Lexists(m_HDFFile.getId(), "EventIndices", H5P_DEFAULT) > 0) { - m_EventDataSet = m_HDFFile.openDataSet("/Events"); - m_EventIndicesDataSet = m_HDFFile.openDataSet("/EventIndices"); - - // Read HDF5 version from Events/HDF5Version to a string - Attribute VersionAttribute = m_EventDataSet.openAttribute("HDFVersion"); - string VersionString; - VersionAttribute.read(VersionAttribute.getStrType(), VersionString); - - if (VersionString == "2.0" || VersionString == "2.1") { - m_HDFStripHitVersion = MHDFStripHitVersion::V2_0; - } else if (VersionString.length() >= 2 && VersionString.compare(0, 2, "2.") == 0) { - m_HDFStripHitVersion = MHDFStripHitVersion::V2_2; - } else { - if (g_Verbosity >= c_Error) cout<= c_Error) cout<>()); - } - - // Initialize the vector for this ASIC key if it doesn't exist - m_ASICPolarities.back()[ASICIsPrimary] = vector(); - } - - // Check Group 2: SP value - else if (match[2].matched) { - if (m_ASICPolarities.empty()) { - if (g_Verbosity >= c_Error) cout<= c_Error) cout< LV; val == 0 <=> HV - m_ASICPolarities.back()[ASICIsPrimary].push_back(val == "1"); - } - } - - // Output results for verification - if (g_Verbosity >= c_Info) { - for (size_t i = 0; i < m_ASICPolarities.size(); ++i) { - cout << "Detector ID " << i << ":" << endl; - for (bool key : {true, false} ) { - cout << " " << (key ? "Primary" : "Secondary") << ": "; - for (bool s : m_ASICPolarities[i][key]) cout << (s ? "LV" : "HV") << " "; - cout << endl; - } - } - } } cout<= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Error) cout<= 2.2 - uint64_t SPWTimeCode = 0; - - - if (m_HDFStripHitVersion <= MHDFStripHitVersion::V1_2) { - - uint16_t StripID; - uint16_t ADCs; - uint16_t TACs; - uint8_t HitType; - uint8_t TimingType; - - 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; - 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; - ++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; - HitType = Hit.m_HitType; - TimingType = Hit.m_TimingType; - } else { - if (g_Verbosity >= c_Error) cout<= c_Info) { - cout<= c_Error) cout<GetNStripHits() > 0) { - MStripHit* H = Event->GetStripHit(0); - delete H; - Event->RemoveStripHit(0); - } - } - IsZeroDataBug = false; - } - - 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); - - // Set boolean flags based on HitType and TimingType - H->IsGuardRing(HitType == 2); - if (H->IsGuardRing() == true) { - Event->SetGuardRingVeto(true); - } - - H->IsNearestNeighbor(HitType == 1); - H->HasFastTiming(TimingType == 1); - - // If the user does not want to include Nearest Neighbors in the data, then this is where we remove them - // NOTE: at some point we will want to remove this code and always include nearest neighbor data - if (m_IncludeNearestNeighbor == false && HitType == 1) { - delete H; // Clean up the memory we just allocated - // Increase counters - NStripHits = static_cast(NumberOfHits); - StripHitIndex++; - continue; - } - - Event->AddStripHit(H); - } else { - if (g_Verbosity >= c_Error) cout<= c_Error) cout<= c_Error) cout << "Buffer is empty or null!" << endl; - return false; - } + EventID = Hit.m_EventID; + TimeCode = Hit.m_TimeCode; + StripID = Hit.m_StripID; + 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<= c_Info) { + cout<= (m_MinHitIndex + m_Buffer_2.size())) { - if (g_Verbosity >= c_Error) cout << m_XmlTag << ": Entry " << i << " is NOT in the current FEEHits buffer!" << endl; - return false; - } - - MHDFStripHit_V2& Hit = m_Buffer_2[IndexInBatch]; - if (m_StripMap.HasReadOutID(Hit.m_StripID) == true) { - MStripHit* H = new MStripHit(); - H->SetDetectorID(m_StripMap.GetDetectorID(Hit.m_StripID)); - H->SetStripID(m_StripMap.GetStripNumber(Hit.m_StripID)); - H->IsLowVoltageStrip(m_StripMap.IsLowVoltage(Hit.m_StripID)); - H->SetADCUnits(Hit.m_EnergyData); - H->SetTAC(Hit.m_TimingData); - - // Set boolean flags based on HitType and TimingType - H->IsGuardRing(Hit.m_HitType == 2); - if (H->IsGuardRing() == true) { - Event->SetGuardRingVeto(true); - } - - H->IsNearestNeighbor(Hit.m_HitType == 1); - H->HasFastTiming(Hit.m_TimingType == 1); - - // If the user does not want to include Nearest Neighbors in the data, then this is where we remove them - // NOTE: at some point we will want to remove this code and always include nearest neighbor data - if (m_IncludeNearestNeighbor == false && Hit.m_HitType == 1) { - delete H; // Clean up the memory we just allocated - // Increase counters - NStripHits = static_cast(NumberOfHits); - StripHitIndex++; - continue; - } - - Event->AddStripHit(H); - } else { - if (g_Verbosity >= c_Error) cout<= c_Error) cout<GetNStripHits() > 0) { + MStripHit* H = Event->GetStripHit(0); + delete H; + Event->RemoveStripHit(0); } } - } else { - if (g_Verbosity >= c_Error) cout<SetID(LongEventID); if (m_HDFStripHitVersion == MHDFStripHitVersion::V1_0) { Event->SetCL(TimeCode); - } else if (m_HDFStripHitVersion >= MHDFStripHitVersion::V2_0) { + } else { Event->SetTI(TimeCode); - if (m_HDFStripHitVersion >= MHDFStripHitVersion::V2_2) { - Event->SetCL(SPWTimeCode); + } + + 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); + + + // Set boolean flags based on HitType and TimingType + H->IsGuardRing(HitType == 2); + if (H->IsGuardRing() == true) { + Event->SetGuardRingVeto(true); } + H->IsNearestNeighbor(HitType == 1); + H->HasFastTiming(TimingType == 1); + + Event->AddStripHit(H); + } else { - Event->SetTI(TimeCode); + if (g_Verbosity >= c_Error) cout<(NumberOfHits); StripHitIndex++; } Event->SetAnalysisProgress(MAssembly::c_EventLoader | MAssembly::c_EventLoaderMeasurement); - m_NEventsInFile++; - m_NGoodEventsInFile++; - return true; } @@ -809,7 +502,7 @@ void MModuleLoaderMeasurementsHDF::Finalize() MModule::Finalize(); cout<<"MModuleLoaderMeasurementsHDF: "<GetValue(); } - - MXmlNode* IncludeNearestNeighborNode = Node->GetNode("IncludeNearestNeighbor"); - if (IncludeNearestNeighborNode != nullptr) { - m_IncludeNearestNeighbor = IncludeNearestNeighborNode->GetValueAsBoolean(); - } return true; } @@ -858,7 +546,6 @@ MXmlNode* MModuleLoaderMeasurementsHDF::CreateXmlConfiguration() new MXmlNode(Node, "FileNameHDF5", m_FileName); new MXmlNode(Node, "LoadContinuationFiles", m_LoadContinuationFiles); new MXmlNode(Node, "FileNameStripMap", m_FileNameStripMap); - new MXmlNode(Node, "IncludeNearestNeighbor", m_IncludeNearestNeighbor); return Node; } From 18e835a69155dd60e0ed91e1e421caec05ac2f6b Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:13:16 -0400 Subject: [PATCH 07/61] fixed fit plotting and reading out CTD bins dn centroids to param txt file --- apps/TrappingCorrectionCs137.cxx | 621 +++++++------------------------ 1 file changed, 129 insertions(+), 492 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 93302348..244fe42b 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -187,8 +187,8 @@ bool TrappingCorrectionCs137::ParseCommandLine(int argc, char** argv) m_PixelCorrect = false; m_MultiRoundStripPairing = false; m_ContinueHDF5 = true; - m_MinEnergy = 40; - m_MaxEnergy = 5000; + m_MinEnergy = 600; + m_MaxEnergy = 700; time_t rawtime; tm* timeinfo; @@ -278,101 +278,69 @@ bool TrappingCorrectionCs137::ParseCommandLine(int argc, char** argv) //////////////////////////////////////////////////////////////////////////////// - //! Do whatever analysis is necessary bool TrappingCorrectionCs137::Analyze() { - //time code just to see + // time code just to see TStopwatch watch; watch.Start(); if (m_Interrupt == true) return false; - // [CTD, HV Energy, LV Energy] for HV illumination and LV illumination - map>> Endpoints; - map>> FullDetEndpoints; + // [CTD, HV Energy, LV Energy] for full detector values + map>> FullDetEndpoints; - // Store the HV and LV input files + // Store the input files vector FileNames; FileNames.push_back(m_FileName); - cout<<"file name stored"< IllumSide; - // IllumSide.push_back(MString("HV")); - // IllumSide.push_back(MString("LV")); - // cout<<"HV and LV integers mapped"< CTDBinDirs; + cout << "file name stored" << endl; - for (int c = 0; c < NCTDBins; ++c) { - - MString CTDDir = PixelDir + MString("/CTDbin_") + c; - CTDBinDirs.push_back(CTDDir); - - if (m_PixelCorrect == true) { - if (std::filesystem::create_directories(CTDDir.Data()) == false) { - cout << "Directory '" << CTDDir << "' already exists or could not be created." << endl; - } - } - } - - - // Prep CTD model parameters. Mirror the model about the x-axis depending which side is being analyzed. - double CTDFitMin = g_MinCTD; double CTDFitMax = g_MaxCTD; MString InputFile = FileNames[0]; + cout << " input file stored as: " << InputFile << endl; vector HDFNames; TH1::SetDefaultSumw2(); - map> CTDHistograms; - map> HVEnergyHistograms; - map> LVEnergyHistograms; + // Detector-level maps organized by [CTDBin][DetID] + map> FullDetCTDHistograms; + map> FullDetHVEnergyHistograms; + map> FullDetLVEnergyHistograms; // 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); - cout<<"hdf names loaded correctly"<SetFileNameStripMap(m_StripMapFile); Loader->SetFileName(File); @@ -391,23 +359,20 @@ bool TrappingCorrectionCs137::Analyze() 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); @@ -416,11 +381,11 @@ bool TrappingCorrectionCs137::Analyze() EventFilter->SetMinimumHits(0); EventFilter->SetMaximumHits(100); EventFilter->SetMinimumTotalEnergy(m_MinEnergy); - EventFilter->SetMaximumTotalEnergy(m_MaxEnergy*2); // Multiply by 2 because this is the event-level energy, i.e. sum over both sides + EventFilter->SetMaximumTotalEnergy(m_MaxEnergy * 2); S->SetModule(EventFilter, MNumber); ++MNumber; - cout<<"Creating strip pairing"<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); @@ -457,100 +421,69 @@ bool TrappingCorrectionCs137::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) ) { + if ((Event->HasAnalysisProgress(MAssembly::c_StripPairing) == true) && (Unfiltered == true)) { - // for each Hit 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(); - // 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) { + 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); } } } - // 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)) { + 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)) { + if ((LVSH->HasCalibratedTiming() == true) && (HVSH->HasCalibratedTiming() == true)) { double CTD = LVSH->GetTiming() - HVSH->GetTiming(); int CTDBin = GetCTDBin(CTD); if (CTDBin < 0) continue; - - 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; - vector> tempvec; - Endpoints[PixelID] = tempvec; - Endpoints[PixelID].push_back(tempHVvec); - Endpoints[PixelID].push_back(tempLVvec); - } - TH1D* CTDHist = CTDHistograms[CTDBin][PixelID]; - TH1D* HVHist = HVEnergyHistograms[CTDBin][PixelID]; - TH1D* LVHist = LVEnergyHistograms[CTDBin][PixelID]; - - // If we didnt find an entry for the CTD and energy histograms, make new ones - if (CTDHist == nullptr) { - char name[128]; sprintf(name,"CTD_Pixel%d_bin%d", PixelID, CTDBin); - CTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); - CTDHist->SetXTitle("CTD (ns)"); - CTDHist->SetYTitle("Hits"); - CTDHistograms[CTDBin][PixelID] = CTDHist; + TH1D* FullCTDHist = FullDetCTDHistograms[CTDBin][DetID]; + TH1D* FullHVHist = FullDetHVEnergyHistograms[CTDBin][DetID]; + TH1D* FullLVHist = FullDetLVEnergyHistograms[CTDBin][DetID]; + + if (FullCTDHist == nullptr) { + char name[128]; sprintf(name, "CTD_Detector%d_bin%d", DetID, CTDBin); + FullCTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD) / 2, g_MinCTD, g_MaxCTD); + FullDetCTDHistograms[CTDBin][DetID] = FullCTDHist; } - if (HVHist == nullptr) { - char name[128]; sprintf(name,"HV_Pixel%d_bin%d", PixelID, CTDBin); - HVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - HVHist->SetXTitle("HV Energy (keV)"); - HVHist->SetYTitle("Hits"); - HVEnergyHistograms[CTDBin][PixelID] = HVHist; + if (FullHVHist == nullptr) { + char name[128]; sprintf(name, "HV_Detector%d_bin%d", DetID, CTDBin); + FullHVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); + FullDetHVEnergyHistograms[CTDBin][DetID] = FullHVHist; } - if (LVHist == nullptr) { - char name[128]; sprintf(name,"LV_Pixel%d_bin%d", PixelID, CTDBin); - LVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - LVHist->SetXTitle("LV Energy (keV)"); - LVHist->SetYTitle("Hits"); - LVEnergyHistograms[CTDBin][PixelID] = LVHist; + if (FullLVHist == nullptr) { + char name[128]; sprintf(name, "LV_Detector%d_bin%d", DetID, CTDBin); + FullLVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); + FullDetLVEnergyHistograms[CTDBin][DetID] = FullLVHist; } - // Add the data to the histograms - CTDHist->Fill(CTD); - HVHist->Fill(HVEnergy); - LVHist->Fill(LVEnergy); + FullCTDHist->Fill(CTD); + FullHVHist->Fill(HVEnergy); + FullLVHist->Fill(LVEnergy); } } } @@ -561,443 +494,146 @@ bool TrappingCorrectionCs137::Analyze() } } - map> FullDetCTDHistograms; - map> FullDetHVEnergyHistograms; - map> FullDetLVEnergyHistograms; - - // 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 + // Do function fitting and recording for full detector outputs for (int c = 0; c < NCTDBins; ++c) { cout << "Processing CTD bin " << c << endl; - for (auto H : CTDHistograms[c]) { - - int PixelID = H.first; - int DetID = (PixelID - (PixelID % 10000)) / 10000; - - TH1D* CTDHist = H.second; - TH1D* HVHist = HVEnergyHistograms[c][PixelID]; - TH1D* LVHist = LVEnergyHistograms[c][PixelID]; - - if (HVHist == nullptr || LVHist == nullptr) continue; + for (auto const& [DetID, FullCTDHist] : FullDetCTDHistograms[c]) { - TH1D* FullCTDHist = FullDetCTDHistograms[c][DetID]; - TH1D* FullHVHist = FullDetHVEnergyHistograms[c][DetID]; - TH1D* FullLVHist = FullDetLVEnergyHistograms[c][DetID]; - - if (FullCTDHist == nullptr) { - char name[128]; - sprintf(name,"CTD_Detector%d_bin%d", DetID, c); - FullCTDHist = new TH1D(name, name, - (g_MaxCTD - g_MinCTD)/2, g_MinCTD, g_MaxCTD); - FullDetCTDHistograms[c][DetID] = FullCTDHist; - } + TH1D* HVHist = FullDetHVEnergyHistograms[c][DetID]; + TH1D* LVHist = FullDetLVEnergyHistograms[c][DetID]; - if (FullHVHist == nullptr) { - char name[128]; - sprintf(name,"HV_Detector%d_bin%d", DetID, c); - FullHVHist = new TH1D(name, name, - (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - FullDetHVEnergyHistograms[c][DetID] = FullHVHist; - } + if (FullCTDHist->Integral() > g_MinCounts && HVHist->Integral() > g_MinCounts && LVHist->Integral() > g_MinCounts) { - if (FullLVHist == nullptr) { - char name[128]; - sprintf(name,"LV_Detector%d_bin%d", DetID, c); - FullLVHist = new TH1D(name, name, - (m_MaxEnergy - m_MinEnergy)*2, m_MinEnergy, m_MaxEnergy); - FullDetLVEnergyHistograms[c][DetID] = FullLVHist; - } - - // Add pixel histograms into full detector histograms - FullCTDHist->Add(CTDHist); - FullHVHist->Add(HVHist); - FullLVHist->Add(LVHist); - - if (m_PixelCorrect==true) { - - int PixelID = H.first; - - TH1D* CTDHist = H.second; - TH1D* HVHist = HVEnergyHistograms[c][PixelID]; - TH1D* LVHist = LVEnergyHistograms[c][PixelID]; - - // Fit histograms and save the results - // Only perform fits if the total counts in each is above the threshold given by g_MinCounts - // cout<Integral()<<" counts in CTD histogram for Pixel ID "<Integral()<<" counts in HV energy histogram for Pixel ID "<Integral()<<" counts in LV energy histogram for Pixel ID "<Integral() > g_MinCounts) && (HVHist->Integral() > g_MinCounts) && (LVHist->Integral() > g_MinCounts)) { - - // Initialize and run the CTD fit - double CTDGuess = H.second->GetBinCenter(H.second->GetMaximumBin()); - TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); - TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); - - // Save the results of the CTD fit - ofstream CTDFitFile(PixelDir + MString("/") + PixelID + MString("_CTDbin_") + c + MString("_CTDFitResult.txt")); - streambuf* coutbuf = cout.rdbuf(); - cout.rdbuf(CTDFitFile.rdbuf()); - if (CTDFit >= 0) { - CTDFit->Print(); - } - cout.rdbuf(coutbuf); - CTDFitFile.close(); - - // Initialize and run the HV photopeak fit - TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); - - // Save the results of the HV photopeak fit - ofstream HVFitFile(PixelDir +MString("/") + PixelID + MString("_CTDbin_") + c + MString("_HVEnergyFitResult_")+ MString(".txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(HVFitFile.rdbuf()); - if (HVFit >= 0) { - HVFit->Print(); - } - cout.rdbuf(coutbuf); - HVFitFile.close(); - - // Initialize and run the LV photopeak fit - TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = LVHist->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); - - // Save the results of the LV photopeak fit - ofstream LVFitFile(PixelDir +MString("/") + PixelID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_")+ MString(".txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(LVFitFile.rdbuf()); - if (LVFit >= 0) { - LVFit->Print(); - } - 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 >= 0) && (HVFit >= 0) && (LVFit >= 0)) { - if (((CTDFit->Chi2()/CTDFit->Ndf()) < 25) && ((HVFit->Chi2()/HVFit->Ndf()) < 25) && ((LVFit->Chi2()/LVFit->Ndf()) < 25)) { - Endpoints[PixelID][0].push_back(CTDFit->Parameter(2)); - Endpoints[PixelID][0].push_back(HVFit->Parameter(1)); - Endpoints[PixelID][0].push_back(LVFit->Parameter(1)); - } else { - cout<<"Fits for Pixel "<Write(); - CTDHistFile.Close(); - - TFile HVHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c +MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); - HVHist->Write(); - HVHistFile.Close(); - - TFile LVHistFile(PixelDir+MString("/")+PixelID+ MString("_CTDbin_") + c + MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); - LVHist->Write(); - LVHistFile.Close(); - - } - } - } - - // Do the same function fitting and recording as above, but for the full detectors rather than pixel-by-pixel - for (int c = 0; c < NCTDBins; ++c) { - - cout << "Processing CTD bin " << c << endl; - - for (auto H : CTDHistograms[c]) { - - int PixelID = H.first; - cout<<"Analyzing Pixel ID "<Integral()<<" bin "<Integral()<<" bin "<Integral()<<" bin "<Integral()<<" and CTD counts are: "<Integral()<Integral() > g_MinCounts) && (FullDetHVEnergyHistograms[c][DetID]->Integral() > g_MinCounts) && (FullDetLVEnergyHistograms[c][DetID]->Integral() > g_MinCounts)) { - - // cout<<"enough counts in the histograms"<GetBinCenter(H.second->GetMaximumBin()); + double CTDGuess = FullCTDHist->GetBinCenter(FullCTDHist->GetMaximumBin()); TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); - TFitResultPtr CTDFit = H.second->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + TFitResultPtr CTDFit = FullCTDHist->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - TFitResultPtr HVFit = FullDetHVEnergyHistograms[c][DetID]->Fit(PhotopeakFunctionHV, "SQ", "", 642, 682); + TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "S", "", 645, 675); TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = FullDetLVEnergyHistograms[c][DetID]->Fit(PhotopeakFunctionLV, "SQ", "", 642, 682); - - // cout<<"generated photopeak functions"<Fit(PhotopeakFunctionLV, "S", "", 645, 675); if ((CTDFit >= 0) && (HVFit >= 0) && (LVFit >= 0)) { - // cout << "Hist fits are positive" << endl; - - // Check if the entry for this DetID exists; if not, initialize the inner vectors - if (FullDetEndpoints.find(DetID) == FullDetEndpoints.end()) { - FullDetEndpoints[DetID] = vector>(2); // Creates index [0] and [1] - } - FullDetEndpoints[DetID][0].push_back(CTDFit->Parameter(2)); - FullDetEndpoints[DetID][0].push_back(HVFit->Parameter(1)); - FullDetEndpoints[DetID][0].push_back(LVFit->Parameter(1)); + // Clear or initialize the vector for this specific bin and detector + FullDetEndpoints[c][DetID].clear(); + + // Parameter(2) is Mu for your CTD function, Parameter(1) is Mu for the Photopeaks + FullDetEndpoints[c][DetID].push_back(CTDFit->Parameter(2)); // Index 0: CTD Centroid + FullDetEndpoints[c][DetID].push_back(HVFit->Parameter(1)); // Index 1: HV Photopeak Mu + FullDetEndpoints[c][DetID].push_back(LVFit->Parameter(1)); // Index 2: LV Photopeak Mu + - ofstream CTDFitFile(DetID+MString("_CTDFitResult_")+ MString(".txt")); + ofstream CTDFitFile(DetID + MString("_CTDFitResult_.txt")); streambuf* coutbuf = cout.rdbuf(); cout.rdbuf(CTDFitFile.rdbuf()); - cout<<"CTD Fit Results for Detector "<= 0) { - // cout<<"CTD fit positive"<Print(); + CTDFit->Print(); } cout.rdbuf(coutbuf); CTDFitFile.close(); - ofstream HVFitFile(DetID + MString("_CTDbin_") + c +MString("_HVEnergyFitResult_")+ MString(".txt")); + ofstream HVFitFile(DetID + MString("_CTDbin_") + c + MString("_HVEnergyFitResult_.txt")); coutbuf = cout.rdbuf(); cout.rdbuf(HVFitFile.rdbuf()); if (HVFit >= 0) { - // cout<<"HV fit positive"<Print(); + HVFit->Print(); } cout.rdbuf(coutbuf); HVFitFile.close(); - ofstream LVFitFile(DetID+ MString("_CTDbin_") + c +MString("_LVEnergyFitResult_")+ MString(".txt")); + ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); coutbuf = cout.rdbuf(); cout.rdbuf(LVFitFile.rdbuf()); if (LVFit >= 0) { - // cout<<"LV fit positive"<Print(); + LVFit->Print(); } cout.rdbuf(coutbuf); LVFitFile.close(); - TFile CTDFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_CTDHist_") + MString("Illum.root"),"recreate"); - + TFile CTDFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_CTDHist_Illum.root"), "recreate"); TCanvas* CTDCanvas = new TCanvas(); CTDCanvas->cd(); - H.second->Draw("hist"); + FullCTDHist->Draw("hist"); CTDFunction->Draw("same"); - cout<<"CTD histogram drawn"<Write(); + FullCTDHist->Write(); CTDFile.Close(); - TFile HVHistFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_HVEnergyHist_") + MString("Illum.root"),"recreate"); - + TFile HVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_HVEnergyHist_Illum.root"), "recreate"); TCanvas* HVHistCanvas = new TCanvas(); HVHistCanvas->cd(); - FullDetHVEnergyHistograms[c][DetID]->Draw("hist"); + HVHist->Draw("Hist"); PhotopeakFunctionHV->Draw("same"); - cout<<"HV histogram drawn"<Write(); + HVHistCanvas->Write(); HVHistFile.Close(); - TFile LVHistFile(m_OutFile+MString("_Det")+DetID+ MString("_CTDbin_") + c +MString("_LVEnergyHist_") + MString("Illum.root"),"recreate"); - + TFile LVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_LVEnergyHist_Illum.root"), "recreate"); TCanvas* LVHistCanvas = new TCanvas(); LVHistCanvas->cd(); - FullDetLVEnergyHistograms[c][DetID]->Draw("hist"); + LVHist->Draw("Hist"); PhotopeakFunctionLV->Draw("same"); - cout<<"LV histogram drawn"<Write(); + LVHistCanvas->Write(); LVHistFile.Close(); } else { - cout<<"Fits failed for CTD bin "< DeltaHVMap; - // map DeltaLVMap; - - // map DeltaHVHist; - // map DeltaLVHist; - - // 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) { - cout<<"Analyzing at Detector levle for detector: "< 0) && (E.second[1].size() > 0)) { - CTD = E.second[0][0]; - HVCentroid = E.second[1][0]; - LVCentroid = E.second[0][1]; - } - - // Loop over each pixel - 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); - - // // 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)) { - - // 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]; - - // // Normalize the differences in Energy to account for calibration differences - // double HVDiff = (HVIllumHVCentroid - LVIllumHVCentroid)*(g_CsPhotopeak/HVIllumHVCentroid); - // double LVDiff = (HVIllumLVCentroid - LVIllumLVCentroid)*(g_CsPhotopeak/HVIllumLVCentroid); - - // DeltaHVMap[DetID]->SetBinContent(hv+1, lv+1, HVDiff); - // DeltaLVMap[DetID]->SetBinContent(hv+1, lv+1, LVDiff); - - // 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<= 3) { + CTDCentroid = FitsVec[0]; + HVCentroid = FitsVec[1]; + LVCentroid = FitsVec[2]; } + + // Write row entries corresponding purely to the detector level measurements + OutputCalFile << c << '\t' + << DetID << '\t' + << CTDCentroid << '\t' + << HVCentroid << '\t' + << LVCentroid << endl; } } OutputCalFile.close(); watch.Stop(); - cout<<"total time (s): "<cd(); - // H.second->SetMinimum(-5.); - // 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(); - // 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(); - // } - // } - -// watch.Stop(); -// cout<<"total time (s): "<SetParName(0, "Gauss norm"); PhotopeakFunction->SetParName(1, "Mu"); @@ -1013,12 +649,12 @@ TF1* TrappingCorrectionCs137::GeneratePhotopeakFunction() PhotopeakFunction->SetParName(3, "Shelf norm"); PhotopeakFunction->SetParameter("Gauss norm", 1000); - PhotopeakFunction->SetParameter("Mu", 662); + PhotopeakFunction->SetParameter("Mu", 661.7); PhotopeakFunction->SetParameter("Sigma", 2); PhotopeakFunction->SetParameter("Shelf norm", 0.05); PhotopeakFunction->SetParLimits(0, 10, 1e8); - PhotopeakFunction->SetParLimits(1, 650, 670); + PhotopeakFunction->SetParLimits(1, 652, 672); PhotopeakFunction->SetParLimits(2, 1.0, 10); PhotopeakFunction->SetParLimits(3, 0, 0.1); @@ -1045,6 +681,7 @@ TF1* TrappingCorrectionCs137::GenerateCTDFunction(double CTDFitMin, double CTDFi CTDFunction->SetParameter("Sigma", 12); CTDFunction->SetParameter("Mu", CTDGuess); + CTDFunction->SetParLimits(0, 0, 1e8); CTDFunction->SetParLimits(1, 0.01, 1); CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); @@ -1062,7 +699,7 @@ int g_NInterruptCatches = 1; MStripHit* TrappingCorrectionCs137::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 MaxEnergy = -numeric_limits::max(); double TotalEnergy = 0.0; MStripHit* MaxStrip = nullptr; @@ -1133,4 +770,4 @@ int main(int argc, char** argv) } -//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// \ No newline at end of file From 53bb70894736d9c02ef445465eeb29963b8690f4 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:28:48 -0400 Subject: [PATCH 08/61] updated photopeak fit function w linear tail --- apps/TrappingCorrectionCs137.cxx | 85 +++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 244fe42b..9ce2983b 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -511,6 +511,10 @@ bool TrappingCorrectionCs137::Analyze() TFitResultPtr CTDFit = FullCTDHist->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); + // PhotopeakFunctionHV->FixParameter(4, 0.5); + // PhotopeakFunctionHV->FixParameter(5, 0.80); + // PhotopeakFunctionHV->FixParameter(6, 0.13); + // PhotopeakFunctionHV->FixParameter(7, 0.028); TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "S", "", 645, 675); TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); @@ -640,23 +644,70 @@ bool TrappingCorrectionCs137::Analyze() TF1* TrappingCorrectionCs137::GeneratePhotopeakFunction() { - // Gaussian with a low-E shelf - TF1* PhotopeakFunction = new TF1("PhotopeakFunction", "gaus(0) + [0]*[3]*(1 - erf((x-[1])/(sqrt(2)*[2])))", 620, 680); - - 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", 661.7); - PhotopeakFunction->SetParameter("Sigma", 2); - PhotopeakFunction->SetParameter("Shelf norm", 0.05); - - PhotopeakFunction->SetParLimits(0, 10, 1e8); - PhotopeakFunction->SetParLimits(1, 652, 672); - PhotopeakFunction->SetParLimits(2, 1.0, 10); - PhotopeakFunction->SetParLimits(3, 0, 0.1); + // Component 1: Core Gaussian + // exp(-(x-x0)^2 / (2*sigma^2)) + MString gaussStr = "exp(-(x-[1])^2 / (2*[2]^2))"; + + // Component 2: Exponential Tail + Shelf + // BoverA * exp(gamma*(x-x0)) * 0.5 * erfc((x-x0)/(sigma*sigma_ratio*sqrt(2))) + MString expTailStr = "[3] * exp([4]*(x-[1])) * 0.5 * erfc((x-[1])/([2]*[5]*sqrt(2)))"; + + // Component 3: Linear Tail + Shelf + // BoverA * CoverB * (1 + D*(x-x0)) * 0.5 * erfc((x-x0)/(sigma*sigma_ratio*sqrt(2))) + MString linTailStr = "[3] * [6] * (1 + [7]*(x-[1])) * 0.5 * erfc((x-[1])/([2]*[5]*sqrt(2)))"; + + // Combine components with an overall normalization scaling factor [0] + MString fullFormula = "[0] * (" + gaussStr + " + " + expTailStr + " + " + linTailStr + ")"; + + // Instantiate TF1 over your expected fit window + TF1* PhotopeakFunction = new TF1("PhotopeakFunction", fullFormula.Data(), 645, 675); + + // Set Parameter Names + PhotopeakFunction->SetParName(0, "Amplitude"); + PhotopeakFunction->SetParName(1, "x0 (Mu)"); + PhotopeakFunction->SetParName(2, "Sigma Gauss"); + PhotopeakFunction->SetParName(3, "BoverA"); + PhotopeakFunction->SetParName(4, "Gamma"); + PhotopeakFunction->SetParName(5, "Sigma Ratio"); + PhotopeakFunction->SetParName(6, "CoverB"); + PhotopeakFunction->SetParName(7, "D (Lin Slope)"); + + // Provide initial sensible guesses for a Cs137 photopeak + PhotopeakFunction->SetParameter("Amplitude", 1000); + PhotopeakFunction->SetParameter("x0 (Mu)", 661.7); + PhotopeakFunction->SetParameter("Sigma Gauss", 2.0); + PhotopeakFunction->SetParameter("BoverA", 0.05); + PhotopeakFunction->SetParameter("Gamma", 0.5); + PhotopeakFunction->SetParameter("Sigma Ratio", 0.85); + PhotopeakFunction->SetParameter("CoverB", 0.13); + PhotopeakFunction->SetParameter("D (Lin Slope)", 0.028); + + // Set boundary limits to stabilize convergence + PhotopeakFunction->SetParLimits(0, 1, 1e8); + PhotopeakFunction->SetParLimits(1, 645, 675); // Keeps peak centered around 662 keV + PhotopeakFunction->SetParLimits(2, 0.5, 10); // Prevents sigma from blowing up or hitting zero + PhotopeakFunction->SetParLimits(3, 0.0, 1.0); // Tail shouldn't be larger than the main peak + PhotopeakFunction->SetParLimits(4, 0.001, 2.0); // Standard range for exponential decay factor + PhotopeakFunction->SetParLimits(5, 0.1, 5.0); // Ratio of shelf width to peak width + PhotopeakFunction->SetParLimits(6, 0.0, 5.0); + PhotopeakFunction->SetParLimits(7, -1.0, 1.0); + // // Gaussian with a low-E shelf + // TF1* PhotopeakFunction = new TF1("PhotopeakFunction", "gaus(0) + [0]*[3]*(1 - erf((x-[1])/(sqrt(2)*[2])))", 620, 680); + + // 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", 661.7); + // PhotopeakFunction->SetParameter("Sigma", 2); + // PhotopeakFunction->SetParameter("Shelf norm", 0.05); + + // PhotopeakFunction->SetParLimits(0, 10, 1e8); + // PhotopeakFunction->SetParLimits(1, 652, 672); + // PhotopeakFunction->SetParLimits(2, 1.0, 10); + // PhotopeakFunction->SetParLimits(3, 0, 0.1); return PhotopeakFunction; } From f9a12c093242f468dc2ff24815b93ed8c18cce53 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 10 Jun 2026 14:07:34 -0400 Subject: [PATCH 09/61] added output txt with spline fit for HV centroids --- apps/TrappingCorrectionCs137.cxx | 117 +++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 9ce2983b..196f808e 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -65,8 +65,8 @@ using namespace std; #include "MAssembly.h" -double g_MinCTD = -350; -double g_MaxCTD = 350; +double g_MinCTD = -300; +double g_MaxCTD = 300; int g_MinCounts = 100; int g_HVStrips = 64; @@ -74,12 +74,43 @@ int g_LVStrips = 64; double g_CsPhotopeak = 661.7; -const int NCTDBins = 5; -double CTDBinWidth = (g_MaxCTD - g_MinCTD) / NCTDBins; +const int NCTDBins = 15; +// We need NCTDBins + 1 edges to define the boundaries of NCTDBins +double g_CTDBinEdges[NCTDBins + 1]; + +// Run this initialization function ONCE at the start of your program (e.g., in main or class constructor) +void InitializeCTDBins() { + double center = (g_MaxCTD + g_MinCTD) / 2.0; + double halfWidth = (g_MaxCTD - g_MinCTD) / 2.0; + + for (int i = 0; i <= NCTDBins; ++i) { + // Map linear fraction from -1.0 (at i=0) to +1.0 (at i=NCTDBins) + double fraction = -1.0 + 2.0 * double(i) / double(NCTDBins); + + // Sinusoidal transformation: creates a higher density of points near the center + // If you prefer an even steeper density difference, you can use: pow(fraction, 3) + double nonLinearFraction = pow(fraction, 3);//sin(fraction * M_PI / 2.0); + + // Calculate the actual CTD boundary coordinate + g_CTDBinEdges[i] = center + halfWidth * nonLinearFraction; + } +} int GetCTDBin(double CTD) { + // Hard bounds check if (CTD < g_MinCTD || CTD >= g_MaxCTD) return -1; - return int((CTD - g_MinCTD) / CTDBinWidth); + + // Perform binary search to find the first edge that is strictly greater than our CTD value + auto it = std::upper_bound(g_CTDBinEdges, g_CTDBinEdges + NCTDBins + 1, CTD); + + // The bin index is simply the distance from the beginning boundary minus 1 + int bin = std::distance(g_CTDBinEdges, it) - 1; + + // Guard against edge cases at the absolute maximum limit + if (bin >= NCTDBins) bin = NCTDBins - 1; + if (bin < 0) bin = 0; + + return bin; } //////////////////////////////////////////////////////////////////////////////// @@ -274,8 +305,6 @@ bool TrappingCorrectionCs137::ParseCommandLine(int argc, char** argv) } - - //////////////////////////////////////////////////////////////////////////////// //! Do whatever analysis is necessary @@ -632,6 +661,78 @@ bool TrappingCorrectionCs137::Analyze() } OutputCalFile.close(); + + // -------------------------------------------------------------------------- + // Generate and Export Linear Splines for Charge Trapping Corrections + // -------------------------------------------------------------------------- + + ofstream SplineOutputFile; + SplineOutputFile.open(m_OutFile + MString("_splines.txt")); + + // Write a clean header explaining the piece-wise linear polynomial coefficients: + // S_i(x) = y + b*(x - x_i) + SplineOutputFile << "# Spline Piece-wise Coefficients for Trapping Correction" << endl; + SplineOutputFile << "Det_ID" << '\t' + << "Interval_i" << '\t' + << "X_i_(CTD_ns)" << '\t' + << "Y_i_(HV_Centroid)" << '\t' + << "b_coeff_(slope)" << endl; + + // Group our points by Detector ID so we can sort them by CTD value + // Map structure: [DetID] -> vector of pairs (CTD_Centroid, HV_Centroid) + map>> DetPointsMap; + + for (int c = 0; c < NCTDBins; ++c) { + for (auto const& [DetID, FitsVec] : FullDetEndpoints[c]) { + if (FitsVec.size() >= 3) { + double ctdCentroid = FitsVec[0]; + double hvCentroid = FitsVec[1]; + DetPointsMap[DetID].push_back(make_pair(ctdCentroid, hvCentroid)); + } + } + } + + // Loop through each detector to compute linear connectors + for (auto& [DetID, PointsVec] : DetPointsMap) { + + // Sort data points in ascending X (CTD) order + sort(PointsVec.begin(), PointsVec.end(), [](const pair& a, const pair& b) { + return a.first < b.first; + }); + + int nPoints = PointsVec.size(); + if (nPoints < 2) { + cout << "Warning: Detector " << DetID << " has too few data points (" << nPoints << ") to form a linear interpolation." << endl; + continue; + } + + cout << "Successfully generated linear spline for Detector " << DetID << " using " << nPoints << " points." << endl; + + // Direct algebraic evaluation of intervals (connecting point i to i+1) + for (int i = 0; i < nPoints - 1; ++i) { + double x_i = PointsVec[i].first; + double y_i = PointsVec[i].second; + + double x_next = PointsVec[i+1].first; + double y_next = PointsVec[i+1].second; + + // Calculate constant linear slope: dy / dx + double b = 0.0; + if (x_next != x_i) { + b = (y_next - y_i) / (x_next - x_i); + } + + // Save everything cleanly to the file match your exact format request + SplineOutputFile << DetID << '\t' + << i << '\t' + << x_i << '\t' + << y_i << '\t' + << b << endl; + } + } + + SplineOutputFile.close(); + cout << "Linear spline calibration file saved successfully." << endl; watch.Stop(); cout << "total time (s): " << watch.CpuTime() << endl; @@ -802,6 +903,8 @@ int main(int argc, char** argv) TApplication TrappingCorrectionApp("TrappingCorrectionApp", 0, 0); + InitializeCTDBins(); + g_Prg = new TrappingCorrectionCs137(); if (g_Prg->ParseCommandLine(argc, argv) == false) { From 29b13f9f17ef10a7258618e3c2425eb904a3e8fb Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:12:35 -0400 Subject: [PATCH 10/61] now output only returns HV energy root fits and comprehensive txt fit file --- apps/TrappingCorrectionCs137.cxx | 244 +++++++++++++++++-------------- 1 file changed, 131 insertions(+), 113 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 196f808e..38e176ef 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -74,7 +74,7 @@ int g_LVStrips = 64; double g_CsPhotopeak = 661.7; -const int NCTDBins = 15; +const int NCTDBins = 30; // We need NCTDBins + 1 edges to define the boundaries of NCTDBins double g_CTDBinEdges[NCTDBins + 1]; @@ -89,7 +89,7 @@ void InitializeCTDBins() { // Sinusoidal transformation: creates a higher density of points near the center // If you prefer an even steeper density difference, you can use: pow(fraction, 3) - double nonLinearFraction = pow(fraction, 3);//sin(fraction * M_PI / 2.0); + double nonLinearFraction = sin(fraction * M_PI / 2.0); // Calculate the actual CTD boundary coordinate g_CTDBinEdges[i] = center + halfWidth * nonLinearFraction; @@ -490,29 +490,29 @@ bool TrappingCorrectionCs137::Analyze() int CTDBin = GetCTDBin(CTD); if (CTDBin < 0) continue; - TH1D* FullCTDHist = FullDetCTDHistograms[CTDBin][DetID]; + // TH1D* FullCTDHist = FullDetCTDHistograms[CTDBin][DetID]; TH1D* FullHVHist = FullDetHVEnergyHistograms[CTDBin][DetID]; - TH1D* FullLVHist = FullDetLVEnergyHistograms[CTDBin][DetID]; + // TH1D* FullLVHist = FullDetLVEnergyHistograms[CTDBin][DetID]; - if (FullCTDHist == nullptr) { - char name[128]; sprintf(name, "CTD_Detector%d_bin%d", DetID, CTDBin); - FullCTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD) / 2, g_MinCTD, g_MaxCTD); - FullDetCTDHistograms[CTDBin][DetID] = FullCTDHist; - } + // if (FullCTDHist == nullptr) { + // char name[128]; sprintf(name, "CTD_Detector%d_bin%d", DetID, CTDBin); + // FullCTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD) / 2, g_MinCTD, g_MaxCTD); + // FullDetCTDHistograms[CTDBin][DetID] = FullCTDHist; + // } if (FullHVHist == nullptr) { char name[128]; sprintf(name, "HV_Detector%d_bin%d", DetID, CTDBin); FullHVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); FullDetHVEnergyHistograms[CTDBin][DetID] = FullHVHist; } - if (FullLVHist == nullptr) { - char name[128]; sprintf(name, "LV_Detector%d_bin%d", DetID, CTDBin); - FullLVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); - FullDetLVEnergyHistograms[CTDBin][DetID] = FullLVHist; - } + // if (FullLVHist == nullptr) { + // char name[128]; sprintf(name, "LV_Detector%d_bin%d", DetID, CTDBin); + // FullLVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); + // FullDetLVEnergyHistograms[CTDBin][DetID] = FullLVHist; + // } - FullCTDHist->Fill(CTD); + // FullCTDHist->Fill(CTD); FullHVHist->Fill(HVEnergy); - FullLVHist->Fill(LVEnergy); + // FullLVHist->Fill(LVEnergy); } } } @@ -523,78 +523,89 @@ bool TrappingCorrectionCs137::Analyze() } } + // Place this outside/before your CTD bin and Detector loops! + ofstream MasterFitFile; + MasterFitFile.open(m_OutFile + MString("_All_CTDBin_FitResults.txt")); + MasterFitFile << "======================================================================" << endl; + MasterFitFile << "MASTER PHOTOPEAK FIT LOG FOR ALL CTD BINS AND DETECTORS" << endl; + MasterFitFile << "======================================================================" << endl << endl; + // Do function fitting and recording for full detector outputs for (int c = 0; c < NCTDBins; ++c) { cout << "Processing CTD bin " << c << endl; - for (auto const& [DetID, FullCTDHist] : FullDetCTDHistograms[c]) { + for (auto const& [DetID, FullHVHist] : FullDetHVEnergyHistograms[c]) { TH1D* HVHist = FullDetHVEnergyHistograms[c][DetID]; - TH1D* LVHist = FullDetLVEnergyHistograms[c][DetID]; + // TH1D* LVHist = FullDetLVEnergyHistograms[c][DetID]; - if (FullCTDHist->Integral() > g_MinCounts && HVHist->Integral() > g_MinCounts && LVHist->Integral() > g_MinCounts) { + if (HVHist->Integral() > g_MinCounts) { - double CTDGuess = FullCTDHist->GetBinCenter(FullCTDHist->GetMaximumBin()); - TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); - TFitResultPtr CTDFit = FullCTDHist->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); + // double CTDGuess = FullCTDHist->GetBinCenter(FullCTDHist->GetMaximumBin()); + // TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); + // TFitResultPtr CTDFit = FullCTDHist->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); - // PhotopeakFunctionHV->FixParameter(4, 0.5); - // PhotopeakFunctionHV->FixParameter(5, 0.80); - // PhotopeakFunctionHV->FixParameter(6, 0.13); - // PhotopeakFunctionHV->FixParameter(7, 0.028); TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "S", "", 645, 675); - TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - TFitResultPtr LVFit = LVHist->Fit(PhotopeakFunctionLV, "S", "", 645, 675); + // TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + // TFitResultPtr LVFit = LVHist->Fit(PhotopeakFunctionLV, "S", "", 645, 675); - if ((CTDFit >= 0) && (HVFit >= 0) && (LVFit >= 0)) { + if ((HVFit >= 0)) { // Clear or initialize the vector for this specific bin and detector FullDetEndpoints[c][DetID].clear(); // Parameter(2) is Mu for your CTD function, Parameter(1) is Mu for the Photopeaks - FullDetEndpoints[c][DetID].push_back(CTDFit->Parameter(2)); // Index 0: CTD Centroid + // FullDetEndpoints[c][DetID].push_back(CTDFit->Parameter(2)); // Index 0: CTD Centroid FullDetEndpoints[c][DetID].push_back(HVFit->Parameter(1)); // Index 1: HV Photopeak Mu - FullDetEndpoints[c][DetID].push_back(LVFit->Parameter(1)); // Index 2: LV Photopeak Mu + // FullDetEndpoints[c][DetID].push_back(LVFit->Parameter(1)); // Index 2: LV Photopeak Mu - ofstream CTDFitFile(DetID + MString("_CTDFitResult_.txt")); - streambuf* coutbuf = cout.rdbuf(); - cout.rdbuf(CTDFitFile.rdbuf()); - cout << "CTD Fit Results for Detector " << DetID << " in CTD bin " << c << endl; - if (CTDFit >= 0) { - CTDFit->Print(); - } - cout.rdbuf(coutbuf); - CTDFitFile.close(); + // ofstream CTDFitFile(DetID + MString("_CTDFitResult_.txt")); + // streambuf* coutbuf = cout.rdbuf(); + // cout.rdbuf(CTDFitFile.rdbuf()); + // cout << "CTD Fit Results for Detector " << DetID << " in CTD bin " << c << endl; + // if (CTDFit >= 0) { + // CTDFit->Print(); + // } + // cout.rdbuf(coutbuf); + // CTDFitFile.close(); - ofstream HVFitFile(DetID + MString("_CTDbin_") + c + MString("_HVEnergyFitResult_.txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(HVFitFile.rdbuf()); - if (HVFit >= 0) { - HVFit->Print(); - } - cout.rdbuf(coutbuf); - HVFitFile.close(); + + MasterFitFile << "------------------------------------------------------------" << endl; + MasterFitFile << " DETECTOR ID: " << DetID << " | CTD BIN INDEX: " << c << endl; + MasterFitFile << "------------------------------------------------------------" << endl; - ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(LVFitFile.rdbuf()); - if (LVFit >= 0) { - LVFit->Print(); - } + // Redirect cout to our master file stream + std::streambuf* coutbuf = cout.rdbuf(); + cout.rdbuf(MasterFitFile.rdbuf()); + + // Passing "V" forces ROOT to print out all parameters, errors, and Chi2 configurations + HVFit->Print("V"); + + // Restore normal terminal routing cout.rdbuf(coutbuf); - LVFitFile.close(); - TFile CTDFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_CTDHist_Illum.root"), "recreate"); - TCanvas* CTDCanvas = new TCanvas(); - CTDCanvas->cd(); - FullCTDHist->Draw("hist"); - CTDFunction->Draw("same"); - FullCTDHist->Write(); - CTDFile.Close(); + MasterFitFile << endl << endl; // Add spacing between different bin entries + + // ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); + // coutbuf = cout.rdbuf(); + // cout.rdbuf(LVFitFile.rdbuf()); + // if (LVFit >= 0) { + // LVFit->Print(); + // } + // cout.rdbuf(coutbuf); + // LVFitFile.close(); + + // TFile CTDFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_CTDHist_Illum.root"), "recreate"); + // TCanvas* CTDCanvas = new TCanvas(); + // CTDCanvas->cd(); + // FullCTDHist->Draw("hist"); + // CTDFunction->Draw("same"); + // FullCTDHist->Write(); + // CTDFile.Close(); TFile HVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_HVEnergyHist_Illum.root"), "recreate"); TCanvas* HVHistCanvas = new TCanvas(); @@ -604,13 +615,13 @@ bool TrappingCorrectionCs137::Analyze() HVHistCanvas->Write(); HVHistFile.Close(); - TFile LVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_LVEnergyHist_Illum.root"), "recreate"); - TCanvas* LVHistCanvas = new TCanvas(); - LVHistCanvas->cd(); - LVHist->Draw("Hist"); - PhotopeakFunctionLV->Draw("same"); - LVHistCanvas->Write(); - LVHistFile.Close(); + // TFile LVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_LVEnergyHist_Illum.root"), "recreate"); + // TCanvas* LVHistCanvas = new TCanvas(); + // LVHistCanvas->cd(); + // LVHist->Draw("Hist"); + // PhotopeakFunctionLV->Draw("same"); + // LVHistCanvas->Write(); + // LVHistFile.Close(); } else { cout << "Fits failed for CTD bin " << c << " Detector " << DetID << endl; @@ -621,6 +632,10 @@ bool TrappingCorrectionCs137::Analyze() } } + // Place this at the absolute end of your Analyze() function + MasterFitFile.close(); + cout << "Master fit results log saved successfully." << endl; + // Setup parameter file ofstream OutputCalFile; OutputCalFile.open(m_OutFile + MString("_parameters.txt")); @@ -628,9 +643,9 @@ bool TrappingCorrectionCs137::Analyze() // Updated header matching your request OutputCalFile << "CTD_Bin" << '\t' << "Det_ID" << '\t' - << "CTD_Centroid_ns" << '\t' - << "HV_Centroid_keV" << '\t' - << "LV_Centroid_keV" << endl; + // << "CTD_Centroid_ns" << '\t' + << "HV_Centroid_keV" << '\t' << endl; + // << "LV_Centroid_keV" cout << "Parameter file set up" << endl; // Loop systematically over each CTD bin first @@ -640,23 +655,23 @@ bool TrappingCorrectionCs137::Analyze() // Loop over the detectors found inside this specific CTD bin for (auto const& [DetID, FitsVec] : FullDetEndpoints[c]) { - double CTDCentroid = 0.0; + // double CTDCentroid = 0.0; double HVCentroid = 0.0; - double LVCentroid = 0.0; + // double LVCentroid = 0.0; // Ensure all 3 parameters (CTD mu, HV mu, LV mu) were successfully saved - if (FitsVec.size() >= 3) { - CTDCentroid = FitsVec[0]; - HVCentroid = FitsVec[1]; - LVCentroid = FitsVec[2]; + if (FitsVec.size() >= 1) { + // CTDCentroid = FitsVec[0]; + HVCentroid = FitsVec[0]; + // LVCentroid = FitsVec[2]; } // Write row entries corresponding purely to the detector level measurements OutputCalFile << c << '\t' << DetID << '\t' - << CTDCentroid << '\t' - << HVCentroid << '\t' - << LVCentroid << endl; + // << CTDCentroid << '\t' + << HVCentroid << '\t' << endl; + // << LVCentroid } } @@ -674,20 +689,25 @@ bool TrappingCorrectionCs137::Analyze() SplineOutputFile << "# Spline Piece-wise Coefficients for Trapping Correction" << endl; SplineOutputFile << "Det_ID" << '\t' << "Interval_i" << '\t' - << "X_i_(CTD_ns)" << '\t' + << "X_i_(CTD_ns_BinMidpoint)" << '\t' << "Y_i_(HV_Centroid)" << '\t' << "b_coeff_(slope)" << endl; // Group our points by Detector ID so we can sort them by CTD value - // Map structure: [DetID] -> vector of pairs (CTD_Centroid, HV_Centroid) + // Map structure: [DetID] -> vector of pairs (CTD_Bin_Midpoint, HV_Centroid) map>> DetPointsMap; for (int c = 0; c < NCTDBins; ++c) { + // Calculate the exact midpoint of this specific variable CTD bin + double ctdBinMidpoint = (g_CTDBinEdges[c] + g_CTDBinEdges[c + 1]) / 2.0; + for (auto const& [DetID, FitsVec] : FullDetEndpoints[c]) { - if (FitsVec.size() >= 3) { - double ctdCentroid = FitsVec[0]; - double hvCentroid = FitsVec[1]; - DetPointsMap[DetID].push_back(make_pair(ctdCentroid, hvCentroid)); + // We only care that the energy photopeak successfully fit (FitsVec[1] is HV mu) + if (FitsVec.size() >= 1) { + double hvCentroid = FitsVec[0]; + + // Push the calculated geometric midpoint instead of the fitted CTD value + DetPointsMap[DetID].push_back(make_pair(ctdBinMidpoint, hvCentroid)); } } } @@ -695,7 +715,7 @@ bool TrappingCorrectionCs137::Analyze() // Loop through each detector to compute linear connectors for (auto& [DetID, PointsVec] : DetPointsMap) { - // Sort data points in ascending X (CTD) order + // Sort data points in ascending X (CTD Midpoint) order sort(PointsVec.begin(), PointsVec.end(), [](const pair& a, const pair& b) { return a.first < b.first; }); @@ -706,14 +726,14 @@ bool TrappingCorrectionCs137::Analyze() continue; } - cout << "Successfully generated linear spline for Detector " << DetID << " using " << nPoints << " points." << endl; + cout << "Successfully generated linear spline for Detector " << DetID << " using " << nPoints << " points (Bin Midpoints)." << endl; // Direct algebraic evaluation of intervals (connecting point i to i+1) for (int i = 0; i < nPoints - 1; ++i) { - double x_i = PointsVec[i].first; + double x_i = PointsVec[i].first; // This is now the exact midpoint of interval i double y_i = PointsVec[i].second; - double x_next = PointsVec[i+1].first; + double x_next = PointsVec[i+1].first; // Exact midpoint of interval i+1 double y_next = PointsVec[i+1].second; // Calculate constant linear slope: dy / dx @@ -722,7 +742,7 @@ bool TrappingCorrectionCs137::Analyze() b = (y_next - y_i) / (x_next - x_i); } - // Save everything cleanly to the file match your exact format request + // Save everything cleanly to the file matching your exact format request SplineOutputFile << DetID << '\t' << i << '\t' << x_i << '\t' @@ -738,8 +758,6 @@ bool TrappingCorrectionCs137::Analyze() return true; } - - //////////////////////////////////////////////////////////////////////////////// @@ -817,30 +835,30 @@ TF1* TrappingCorrectionCs137::GeneratePhotopeakFunction() //////////////////////////////////////////////////////////////////////////////// -TF1* TrappingCorrectionCs137::GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess) -{ - // 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)))", CTDFitMin, CTDFitMax); +// TF1* TrappingCorrectionCs137::GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess) +// { +// // 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)))", CTDFitMin, CTDFitMax); - CTDFunction->SetParName(0, "Norm"); - CTDFunction->SetParName(1, "Lambda"); - CTDFunction->SetParName(2, "Mu"); - CTDFunction->SetParName(3, "Sigma"); - CTDFunction->SetParName(4, "Flip"); +// 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", 12); - CTDFunction->SetParameter("Mu", CTDGuess); +// CTDFunction->SetParameter("Norm", 1000); +// CTDFunction->SetParameter("Lambda", 0.05); +// CTDFunction->SetParameter("Sigma", 12); +// CTDFunction->SetParameter("Mu", CTDGuess); - CTDFunction->SetParLimits(0, 0, 1e8); - CTDFunction->SetParLimits(1, 0.01, 1); - CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); - CTDFunction->SetParLimits(3, 6, 30); +// CTDFunction->SetParLimits(0, 0, 1e8); +// CTDFunction->SetParLimits(1, 0.01, 1); +// CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); +// CTDFunction->SetParLimits(3, 6, 30); - return CTDFunction; -} +// return CTDFunction; +// } //////////////////////////////////////////////////////////////////////////////// From b9e11f3682b298b60f2ad9c88dcf3d297dbfca20 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:25:55 -0400 Subject: [PATCH 11/61] added centroid error to spline readout txt --- apps/TrappingCorrectionCs137.cxx | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 38e176ef..487dabe4 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -65,9 +65,9 @@ using namespace std; #include "MAssembly.h" -double g_MinCTD = -300; -double g_MaxCTD = 300; -int g_MinCounts = 100; +double g_MinCTD = -250; +double g_MaxCTD = 250; +int g_MinCounts = 250; int g_HVStrips = 64; int g_LVStrips = 64; @@ -133,7 +133,7 @@ class TrappingCorrectionCs137 void Interrupt() { m_Interrupt = true; } //! Produce functions for fitting - TF1* GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess); + // TF1* GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess); TF1* GeneratePhotopeakFunction(); MStripHit* GetDominantStrip(vector& Strips, double& EnergyFraction); @@ -200,6 +200,8 @@ bool TrappingCorrectionCs137::ParseCommandLine(int argc, char** argv) Usage<<" -m: strip map file name (.map)"< i+1) && (argv[i+1][0] != '-' || isalpha(argv[i+1][1]) == 0))){ cout<<"Error: Option "<Parameter(2)); // Index 0: CTD Centroid FullDetEndpoints[c][DetID].push_back(HVFit->Parameter(1)); // Index 1: HV Photopeak Mu + FullDetEndpoints[c][DetID].push_back(HVFit->ParError(1)); // Index 2: HV Photopeak Mu Error // FullDetEndpoints[c][DetID].push_back(LVFit->Parameter(1)); // Index 2: LV Photopeak Mu @@ -644,7 +655,8 @@ bool TrappingCorrectionCs137::Analyze() OutputCalFile << "CTD_Bin" << '\t' << "Det_ID" << '\t' // << "CTD_Centroid_ns" << '\t' - << "HV_Centroid_keV" << '\t' << endl; + << "HV_Centroid_keV" << '\t' + <<"HV_Centroid_error_keV" << '\t' << endl; // << "LV_Centroid_keV" cout << "Parameter file set up" << endl; @@ -657,12 +669,14 @@ bool TrappingCorrectionCs137::Analyze() // double CTDCentroid = 0.0; double HVCentroid = 0.0; + double HVCentroidError = 0.0; // double LVCentroid = 0.0; // Ensure all 3 parameters (CTD mu, HV mu, LV mu) were successfully saved if (FitsVec.size() >= 1) { // CTDCentroid = FitsVec[0]; HVCentroid = FitsVec[0]; + HVCentroidError = FitsVec[1]; // LVCentroid = FitsVec[2]; } @@ -670,7 +684,8 @@ bool TrappingCorrectionCs137::Analyze() OutputCalFile << c << '\t' << DetID << '\t' // << CTDCentroid << '\t' - << HVCentroid << '\t' << endl; + << HVCentroid << '\t' + << HVCentroidError << '\t' << endl; // << LVCentroid } } From 8bc3f4f844f5657aa76e5c4dfe6ca91b343a80b2 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:08:16 -0700 Subject: [PATCH 12/61] writes min and max CTD from data to splines txt file --- apps/TrappingCorrectionCs137.cxx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 487dabe4..7ab1ae84 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -67,14 +67,14 @@ using namespace std; double g_MinCTD = -250; double g_MaxCTD = 250; -int g_MinCounts = 250; +int g_MinCounts = 1500; int g_HVStrips = 64; int g_LVStrips = 64; double g_CsPhotopeak = 661.7; -const int NCTDBins = 30; +const int NCTDBins = 50; // We need NCTDBins + 1 edges to define the boundaries of NCTDBins double g_CTDBinEdges[NCTDBins + 1]; @@ -727,6 +727,26 @@ bool TrappingCorrectionCs137::Analyze() } } + // Find Absolute Global Min and Max CTD values --- + double globalMinCTD = 1e9; // Initialize to a large positive number + double globalMaxCTD = -1e9; // Initialize to a large negative number + bool foundAnyPoints = false; + + for (auto const& [DetID, PointsVec] : DetPointsMap) { + for (auto const& pt : PointsVec) { + double ctdVal = pt.first; + if (ctdVal < globalMinCTD) globalMinCTD = ctdVal; + if (ctdVal > globalMaxCTD) globalMaxCTD = ctdVal; + foundAnyPoints = true; + } + } + + // If no data points were mapped at all, fall back safely to global system limits + if (!foundAnyPoints) { + globalMinCTD = g_MinCTD; + globalMaxCTD = g_MaxCTD; + } + // Loop through each detector to compute linear connectors for (auto& [DetID, PointsVec] : DetPointsMap) { @@ -758,6 +778,7 @@ bool TrappingCorrectionCs137::Analyze() } // Save everything cleanly to the file matching your exact format request + SplineOutputFile << "# Global Dataset Limits: Min_CTD = " << globalMinCTD << " ns, Max_CTD = " << globalMaxCTD << " ns" << endl; SplineOutputFile << DetID << '\t' << i << '\t' << x_i << '\t' From 3d970d35c3bf23c2215609ea6ae087697b0ca685 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:46:25 -0700 Subject: [PATCH 13/61] adapted module for trapping correction, wrote function for sim input file --- src/MModuleTrappingCorrection.cxx | 562 ++++++++++++++++++++++++++++++ 1 file changed, 562 insertions(+) create mode 100644 src/MModuleTrappingCorrection.cxx diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx new file mode 100644 index 00000000..5f8e8de2 --- /dev/null +++ b/src/MModuleTrappingCorrection.cxx @@ -0,0 +1,562 @@ +/* + * MModuleTrappingCorrection.cxx + * + * + * Copyright (C) 2008-2008 by Andreas Zoglauer, Alex Lowell, + * Sean Pike, Carolyn Kierans. + * 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. + * + */ + + +//////////////////////////////////////////////////////////////////////////////// +// +// MModuleTrappingCorrection +// +//////////////////////////////////////////////////////////////////////////////// + + +// Include the header: +#include "MModuleTrappingCorrection.h" +#include "MGUIOptionsTrappingCorrection.h" + +// Standard libs: + +// ROOT libs: +#include "TMath.h" +#include "TGClient.h" +#include "TH1.h" + +// MEGAlib libs: + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MModuleTrappingCorrection) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() +{ + // Construct an instance of MModuleTrappingCorrection + + // Set all module relevant information + + // Set the module name --- has to be unique + m_Name = "Trapping Correction"; // - correcting energies for charge trapping (by Sophie); + + // Set the XML tag --- has to be unique --- no spaces allowed + m_XmlTag = "TrappingCorrection"; + + // Set all modules, which have to be done before this module + AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); + AddPreceedingModuleType(MAssembly::c_StripPairing, true); + AddPreceedingModuleType(MAssembly::c_TACcut, true); + AddPreceedingModuleType(MAssembly::c_DepthCalibration, true); +// AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection, false); // Soft requirement + + // Set all types this modules handles + AddModuleType(MAssembly::c_DepthCorrection); + AddModuleType(MAssembly::c_PositionDetermiation); + + // Set all modules, which can follow this module + AddSucceedingModuleType(MAssembly::c_NoRestriction); + + // Set if this module has an options GUI + // If true, overwrite ShowOptionsGUI() with the call to the GUI! + m_HasOptionsGUI = true; + // If true, you have to derive a class from MGUIOptions (use MGUIOptionsTemplate) + // and implement all your GUI options + + // Allow the use of multiple threads and instances + m_AllowMultiThreading = true; + m_AllowMultipleInstances = false; + + +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MModuleTrappingCorrection::~MModuleTrappingCorrection() +{ + // Delete this instance of MModuleTrappingCorrection +} + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTrappingCorrection::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. + vector DetList = m_Geometry->GetDetectorList(); + + // 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. + // If using the card cage at UCSD, default to DetID=11. + unsigned int DetID = i; + if (m_UCSDOverride == true) { + DetID = 11; + } + + 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(); + + if (g_Verbosity >= c_Info) { + 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; + } else { + if (g_Verbosity >= c_Error) { + cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a duplicate detector: "<= c_Error) { + cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a Strip3D detector with "<GetNSensitiveVolumes()<<" Sensitive Volumes."<GetAvailableModuleByXmlTag("EnergyCalibration"); + if (m_EnergyCalibration == nullptr) { + cout << "MModuleTrappingCorrection: couldn't resolve pointer to Energy Calibration Module... need access to this module for energy resolution lookup!" << endl; + return false; + } + + return MModule::Initialize(); +} + + +//////////////////////////////////////////////////////////////////////////////// + +// void MModuleTrappingCorrection::CreateExpos() +// { +// // Create all expos + +// if (HasExpos() == true) return; + +// // Set the histogram display +// m_ExpoTrappingCorrection = new MGUIExpoTrappingCorrection(this); +// m_ExpoTrappingCorrection->SetDepthHistogramArrangement(&m_DetectorIDs); +// for (unsigned int i = 0; i < m_DetectorIDs.size(); ++i){ +// unsigned int DetID = m_DetectorIDs[i]; +// double thickness = m_Thicknesses[DetID]; +// m_ExpoTrappingCorrection->SetDepthHistogramParameters(DetID, 120, -thickness/2.0,thickness/2.0); +// } +// m_Expos.push_back(m_ExpoTrappingCorrection); +// } + + +///////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) +{ + + if (Event->GetGuardRingVeto() == true) { + //TODO: Handle events with GR vetos + + Event->SetTrappingCorrectionError("GR Veto"); + 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); + + int Grade = GetHitGrade(H); + + // Handle different grades differently + // GRADE=-1 is an error. Break from the loop and continue. + if (Grade < 0){ + H->SetNoDepth(); + Event->SetTrappingCorrectionError("Error in Trapping Correction"); + 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->SetTrappingCorrectionError("Multiple hits on single strip"); + if (Grade==5) { + ++m_Error5; + } else if (Grade==6) { + ++m_Error6; + } + } else { // If the Grade is 0-4, we can handle it. + + // Get the position from the depth cal. If error is thrown, record and no depth. + // Take a Hit and separate its activated X- and Y-strips into separate vectors. + vector LVStrips; + vector HVStrips; + + for (unsigned int j = 0; j < H->GetNStripHits(); ++j) { + MStripHit* SH = H->GetStripHit(j); + if (SH->IsLowVoltageStrip()) LVStrips.push_back(SH); else HVStrips.push_back(SH); + } + + 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 = LVSH->GetDetectorID(); + int LVStripID = LVSH->GetStripID(); + int HVStripID = HVSH->GetStripID(); + // int PixelCode = 10000*DetID + 100*LVStripID + HVStripID; + + + + + int Zpos = H->GetPosition(); + int Zpos_res = H->GetPositionResolution(); + + + + + + } + } + } + + // Event->SetAnalysisProgress(MAssembly::c_DepthCorrection | MAssembly::c_PositionDetermiation); + + return true; +} + + +///////////////////////////////////////////////////////////////////////////////// + + +MStripHit* MModuleTrappingCorrection::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; + 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; +} + + +///////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) +{ + MFile SimCCEFile; + if (SimCCEFile.Open(FileName) == false) { + cout << "ERROR in MModuleTrappingCorrection::LoadSimCCEFile: failed to open file." << endl; + return false; + } + + // Clear existing array data before loading new files + m_Depths.clear(); + m_CCE_HVs.clear(); + + MString Line; + int ValidLineCount = 0; + + while (SimCCEFile.ReadLine(Line)) { + // Skip comment lines + if (Line.BeginsWith('#') == true) { + continue; + } + + std::vector Tokens = Line.Tokenize(","); + + // Skip empty lines safely + if (Tokens.size() == 0) { + continue; + } + + if (ValidLineCount == 0) { + // Step 1: Read parameters A, B, and C from the first line + if (Tokens.size() == 3) { + m_ParamA = Tokens[0].ToDouble(); + m_ParamB = Tokens[1].ToDouble(); + m_ParamC = Tokens[2].ToDouble(); + ValidLineCount++; + } else { + cout << "ERROR in LoadSimCCEFile: Expected 3 parameters (A,B,C) on the first line." << endl; + SimCCEFile.Close(); + return false; + } + } + else if (ValidLineCount == 1) { + // Step 2: Skip the second line which is the column header (z_depth_mm,CCE_HV) + ValidLineCount++; + } + else { + // Step 3: Read the rest of the rows into your depth and CCE HV arrays + if (Tokens.size() == 2) { + m_Depths.push_back(Tokens[0].ToDouble()); + m_CCE_HVs.push_back(Tokens[1].ToDouble()); + ValidLineCount++; + } + } + } + + SimCCEFile.Close(); + + // Print summary to console if verbose logging is enabled + if (g_Verbosity >= c_Info) { + cout << m_XmlTag << "Loaded parameters: A=" << m_ParamA + << ", B=" << m_ParamB << ", C=" << m_ParamC << endl; + cout << m_XmlTag << "Loaded " << m_Depths.size() << " data points into arrays." << endl; + } + + return true; +} + + +///////////////////////////////////////////////////////////////////////////////// + + +int MModuleTrappingCorrection::GetHitGrade(MHit* H){ + // Function for choosing which Depth-to-CTD relation to use for a given event. + // At time of writing, intention is to choose a CTD based on sub-pixel region determined via charge sharing (Event "grade"). + // 5 possible grades, and one Error Grade, -1. GRADE 4 is as yet uncategorized complicated geometry. GRADE 5 means multiple, presumably separated strip hits. + + //organize x and y strips into vectors + if (H == nullptr) { + return -1; + } + if (H->GetNStripHits() == 0) { + // Error if no strip hits listed. Bad grade is returned + if (g_Verbosity >= c_Error) cout << m_XmlTag << "ERROR in MModuleTrappingCorrection: HIT WITH NO STRIP HITS" << endl; + return -1; + } + + // Take a Hit and separate its activated p and n strips into separate vectors. + 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 == nullptr ) { + if (g_Verbosity >= c_Error) cout << m_XmlTag << "ERROR in MModuleTrappingCorrection: Trapping Correction: got NULL strip hit :( " << endl; + return -1; + } + if (SH->GetEnergy() == 0 ) { + if (g_Verbosity >= c_Error) cout << m_XmlTag << "ERROR in MModuleTrappingCorrection: Trapping Correction: got strip without energy :( " << endl; + return -1; + } + if (SH->IsLowVoltageStrip()) { + LVStrips.push_back(SH); + LVStripIDs.push_back(SH->GetStripID()); + } + else { + HVStrips.push_back(SH); + HVStripIDs.push_back(SH->GetStripID()); + } + } + + // If the same strip has multiple hits, this is a bad grade. + bool MultiHitX = H->GetStripHitMultipleTimesX(); + bool MultiHitY = H->GetStripHitMultipleTimesY(); + if (MultiHitX || MultiHitY) { + return 5; + } + + 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 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 ( ((HVmax - HVmin) >= (HVStrips.size())) || ((LVmax - LVmin) >= (LVStrips.size())) ) { + return 6; + } + } + else{ + return -1; + } + + int return_value; + // If 1 strip on each side, GRADE=0 + // This represents the center of the pixel + 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 ( (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 ( (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 ( (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 ( (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 ( (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 ( (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 ( (LVStrips.size() == 3) && (HVStrips.size() == 2) ) { + return_value = 1; + } + + else { + // If more complicated than the above cases, return 4 for now. + // TODO: Handle more complicated charge distributions. + return_value = 4; + } + + return return_value; +} + +///////////////////////////////////////////////////////////////////////////////// + + +void MModuleTrappingCorrection::ShowOptionsGUI() +{ + // Show the options GUI - or do nothing + MGUIOptionsTrappingCorrection* Options = new MGUIOptionsTrappingCorrection(this); + Options->Create(); + gClient->WaitForUnmap(Options); +} + + +///////////////////////////////////////////////////////////////////////////////// + + +bool MModuleTrappingCorrection::ReadXmlConfiguration(MXmlNode* Node) +{ + //! Read the configuration data from an XML node + + MXmlNode* SimCCEFileNameNode = Node->GetNode("SimCCEFileName"); + if (SimCCEFileNameNode != nullptr) { + m_SimCCEFile = SimCCEFileNameNode->GetValue(); + } + + return true; +} + + +///////////////////////////////////////////////////////////////////////////////// + +MXmlNode* MModuleTrappingCorrection::CreateXmlConfiguration() +{ + //! Create an XML node tree from the configuration + + MXmlNode* Node = new MXmlNode(0,m_XmlTag); + new MXmlNode(Node, "SimCCEFileName", m_SimCCEFile); + + return Node; +} + +void MModuleTrappingCorrection::Finalize() +{ + + MModule::Finalize(); + cout << "finalize is working" << endl; + + // Clean up maps and vectors + m_Detectors.clear(); + m_DetectorIDs.clear(); + +} + + + +// MModuleTrappingCorrection.cxx: the end... +//////////////////////////////////////////////////////////////////////////////// From ae68931240115ac5fd92c6114c0b98babecc03fc Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:51:52 -0700 Subject: [PATCH 14/61] Adapted header to trapping correction --- include/MModuleTrappingCorrection.h | 141 ++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 include/MModuleTrappingCorrection.h diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h new file mode 100644 index 00000000..bb608242 --- /dev/null +++ b/include/MModuleTrappingCorrection.h @@ -0,0 +1,141 @@ +/* + * MModuleTrappingCorrection.h + * + * Copyright (C) 2008-2008 by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MModuleTrappingCorrection__ +#define __MModuleTrappingCorrection__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// Standard libs: +#include +#include +#include +#include + +// ROOT libs: + +// MEGAlib libs: +#include "MGlobal.h" +#include "MModule.h" +#include "MModuleEnergyCalibration.h" +#include "MDStrip3D.h" +#include "MDShapeBRIK.h" +#include "MGUIExpoTrappingCorrection.h" + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +class MModuleTrappingCorrection : public MModule +{ + // public interface: + public: + //! Default constructor + MModuleTrappingCorrection(); + //! Default destructor + virtual ~MModuleTrappingCorrection(); + + //! Create a new object of this class + virtual MModuleTrappingCorrection* Clone() { return new MModuleTrappingCorrection(); } + + //! Initialize the module + virtual bool Initialize(); + + //! Create the expos + virtual void CreateExpos(); + + //! Main data analysis routine, which updates the event to a new level + virtual bool AnalyzeEvent(MReadOutAssembly* Event); + + //! Show the options GUI + virtual void ShowOptionsGUI(); + + //! Set filename for coefficients file + void SetSimCCEFileName( const MString& FileName) { m_SimCCEFile = FileName; } + //! Get filename for coefficients file + MString GetSimCCEFileName() const { return m_SimCCEFile; } + + + + //! Read the XML configuration + bool ReadXmlConfiguration(MXmlNode* Node); + + //! Create the XML configuration + MXmlNode* CreateXmlConfiguration(); + + //! Finalize + void Finalize(); + + // protected methods: + protected: + //! Returns the strip with most energy from vector Strips, also gives back the energy fraction + MStripHit* GetDominantStrip(std::vector& Strips, double& EnergyFraction); + + //! Retrieve the appropriate Depth values given the DetID + vector GetDepth(int DetID); + + //! Retrieve the appropriate CTD values given the DetID and Grade + vector GetCTD(int DetID, int Grade); + + //! Determine the Grade (geometry of charge sharing) of the Hit + int GetHitGrade(MHit* H); + + //! Load in the specified coefficients file + bool LoadSimCCEFile(MString FName); + + + + // private methods + private: + + + // protected members: + protected: + + unordered_map> m_SimCCE; + double m_SimCCE_Energy; + MString m_SimCCEFile; + + unordered_map m_Detectors; + vector m_DetectorIDs; + MModuleEnergyCalibration* m_EnergyCalibration; + MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; + + // The CTD Map maps each detector (int) to a 2D array of CTD values. + // unordered_map>> m_CTDMap; + // unordered_map> m_DepthGrid; + // unordered_map> m_SplineMap; + + bool m_SimCCEFileIsLoaded; + + + + // private members: + private: + + + + +#ifdef ___CLING___ + public: + ClassDef(MModuleTrappingCorrection, 0) // no description +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// From acf6b1fd53cf976845ad399829123076eb66a2b7 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:56:02 -0700 Subject: [PATCH 15/61] added params for sim cce input file --- include/MModuleTrappingCorrection.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index bb608242..aeda7cea 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -120,6 +120,12 @@ class MModuleTrappingCorrection : public MModule bool m_SimCCEFileIsLoaded; + double m_ParamA; + double m_ParamB; + double m_ParamC; + std::vector m_Depths; + std::vector m_CCE_HVs; + // private members: From 17cfbd6ead55ddddfbd7d985b5e3c11ec7385323 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:19:06 -0700 Subject: [PATCH 16/61] added function for CCE corrected energy + interpolation helper function --- src/MModuleTrappingCorrection.cxx | 49 ++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 5f8e8de2..fbcde2ac 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -270,7 +270,13 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) int Zpos_res = H->GetPositionResolution(); - + // You can freely read the data now + for (size_t i = 0; i < m_Depths.size(); ++i) { + double currentDepth = m_Depths[i]; + double currentCCE = m_CCE_HVs[i]; + + // Do your analysis calculations here... + } } @@ -381,6 +387,47 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) } +///////////////////////////////////////////////////////////////////////////////// + +double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted) { + + // 2. Look up the simulation CCE baseline using the helper + double cce_base = Interpolate(ctd_val, m_Depths, sim_cce_sorted); + + // 3. Evaluate the physical trapping function model using class global popt variables + double expected_centroid_scaled = m_ParamA * (1.0 - m_ParamB * (1.0 - cce_base)) * (1.0 - m_ParamC * (1.0 - cce_base)); + + // 4. Prevent division-by-zero or non-physical negative values + if (expected_centroid_scaled <= 0.0) { + return uncorrected_energy; + } + + // 5. Reconstruct the true un-trapped energy deposition + return uncorrected_energy / expected_centroid_scaled; +} + + +///////////////////////////////////////////////////////////////////////////////// + + +double MModuleTrappingCorrection::Interpolate(double x, const std::vector& xp, const std::vector& fp) { + if (xp.empty()) return 0.0; + if (x <= xp.front()) return fp.front(); + if (x >= xp.back()) return fp.back(); + + // Find the first element which is greater than or equal to x + auto it = std::lower_bound(xp.begin(), xp.end(), x); + size_t idx = std::distance(xp.begin(), it); + + // Linear interpolation formula + double x0 = xp[idx - 1]; + double x1 = xp[idx]; + double y0 = fp[idx - 1]; + double y1 = fp[idx]; + + return y0 + (x - x0) * (y1 - y0) / (x1 - x0); +} + ///////////////////////////////////////////////////////////////////////////////// From b194068231613c00e555ab4e713056a358a0aafe Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:30:16 -0700 Subject: [PATCH 17/61] updating hit energies with correction factor --- src/MModuleTrappingCorrection.cxx | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index fbcde2ac..6dc49b70 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -263,20 +263,25 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) int HVStripID = HVSH->GetStripID(); // int PixelCode = 10000*DetID + 100*LVStripID + HVStripID; - + + // Get the position value (assumed from event/hit context H) + int Zpos = H->GetPosition(); + double ctd_val = static_cast(Zpos); - int Zpos = H->GetPosition(); - int Zpos_res = H->GetPositionResolution(); - + // Correct the Low Voltage side energy if the hit pointer exists + if (LVSH != nullptr) { + double rawLVEnergy = LVSH->GetEnergy(); // Replace with actual getter method for your hit class + double correctedLVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawLVEnergy, m_CCEs_LV); + LVSH->SetEnergy(correctedLVEnergy); // Replace with actual setter method for your hit class + } - // You can freely read the data now - for (size_t i = 0; i < m_Depths.size(); ++i) { - double currentDepth = m_Depths[i]; - double currentCCE = m_CCE_HVs[i]; - - // Do your analysis calculations here... - } + // Correct the High Voltage side energy if the hit pointer exists + if (HVSH != nullptr) { + double rawHVEnergy = HVSH->GetEnergy(); // Replace with actual getter method for your hit class + double correctedHVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawHVEnergy, m_CCEs_HV); + HVSH->SetEnergy(correctedHVEnergy); // Replace with actual setter method for your hit class + } } From 124d92bc1565303243b7f6b7c6a3fda7898269d0 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:32:51 -0700 Subject: [PATCH 18/61] added LV CCE column to sim read in --- src/MModuleTrappingCorrection.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 6dc49b70..1a96a98e 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -335,6 +335,7 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Clear existing array data before loading new files m_Depths.clear(); m_CCE_HVs.clear(); + m_CCEs_LVs.clear(); MString Line; int ValidLineCount = 0; @@ -371,9 +372,10 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) } else { // Step 3: Read the rest of the rows into your depth and CCE HV arrays - if (Tokens.size() == 2) { + if (Tokens.size() == 3) { m_Depths.push_back(Tokens[0].ToDouble()); m_CCE_HVs.push_back(Tokens[1].ToDouble()); + m_CCEs_LVs.push_back(Tokens[2].ToDouble()) ValidLineCount++; } } From 46eb4b4ab1b212e0d9671b8c10f01894514fa547 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 14:56:34 -0700 Subject: [PATCH 19/61] updated assembly files and removed GUI functionality --- include/MAssembly.h | 1 + include/MModuleTrappingCorrection.h | 16 ++++++++-------- src/MAssembly.cxx | 2 ++ src/MModuleTrappingCorrection.cxx | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/MAssembly.h b/include/MAssembly.h index 396f5b13..3a1bce53 100644 --- a/include/MAssembly.h +++ b/include/MAssembly.h @@ -73,6 +73,7 @@ class MAssembly static const uint64_t c_FlagHits = (1 << 22); static const uint64_t c_Diagnostics = (1 << 23); static const uint64_t c_ResponseGeneration = (1 << 24); + static const uint64_t c_TrappingCorrection = (1 << 25); // IMPORTANT: diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index aeda7cea..f9d38f22 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -30,7 +30,7 @@ #include "MModuleEnergyCalibration.h" #include "MDStrip3D.h" #include "MDShapeBRIK.h" -#include "MGUIExpoTrappingCorrection.h" +// #include "MGUIExpoTrappingCorrection.h" // Forward declarations: @@ -62,9 +62,9 @@ class MModuleTrappingCorrection : public MModule //! Show the options GUI virtual void ShowOptionsGUI(); - //! Set filename for coefficients file + //! Set filename for SimCCE file void SetSimCCEFileName( const MString& FileName) { m_SimCCEFile = FileName; } - //! Get filename for coefficients file + //! Get filename for SimCCE file MString GetSimCCEFileName() const { return m_SimCCEFile; } @@ -83,16 +83,16 @@ class MModuleTrappingCorrection : public MModule //! Returns the strip with most energy from vector Strips, also gives back the energy fraction MStripHit* GetDominantStrip(std::vector& Strips, double& EnergyFraction); - //! Retrieve the appropriate Depth values given the DetID - vector GetDepth(int DetID); + // //! Retrieve the appropriate Depth values given the DetID + // vector GetDepth(int DetID); - //! Retrieve the appropriate CTD values given the DetID and Grade - vector GetCTD(int DetID, int Grade); + // //! Retrieve the appropriate CTD values given the DetID and Grade + // vector GetCTD(int DetID, int Grade); //! Determine the Grade (geometry of charge sharing) of the Hit int GetHitGrade(MHit* H); - //! Load in the specified coefficients file + //! Load in the specified SimCCE file bool LoadSimCCEFile(MString FName); diff --git a/src/MAssembly.cxx b/src/MAssembly.cxx index 70340d41..7bcc18df 100644 --- a/src/MAssembly.cxx +++ b/src/MAssembly.cxx @@ -67,6 +67,7 @@ using namespace std; #include "MModuleLoaderMeasurementsFITS.h" #include "MModuleEnergyCalibration.h" #include "MModuleDepthCalibration.h" +#include "MModuleTrappingCorrection.h" #include "MModuleStripPairingMultiRoundChiSquare.h" #include "MModuleStripPairingChiSquare.h" #include "MModuleEventFilter.h" @@ -137,6 +138,7 @@ MAssembly::MAssembly() m_Supervisor->AddAvailableModule(new MModuleStripPairingMultiRoundChiSquare()); m_Supervisor->AddAvailableModule(new MModuleStripPairingChiSquare()); m_Supervisor->AddAvailableModule(new MModuleDepthCalibration()); + m_Supervisor->AddAvailableModule(new MModuleTrappingCorrection()); m_Supervisor->AddAvailableModule(new MModuleEventSaver()); m_Supervisor->AddAvailableModule(new MModuleSaverMeasurementsL0()); diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 1a96a98e..147727d4 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -26,7 +26,7 @@ // Include the header: #include "MModuleTrappingCorrection.h" -#include "MGUIOptionsTrappingCorrection.h" +// #include "MGUIOptionsTrappingCorrection.h" // Standard libs: @@ -69,7 +69,7 @@ MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() // AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection, false); // Soft requirement // Set all types this modules handles - AddModuleType(MAssembly::c_DepthCorrection); + AddModuleType(MAssembly::c_TrappingCorrection); AddModuleType(MAssembly::c_PositionDetermiation); // Set all modules, which can follow this module @@ -288,7 +288,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) } } - // Event->SetAnalysisProgress(MAssembly::c_DepthCorrection | MAssembly::c_PositionDetermiation); + Event->SetAnalysisProgress(MAssembly::c_TrappingCorrection); return true; } From 50177b39900fe28312ad1c6f055ad6776f379ba0 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 3 Jul 2026 15:22:14 -0700 Subject: [PATCH 20/61] correction compiles error free --- include/MModuleTrappingCorrection.h | 15 ++++-- src/MModuleTrappingCorrection.cxx | 73 ++++++++++++----------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index f9d38f22..62c5704c 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -53,8 +53,8 @@ class MModuleTrappingCorrection : public MModule //! Initialize the module virtual bool Initialize(); - //! Create the expos - virtual void CreateExpos(); + // //! Create the expos + // virtual void CreateExpos(); //! Main data analysis routine, which updates the event to a new level virtual bool AnalyzeEvent(MReadOutAssembly* Event); @@ -95,6 +95,12 @@ class MModuleTrappingCorrection : public MModule //! Load in the specified SimCCE file bool LoadSimCCEFile(MString FName); + //! Get the Sim-based corrected energy given the CTD value, uncorrected energy, and the sorted Sim CCE values + double GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted); + + //! Interpolate a value given x, xp, and fp + double Interpolate(double x, const std::vector& xp, const std::vector& fp); + // private methods @@ -111,7 +117,7 @@ class MModuleTrappingCorrection : public MModule unordered_map m_Detectors; vector m_DetectorIDs; MModuleEnergyCalibration* m_EnergyCalibration; - MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; + // MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; // The CTD Map maps each detector (int) to a 2D array of CTD values. // unordered_map>> m_CTDMap; @@ -124,7 +130,8 @@ class MModuleTrappingCorrection : public MModule double m_ParamB; double m_ParamC; std::vector m_Depths; - std::vector m_CCE_HVs; + std::vector m_CCEs_HV; + std::vector m_CCEs_LV; diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 147727d4..16b3aa89 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -65,7 +65,7 @@ MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); AddPreceedingModuleType(MAssembly::c_StripPairing, true); AddPreceedingModuleType(MAssembly::c_TACcut, true); - AddPreceedingModuleType(MAssembly::c_DepthCalibration, true); + AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); // AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection, false); // Soft requirement // Set all types this modules handles @@ -113,9 +113,7 @@ bool MModuleTrappingCorrection::Initialize() // 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 == true) { - DetID = 11; - } + MDDetector* det = DetList[i]; vector DetectorNames; @@ -125,20 +123,9 @@ bool MModuleTrappingCorrection::Initialize() 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(); if (g_Verbosity >= c_Info) { 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; @@ -205,7 +192,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) if (Event->GetGuardRingVeto() == true) { //TODO: Handle events with GR vetos - Event->SetTrappingCorrectionError("GR Veto"); + // Event->SetTrappingCorrectionError("GR Veto"); return false; } else { @@ -222,22 +209,22 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // GRADE=-1 is an error. Break from the loop and continue. if (Grade < 0){ H->SetNoDepth(); - Event->SetTrappingCorrectionError("Error in Trapping Correction"); - 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. + // // Event->SetTrappingCorrectionError("Error in Trapping Correction"); + // 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->SetTrappingCorrectionError("Multiple hits on single strip"); - if (Grade==5) { - ++m_Error5; - } else if (Grade==6) { - ++m_Error6; - } + // // Event->SetTrappingCorrectionError("Multiple hits on single strip"); + // if (Grade==5) { + // ++m_Error5; + // } else if (Grade==6) { + // ++m_Error6; + // } } else { // If the Grade is 0-4, we can handle it. // Get the position from the depth cal. If error is thrown, record and no depth. @@ -266,7 +253,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Get the position value (assumed from event/hit context H) - int Zpos = H->GetPosition(); + double Zpos = H->GetPosition().GetZ(); double ctd_val = static_cast(Zpos); // Correct the Low Voltage side energy if the hit pointer exists @@ -334,8 +321,8 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Clear existing array data before loading new files m_Depths.clear(); - m_CCE_HVs.clear(); - m_CCEs_LVs.clear(); + m_CCEs_HV.clear(); + m_CCEs_LV.clear(); MString Line; int ValidLineCount = 0; @@ -374,8 +361,8 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Step 3: Read the rest of the rows into your depth and CCE HV arrays if (Tokens.size() == 3) { m_Depths.push_back(Tokens[0].ToDouble()); - m_CCE_HVs.push_back(Tokens[1].ToDouble()); - m_CCEs_LVs.push_back(Tokens[2].ToDouble()) + m_CCEs_HV.push_back(Tokens[1].ToDouble()); + m_CCEs_LV.push_back(Tokens[2].ToDouble()); ValidLineCount++; } } @@ -561,13 +548,13 @@ int MModuleTrappingCorrection::GetHitGrade(MHit* H){ ///////////////////////////////////////////////////////////////////////////////// -void MModuleTrappingCorrection::ShowOptionsGUI() -{ - // Show the options GUI - or do nothing - MGUIOptionsTrappingCorrection* Options = new MGUIOptionsTrappingCorrection(this); - Options->Create(); - gClient->WaitForUnmap(Options); -} +// void MModuleTrappingCorrection::ShowOptionsGUI() +// { +// // Show the options GUI - or do nothing +// MGUIOptionsTrappingCorrection* Options = new MGUIOptionsTrappingCorrection(this); +// Options->Create(); +// gClient->WaitForUnmap(Options); +// } ///////////////////////////////////////////////////////////////////////////////// From e1d03e221a6ab785792e1080610c90b25c4085a7 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:10:59 -0700 Subject: [PATCH 21/61] added fitting and param readout for HV strips --- apps/TrappingCorrectionCs137.cxx | 77 +++++++++++++++++--------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 7ab1ae84..177a9b51 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -502,7 +502,7 @@ bool TrappingCorrectionCs137::Analyze() // TH1D* FullCTDHist = FullDetCTDHistograms[CTDBin][DetID]; TH1D* FullHVHist = FullDetHVEnergyHistograms[CTDBin][DetID]; - // TH1D* FullLVHist = FullDetLVEnergyHistograms[CTDBin][DetID]; + TH1D* FullLVHist = FullDetLVEnergyHistograms[CTDBin][DetID]; // if (FullCTDHist == nullptr) { // char name[128]; sprintf(name, "CTD_Detector%d_bin%d", DetID, CTDBin); @@ -514,15 +514,15 @@ bool TrappingCorrectionCs137::Analyze() FullHVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); FullDetHVEnergyHistograms[CTDBin][DetID] = FullHVHist; } - // if (FullLVHist == nullptr) { - // char name[128]; sprintf(name, "LV_Detector%d_bin%d", DetID, CTDBin); - // FullLVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); - // FullDetLVEnergyHistograms[CTDBin][DetID] = FullLVHist; - // } + if (FullLVHist == nullptr) { + char name[128]; sprintf(name, "LV_Detector%d_bin%d", DetID, CTDBin); + FullLVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); + FullDetLVEnergyHistograms[CTDBin][DetID] = FullLVHist; + } // FullCTDHist->Fill(CTD); FullHVHist->Fill(HVEnergy); - // FullLVHist->Fill(LVEnergy); + FullLVHist->Fill(LVEnergy); } } } @@ -559,8 +559,8 @@ bool TrappingCorrectionCs137::Analyze() TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "S", "", 645, 675); - // TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); - // TFitResultPtr LVFit = LVHist->Fit(PhotopeakFunctionLV, "S", "", 645, 675); + TF1* PhotopeakFunctionLV = GeneratePhotopeakFunction(); + TFitResultPtr LVFit = LVHist->Fit(PhotopeakFunctionLV, "S", "", 645, 675); if ((HVFit >= 0)) { @@ -571,7 +571,8 @@ bool TrappingCorrectionCs137::Analyze() // FullDetEndpoints[c][DetID].push_back(CTDFit->Parameter(2)); // Index 0: CTD Centroid FullDetEndpoints[c][DetID].push_back(HVFit->Parameter(1)); // Index 1: HV Photopeak Mu FullDetEndpoints[c][DetID].push_back(HVFit->ParError(1)); // Index 2: HV Photopeak Mu Error - // FullDetEndpoints[c][DetID].push_back(LVFit->Parameter(1)); // Index 2: LV Photopeak Mu + FullDetEndpoints[c][DetID].push_back(LVFit->Parameter(1)); // Index 2: LV Photopeak Mu + FullDetEndpoints[c][DetID].push_back(LVFit->ParError(1)); // Index 2: HV Photopeak Mu Error // ofstream CTDFitFile(DetID + MString("_CTDFitResult_.txt")); @@ -601,14 +602,14 @@ bool TrappingCorrectionCs137::Analyze() MasterFitFile << endl << endl; // Add spacing between different bin entries - // ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); - // coutbuf = cout.rdbuf(); - // cout.rdbuf(LVFitFile.rdbuf()); - // if (LVFit >= 0) { - // LVFit->Print(); - // } - // cout.rdbuf(coutbuf); - // LVFitFile.close(); + ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); + coutbuf = cout.rdbuf(); + cout.rdbuf(LVFitFile.rdbuf()); + if (LVFit >= 0) { + LVFit->Print(); + } + cout.rdbuf(coutbuf); + LVFitFile.close(); // TFile CTDFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_CTDHist_Illum.root"), "recreate"); // TCanvas* CTDCanvas = new TCanvas(); @@ -626,13 +627,13 @@ bool TrappingCorrectionCs137::Analyze() HVHistCanvas->Write(); HVHistFile.Close(); - // TFile LVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_LVEnergyHist_Illum.root"), "recreate"); - // TCanvas* LVHistCanvas = new TCanvas(); - // LVHistCanvas->cd(); - // LVHist->Draw("Hist"); - // PhotopeakFunctionLV->Draw("same"); - // LVHistCanvas->Write(); - // LVHistFile.Close(); + TFile LVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_LVEnergyHist_Illum.root"), "recreate"); + TCanvas* LVHistCanvas = new TCanvas(); + LVHistCanvas->cd(); + LVHist->Draw("Hist"); + PhotopeakFunctionLV->Draw("same"); + LVHistCanvas->Write(); + LVHistFile.Close(); } else { cout << "Fits failed for CTD bin " << c << " Detector " << DetID << endl; @@ -652,12 +653,13 @@ bool TrappingCorrectionCs137::Analyze() OutputCalFile.open(m_OutFile + MString("_parameters.txt")); // Updated header matching your request - OutputCalFile << "CTD_Bin" << '\t' - << "Det_ID" << '\t' - // << "CTD_Centroid_ns" << '\t' + OutputCalFile << "Det_ID" << '\t' + << "CTD_Bin" << '\t' + << "CTD_Centroid_ns" << '\t' << "HV_Centroid_keV" << '\t' - <<"HV_Centroid_error_keV" << '\t' << endl; - // << "LV_Centroid_keV" + <<"HV_Centroid_error_keV" << '\t' + << "LV_Centroid_keV" << '\t' + <<"LV_Centroid_error_keV" << '\t' << endl; cout << "Parameter file set up" << endl; // Loop systematically over each CTD bin first @@ -670,23 +672,26 @@ bool TrappingCorrectionCs137::Analyze() // double CTDCentroid = 0.0; double HVCentroid = 0.0; double HVCentroidError = 0.0; - // double LVCentroid = 0.0; + double LVCentroid = 0.0; + double LVCentroidError = 0.0; // Ensure all 3 parameters (CTD mu, HV mu, LV mu) were successfully saved if (FitsVec.size() >= 1) { // CTDCentroid = FitsVec[0]; HVCentroid = FitsVec[0]; HVCentroidError = FitsVec[1]; - // LVCentroid = FitsVec[2]; + LVCentroid = FitsVec[2]; + LVCentroidError = FitsVec[3]; } // Write row entries corresponding purely to the detector level measurements - OutputCalFile << c << '\t' - << DetID << '\t' + OutputCalFile << DetID << '\t' + << c << '\t' // << CTDCentroid << '\t' << HVCentroid << '\t' - << HVCentroidError << '\t' << endl; - // << LVCentroid + << HVCentroidError << '\t' + << LVCentroid << '\t' + << LVCentroidError << '\t' << endl; } } From a383733749ff913e27b773685d28386a7f45b10a Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:21:11 -0700 Subject: [PATCH 22/61] removed spline fitting and consolidated to one param file output --- apps/TrappingCorrectionCs137.cxx | 109 ++----------------------------- 1 file changed, 7 insertions(+), 102 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 177a9b51..33d3cb97 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -655,7 +655,7 @@ bool TrappingCorrectionCs137::Analyze() // Updated header matching your request OutputCalFile << "Det_ID" << '\t' << "CTD_Bin" << '\t' - << "CTD_Centroid_ns" << '\t' + << "CTD_BinMidpoint_ns" << '\t' << "HV_Centroid_keV" << '\t' <<"HV_Centroid_error_keV" << '\t' << "LV_Centroid_keV" << '\t' @@ -664,12 +664,15 @@ bool TrappingCorrectionCs137::Analyze() // Loop systematically over each CTD bin first for (int c = 0; c < NCTDBins; ++c) { + cout << "Writing output tracking parameters for CTD bin: " << c << endl; + // Calculate the exact midpoint of this specific variable CTD bin + double ctdBinMidpoint = (g_CTDBinEdges[c] + g_CTDBinEdges[c + 1]) / 2.0; + // Loop over the detectors found inside this specific CTD bin for (auto const& [DetID, FitsVec] : FullDetEndpoints[c]) { - // double CTDCentroid = 0.0; double HVCentroid = 0.0; double HVCentroidError = 0.0; double LVCentroid = 0.0; @@ -677,7 +680,6 @@ bool TrappingCorrectionCs137::Analyze() // Ensure all 3 parameters (CTD mu, HV mu, LV mu) were successfully saved if (FitsVec.size() >= 1) { - // CTDCentroid = FitsVec[0]; HVCentroid = FitsVec[0]; HVCentroidError = FitsVec[1]; LVCentroid = FitsVec[2]; @@ -687,7 +689,7 @@ bool TrappingCorrectionCs137::Analyze() // Write row entries corresponding purely to the detector level measurements OutputCalFile << DetID << '\t' << c << '\t' - // << CTDCentroid << '\t' + << ctdBinMidpoint << '\t' << HVCentroid << '\t' << HVCentroidError << '\t' << LVCentroid << '\t' @@ -696,104 +698,7 @@ bool TrappingCorrectionCs137::Analyze() } OutputCalFile.close(); - - // -------------------------------------------------------------------------- - // Generate and Export Linear Splines for Charge Trapping Corrections - // -------------------------------------------------------------------------- - - ofstream SplineOutputFile; - SplineOutputFile.open(m_OutFile + MString("_splines.txt")); - - // Write a clean header explaining the piece-wise linear polynomial coefficients: - // S_i(x) = y + b*(x - x_i) - SplineOutputFile << "# Spline Piece-wise Coefficients for Trapping Correction" << endl; - SplineOutputFile << "Det_ID" << '\t' - << "Interval_i" << '\t' - << "X_i_(CTD_ns_BinMidpoint)" << '\t' - << "Y_i_(HV_Centroid)" << '\t' - << "b_coeff_(slope)" << endl; - - // Group our points by Detector ID so we can sort them by CTD value - // Map structure: [DetID] -> vector of pairs (CTD_Bin_Midpoint, HV_Centroid) - map>> DetPointsMap; - - for (int c = 0; c < NCTDBins; ++c) { - // Calculate the exact midpoint of this specific variable CTD bin - double ctdBinMidpoint = (g_CTDBinEdges[c] + g_CTDBinEdges[c + 1]) / 2.0; - - for (auto const& [DetID, FitsVec] : FullDetEndpoints[c]) { - // We only care that the energy photopeak successfully fit (FitsVec[1] is HV mu) - if (FitsVec.size() >= 1) { - double hvCentroid = FitsVec[0]; - - // Push the calculated geometric midpoint instead of the fitted CTD value - DetPointsMap[DetID].push_back(make_pair(ctdBinMidpoint, hvCentroid)); - } - } - } - - // Find Absolute Global Min and Max CTD values --- - double globalMinCTD = 1e9; // Initialize to a large positive number - double globalMaxCTD = -1e9; // Initialize to a large negative number - bool foundAnyPoints = false; - - for (auto const& [DetID, PointsVec] : DetPointsMap) { - for (auto const& pt : PointsVec) { - double ctdVal = pt.first; - if (ctdVal < globalMinCTD) globalMinCTD = ctdVal; - if (ctdVal > globalMaxCTD) globalMaxCTD = ctdVal; - foundAnyPoints = true; - } - } - - // If no data points were mapped at all, fall back safely to global system limits - if (!foundAnyPoints) { - globalMinCTD = g_MinCTD; - globalMaxCTD = g_MaxCTD; - } - - // Loop through each detector to compute linear connectors - for (auto& [DetID, PointsVec] : DetPointsMap) { - - // Sort data points in ascending X (CTD Midpoint) order - sort(PointsVec.begin(), PointsVec.end(), [](const pair& a, const pair& b) { - return a.first < b.first; - }); - - int nPoints = PointsVec.size(); - if (nPoints < 2) { - cout << "Warning: Detector " << DetID << " has too few data points (" << nPoints << ") to form a linear interpolation." << endl; - continue; - } - - cout << "Successfully generated linear spline for Detector " << DetID << " using " << nPoints << " points (Bin Midpoints)." << endl; - - // Direct algebraic evaluation of intervals (connecting point i to i+1) - for (int i = 0; i < nPoints - 1; ++i) { - double x_i = PointsVec[i].first; // This is now the exact midpoint of interval i - double y_i = PointsVec[i].second; - - double x_next = PointsVec[i+1].first; // Exact midpoint of interval i+1 - double y_next = PointsVec[i+1].second; - - // Calculate constant linear slope: dy / dx - double b = 0.0; - if (x_next != x_i) { - b = (y_next - y_i) / (x_next - x_i); - } - - // Save everything cleanly to the file matching your exact format request - SplineOutputFile << "# Global Dataset Limits: Min_CTD = " << globalMinCTD << " ns, Max_CTD = " << globalMaxCTD << " ns" << endl; - SplineOutputFile << DetID << '\t' - << i << '\t' - << x_i << '\t' - << y_i << '\t' - << b << endl; - } - } - - SplineOutputFile.close(); - cout << "Linear spline calibration file saved successfully." << endl; + cout << "Parameters file saved successfully." << endl; watch.Stop(); cout << "total time (s): " << watch.CpuTime() << endl; From 0f13cb3016ad65565bfbea2d9239e24bb17b8a0c Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:28:33 -0700 Subject: [PATCH 23/61] fixed compilation error --- apps/TrappingCorrectionCs137.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 33d3cb97..eb41d0dd 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -548,7 +548,7 @@ bool TrappingCorrectionCs137::Analyze() for (auto const& [DetID, FullHVHist] : FullDetHVEnergyHistograms[c]) { TH1D* HVHist = FullDetHVEnergyHistograms[c][DetID]; - // TH1D* LVHist = FullDetLVEnergyHistograms[c][DetID]; + TH1D* LVHist = FullDetLVEnergyHistograms[c][DetID]; if (HVHist->Integral() > g_MinCounts) { From 8187914f1f790ccb69f3e7890e9abe196ee6bd64 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 9 Jul 2026 11:30:41 -0700 Subject: [PATCH 24/61] added GUI options for input param file --- include/MGUIOptionsTrappingCorrection.h | 121 ++++++++++++ src/MGUIOptionsTrappingCorrection.cxx | 250 ++++++++++++++++++++++++ 2 files changed, 371 insertions(+) create mode 100644 include/MGUIOptionsTrappingCorrection.h create mode 100644 src/MGUIOptionsTrappingCorrection.cxx diff --git a/include/MGUIOptionsTrappingCorrection.h b/include/MGUIOptionsTrappingCorrection.h new file mode 100644 index 00000000..b764440a --- /dev/null +++ b/include/MGUIOptionsTrappingCorrection.h @@ -0,0 +1,121 @@ +/* + * MGUIOptionsTrappingCorrection.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice.:q + * + */ + + +#ifndef __MGUIOptionsTrappingCorrection__ +#define __MGUIOptionsTrappingCorrection__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// ROOT libs: +#include +#include +#include +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MGlobal.h" +#include "MGUIEFileSelector.h" +#include "MGUIOptions.h" +#include "MGUIERBList.h" +#include "MGUIEEntry.h" + +// Nuclearizer libs: +#include "MModule.h" + + +// Forward declarations: + + +//////////////////////////////////////////////////////////////////////////////// + + +//! The user interface for the universal energy calibration +class MGUIOptionsTrappingCorrection : public MGUIOptions +{ + // public Session: + public: + //! Default constructor + MGUIOptionsTrappingCorrection(MModule* Module); + //! Default destructor + virtual ~MGUIOptionsTrappingCorrection(); + + // //! 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(); + + // //! Toggle the radio buttons + // void ToggleRadioButtons(int WidgetID); + + + // protected members: + protected: + + // private members: + private: + + //! Select which file to load + MGUIEFileSelector* m_FileSelector; + + // //! Radio button for ignoring the slow threshold cut + // TGRadioButton* m_SlowThresholdCutRBIgnore; + + // //! Radio button for using a fixed slow threshold cut + // TGRadioButton* m_SlowThresholdCutRBFixed; + // //! The slow threshold cut entry box + // MGUIEEntry* m_SlowThresholdCutFixedValue; + + // //! Radio button for reading slow threshold cuts from a file + // TGRadioButton* m_SlowThresholdCutRBFile; + // //! The slow threshold cut file selector + // MGUIEFileSelector* m_SlowThresholdCutFileSelector; + + // //! Radio button for ignoring the threshold cut for Nearest Neighbors + // TGRadioButton* m_SlowThresholdCutNearestNeighborRBIgnore; + // //! Radio button for using a fixed threshold cut for Nearest Neighbors + // TGRadioButton* m_SlowThresholdCutNearestNeighborRBFixed; + // //! The threshold cut entry box for Nearest Neighbors + // MGUIEEntry* m_SlowThresholdCutNearestNeighborFixedValue; + + + // //! IDs of radio buttons + // //! The numbers should be identical to MSlowThresholdCutModes + // enum RBButtonIDs { c_SlowThresholdIgnore = 0, + // c_SlowThresholdFixed, + // c_SlowThresholdFile, + // c_SlowThresholdNearestNeighborIgnore = 100, + // c_SlowThresholdNearestNeighborFixed}; + + +#ifdef ___CLING___ + public: + ClassDef(MGUIOptionsTrappingCorrection, 1) +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MGUIOptionsTrappingCorrection.cxx b/src/MGUIOptionsTrappingCorrection.cxx new file mode 100644 index 00000000..a944bf81 --- /dev/null +++ b/src/MGUIOptionsTrappingCorrection.cxx @@ -0,0 +1,250 @@ +/* + * MGUIOptionsTrappingCorrection.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 "MGUIOptionsTrappingCorrection.h" + +// Standard libs: + +// ROOT libs: +#include +#include +#include +#include + +// MEGAlib libs: +#include "MStreams.h" +#include "MModule.h" +#include "MModuleTrappingCorrection.h" + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MGUIOptionsTrappingCorrection) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIOptionsTrappingCorrection::MGUIOptionsTrappingCorrection(MModule* Module) + : MGUIOptions(Module) +{ + // standard constructor +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIOptionsTrappingCorrection::~MGUIOptionsTrappingCorrection() +{ + // kDeepCleanup is activated +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIOptionsTrappingCorrection::Create() +{ + PreCreate(); + + TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 10, 10, 10, 10); + TGLayoutHints* FileSelectorLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 10, 10, 10, 10); + + // File loader for energy calibration file + m_FileSelector = new MGUIEFileSelector(m_OptionsFrame, "Please select a trapping parameter file:", + dynamic_cast(m_Module)->GetFileName()); + m_FileSelector->SetFileType("Trapping parameter file", "*.csv"); + m_OptionsFrame->AddFrame(m_FileSelector, FileSelectorLayout); + + + // TGLabel* SlowThresholdLabel = new TGLabel(m_OptionsFrame, "Please choose how to handle the slow threshold cut:"); + // m_OptionsFrame->AddFrame(SlowThresholdLabel, LabelLayout); + + + // TGLayoutHints* RBLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 40, 10, 2, 0); + // TGLayoutHints* RBOptionLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 60, 10, 2, 0); + // TGLayoutHints* RBOptionStretchLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 60, 10, 2, 0); + + // m_SlowThresholdCutRBIgnore = new TGRadioButton(m_OptionsFrame, "Do not apply a slow threshold cut", c_SlowThresholdIgnore); + // m_SlowThresholdCutRBIgnore->Associate(this); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutRBIgnore, RBLayout); + + + // m_SlowThresholdCutRBFixed = new TGRadioButton(m_OptionsFrame, "Use one uniform slow threshold cut for all strips", c_SlowThresholdFixed); + // m_SlowThresholdCutRBFixed->Associate(this); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutRBFixed, RBLayout); + + // m_SlowThresholdCutFixedValue = new MGUIEEntry(m_OptionsFrame, "Set threshold value [keV]:", false, dynamic_cast(m_Module)->GetSlowThresholdCutFixedValue(), true, 0.0); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutFixedValue, RBOptionLayout); + + + // m_SlowThresholdCutRBFile = new TGRadioButton(m_OptionsFrame, "Read slow threshold cuts from file (unique to each strip)", c_SlowThresholdFile); + // m_SlowThresholdCutRBFile->Associate(this); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutRBFile, RBLayout); + + // m_SlowThresholdCutFileSelector = new MGUIEFileSelector(m_OptionsFrame, "", dynamic_cast(m_Module)->GetSlowThresholdCutFileName()); + // m_SlowThresholdCutFileSelector->SetFileType("Slow threshold cut per strip file", "*.csv"); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutFileSelector, RBOptionStretchLayout); + + + // // Toggle the right button + // MSlowThresholdCutModes SlowThresholdCutMode = dynamic_cast(m_Module)->GetSlowThresholdCutMode(); + // ToggleRadioButtons(static_cast(SlowThresholdCutMode)); + + + // // Nearest Neighbor threshold cuts! + // TGLabel* NearestNeighborLabel = new TGLabel(m_OptionsFrame, "Please choose how to handle the threshold cut for Nearest Neighbors:"); + // m_OptionsFrame->AddFrame(NearestNeighborLabel, LabelLayout); + + // m_SlowThresholdCutNearestNeighborRBIgnore = new TGRadioButton(m_OptionsFrame, "Do not apply a slow threshold cut to Nearest Neighbors", c_SlowThresholdNearestNeighborIgnore); + // m_SlowThresholdCutNearestNeighborRBIgnore->Associate(this); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutNearestNeighborRBIgnore, RBLayout); + + // m_SlowThresholdCutNearestNeighborRBFixed = new TGRadioButton(m_OptionsFrame, "Use one uniform slow threshold cut for all Nearest Neighbors", c_SlowThresholdNearestNeighborFixed); + // m_SlowThresholdCutNearestNeighborRBFixed->Associate(this); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutNearestNeighborRBFixed, RBLayout); + + // m_SlowThresholdCutNearestNeighborFixedValue = new MGUIEEntry(m_OptionsFrame, "Set threshold value [keV] for Nearest Neighbors:", false, dynamic_cast(m_Module)->GetNearestNeighborThreshold()); + // m_OptionsFrame->AddFrame(m_SlowThresholdCutNearestNeighborFixedValue, RBOptionLayout); + + // MNearestNeighborCutModes NearestNeighborCutMode = dynamic_cast(m_Module)->GetNearestNeighborCutMode(); + // ToggleRadioButtons(static_cast(NearestNeighborCutMode)); + + + // PostCreate(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +// bool MGUIOptionsTrappingCorrection::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; +// case kCM_RADIOBUTTON: +// ToggleRadioButtons(Parameter1); +// break; +// case kCM_CHECKBUTTON: +// break; +// default: +// break; +// } +// break; +// default: +// break; +// } + +// if (Status == false) { +// return false; +// } + +// // Call also base class +// return MGUIOptions::ProcessMessage(Message, Parameter1, Parameter2); +// } + + +//////////////////////////////////////////////////////////////////////////////// + + +// void MGUIOptionsTrappingCorrection::ToggleRadioButtons(int WidgetID) +// { +// // Toggle the radio buttons and the entry fields + +// if (WidgetID == m_SlowThresholdCutRBIgnore->WidgetId()) { +// m_SlowThresholdCutRBIgnore->SetState(kButtonDown); +// m_SlowThresholdCutRBFixed->SetState(kButtonUp); +// m_SlowThresholdCutFixedValue->SetEnabled(false); +// m_SlowThresholdCutRBFile->SetState(kButtonUp); +// m_SlowThresholdCutFileSelector->SetEnabled(false); +// } else if (WidgetID == m_SlowThresholdCutRBFixed->WidgetId()) { +// m_SlowThresholdCutRBIgnore->SetState(kButtonUp); +// m_SlowThresholdCutRBFixed->SetState(kButtonDown); +// m_SlowThresholdCutFixedValue->SetEnabled(true); +// m_SlowThresholdCutRBFile->SetState(kButtonUp); +// m_SlowThresholdCutFileSelector->SetEnabled(false); +// } else if (WidgetID == m_SlowThresholdCutRBFile->WidgetId()) { +// m_SlowThresholdCutRBIgnore->SetState(kButtonUp); +// m_SlowThresholdCutRBFixed->SetState(kButtonUp); +// m_SlowThresholdCutFixedValue->SetEnabled(false); +// m_SlowThresholdCutRBFile->SetState(kButtonDown); +// m_SlowThresholdCutFileSelector->SetEnabled(true); +// } + +// // Nearest Neighbors +// if (WidgetID == c_SlowThresholdNearestNeighborIgnore || WidgetID == c_SlowThresholdNearestNeighborFixed) { +// if (WidgetID == c_SlowThresholdNearestNeighborIgnore) { +// m_SlowThresholdCutNearestNeighborRBIgnore->SetState(kButtonDown); +// m_SlowThresholdCutNearestNeighborRBFixed->SetState(kButtonUp); +// m_SlowThresholdCutNearestNeighborFixedValue->SetEnabled(false); +// } else if (WidgetID == c_SlowThresholdNearestNeighborFixed) { +// m_SlowThresholdCutNearestNeighborRBIgnore->SetState(kButtonUp); +// m_SlowThresholdCutNearestNeighborRBFixed->SetState(kButtonDown); +// m_SlowThresholdCutNearestNeighborFixedValue->SetEnabled(true); +// } +// } +// } + + +//////////////////////////////////////////////////////////////////////////////// + + +bool MGUIOptionsTrappingCorrection::OnApply() +{ + // Modify this to store the data in the module! + + dynamic_cast(m_Module)->SetFileName(m_FileSelector->GetFileName()); + + // if (m_SlowThresholdCutRBIgnore->GetState() == kButtonDown) { + // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_Ignore); + // } else if (m_SlowThresholdCutRBFixed->GetState() == kButtonDown) { + // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_Fixed); + // } if (m_SlowThresholdCutRBFile->GetState() == kButtonDown) { + // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_File); + // } + + // dynamic_cast(m_Module)->SetSlowThresholdCutFixedValue(m_SlowThresholdCutFixedValue->GetAsDouble()); + // dynamic_cast(m_Module)->SetSlowThresholdCutFileName(m_SlowThresholdCutFileSelector->GetFileName()); + + // // Nearest Neighbors + // if (m_SlowThresholdCutNearestNeighborRBIgnore->GetState() == kButtonDown) { + // dynamic_cast(m_Module)->SetNearestNeighborCutMode(MNearestNeighborCutModes::e_Ignore); + // } else { + // dynamic_cast(m_Module)->SetNearestNeighborCutMode(MNearestNeighborCutModes::e_Fixed); + // } + + // dynamic_cast(m_Module)->SetNearestNeighborThreshold(m_SlowThresholdCutNearestNeighborFixedValue->GetAsDouble()); + + return true; +} + + +// MGUIOptionsTrappingCorrection: the end... +//////////////////////////////////////////////////////////////////////////////// From 34381ba65eef3096287b3e5c70d208376366c96f Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 9 Jul 2026 16:27:51 -0700 Subject: [PATCH 25/61] added expo with HV, LV photopeak plots --- include/MGUIExpoTrappingCorrection.h | 98 ++++++++++++ include/MGUIOptionsTrappingCorrection.h | 2 +- include/MModuleTrappingCorrection.h | 22 ++- src/MGUIExpoTrappingCorrection.cxx | 189 ++++++++++++++++++++++++ src/MGUIOptionsTrappingCorrection.cxx | 17 +-- src/MModuleTrappingCorrection.cxx | 55 ++++--- 6 files changed, 343 insertions(+), 40 deletions(-) create mode 100644 include/MGUIExpoTrappingCorrection.h create mode 100644 src/MGUIExpoTrappingCorrection.cxx diff --git a/include/MGUIExpoTrappingCorrection.h b/include/MGUIExpoTrappingCorrection.h new file mode 100644 index 00000000..89ca23d1 --- /dev/null +++ b/include/MGUIExpoTrappingCorrection.h @@ -0,0 +1,98 @@ +/* + * MGUIExpoTrappingCorrection.h + * + * Copyright (C) by Andreas Zoglauer. + * All rights reserved. + * + * Please see the source-file for the copyright-notice. + * + */ + + +#ifndef __MGUIExpoTrappingCorrection__ +#define __MGUIExpoTrappingCorrection__ + + +//////////////////////////////////////////////////////////////////////////////// + + +// 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 MGUIExpoTrappingCorrection : public MGUIExpo +{ + // public Session: + public: + //! Default constructor + MGUIExpoTrappingCorrection(MModule* Module); + //! Default destructor + virtual ~MGUIExpoTrappingCorrection(); + + //! 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 energy histogram parameters + void SetEnergyHistogramParameters(int NBins, double Min, double Max); + + //! Add data to the energy histogram + void AddEnergy(double Energy); + + // protected methods: + protected: + + + // protected members: + protected: + + // private members: + private: + //! Energy canvas + TRootEmbeddedCanvas* m_EnergyCanvas; + //! Energy histogram + TH1D* m_Energy; + + + +#ifdef ___CLING___ + public: + ClassDef(MGUIExpoTrappingCorrection, 1) // basic class for dialog windows +#endif + +}; + +#endif + + +//////////////////////////////////////////////////////////////////////////////// diff --git a/include/MGUIOptionsTrappingCorrection.h b/include/MGUIOptionsTrappingCorrection.h index b764440a..903419f5 100644 --- a/include/MGUIOptionsTrappingCorrection.h +++ b/include/MGUIOptionsTrappingCorrection.h @@ -76,7 +76,7 @@ class MGUIOptionsTrappingCorrection : public MGUIOptions private: //! Select which file to load - MGUIEFileSelector* m_FileSelector; + MGUIEFileSelector* m_SimCCEFileSelector; // //! Radio button for ignoring the slow threshold cut // TGRadioButton* m_SlowThresholdCutRBIgnore; diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 62c5704c..ee4bd297 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -27,10 +27,15 @@ // MEGAlib libs: #include "MGlobal.h" #include "MModule.h" +// #include "MModuleTrappingCorrection.h" +#include "MGUIEEntry.h" + + + +// Nuclearizer libs: +#include "MGUIExpoPlotSpectrum.h" #include "MModuleEnergyCalibration.h" -#include "MDStrip3D.h" -#include "MDShapeBRIK.h" -// #include "MGUIExpoTrappingCorrection.h" +#include "MGUIExpoTrappingCorrection.h" // Forward declarations: @@ -53,8 +58,8 @@ class MModuleTrappingCorrection : public MModule //! Initialize the module virtual bool Initialize(); - // //! Create the expos - // virtual void CreateExpos(); + //! Create the expos + virtual void CreateExpos(); //! Main data analysis routine, which updates the event to a new level virtual bool AnalyzeEvent(MReadOutAssembly* Event); @@ -64,6 +69,7 @@ class MModuleTrappingCorrection : public MModule //! Set filename for SimCCE file void SetSimCCEFileName( const MString& FileName) { m_SimCCEFile = FileName; } + //! Get filename for SimCCE file MString GetSimCCEFileName() const { return m_SimCCEFile; } @@ -117,7 +123,7 @@ class MModuleTrappingCorrection : public MModule unordered_map m_Detectors; vector m_DetectorIDs; MModuleEnergyCalibration* m_EnergyCalibration; - // MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; + MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; // The CTD Map maps each detector (int) to a 2D array of CTD values. // unordered_map>> m_CTDMap; @@ -138,7 +144,9 @@ class MModuleTrappingCorrection : public MModule // private members: private: - + //! Updated GUI to display the energy histogram + MGUIExpoPlotSpectrum* m_ExpoSpectrum; + // MGUIExpoPlotSpectrum* m_ExpoSpectrum_LV; #ifdef ___CLING___ diff --git a/src/MGUIExpoTrappingCorrection.cxx b/src/MGUIExpoTrappingCorrection.cxx new file mode 100644 index 00000000..e5e55b2d --- /dev/null +++ b/src/MGUIExpoTrappingCorrection.cxx @@ -0,0 +1,189 @@ +/* + * MGUIExpoTrappingCorrection.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 "MGUIExpoTrappingCorrection.h" + +// Standard libs: + +// ROOT libs: +#include +#include +#include +#include +#include + +// MEGAlib libs: +#include "MStreams.h" + + + +//////////////////////////////////////////////////////////////////////////////// + + +#ifdef ___CLING___ +ClassImp(MGUIExpoTrappingCorrection) +#endif + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIExpo(Module) +{ + // standard constructor + + // Set the new title of the tab here: + m_TabTitle = "Trapping Correction"; + + // Add all histograms and canvases below + m_Energy = new TH1D("", "Spectrum combined hits", 200, 0, 1000); + m_Energy->SetXTitle("Energy [keV]"); + m_Energy->SetYTitle("counts"); + m_Energy->SetFillColor(kAzure+7); + + m_EnergyCanvas = 0; + + // use hierarchical cleaning + SetCleanup(kDeepCleanup); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +MGUIExpoTrappingCorrection::~MGUIExpoTrappingCorrection() +{ + // kDeepCleanup is activated +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTrappingCorrection::Reset() +{ + //! Reset the data in the UI + + m_Mutex.Lock(); + + m_Energy->Reset(); + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTrappingCorrection::SetEnergyHistogramParameters(int NBins, double Min, double Max) +{ + // Set the energy histogram parameters + + m_Mutex.Lock(); + + m_Energy->SetBins(NBins, Min, Max); + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTrappingCorrection::AddEnergy(double Energy) +{ + // Add data to the energy histogram + + m_Mutex.Lock(); + + m_Energy->Fill(Energy); + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTrappingCorrection::Export(const MString& FileName) +{ + // Add data to the energy histogram + + m_Mutex.Lock(); + + m_EnergyCanvas->GetCanvas()->SaveAs(FileName); + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTrappingCorrection::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); + + TGHorizontalFrame* HFrame = new TGHorizontalFrame(this); + AddFrame(HFrame, CanvasLayout); + + + m_EnergyCanvas = new TRootEmbeddedCanvas("Energy", HFrame, 100, 100); + HFrame->AddFrame(m_EnergyCanvas, CanvasLayout); + + m_EnergyCanvas->GetCanvas()->cd(); + m_EnergyCanvas->GetCanvas()->SetGridy(); + m_EnergyCanvas->GetCanvas()->SetGridx(); + m_Energy->Draw(); + m_EnergyCanvas->GetCanvas()->Update(); + + m_IsCreated = true; + + m_Mutex.UnLock(); +} + + +//////////////////////////////////////////////////////////////////////////////// + + +void MGUIExpoTrappingCorrection::Update() +{ + //! Update the frame + + m_Mutex.Lock(); + + if (m_EnergyCanvas != 0) { + m_EnergyCanvas->GetCanvas()->Modified(); + m_EnergyCanvas->GetCanvas()->Update(); + } + + m_Mutex.UnLock(); +} + + +// MGUIExpoTrappingCorrection: the end... +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/MGUIOptionsTrappingCorrection.cxx b/src/MGUIOptionsTrappingCorrection.cxx index a944bf81..e7dbfc1c 100644 --- a/src/MGUIOptionsTrappingCorrection.cxx +++ b/src/MGUIOptionsTrappingCorrection.cxx @@ -67,14 +67,11 @@ void MGUIOptionsTrappingCorrection::Create() { PreCreate(); - TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 10, 10, 10, 10); - TGLayoutHints* FileSelectorLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 10, 10, 10, 10); - - // File loader for energy calibration file - m_FileSelector = new MGUIEFileSelector(m_OptionsFrame, "Please select a trapping parameter file:", - dynamic_cast(m_Module)->GetFileName()); - m_FileSelector->SetFileType("Trapping parameter file", "*.csv"); - m_OptionsFrame->AddFrame(m_FileSelector, FileSelectorLayout); + m_SimCCEFileSelector = new MGUIEFileSelector(m_OptionsFrame, "Select a trapping parameter file:", + dynamic_cast(m_Module)->GetSimCCEFileName()); + m_SimCCEFileSelector->SetFileType("trapping parameters", "*.csv"); + TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); + m_OptionsFrame->AddFrame(m_SimCCEFileSelector, LabelLayout); // TGLabel* SlowThresholdLabel = new TGLabel(m_OptionsFrame, "Please choose how to handle the slow threshold cut:"); @@ -220,7 +217,7 @@ bool MGUIOptionsTrappingCorrection::OnApply() { // Modify this to store the data in the module! - dynamic_cast(m_Module)->SetFileName(m_FileSelector->GetFileName()); + dynamic_cast(m_Module)->SetSimCCEFileName(m_SimCCEFileSelector->GetFileName()); // if (m_SlowThresholdCutRBIgnore->GetState() == kButtonDown) { // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_Ignore); @@ -231,7 +228,7 @@ bool MGUIOptionsTrappingCorrection::OnApply() // } // dynamic_cast(m_Module)->SetSlowThresholdCutFixedValue(m_SlowThresholdCutFixedValue->GetAsDouble()); - // dynamic_cast(m_Module)->SetSlowThresholdCutFileName(m_SlowThresholdCutFileSelector->GetFileName()); + // dynamic_cast(m_Module)->SetSlowThresholdCutFileName(m_SlowThresholdCutFileSelector->GetSimCCEFileName()); // // Nearest Neighbors // if (m_SlowThresholdCutNearestNeighborRBIgnore->GetState() == kButtonDown) { diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 16b3aa89..f8379cbe 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -26,7 +26,6 @@ // Include the header: #include "MModuleTrappingCorrection.h" -// #include "MGUIOptionsTrappingCorrection.h" // Standard libs: @@ -36,7 +35,12 @@ #include "TH1.h" // MEGAlib libs: +#include "MString.h" +// Nuclearizer libs: +#include "MGUIOptionsTrappingCorrection.h" +#include "MGUIExpoPlotSpectrum.h" +#include "MModuleEnergyCalibration.h" //////////////////////////////////////////////////////////////////////////////// @@ -165,22 +169,21 @@ bool MModuleTrappingCorrection::Initialize() //////////////////////////////////////////////////////////////////////////////// -// void MModuleTrappingCorrection::CreateExpos() -// { -// // Create all expos +void MModuleTrappingCorrection::CreateExpos() +{ + // Create all expos + + if (HasExpos() == true) return; -// if (HasExpos() == true) return; + // Set the histogram display + m_ExpoSpectrum = new MGUIExpoPlotSpectrum(this); + m_ExpoSpectrum->SetEnergyHistogramParameters(200, 0, 2000); + m_Expos.push_back(m_ExpoSpectrum); -// // Set the histogram display -// m_ExpoTrappingCorrection = new MGUIExpoTrappingCorrection(this); -// m_ExpoTrappingCorrection->SetDepthHistogramArrangement(&m_DetectorIDs); -// for (unsigned int i = 0; i < m_DetectorIDs.size(); ++i){ -// unsigned int DetID = m_DetectorIDs[i]; -// double thickness = m_Thicknesses[DetID]; -// m_ExpoTrappingCorrection->SetDepthHistogramParameters(DetID, 120, -thickness/2.0,thickness/2.0); -// } -// m_Expos.push_back(m_ExpoTrappingCorrection); -// } +// m_ExpoSpectrum_LV = new MGUIExpoPlotSpectrum(this); +// m_ExpoSpectrum_LV->SetEnergyHistogramParameters(200, 0, 2000); +// m_Expos.push_back(m_ExpoSpectrum_LV); +} ///////////////////////////////////////////////////////////////////////////////// @@ -261,6 +264,10 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) double rawLVEnergy = LVSH->GetEnergy(); // Replace with actual getter method for your hit class double correctedLVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawLVEnergy, m_CCEs_LV); LVSH->SetEnergy(correctedLVEnergy); // Replace with actual setter method for your hit class + + if (HasExpos() == true) { + m_ExpoSpectrum->AddEnergyFinal(correctedLVEnergy, LVSH->IsNearestNeighbor(), LVSH->IsLowVoltageStrip()); + } } // Correct the High Voltage side energy if the hit pointer exists @@ -268,6 +275,10 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) double rawHVEnergy = HVSH->GetEnergy(); // Replace with actual getter method for your hit class double correctedHVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawHVEnergy, m_CCEs_HV); HVSH->SetEnergy(correctedHVEnergy); // Replace with actual setter method for your hit class + + if (HasExpos() == true) { + m_ExpoSpectrum->AddEnergyFinal(correctedHVEnergy, HVSH->IsNearestNeighbor(), HVSH->IsLowVoltageStrip()); + } } @@ -548,13 +559,13 @@ int MModuleTrappingCorrection::GetHitGrade(MHit* H){ ///////////////////////////////////////////////////////////////////////////////// -// void MModuleTrappingCorrection::ShowOptionsGUI() -// { -// // Show the options GUI - or do nothing -// MGUIOptionsTrappingCorrection* Options = new MGUIOptionsTrappingCorrection(this); -// Options->Create(); -// gClient->WaitForUnmap(Options); -// } +void MModuleTrappingCorrection::ShowOptionsGUI() +{ + // Show the options GUI - or do nothing + MGUIOptionsTrappingCorrection* Options = new MGUIOptionsTrappingCorrection(this); + Options->Create(); + gClient->WaitForUnmap(Options); +} ///////////////////////////////////////////////////////////////////////////////// From 3f8f10988e03dca600342a0aebf8cb9d14238217 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:24:55 -0700 Subject: [PATCH 26/61] implemented finish function to return line shift and corrected res --- include/MModuleTrappingCorrection.h | 23 ++-- src/MGUIOptionsTrappingCorrection.cxx | 8 +- src/MModuleTrappingCorrection.cxx | 161 ++++++++++++++++++++++---- 3 files changed, 158 insertions(+), 34 deletions(-) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index ee4bd297..283b1fbf 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -27,7 +27,6 @@ // MEGAlib libs: #include "MGlobal.h" #include "MModule.h" -// #include "MModuleTrappingCorrection.h" #include "MGUIEEntry.h" @@ -36,6 +35,7 @@ #include "MGUIExpoPlotSpectrum.h" #include "MModuleEnergyCalibration.h" #include "MGUIExpoTrappingCorrection.h" +#include "MGUIOptionsTrappingCorrection.h" // Forward declarations: @@ -73,6 +73,9 @@ class MModuleTrappingCorrection : public MModule //! Get filename for SimCCE file MString GetSimCCEFileName() const { return m_SimCCEFile; } + //! Finalize the module + virtual void Finalize(); + //! Read the XML configuration @@ -81,8 +84,8 @@ class MModuleTrappingCorrection : public MModule //! Create the XML configuration MXmlNode* CreateXmlConfiguration(); - //! Finalize - void Finalize(); + // //! Finalize + // void Finalize(); // protected methods: protected: @@ -102,7 +105,7 @@ class MModuleTrappingCorrection : public MModule bool LoadSimCCEFile(MString FName); //! Get the Sim-based corrected energy given the CTD value, uncorrected energy, and the sorted Sim CCE values - double GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted); + double GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted, double paramA, double paramB, double paramC); //! Interpolate a value given x, xp, and fp double Interpolate(double x, const std::vector& xp, const std::vector& fp); @@ -132,9 +135,12 @@ class MModuleTrappingCorrection : public MModule bool m_SimCCEFileIsLoaded; - double m_ParamA; - double m_ParamB; - double m_ParamC; + double m_ParamA_HV; + double m_ParamB_HV; + double m_ParamC_HV; + double m_ParamA_LV; + double m_ParamB_LV; + double m_ParamC_LV; std::vector m_Depths; std::vector m_CCEs_HV; std::vector m_CCEs_LV; @@ -146,7 +152,8 @@ class MModuleTrappingCorrection : public MModule //! Updated GUI to display the energy histogram MGUIExpoPlotSpectrum* m_ExpoSpectrum; - // MGUIExpoPlotSpectrum* m_ExpoSpectrum_LV; + + TF1* GeneratePhotopeakFunction(); #ifdef ___CLING___ diff --git a/src/MGUIOptionsTrappingCorrection.cxx b/src/MGUIOptionsTrappingCorrection.cxx index e7dbfc1c..e8cfd00f 100644 --- a/src/MGUIOptionsTrappingCorrection.cxx +++ b/src/MGUIOptionsTrappingCorrection.cxx @@ -78,9 +78,9 @@ void MGUIOptionsTrappingCorrection::Create() // m_OptionsFrame->AddFrame(SlowThresholdLabel, LabelLayout); - // TGLayoutHints* RBLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 40, 10, 2, 0); - // TGLayoutHints* RBOptionLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 60, 10, 2, 0); - // TGLayoutHints* RBOptionStretchLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 60, 10, 2, 0); + TGLayoutHints* RBLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 40, 10, 2, 0); + TGLayoutHints* RBOptionLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 60, 10, 2, 0); + TGLayoutHints* RBOptionStretchLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 60, 10, 2, 0); // m_SlowThresholdCutRBIgnore = new TGRadioButton(m_OptionsFrame, "Do not apply a slow threshold cut", c_SlowThresholdIgnore); // m_SlowThresholdCutRBIgnore->Associate(this); @@ -128,7 +128,7 @@ void MGUIOptionsTrappingCorrection::Create() // ToggleRadioButtons(static_cast(NearestNeighborCutMode)); - // PostCreate(); + PostCreate(); } diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index f8379cbe..914019d9 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -39,6 +39,7 @@ // Nuclearizer libs: #include "MGUIOptionsTrappingCorrection.h" +#include "MGUIExpoTrappingCorrection.h" #include "MGUIExpoPlotSpectrum.h" #include "MModuleEnergyCalibration.h" @@ -70,11 +71,12 @@ MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() AddPreceedingModuleType(MAssembly::c_StripPairing, true); AddPreceedingModuleType(MAssembly::c_TACcut, true); AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); + AddPreceedingModuleType(MAssembly::c_DepthCorrection, true); // AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection, false); // Soft requirement // Set all types this modules handles AddModuleType(MAssembly::c_TrappingCorrection); - AddModuleType(MAssembly::c_PositionDetermiation); + // AddModuleType(MAssembly::c_PositionDetermiation); // Set all modules, which can follow this module AddSucceedingModuleType(MAssembly::c_NoRestriction); @@ -180,9 +182,7 @@ void MModuleTrappingCorrection::CreateExpos() m_ExpoSpectrum->SetEnergyHistogramParameters(200, 0, 2000); m_Expos.push_back(m_ExpoSpectrum); -// m_ExpoSpectrum_LV = new MGUIExpoPlotSpectrum(this); -// m_ExpoSpectrum_LV->SetEnergyHistogramParameters(200, 0, 2000); -// m_Expos.push_back(m_ExpoSpectrum_LV); + } @@ -220,7 +220,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // } 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. + } 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->SetTrappingCorrectionError("Multiple hits on single strip"); // if (Grade==5) { @@ -262,7 +262,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Correct the Low Voltage side energy if the hit pointer exists if (LVSH != nullptr) { double rawLVEnergy = LVSH->GetEnergy(); // Replace with actual getter method for your hit class - double correctedLVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawLVEnergy, m_CCEs_LV); + double correctedLVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawLVEnergy, m_CCEs_LV, m_ParamA_LV, m_ParamB_LV, m_ParamC_LV); LVSH->SetEnergy(correctedLVEnergy); // Replace with actual setter method for your hit class if (HasExpos() == true) { @@ -273,7 +273,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Correct the High Voltage side energy if the hit pointer exists if (HVSH != nullptr) { double rawHVEnergy = HVSH->GetEnergy(); // Replace with actual getter method for your hit class - double correctedHVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawHVEnergy, m_CCEs_HV); + double correctedHVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawHVEnergy, m_CCEs_HV, m_ParamA_HV, m_ParamB_HV, m_ParamC_HV); HVSH->SetEnergy(correctedHVEnergy); // Replace with actual setter method for your hit class if (HasExpos() == true) { @@ -294,6 +294,61 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) ///////////////////////////////////////////////////////////////////////////////// +void MModuleTrappingCorrection::Finalize() +{ + // 1. Let the base class handle its core finalization routine first + MModule::Finalize(); + + if (m_ExpoSpectrum == nullptr) { + cout << "ERROR in MModuleTrappingCorrection::Finalize: Expo plot spectrum is null." << endl; + return; + } + + // 2. Locate the histograms dynamically from ROOT's global memory map + TH1D* histLV = (TH1D*) gDirectory->Get("EnergyHistogramLVFinal"); + TH1D* histHV = (TH1D*) gDirectory->Get("EnergyHistogramHVFinal"); + + if (histLV == nullptr) histLV = (TH1D*) gDirectory->Get("m_EnergyHistogramLVFinal"); + if (histHV == nullptr) histHV = (TH1D*) gDirectory->Get("m_EnergyHistogramHVFinal"); + + // 3. Perform the analytical fit for the Low Voltage spectrum + if (histLV != nullptr && histLV->GetEntries() > 0) { + TF1* fitFuncLV = GeneratePhotopeakFunction(); + fitFuncLV->SetParameter("Amplitude", histLV->GetBinContent(histLV->GetMaximumBin())); + + histLV->Fit(fitFuncLV, "RQ"); + + double mu = fitFuncLV->GetParameter("x0 (Mu)"); + double fwhm = 2.35482 * fitFuncLV->GetParameter("Sigma Gauss"); + + if (g_Verbosity >= c_Info) { + cout << m_XmlTag << " --- LV FINAL SPECTRUM FIT ---" << endl; + cout << " Centroid (Mu): " << mu << " keV | FWHM: " << fwhm << " keV" << endl; + } + delete fitFuncLV; + } + + // 4. Perform the analytical fit for the High Voltage spectrum + if (histHV != nullptr && histHV->GetEntries() > 0) { + TF1* fitFuncHV = GeneratePhotopeakFunction(); + fitFuncHV->SetParameter("Amplitude", histHV->GetBinContent(histHV->GetMaximumBin())); + + histHV->Fit(fitFuncHV, "RQ"); + + double mu = fitFuncHV->GetParameter("x0 (Mu)"); + double fwhm = 2.35482 * fitFuncHV->GetParameter("Sigma Gauss"); + + if (g_Verbosity >= c_Info) { + cout << m_XmlTag << " --- HV FINAL SPECTRUM FIT ---" << endl; + cout << " Centroid (Mu): " << mu << " keV | FWHM: " << fwhm << " keV" << endl; + } + delete fitFuncHV; + } + + return; // Clean exit for a void function +} + +///////////////////////////////////////////////////////////////////////////////// MStripHit* MModuleTrappingCorrection::GetDominantStrip(vector& Strips, double& EnergyFraction) { @@ -353,10 +408,13 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) if (ValidLineCount == 0) { // Step 1: Read parameters A, B, and C from the first line - if (Tokens.size() == 3) { - m_ParamA = Tokens[0].ToDouble(); - m_ParamB = Tokens[1].ToDouble(); - m_ParamC = Tokens[2].ToDouble(); + if (Tokens.size() == 6) { + m_ParamA_HV = Tokens[0].ToDouble(); + m_ParamB_HV = Tokens[1].ToDouble(); + m_ParamC_HV = Tokens[2].ToDouble(); + m_ParamA_LV = Tokens[3].ToDouble(); + m_ParamB_LV = Tokens[4].ToDouble(); + m_ParamC_LV = Tokens[5].ToDouble(); ValidLineCount++; } else { cout << "ERROR in LoadSimCCEFile: Expected 3 parameters (A,B,C) on the first line." << endl; @@ -383,8 +441,8 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Print summary to console if verbose logging is enabled if (g_Verbosity >= c_Info) { - cout << m_XmlTag << "Loaded parameters: A=" << m_ParamA - << ", B=" << m_ParamB << ", C=" << m_ParamC << endl; + cout << m_XmlTag << "Loaded HV parameters: A=" << m_ParamA_HV + << ", B=" << m_ParamB_HV << ", C=" << m_ParamC_HV << endl; cout << m_XmlTag << "Loaded " << m_Depths.size() << " data points into arrays." << endl; } @@ -394,13 +452,13 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) ///////////////////////////////////////////////////////////////////////////////// -double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted) { +double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted, double paramA, double paramB, double paramC) { // 2. Look up the simulation CCE baseline using the helper double cce_base = Interpolate(ctd_val, m_Depths, sim_cce_sorted); // 3. Evaluate the physical trapping function model using class global popt variables - double expected_centroid_scaled = m_ParamA * (1.0 - m_ParamB * (1.0 - cce_base)) * (1.0 - m_ParamC * (1.0 - cce_base)); + double expected_centroid_scaled = paramA * (1.0 - paramB * (1.0 - cce_base)) * (1.0 - paramC * (1.0 - cce_base)); // 4. Prevent division-by-zero or non-physical negative values if (expected_centroid_scaled <= 0.0) { @@ -596,19 +654,78 @@ MXmlNode* MModuleTrappingCorrection::CreateXmlConfiguration() return Node; } -void MModuleTrappingCorrection::Finalize() -{ +// void MModuleTrappingCorrection::Finalize() +// { - MModule::Finalize(); - cout << "finalize is working" << endl; +// MModule::Finalize(); +// cout << "finalize is working" << endl; + +// // Clean up maps and vectors +// m_Detectors.clear(); +// m_DetectorIDs.clear(); + +// } + +//////////////////////////////////////////////////////////////////////////////// - // Clean up maps and vectors - m_Detectors.clear(); - m_DetectorIDs.clear(); +TF1* MModuleTrappingCorrection::GeneratePhotopeakFunction() +{ + // Component 1: Core Gaussian + // exp(-(x-x0)^2 / (2*sigma^2)) + MString gaussStr = "exp(-(x-[1])^2 / (2*[2]^2))"; + + // Component 2: Exponential Tail + Shelf + // BoverA * exp(gamma*(x-x0)) * 0.5 * erfc((x-x0)/(sigma*sigma_ratio*sqrt(2))) + MString expTailStr = "[3] * exp([4]*(x-[1])) * 0.5 * erfc((x-[1])/([2]*[5]*sqrt(2)))"; + + // Component 3: Linear Tail + Shelf + // BoverA * CoverB * (1 + D*(x-x0)) * 0.5 * erfc((x-x0)/(sigma*sigma_ratio*sqrt(2))) + MString linTailStr = "[3] * [6] * (1 + [7]*(x-[1])) * 0.5 * erfc((x-[1])/([2]*[5]*sqrt(2)))"; + + // Combine components with an overall normalization scaling factor [0] + MString fullFormula = "[0] * (" + gaussStr + " + " + expTailStr + " + " + linTailStr + ")"; + + // Instantiate TF1 over your expected fit window + TF1* PhotopeakFunction = new TF1("PhotopeakFunction", fullFormula.Data(), 645, 675); + + // Set Parameter Names + PhotopeakFunction->SetParName(0, "Amplitude"); + PhotopeakFunction->SetParName(1, "x0 (Mu)"); + PhotopeakFunction->SetParName(2, "Sigma Gauss"); + PhotopeakFunction->SetParName(3, "BoverA"); + PhotopeakFunction->SetParName(4, "Gamma"); + PhotopeakFunction->SetParName(5, "Sigma Ratio"); + PhotopeakFunction->SetParName(6, "CoverB"); + PhotopeakFunction->SetParName(7, "D (Lin Slope)"); + + // Provide initial sensible guesses for a Cs137 photopeak + PhotopeakFunction->SetParameter("Amplitude", 1000); + PhotopeakFunction->SetParameter("x0 (Mu)", 661.7); + PhotopeakFunction->SetParameter("Sigma Gauss", 2.0); + PhotopeakFunction->SetParameter("BoverA", 0.05); + PhotopeakFunction->SetParameter("Gamma", 0.5); + PhotopeakFunction->SetParameter("Sigma Ratio", 0.85); + PhotopeakFunction->SetParameter("CoverB", 0.13); + PhotopeakFunction->SetParameter("D (Lin Slope)", 0.028); + + // Set boundary limits to stabilize convergence + PhotopeakFunction->SetParLimits(0, 1, 1e8); + PhotopeakFunction->SetParLimits(1, 645, 675); // Keeps peak centered around 662 keV + PhotopeakFunction->SetParLimits(2, 0.5, 10); // Prevents sigma from blowing up or hitting zero + PhotopeakFunction->SetParLimits(3, 0.0, 1.0); // Tail shouldn't be larger than the main peak + PhotopeakFunction->SetParLimits(4, 0.001, 2.0); // Standard range for exponential decay factor + PhotopeakFunction->SetParLimits(5, 0.1, 5.0); // Ratio of shelf width to peak width + PhotopeakFunction->SetParLimits(6, 0.0, 5.0); + PhotopeakFunction->SetParLimits(7, -1.0, 1.0); + + return PhotopeakFunction; } +//////////////////////////////////////////////////////////////////////////////// + + // MModuleTrappingCorrection.cxx: the end... //////////////////////////////////////////////////////////////////////////////// From b7c1cb76cb3d1f5c790550088faffa73240a4df3 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:24:09 -0700 Subject: [PATCH 27/61] cleaned up commented code --- include/MGUIOptionsTrappingCorrection.h | 34 ------ include/MModuleTrappingCorrection.h | 11 -- src/MGUIOptionsTrappingCorrection.cxx | 148 ------------------------ src/MModuleTrappingCorrection.cxx | 138 +++++++--------------- 4 files changed, 43 insertions(+), 288 deletions(-) diff --git a/include/MGUIOptionsTrappingCorrection.h b/include/MGUIOptionsTrappingCorrection.h index 903419f5..e5ff733c 100644 --- a/include/MGUIOptionsTrappingCorrection.h +++ b/include/MGUIOptionsTrappingCorrection.h @@ -53,9 +53,6 @@ class MGUIOptionsTrappingCorrection : public MGUIOptions //! Default destructor virtual ~MGUIOptionsTrappingCorrection(); - // //! Process all button, etc. messages - // virtual bool ProcessMessage(long Message, long Parameter1, long Parameter2); - //! The creation part which gets overwritten virtual void Create(); @@ -65,8 +62,6 @@ class MGUIOptionsTrappingCorrection : public MGUIOptions //! Actions after the Apply or OK button has been pressed virtual bool OnApply(); - // //! Toggle the radio buttons - // void ToggleRadioButtons(int WidgetID); // protected members: @@ -78,35 +73,6 @@ class MGUIOptionsTrappingCorrection : public MGUIOptions //! Select which file to load MGUIEFileSelector* m_SimCCEFileSelector; - // //! Radio button for ignoring the slow threshold cut - // TGRadioButton* m_SlowThresholdCutRBIgnore; - - // //! Radio button for using a fixed slow threshold cut - // TGRadioButton* m_SlowThresholdCutRBFixed; - // //! The slow threshold cut entry box - // MGUIEEntry* m_SlowThresholdCutFixedValue; - - // //! Radio button for reading slow threshold cuts from a file - // TGRadioButton* m_SlowThresholdCutRBFile; - // //! The slow threshold cut file selector - // MGUIEFileSelector* m_SlowThresholdCutFileSelector; - - // //! Radio button for ignoring the threshold cut for Nearest Neighbors - // TGRadioButton* m_SlowThresholdCutNearestNeighborRBIgnore; - // //! Radio button for using a fixed threshold cut for Nearest Neighbors - // TGRadioButton* m_SlowThresholdCutNearestNeighborRBFixed; - // //! The threshold cut entry box for Nearest Neighbors - // MGUIEEntry* m_SlowThresholdCutNearestNeighborFixedValue; - - - // //! IDs of radio buttons - // //! The numbers should be identical to MSlowThresholdCutModes - // enum RBButtonIDs { c_SlowThresholdIgnore = 0, - // c_SlowThresholdFixed, - // c_SlowThresholdFile, - // c_SlowThresholdNearestNeighborIgnore = 100, - // c_SlowThresholdNearestNeighborFixed}; - #ifdef ___CLING___ public: diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 283b1fbf..32887ce2 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -77,15 +77,12 @@ class MModuleTrappingCorrection : public MModule virtual void Finalize(); - //! Read the XML configuration bool ReadXmlConfiguration(MXmlNode* Node); //! Create the XML configuration MXmlNode* CreateXmlConfiguration(); - // //! Finalize - // void Finalize(); // protected methods: protected: @@ -94,9 +91,6 @@ class MModuleTrappingCorrection : public MModule // //! Retrieve the appropriate Depth values given the DetID // vector GetDepth(int DetID); - - // //! Retrieve the appropriate CTD values given the DetID and Grade - // vector GetCTD(int DetID, int Grade); //! Determine the Grade (geometry of charge sharing) of the Hit int GetHitGrade(MHit* H); @@ -128,11 +122,6 @@ class MModuleTrappingCorrection : public MModule MModuleEnergyCalibration* m_EnergyCalibration; MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; - // The CTD Map maps each detector (int) to a 2D array of CTD values. - // unordered_map>> m_CTDMap; - // unordered_map> m_DepthGrid; - // unordered_map> m_SplineMap; - bool m_SimCCEFileIsLoaded; double m_ParamA_HV; diff --git a/src/MGUIOptionsTrappingCorrection.cxx b/src/MGUIOptionsTrappingCorrection.cxx index e8cfd00f..117ba531 100644 --- a/src/MGUIOptionsTrappingCorrection.cxx +++ b/src/MGUIOptionsTrappingCorrection.cxx @@ -73,61 +73,11 @@ void MGUIOptionsTrappingCorrection::Create() TGLayoutHints* LabelLayout = new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX, 10, 10, 10, 10); m_OptionsFrame->AddFrame(m_SimCCEFileSelector, LabelLayout); - - // TGLabel* SlowThresholdLabel = new TGLabel(m_OptionsFrame, "Please choose how to handle the slow threshold cut:"); - // m_OptionsFrame->AddFrame(SlowThresholdLabel, LabelLayout); - - TGLayoutHints* RBLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 40, 10, 2, 0); TGLayoutHints* RBOptionLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop, 60, 10, 2, 0); TGLayoutHints* RBOptionStretchLayout = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 60, 10, 2, 0); - // m_SlowThresholdCutRBIgnore = new TGRadioButton(m_OptionsFrame, "Do not apply a slow threshold cut", c_SlowThresholdIgnore); - // m_SlowThresholdCutRBIgnore->Associate(this); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutRBIgnore, RBLayout); - - - // m_SlowThresholdCutRBFixed = new TGRadioButton(m_OptionsFrame, "Use one uniform slow threshold cut for all strips", c_SlowThresholdFixed); - // m_SlowThresholdCutRBFixed->Associate(this); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutRBFixed, RBLayout); - - // m_SlowThresholdCutFixedValue = new MGUIEEntry(m_OptionsFrame, "Set threshold value [keV]:", false, dynamic_cast(m_Module)->GetSlowThresholdCutFixedValue(), true, 0.0); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutFixedValue, RBOptionLayout); - - - // m_SlowThresholdCutRBFile = new TGRadioButton(m_OptionsFrame, "Read slow threshold cuts from file (unique to each strip)", c_SlowThresholdFile); - // m_SlowThresholdCutRBFile->Associate(this); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutRBFile, RBLayout); - - // m_SlowThresholdCutFileSelector = new MGUIEFileSelector(m_OptionsFrame, "", dynamic_cast(m_Module)->GetSlowThresholdCutFileName()); - // m_SlowThresholdCutFileSelector->SetFileType("Slow threshold cut per strip file", "*.csv"); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutFileSelector, RBOptionStretchLayout); - - - // // Toggle the right button - // MSlowThresholdCutModes SlowThresholdCutMode = dynamic_cast(m_Module)->GetSlowThresholdCutMode(); - // ToggleRadioButtons(static_cast(SlowThresholdCutMode)); - - // // Nearest Neighbor threshold cuts! - // TGLabel* NearestNeighborLabel = new TGLabel(m_OptionsFrame, "Please choose how to handle the threshold cut for Nearest Neighbors:"); - // m_OptionsFrame->AddFrame(NearestNeighborLabel, LabelLayout); - - // m_SlowThresholdCutNearestNeighborRBIgnore = new TGRadioButton(m_OptionsFrame, "Do not apply a slow threshold cut to Nearest Neighbors", c_SlowThresholdNearestNeighborIgnore); - // m_SlowThresholdCutNearestNeighborRBIgnore->Associate(this); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutNearestNeighborRBIgnore, RBLayout); - - // m_SlowThresholdCutNearestNeighborRBFixed = new TGRadioButton(m_OptionsFrame, "Use one uniform slow threshold cut for all Nearest Neighbors", c_SlowThresholdNearestNeighborFixed); - // m_SlowThresholdCutNearestNeighborRBFixed->Associate(this); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutNearestNeighborRBFixed, RBLayout); - - // m_SlowThresholdCutNearestNeighborFixedValue = new MGUIEEntry(m_OptionsFrame, "Set threshold value [keV] for Nearest Neighbors:", false, dynamic_cast(m_Module)->GetNearestNeighborThreshold()); - // m_OptionsFrame->AddFrame(m_SlowThresholdCutNearestNeighborFixedValue, RBOptionLayout); - - // MNearestNeighborCutModes NearestNeighborCutMode = dynamic_cast(m_Module)->GetNearestNeighborCutMode(); - // ToggleRadioButtons(static_cast(NearestNeighborCutMode)); - - PostCreate(); } @@ -135,110 +85,12 @@ void MGUIOptionsTrappingCorrection::Create() //////////////////////////////////////////////////////////////////////////////// -// bool MGUIOptionsTrappingCorrection::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; -// case kCM_RADIOBUTTON: -// ToggleRadioButtons(Parameter1); -// break; -// case kCM_CHECKBUTTON: -// break; -// default: -// break; -// } -// break; -// default: -// break; -// } - -// if (Status == false) { -// return false; -// } - -// // Call also base class -// return MGUIOptions::ProcessMessage(Message, Parameter1, Parameter2); -// } - - -//////////////////////////////////////////////////////////////////////////////// - - -// void MGUIOptionsTrappingCorrection::ToggleRadioButtons(int WidgetID) -// { -// // Toggle the radio buttons and the entry fields - -// if (WidgetID == m_SlowThresholdCutRBIgnore->WidgetId()) { -// m_SlowThresholdCutRBIgnore->SetState(kButtonDown); -// m_SlowThresholdCutRBFixed->SetState(kButtonUp); -// m_SlowThresholdCutFixedValue->SetEnabled(false); -// m_SlowThresholdCutRBFile->SetState(kButtonUp); -// m_SlowThresholdCutFileSelector->SetEnabled(false); -// } else if (WidgetID == m_SlowThresholdCutRBFixed->WidgetId()) { -// m_SlowThresholdCutRBIgnore->SetState(kButtonUp); -// m_SlowThresholdCutRBFixed->SetState(kButtonDown); -// m_SlowThresholdCutFixedValue->SetEnabled(true); -// m_SlowThresholdCutRBFile->SetState(kButtonUp); -// m_SlowThresholdCutFileSelector->SetEnabled(false); -// } else if (WidgetID == m_SlowThresholdCutRBFile->WidgetId()) { -// m_SlowThresholdCutRBIgnore->SetState(kButtonUp); -// m_SlowThresholdCutRBFixed->SetState(kButtonUp); -// m_SlowThresholdCutFixedValue->SetEnabled(false); -// m_SlowThresholdCutRBFile->SetState(kButtonDown); -// m_SlowThresholdCutFileSelector->SetEnabled(true); -// } - -// // Nearest Neighbors -// if (WidgetID == c_SlowThresholdNearestNeighborIgnore || WidgetID == c_SlowThresholdNearestNeighborFixed) { -// if (WidgetID == c_SlowThresholdNearestNeighborIgnore) { -// m_SlowThresholdCutNearestNeighborRBIgnore->SetState(kButtonDown); -// m_SlowThresholdCutNearestNeighborRBFixed->SetState(kButtonUp); -// m_SlowThresholdCutNearestNeighborFixedValue->SetEnabled(false); -// } else if (WidgetID == c_SlowThresholdNearestNeighborFixed) { -// m_SlowThresholdCutNearestNeighborRBIgnore->SetState(kButtonUp); -// m_SlowThresholdCutNearestNeighborRBFixed->SetState(kButtonDown); -// m_SlowThresholdCutNearestNeighborFixedValue->SetEnabled(true); -// } -// } -// } - - -//////////////////////////////////////////////////////////////////////////////// - - bool MGUIOptionsTrappingCorrection::OnApply() { // Modify this to store the data in the module! dynamic_cast(m_Module)->SetSimCCEFileName(m_SimCCEFileSelector->GetFileName()); - // if (m_SlowThresholdCutRBIgnore->GetState() == kButtonDown) { - // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_Ignore); - // } else if (m_SlowThresholdCutRBFixed->GetState() == kButtonDown) { - // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_Fixed); - // } if (m_SlowThresholdCutRBFile->GetState() == kButtonDown) { - // dynamic_cast(m_Module)->SetSlowThresholdCutMode(MSlowThresholdCutModes::e_File); - // } - - // dynamic_cast(m_Module)->SetSlowThresholdCutFixedValue(m_SlowThresholdCutFixedValue->GetAsDouble()); - // dynamic_cast(m_Module)->SetSlowThresholdCutFileName(m_SlowThresholdCutFileSelector->GetSimCCEFileName()); - - // // Nearest Neighbors - // if (m_SlowThresholdCutNearestNeighborRBIgnore->GetState() == kButtonDown) { - // dynamic_cast(m_Module)->SetNearestNeighborCutMode(MNearestNeighborCutModes::e_Ignore); - // } else { - // dynamic_cast(m_Module)->SetNearestNeighborCutMode(MNearestNeighborCutModes::e_Fixed); - // } - - // dynamic_cast(m_Module)->SetNearestNeighborThreshold(m_SlowThresholdCutNearestNeighborFixedValue->GetAsDouble()); - return true; } diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 914019d9..e5670dba 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -3,7 +3,7 @@ * * * Copyright (C) 2008-2008 by Andreas Zoglauer, Alex Lowell, - * Sean Pike, Carolyn Kierans. + * Sophie Haight, Carolyn Kierans. * All rights reserved. * * @@ -72,11 +72,9 @@ MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() AddPreceedingModuleType(MAssembly::c_TACcut, true); AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); AddPreceedingModuleType(MAssembly::c_DepthCorrection, true); -// AddPreceedingModuleType(MAssembly::c_CrosstalkCorrection, false); // Soft requirement // Set all types this modules handles AddModuleType(MAssembly::c_TrappingCorrection); - // AddModuleType(MAssembly::c_PositionDetermiation); // Set all modules, which can follow this module AddSucceedingModuleType(MAssembly::c_NoRestriction); @@ -84,8 +82,6 @@ MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() // Set if this module has an options GUI // If true, overwrite ShowOptionsGUI() with the call to the GUI! m_HasOptionsGUI = true; - // If true, you have to derive a class from MGUIOptions (use MGUIOptionsTemplate) - // and implement all your GUI options // Allow the use of multiple threads and instances m_AllowMultiThreading = true; @@ -114,40 +110,28 @@ bool MModuleTrappingCorrection::Initialize() // ie DetID=0 should be the 0th detector in m_Detectors, DetID=1 should the 1st, etc. vector DetList = m_Geometry->GetDetectorList(); - // Look through the Geometry and get the names and thicknesses of all the detectors. + // Look through the Geometry and get the names 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. - // If using the card cage at UCSD, default to DetID=11. unsigned int DetID = i; - 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); - - if (g_Verbosity >= c_Info) { - cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; - } - m_DetectorIDs.push_back(DetID); - m_Detectors[DetID] = det; - } else { - if (g_Verbosity >= c_Error) { - cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a duplicate detector: "<= c_Error) { - cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a Strip3D detector with "<GetNSensitiveVolumes()<<" Sensitive Volumes."<= c_Info) { + cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; + } + m_DetectorIDs.push_back(DetID); + m_Detectors[DetID] = det; + } else { + if (g_Verbosity >= c_Error) { + cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a duplicate detector: "<GetGuardRingVeto() == true) { - //TODO: Handle events with GR vetos + //Right now we cannot use events w gaurd ring veto // Event->SetTrappingCorrectionError("GR Veto"); return false; @@ -208,29 +192,16 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) int Grade = GetHitGrade(H); - // Handle different grades differently + // Handle different grades differently + // Get the position from the depth cal. If error is thrown, record and no depth. + // GRADE=-1 is an error. Break from the loop and continue. if (Grade < 0){ H->SetNoDepth(); - // // Event->SetTrappingCorrectionError("Error in Trapping Correction"); - // 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->SetTrappingCorrectionError("Multiple hits on single strip"); - // if (Grade==5) { - // ++m_Error5; - // } else if (Grade==6) { - // ++m_Error6; - // } } else { // If the Grade is 0-4, we can handle it. - // Get the position from the depth cal. If error is thrown, record and no depth. // Take a Hit and separate its activated X- and Y-strips into separate vectors. vector LVStrips; vector HVStrips; @@ -240,30 +211,22 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) if (SH->IsLowVoltageStrip()) LVStrips.push_back(SH); else HVStrips.push_back(SH); } + // For the hits in and events corresponding to the HV, LV sides, get the dominant strip and its energy fraction + // This is used to determine the CTD value for the event 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 = LVSH->GetDetectorID(); - int LVStripID = LVSH->GetStripID(); - int HVStripID = HVSH->GetStripID(); - // int PixelCode = 10000*DetID + 100*LVStripID + HVStripID; - - - // Get the position value (assumed from event/hit context H) double Zpos = H->GetPosition().GetZ(); - double ctd_val = static_cast(Zpos); + double depth_val = static_cast(Zpos); // Correct the Low Voltage side energy if the hit pointer exists if (LVSH != nullptr) { - double rawLVEnergy = LVSH->GetEnergy(); // Replace with actual getter method for your hit class - double correctedLVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawLVEnergy, m_CCEs_LV, m_ParamA_LV, m_ParamB_LV, m_ParamC_LV); - LVSH->SetEnergy(correctedLVEnergy); // Replace with actual setter method for your hit class + double rawLVEnergy = LVSH->GetEnergy(); + double correctedLVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawLVEnergy, m_CCEs_LV, m_ParamA_LV, m_ParamB_LV, m_ParamC_LV); + LVSH->SetEnergy(correctedLVEnergy); if (HasExpos() == true) { m_ExpoSpectrum->AddEnergyFinal(correctedLVEnergy, LVSH->IsNearestNeighbor(), LVSH->IsLowVoltageStrip()); @@ -272,9 +235,9 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Correct the High Voltage side energy if the hit pointer exists if (HVSH != nullptr) { - double rawHVEnergy = HVSH->GetEnergy(); // Replace with actual getter method for your hit class - double correctedHVEnergy = GetSimBasedCorrectedEnergy(ctd_val, rawHVEnergy, m_CCEs_HV, m_ParamA_HV, m_ParamB_HV, m_ParamC_HV); - HVSH->SetEnergy(correctedHVEnergy); // Replace with actual setter method for your hit class + double rawHVEnergy = HVSH->GetEnergy(); + double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV, m_ParamA_HV, m_ParamB_HV, m_ParamC_HV); + HVSH->SetEnergy(correctedHVEnergy); if (HasExpos() == true) { m_ExpoSpectrum->AddEnergyFinal(correctedHVEnergy, HVSH->IsNearestNeighbor(), HVSH->IsLowVoltageStrip()); @@ -296,7 +259,6 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) void MModuleTrappingCorrection::Finalize() { - // 1. Let the base class handle its core finalization routine first MModule::Finalize(); if (m_ExpoSpectrum == nullptr) { @@ -304,17 +266,16 @@ void MModuleTrappingCorrection::Finalize() return; } - // 2. Locate the histograms dynamically from ROOT's global memory map + // Locate the histograms dynamically from ROOT's global memory map TH1D* histLV = (TH1D*) gDirectory->Get("EnergyHistogramLVFinal"); TH1D* histHV = (TH1D*) gDirectory->Get("EnergyHistogramHVFinal"); if (histLV == nullptr) histLV = (TH1D*) gDirectory->Get("m_EnergyHistogramLVFinal"); if (histHV == nullptr) histHV = (TH1D*) gDirectory->Get("m_EnergyHistogramHVFinal"); - // 3. Perform the analytical fit for the Low Voltage spectrum + // Perform the photopeak fit for the LV peak if (histLV != nullptr && histLV->GetEntries() > 0) { TF1* fitFuncLV = GeneratePhotopeakFunction(); - fitFuncLV->SetParameter("Amplitude", histLV->GetBinContent(histLV->GetMaximumBin())); histLV->Fit(fitFuncLV, "RQ"); @@ -328,10 +289,9 @@ void MModuleTrappingCorrection::Finalize() delete fitFuncLV; } - // 4. Perform the analytical fit for the High Voltage spectrum + // Perform the photopeak fit for the HV peak if (histHV != nullptr && histHV->GetEntries() > 0) { TF1* fitFuncHV = GeneratePhotopeakFunction(); - fitFuncHV->SetParameter("Amplitude", histHV->GetBinContent(histHV->GetMaximumBin())); histHV->Fit(fitFuncHV, "RQ"); @@ -345,8 +305,7 @@ void MModuleTrappingCorrection::Finalize() delete fitFuncHV; } - return; // Clean exit for a void function -} + return; ///////////////////////////////////////////////////////////////////////////////// @@ -407,7 +366,7 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) } if (ValidLineCount == 0) { - // Step 1: Read parameters A, B, and C from the first line + // Read parameters A, B, and C from the first line if (Tokens.size() == 6) { m_ParamA_HV = Tokens[0].ToDouble(); m_ParamB_HV = Tokens[1].ToDouble(); @@ -417,17 +376,17 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) m_ParamC_LV = Tokens[5].ToDouble(); ValidLineCount++; } else { - cout << "ERROR in LoadSimCCEFile: Expected 3 parameters (A,B,C) on the first line." << endl; + cout << "ERROR in LoadSimCCEFile: Expected 6 parameters (A,B,C for HV, LV) on the first line." << endl; SimCCEFile.Close(); return false; } } else if (ValidLineCount == 1) { - // Step 2: Skip the second line which is the column header (z_depth_mm,CCE_HV) + // Skip the second line which is the column header (z_depth_mm,CCE_HV) ValidLineCount++; } else { - // Step 3: Read the rest of the rows into your depth and CCE HV arrays + // Read the rest of the rows into your depth and CCE HV arrays if (Tokens.size() == 3) { m_Depths.push_back(Tokens[0].ToDouble()); m_CCEs_HV.push_back(Tokens[1].ToDouble()); @@ -452,20 +411,20 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) ///////////////////////////////////////////////////////////////////////////////// -double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted, double paramA, double paramB, double paramC) { +double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double depth_val, double uncorrected_energy, const std::vector& sim_cce_sorted, double paramA, double paramB, double paramC) { - // 2. Look up the simulation CCE baseline using the helper - double cce_base = Interpolate(ctd_val, m_Depths, sim_cce_sorted); + // Look up the simulation CCE baseline using the interpolate function + double cce_base = Interpolate(depth_val, m_Depths, sim_cce_sorted); - // 3. Evaluate the physical trapping function model using class global popt variables + // Evaluate the physical trapping function model using class global popt variables double expected_centroid_scaled = paramA * (1.0 - paramB * (1.0 - cce_base)) * (1.0 - paramC * (1.0 - cce_base)); - // 4. Prevent division-by-zero or non-physical negative values + // Prevent division-by-zero or non-physical negative values if (expected_centroid_scaled <= 0.0) { return uncorrected_energy; } - // 5. Reconstruct the true un-trapped energy deposition + //Reconstruct the true un-trapped energy return uncorrected_energy / expected_centroid_scaled; } @@ -474,6 +433,7 @@ double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double ctd_val, dou double MModuleTrappingCorrection::Interpolate(double x, const std::vector& xp, const std::vector& fp) { + // need an interpolation function to get continuour CCE values from the discrete simulation data if (xp.empty()) return 0.0; if (x <= xp.front()) return fp.front(); if (x >= xp.back()) return fp.back(); @@ -654,18 +614,6 @@ MXmlNode* MModuleTrappingCorrection::CreateXmlConfiguration() return Node; } -// void MModuleTrappingCorrection::Finalize() -// { - -// MModule::Finalize(); -// cout << "finalize is working" << endl; - -// // Clean up maps and vectors -// m_Detectors.clear(); -// m_DetectorIDs.clear(); - -// } - //////////////////////////////////////////////////////////////////////////////// From b8f1556ddb7a445c8e4e259db1826c5ed3f3327f Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:27:39 -0700 Subject: [PATCH 28/61] cleaned up more commented code --- src/MModuleTrappingCorrection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index e5670dba..62bfbdff 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -177,7 +177,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) { if (Event->GetGuardRingVeto() == true) { - //Right now we cannot use events w gaurd ring veto + //Right now we cannot use events w GR veto // Event->SetTrappingCorrectionError("GR Veto"); return false; From df25e2b4d794f2b8302d9d8037131008d1a9ed0e Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:01:32 -0700 Subject: [PATCH 29/61] updated HDF loader header file --- include/MModuleLoaderMeasurementsHDF.h | 80 +++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/include/MModuleLoaderMeasurementsHDF.h b/include/MModuleLoaderMeasurementsHDF.h index 876c1e0c..eea94b07 100644 --- a/include/MModuleLoaderMeasurementsHDF.h +++ b/include/MModuleLoaderMeasurementsHDF.h @@ -1,7 +1,7 @@ /* * MModuleLoaderMeasurementsHDF.h * - * Copyright (C) by Andreas Zoglauer. + * Copyright (C) by Andreas Zoglauer, Felix Hagemann. * All rights reserved. * * Please see the source-file for the copyright-notice. @@ -39,13 +39,15 @@ using namespace H5; //! The versions of the strip hits stored in the HDF file -enum class MHDFStripHitVersion { V1_0, V1_2 }; +enum class MHDFStripHitVersion { V1_0, V1_2, V2_0, V2_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"; + case MHDFStripHitVersion::V2_0: return os<<"2.0"; + case MHDFStripHitVersion::V2_2: return os<<"2.2"; default: return os<<"Unknown"; } } @@ -96,6 +98,53 @@ struct MHDFStripHit_V1_2 { uint8_t m_CRC; }; +//! Version 2 of the HDF5 hit info +struct MHDFStripHit_V2 { + uint32_t m_EventIndex; + uint8_t m_HitType; + uint8_t m_TimingType; + uint16_t m_StripID; + uint16_t m_EnergyData; + uint16_t m_TimingData; +}; + +//! Version 2.0 of the HDF5 event info +struct MHDFEvent_V2_0 { + uint16_t m_EventID; + uint64_t m_TimeCode; + // Nanoseconds since epoch + uint64_t m_GSETimeCode; + uint8_t m_Hits; + uint16_t m_Bytes; + uint8_t m_EventType; + uint8_t m_CRC; +}; + +//! Version 2.2 of the HDF5 event info (adding SPWTimeCode) +struct MHDFEvent_V2_2 { + uint16_t m_EventID; + uint64_t m_TimeCode; + // Nanoseconds since epoch + uint64_t m_GSETimeCode; + // Nanoseconds since start of acquisition + uint64_t m_SPWTimeCode; + uint8_t m_Hits; + uint16_t m_Bytes; + uint8_t m_EventType; + uint8_t m_CRC; +}; + +//! HDF5 EventIndices (for HDF5v2 data) +struct MHDFEventIndices_V2 { + uint32_t m_FEEHits[2]; + uint32_t m_ACSHits[2]; + uint32_t m_HS[2]; + uint32_t m_SinglesCounts[2]; + uint32_t m_DIBCoincidence[2]; + uint32_t m_DetectorHits[2]; + uint32_t m_DetectorLiveTime[2]; +}; + //! The version string struct MHDFStripHitVersionString { char string_col[256]; @@ -149,6 +198,11 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements virtual bool ReadXmlConfiguration(MXmlNode* Node); //! Create an XML node tree from the configuration virtual MXmlNode* CreateXmlConfiguration(); + + //! Enable/Disable including nearest neighbors + bool GetIncludeNearestNeighbor() const { return m_IncludeNearestNeighbor; } + //! Set nearest neighbor variable + void SetIncludeNearestNeighbor(bool Include) { m_IncludeNearestNeighbor = Include; } // protected methods: @@ -191,10 +245,18 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! The HDF5 data set DataSet m_HDFDataSet; + DataSet m_EventDataSet; + DataSet m_EventIndicesDataSet; - //! The HDF5 compond data type + //! The HDF5 compound data type (v1) CompType m_HDFCompoundDataType; + //! The HDF5 compound data types (v2) + CompType m_EventCompoundDataType; + CompType m_EventIndicesCompoundDataType; + CompType m_HDFFEECompoundDataType; + + //! The version of the strip hit structure MHDFStripHitVersion m_HDFStripHitVersion; @@ -206,12 +268,18 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! The current index in the batch unsigned int m_CurrentBatchIndex; + unsigned int m_MinHitIndex; // The various batches: //! The MHDFStripHit_V1_0 batch: vector m_Buffer_1_0; //! The MHDFStripHit_V1_2 batch: vector m_Buffer_1_2; + //! The MHDFStripHit_V2 batch: + vector m_Buffer_2; + vector m_EventIndices_2; + vector m_EventData_2_0; + vector m_EventData_2_2; //! Total number of hits in a file hsize_t m_TotalHits; @@ -228,8 +296,14 @@ class MModuleLoaderMeasurementsHDF : public MModuleLoaderMeasurements //! The file name of the strip map MString m_FileNameStripMap; + //! The map which ASICs are HV/LV for HDFv2 + vector>> m_ASICPolarities; + //! The strip map MStripMap m_StripMap; + + //! Variable that deteremines if the user wants to include Nearest Neighbors + bool m_IncludeNearestNeighbor; #ifdef ___CLING___ public: From e1923d18708bf38ffcb5b802c6d2cca3a5635ca5 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:04:05 -0700 Subject: [PATCH 30/61] I'm just trying to get the HDF loader module up to date --- src/MModuleLoaderMeasurementsHDF.cxx | 153 +++++++++++++++++++-------- 1 file changed, 108 insertions(+), 45 deletions(-) diff --git a/src/MModuleLoaderMeasurementsHDF.cxx b/src/MModuleLoaderMeasurementsHDF.cxx index 3d88b4f9..1f3afc4e 100644 --- a/src/MModuleLoaderMeasurementsHDF.cxx +++ b/src/MModuleLoaderMeasurementsHDF.cxx @@ -2,7 +2,7 @@ * MModuleLoaderMeasurementsHDF.cxx * * - * Copyright (C) by Andreas Zoglauer. + * Copyright (C) by Andreas Zoglauer, Felix Hagemann. * All rights reserved. * * @@ -28,6 +28,7 @@ // Standard libs: #include +#include using namespace std; // ROOT libs: @@ -75,6 +76,8 @@ MModuleLoaderMeasurementsHDF::MModuleLoaderMeasurementsHDF() : MModuleLoaderMeas m_LoadContinuationFiles = false; m_FileNameStripMap = ""; + + m_IncludeNearestNeighbor = true; } @@ -322,7 +325,11 @@ bool MModuleLoaderMeasurementsHDF::OpenHDF5File(MString FileName) } // Get the data set - m_HDFDataSet = m_HDFFile.openDataSet("/Hits"); + if (m_HDFStripHitVersion <= MHDFStripHitVersion::V1_2) { + m_HDFDataSet = m_HDFFile.openDataSet("/Hits"); + } else { + m_HDFDataSet = m_HDFFile.openDataSet("/FEEHits"); + } // Get the data space DataSpace DS = m_HDFDataSet.getSpace(); @@ -446,7 +453,7 @@ bool MModuleLoaderMeasurementsHDF::OpenHDF5File(MString FileName) return false; } - DS.getSimpleExtentDims(&m_TotalHits, nullptr); + if (m_HDFStripHitVersion <= MHDFStripHitVersion::V1_2) DS.getSimpleExtentDims(&m_TotalHits, nullptr); m_CurrentHit = 0; if (ReadBatchHits() == false) { @@ -455,7 +462,7 @@ bool MModuleLoaderMeasurementsHDF::OpenHDF5File(MString FileName) } } catch (const H5::Exception& E) { - if (g_Verbosity >= c_Error) cout<= c_Error) cout<= c_Error) cout<= c_Info) { - cout<= c_Info) { + cout<SetAnalysisProgress(MAssembly::c_EventLoader | MAssembly::c_EventLoaderMeasurement); + m_NEventsInFile++; + m_NGoodEventsInFile++; + return true; } @@ -819,7 +876,7 @@ void MModuleLoaderMeasurementsHDF::Finalize() MModule::Finalize(); cout<<"MModuleLoaderMeasurementsHDF: "<GetValue(); } + + MXmlNode* IncludeNearestNeighborNode = Node->GetNode("IncludeNearestNeighbor"); + if (IncludeNearestNeighborNode != nullptr) { + m_IncludeNearestNeighbor = IncludeNearestNeighborNode->GetValueAsBoolean(); + } return true; } @@ -863,6 +925,7 @@ MXmlNode* MModuleLoaderMeasurementsHDF::CreateXmlConfiguration() new MXmlNode(Node, "FileNameHDF5", m_FileName); new MXmlNode(Node, "LoadContinuationFiles", m_LoadContinuationFiles); new MXmlNode(Node, "FileNameStripMap", m_FileNameStripMap); + new MXmlNode(Node, "IncludeNearestNeighbor", m_IncludeNearestNeighbor); return Node; } From 5b3171e8ac3a58ce26bed87f469a323fafb8f1b3 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:06:30 -0700 Subject: [PATCH 31/61] fixed compiliation error --- src/MModuleTrappingCorrection.cxx | 43 +++++++++++++++++-------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 62bfbdff..75d16306 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -117,18 +117,24 @@ bool MModuleTrappingCorrection::Initialize() MDDetector* det = DetList[i]; vector DetectorNames; - - if (find(DetectorNames.begin(), DetectorNames.end(), det_name) == DetectorNames.end()) { - DetectorNames.push_back(det_name); - - if (g_Verbosity >= c_Info) { - cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; - } - m_DetectorIDs.push_back(DetID); - m_Detectors[DetID] = det; - } else { - if (g_Verbosity >= c_Error) { - cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a duplicate detector: "<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); + + if (g_Verbosity >= c_Info) { + cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; + } + m_DetectorIDs.push_back(DetID); + m_Detectors[DetID] = det; + } else { + if (g_Verbosity >= c_Error) { + cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a duplicate detector: "<IsLowVoltageStrip()) LVStrips.push_back(SH); else HVStrips.push_back(SH); } - // For the hits in and events corresponding to the HV, LV sides, get the dominant strip and its energy fraction - // This is used to determine the CTD value for the event + // Get the dominant strip for the hit and its energy fraction for both LV and HV sides double LVEnergyFraction; double HVEnergyFraction; MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); // Get the position value (assumed from event/hit context H) - double Zpos = H->GetPosition().GetZ(); - double depth_val = static_cast(Zpos); + double depth_val = H->GetPosition().GetZ(); + // double depth_val = static_cast(Zpos); // Correct the Low Voltage side energy if the hit pointer exists if (LVSH != nullptr) { @@ -306,7 +311,7 @@ void MModuleTrappingCorrection::Finalize() } return; - +} ///////////////////////////////////////////////////////////////////////////////// MStripHit* MModuleTrappingCorrection::GetDominantStrip(vector& Strips, double& EnergyFraction) @@ -495,8 +500,8 @@ int MModuleTrappingCorrection::GetHitGrade(MHit* H){ } // If the same strip has multiple hits, this is a bad grade. - bool MultiHitX = H->GetStripHitMultipleTimesX(); - bool MultiHitY = H->GetStripHitMultipleTimesY(); + bool MultiHitX = H->GetStripHitMultipleTimesLV(); + bool MultiHitY = H->GetStripHitMultipleTimesHV(); if (MultiHitX || MultiHitY) { return 5; } From 40ff725ff8c11748525a98a762d3d62f362d2fb1 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:46:52 -0700 Subject: [PATCH 32/61] cleaned up commented code on trapping characterization app --- apps/TrappingCorrectionCs137.cxx | 61 ++------------------------------ 1 file changed, 2 insertions(+), 59 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index eb41d0dd..4017837c 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -504,11 +504,6 @@ bool TrappingCorrectionCs137::Analyze() TH1D* FullHVHist = FullDetHVEnergyHistograms[CTDBin][DetID]; TH1D* FullLVHist = FullDetLVEnergyHistograms[CTDBin][DetID]; - // if (FullCTDHist == nullptr) { - // char name[128]; sprintf(name, "CTD_Detector%d_bin%d", DetID, CTDBin); - // FullCTDHist = new TH1D(name, name, (g_MaxCTD - g_MinCTD) / 2, g_MinCTD, g_MaxCTD); - // FullDetCTDHistograms[CTDBin][DetID] = FullCTDHist; - // } if (FullHVHist == nullptr) { char name[128]; sprintf(name, "HV_Detector%d_bin%d", DetID, CTDBin); FullHVHist = new TH1D(name, name, (m_MaxEnergy - m_MinEnergy) * 2, m_MinEnergy, m_MaxEnergy); @@ -552,10 +547,6 @@ bool TrappingCorrectionCs137::Analyze() if (HVHist->Integral() > g_MinCounts) { - // double CTDGuess = FullCTDHist->GetBinCenter(FullCTDHist->GetMaximumBin()); - // TF1* CTDFunction = GenerateCTDFunction(CTDFitMin, CTDFitMax, CTDGuess); - // TFitResultPtr CTDFit = FullCTDHist->Fit(CTDFunction, "SQ", "", CTDFitMin, CTDFitMax); - TF1* PhotopeakFunctionHV = GeneratePhotopeakFunction(); TFitResultPtr HVFit = HVHist->Fit(PhotopeakFunctionHV, "S", "", 645, 675); @@ -575,17 +566,6 @@ bool TrappingCorrectionCs137::Analyze() FullDetEndpoints[c][DetID].push_back(LVFit->ParError(1)); // Index 2: HV Photopeak Mu Error - // ofstream CTDFitFile(DetID + MString("_CTDFitResult_.txt")); - // streambuf* coutbuf = cout.rdbuf(); - // cout.rdbuf(CTDFitFile.rdbuf()); - // cout << "CTD Fit Results for Detector " << DetID << " in CTD bin " << c << endl; - // if (CTDFit >= 0) { - // CTDFit->Print(); - // } - // cout.rdbuf(coutbuf); - // CTDFitFile.close(); - - MasterFitFile << "------------------------------------------------------------" << endl; MasterFitFile << " DETECTOR ID: " << DetID << " | CTD BIN INDEX: " << c << endl; MasterFitFile << "------------------------------------------------------------" << endl; @@ -611,14 +591,6 @@ bool TrappingCorrectionCs137::Analyze() cout.rdbuf(coutbuf); LVFitFile.close(); - // TFile CTDFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_CTDHist_Illum.root"), "recreate"); - // TCanvas* CTDCanvas = new TCanvas(); - // CTDCanvas->cd(); - // FullCTDHist->Draw("hist"); - // CTDFunction->Draw("same"); - // FullCTDHist->Write(); - // CTDFile.Close(); - TFile HVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_HVEnergyHist_Illum.root"), "recreate"); TCanvas* HVHistCanvas = new TCanvas(); HVHistCanvas->cd(); @@ -781,37 +753,8 @@ TF1* TrappingCorrectionCs137::GeneratePhotopeakFunction() //////////////////////////////////////////////////////////////////////////////// -// TF1* TrappingCorrectionCs137::GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess) -// { -// // 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)))", CTDFitMin, CTDFitMax); - -// 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", 12); -// CTDFunction->SetParameter("Mu", CTDGuess); - - -// CTDFunction->SetParLimits(0, 0, 1e8); -// CTDFunction->SetParLimits(1, 0.01, 1); -// CTDFunction->SetParLimits(2, CTDFitMin, CTDFitMax); -// CTDFunction->SetParLimits(3, 6, 30); - -// return CTDFunction; -// } - - -//////////////////////////////////////////////////////////////////////////////// - - -TrappingCorrectionCs137* g_Prg = 0; -int g_NInterruptCatches = 1; +// TrappingCorrectionCs137* g_Prg = 0; +// int g_NInterruptCatches = 1; MStripHit* TrappingCorrectionCs137::GetDominantStrip(vector& Strips, double& EnergyFraction) { From ff21a0e82d2a2be4c9f367e9a0a5f61a42f2797f Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:51:00 -0700 Subject: [PATCH 33/61] added dummy trapping parameter file to dee resource folder --- ...mmy_trapping_parameters_singledetector.csv | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 resource/dee/dummy_trapping_parameters_singledetector.csv diff --git a/resource/dee/dummy_trapping_parameters_singledetector.csv b/resource/dee/dummy_trapping_parameters_singledetector.csv new file mode 100644 index 00000000..580a741a --- /dev/null +++ b/resource/dee/dummy_trapping_parameters_singledetector.csv @@ -0,0 +1,153 @@ +1.0024045968768727,0.599438386875331,0.6343250169433193,1.0020865536682357,-21.933959500314355,21.073550128312775 +z_depth_mm,CCE_HV,CCE_LV +7.5,0.9997843655589124,0.9997843655589124 +7.4,0.9997848393262908,0.9997848393262908 +7.3,0.9997840856694716,0.9997840856694716 +7.2,0.9997806884891888,0.9997806884891888 +7.1,0.9997758754373276,0.9997758754373276 +7.0,0.9997707787718172,0.9997707787718172 +6.9,0.9997636051351584,0.9997636051351584 +6.8,0.999755204264947,0.999755204264947 +6.7,0.9997458590954548,0.9997458590954548 +6.6,0.9997364194692084,0.9997364194692084 +6.5,0.999725658069214,0.999725658069214 +6.4,0.9997145189366148,0.9997145189366148 +6.3,0.9997024356968855,0.9997024356968855 +6.2,0.9996912963246354,0.9996912963246354 +6.1,0.999677136109408,0.999677136109408 +6.0,0.9996661851507654,0.9996661851507654 +5.9,0.9996515526810562,0.9996515526810562 +5.8,0.9996379586807026,0.9996379586807026 +5.7,0.9996255913707786,0.9996255913707786 +5.6,0.9996102033709772,0.9996102033709772 +5.5,0.999594721202322,0.999594721202322 +5.4,0.9995798049527872,0.9995798049527872 +5.3,0.999564227855144,0.999564227855144 +5.2,0.9995502555243504,0.9995502555243504 +5.1,0.9995346787208024,0.9995346787208024 +5.0,0.999519667507766,0.999519667507766 +4.9,0.99950295752719,0.99950295752719 +4.8,0.9994871911622304,0.9994871911622304 +4.7,0.999469159716861,0.999469159716861 +4.6,0.9994526381252908,0.9994526381252908 +4.5,0.9994371547016008,0.9994371547016008 +4.4,0.9994213880406564,0.9994213880406564 +4.3,0.9994032619632196,0.9994032619632196 +4.2,0.9993852302143508,0.9993852302143508 +4.1,0.9993684250509454,0.9993684250509454 +4.0,0.9993520916352928,0.9993520916352928 +3.9,0.9993343424875064,0.9993343424875064 +3.8,0.9993164044582996,0.9993164044582996 +3.7,0.999297428814204,0.999297428814204 +3.6,0.99928015151698,0.99928015151698 +3.5,0.9992625909333068,0.9992625909333068 +3.4,0.9992452189127492,0.9992452189127492 +3.3,0.999225959366186,0.999225959366186 +3.2,0.9992082093201582,0.9992082093201582 +3.1,0.9991874396841024,0.9991874396841024 +3.0,0.9991689353863444,0.9991689353863444 +2.9,0.9991517517005,0.9991517517005 +2.8,0.9991346621171212,0.9991346621171212 +2.7,0.9991153079954752,0.9991153079954752 +2.6,0.9990968969979592,0.9990968969979592 +2.5,0.9990782980441476,0.9990782980441476 +2.4,0.9990586611355716,0.9990586611355716 +2.3,0.9990377963471704,0.9990377963471704 +2.2,0.99901910171742,0.99901910171742 +2.1,0.9989998419330156,0.9989998419330156 +2.0,0.9989818079232482,0.9989818079232482 +1.9,0.998961887197356,0.998961887197356 +1.8,0.9989437587198526,0.9989437587198526 +1.7,0.9989214776998088,0.9989214776998088 +1.6,0.9989018404721522,0.9989018404721522 +1.5,0.9988816364866144,0.9988816364866144 +1.4,0.9988633188339436,0.9988633188339436 +1.3,0.9988429259487488,0.9988429259487488 +1.2,0.9988224369491642,0.9988224369491642 +1.1,0.9988027045247908,0.9988027045247908 +1.0,0.9987834427982912,0.9987834427982912 +0.9,0.9987636159823396,0.9987636159823396 +0.8,0.9987405800150732,0.9987405800150732 +0.7,0.998719998337024,0.998719998337024 +0.6,0.9986995108170164,0.9986995108170164 +0.5,0.9986790214744364,0.9986790214744364 +0.4,0.9986574013277176,0.9986574013277176 +0.3,0.998636064024602,0.998636064024602 +0.2,0.9986158575897858,0.9986158575897858 +0.1,0.9985945199463312,0.9985945199463312 +0.0,0.998572711135827,0.998572711135827 +-0.1,0.998552126990966,0.998552126990966 +-0.2,0.9985306948245288,0.9985306948245288 +-0.3,0.9985086027152572,0.9985086027152572 +-0.4,0.9984850000393304,0.9984850000393304 +-0.5,0.9984639454414344,0.9984639454414344 +-0.6,0.998442419766231,0.998442419766231 +-0.7,0.9984200416186334,0.9984200416186334 +-0.8,0.9983979489884688,0.9983979489884688 +-0.9,0.9983749120858002,0.9983749120858002 +-1.0,0.9983546104679136,0.9983546104679136 +-1.1,0.9983311017405946,0.9983311017405946 +-1.2,0.9983087254562776,0.9983087254562776 +-1.3,0.998286538765916,0.998286538765916 +-1.4,0.998263876940509,0.998263876940509 +-1.5,0.9982415952978057,0.9982415952978057 +-1.6,0.9982173308397496,0.9982173308397496 +-1.7,0.9981947664332018,0.9981947664332018 +-1.8,0.9981699363282376,0.9981699363282376 +-1.9,0.9981473713950654,0.9981473713950654 +-2.0,0.9981231068687314,0.9981231068687314 +-2.1,0.9980998811979256,0.9980998811979256 +-2.2,0.9980762751630516,0.9980762751630516 +-2.3,0.9980518220843966,0.9980518220843966 +-2.4,0.998028690195372,0.998028690195372 +-2.5,0.9980031991192292,0.9980031991192292 +-2.6,0.9979819523802372,0.9979819523802372 +-2.7,0.9979565550854832,0.9979565550854832 +-2.8,0.997931535032997,0.997931535032997 +-2.9,0.9979072710390456,0.9979072710390456 +-3.0,0.9978819685120324,0.9978819685120324 +-3.1,0.9978582671402304,0.9978582671402304 +-3.2,0.9978335306200926,0.9978335306200926 +-3.3,0.997808510435997,0.997808510435997 +-3.4,0.9977822637104984,0.9977822637104984 +-3.5,0.9977574333711066,0.9977574333711066 +-3.6,0.99773118663829,0.99773118663829 +-3.7,0.9977044680576383,0.9977044680576383 +-3.8,0.9976782208784912,0.9976782208784912 +-3.9,0.997653389420603,0.997653389420603 +-4.0,0.9976263873592934,0.9976263873592934 +-4.1,0.9975992911078352,0.9975992911078352 +-4.2,0.9975741729180628,0.9975741729180628 +-4.3,0.99754641549766,0.99754641549766 +-4.4,0.9975196961366052,0.9975196961366052 +-4.5,0.9974929774727094,0.9974929774727094 +-4.6,0.9974665408455404,0.9974665408455404 +-4.7,0.9974386889789368,0.9974386889789368 +-4.8,0.997410742940092,0.997410742940092 +-4.9,0.99738430228969,0.99738430228969 +-5.0,0.9973561671196124,0.9973561671196124 +-5.1,0.997328221022722,0.997328221022722 +-5.2,0.9972992356196227,0.9972992356196227 +-5.3,0.9972706286272036,0.9972706286272036 +-5.4,0.9972419259134844,0.9972419259134844 +-5.5,0.9972125636070748,0.9972125636070748 +-5.6,0.9971824457327526,0.9971824457327526 +-5.7,0.997152611360722,0.997152611360722 +-5.8,0.9971225881635524,0.9971225881635524 +-5.9,0.9970948253503598,0.9970948253503598 +-6.0,0.9970650850558636,0.9970650850558636 +-6.1,0.9970340232588428,0.9970340232588428 +-6.2,0.9970027720667292,0.9970027720667292 +-6.3,0.9969721823277168,0.9969721823277168 +-6.4,0.9969408369958432,0.9969408369958432 +-6.5,0.9969083575293533,0.9969083575293533 +-6.6,0.996876918057559,0.996876918057559 +-6.7,0.9968444400446544,0.9968444400446544 +-6.8,0.9968114899676088,0.9968114899676088 +-6.9,0.9967795781256784,0.9967795781256784 +-7.0,0.9967453062658024,0.9967453062658024 +-7.1,0.9967126394241572,0.9967126394241572 +-7.2,0.996678461977118,0.996678461977118 +-7.3,0.9966433404017078,0.9966433404017078 +-7.4,0.9966101070830398,0.9966101070830398 +-7.5,0.9965741357920954,0.9965741357920954 From 8157795063db40cea51d07858de4a659d94de320 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 24 Jul 2026 10:06:26 -0700 Subject: [PATCH 34/61] removed duplicate functions from depth cal and reassigned them as public in depth header --- include/MModuleDepthCalibration.h | 12 +- include/MModuleTrappingCorrection.h | 21 +-- src/MModuleTrappingCorrection.cxx | 242 +++++++++------------------- 3 files changed, 98 insertions(+), 177 deletions(-) diff --git a/include/MModuleDepthCalibration.h b/include/MModuleDepthCalibration.h index 0926a61f..b3381de3 100644 --- a/include/MModuleDepthCalibration.h +++ b/include/MModuleDepthCalibration.h @@ -119,13 +119,18 @@ class MModuleDepthCalibration : public MModule //! Create the XML configuration MXmlNode* CreateXmlConfiguration(); + //! Returns the strip with most energy from vector Strips, also gives back the energy fraction + MStripHit* GetDominantStrip(std::vector& Strips, double& EnergyFraction); + + + //! Determine the Grade (geometry of charge sharing) of the Hit + int GetHitGrade(MHit* H); + //! Finalize void Finalize(); // protected methods: protected: - //! Returns the strip with most energy from vector Strips, also gives back the energy fraction - MStripHit* GetDominantStrip(std::vector& Strips, double& EnergyFraction); //! Retrieve the appropriate Depth values given the DetID vector GetDepth(int DetID); @@ -141,9 +146,6 @@ class MModuleDepthCalibration : public MModule //! Adds a Depth-to-CTD relation bool AddDepthCTD(vector Depth, vector> CTDArr, int DetID, unordered_map>& DepthGrid, unordered_map>>& CTDMap, unordered_map>& SplineMap, unsigned int NPoints); - //! Determine the Grade (geometry of charge sharing) of the Hit - int GetHitGrade(MHit* H); - //! Return the coefficients for a pixel vector* GetPixelCoeffs(int PixelCode); diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 32887ce2..d25b83b3 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -36,6 +36,7 @@ #include "MModuleEnergyCalibration.h" #include "MGUIExpoTrappingCorrection.h" #include "MGUIOptionsTrappingCorrection.h" +#include "MModuleDepthCalibration.h" // Forward declarations: @@ -76,24 +77,19 @@ class MModuleTrappingCorrection : public MModule //! Finalize the module virtual void Finalize(); - //! Read the XML configuration bool ReadXmlConfiguration(MXmlNode* Node); //! Create the XML configuration MXmlNode* CreateXmlConfiguration(); + + // Getters to retrieve the calculated values after Finalize() runs + double GetDirectFWHM_LV() const { return m_DirectFWHM_LV; } + double GetDirectFWHM_HV() const { return m_DirectFWHM_HV; } // protected methods: protected: - //! Returns the strip with most energy from vector Strips, also gives back the energy fraction - MStripHit* GetDominantStrip(std::vector& Strips, double& EnergyFraction); - - // //! Retrieve the appropriate Depth values given the DetID - // vector GetDepth(int DetID); - - //! Determine the Grade (geometry of charge sharing) of the Hit - int GetHitGrade(MHit* H); //! Load in the specified SimCCE file bool LoadSimCCEFile(MString FName); @@ -139,11 +135,18 @@ class MModuleTrappingCorrection : public MModule // private members: private: + MModuleDepthCalibration* m_DepthCalibration = nullptr; + //! Updated GUI to display the energy histogram MGUIExpoPlotSpectrum* m_ExpoSpectrum; TF1* GeneratePhotopeakFunction(); + double CalculateDirectFWHM(TH1D* hist); + + double m_DirectFWHM_LV = 0.0; + double m_DirectFWHM_HV = 0.0; + #ifdef ___CLING___ public: diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 75d16306..bc084b33 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -42,6 +42,8 @@ #include "MGUIExpoTrappingCorrection.h" #include "MGUIExpoPlotSpectrum.h" #include "MModuleEnergyCalibration.h" +#include "MModuleDepthCalibration.h" + //////////////////////////////////////////////////////////////////////////////// @@ -70,7 +72,6 @@ MModuleTrappingCorrection::MModuleTrappingCorrection() : MModule() AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); AddPreceedingModuleType(MAssembly::c_StripPairing, true); AddPreceedingModuleType(MAssembly::c_TACcut, true); - AddPreceedingModuleType(MAssembly::c_EnergyCalibration, true); AddPreceedingModuleType(MAssembly::c_DepthCorrection, true); // Set all types this modules handles @@ -155,6 +156,12 @@ bool MModuleTrappingCorrection::Initialize() return false; } + m_DepthCalibration = (MModuleDepthCalibration*) S->GetAvailableModuleByXmlTag("DepthCalibration"); + if (m_DepthCalibration == nullptr) { + cout << "MModuleTrappingCorrection: couldn't resolve pointer to Depth Calibration Module... need access to this module for depth resolution lookup!" << endl; + return false; + } + return MModule::Initialize(); } @@ -196,7 +203,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // instances of the MStripHit class. MHit* H = Event->GetHit(i); - int Grade = GetHitGrade(H); + int Grade = m_DepthCalibration->GetHitGrade(H); // Handle different grades differently // Get the position from the depth cal. If error is thrown, record and no depth. @@ -218,13 +225,15 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) } // Get the dominant strip for the hit and its energy fraction for both LV and HV sides + //s.t we cna determine the depth anf energy to correct double LVEnergyFraction; double HVEnergyFraction; - MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); - MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); + MStripHit* LVSH = m_DepthCalibration->GetDominantStrip(LVStrips, LVEnergyFraction); + MStripHit* HVSH = m_DepthCalibration->GetDominantStrip(HVStrips, HVEnergyFraction); // Get the position value (assumed from event/hit context H) double depth_val = H->GetPosition().GetZ(); + // cout<<"Depth value: "<(Zpos); // Correct the Low Voltage side energy if the hit pointer exists @@ -278,65 +287,50 @@ void MModuleTrappingCorrection::Finalize() if (histLV == nullptr) histLV = (TH1D*) gDirectory->Get("m_EnergyHistogramLVFinal"); if (histHV == nullptr) histHV = (TH1D*) gDirectory->Get("m_EnergyHistogramHVFinal"); - // Perform the photopeak fit for the LV peak + // Perform the photopeak fit and direct calculation for the LV peak if (histLV != nullptr && histLV->GetEntries() > 0) { + // Calculate raw FWHM directly from the histogram + m_DirectFWHM_LV = CalculateDirectFWHM(histLV); + TF1* fitFuncLV = GeneratePhotopeakFunction(); - + fitFuncLV->SetParameter("Amplitude", histLV->GetBinContent(histLV->GetMaximumBin())); histLV->Fit(fitFuncLV, "RQ"); double mu = fitFuncLV->GetParameter("x0 (Mu)"); - double fwhm = 2.35482 * fitFuncLV->GetParameter("Sigma Gauss"); + double fwhm_fit = 2.35482 * fitFuncLV->GetParameter("Sigma Gauss"); if (g_Verbosity >= c_Info) { - cout << m_XmlTag << " --- LV FINAL SPECTRUM FIT ---" << endl; - cout << " Centroid (Mu): " << mu << " keV | FWHM: " << fwhm << " keV" << endl; + cout << m_XmlTag << " --- LV FINAL SPECTRUM RESULTS ---" << endl; + cout << " Centroid (Mu) : " << mu << " keV" << endl; + cout << " Fitted Gaussian FWHM : " << fwhm_fit << " keV" << endl; + cout << " Direct Histogram FWHM: " << m_DirectFWHM_LV << " keV" << endl; } delete fitFuncLV; } - // Perform the photopeak fit for the HV peak + // Perform the photopeak fit and direct calculation for the HV peak if (histHV != nullptr && histHV->GetEntries() > 0) { + // Calculate raw FWHM directly from the histogram + m_DirectFWHM_HV = CalculateDirectFWHM(histHV); + TF1* fitFuncHV = GeneratePhotopeakFunction(); - + fitFuncHV->SetParameter("Amplitude", histHV->GetBinContent(histHV->GetMaximumBin())); histHV->Fit(fitFuncHV, "RQ"); double mu = fitFuncHV->GetParameter("x0 (Mu)"); - double fwhm = 2.35482 * fitFuncHV->GetParameter("Sigma Gauss"); + double fwhm_fit = 2.35482 * fitFuncHV->GetParameter("Sigma Gauss"); if (g_Verbosity >= c_Info) { - cout << m_XmlTag << " --- HV FINAL SPECTRUM FIT ---" << endl; - cout << " Centroid (Mu): " << mu << " keV | FWHM: " << fwhm << " keV" << endl; + cout << m_XmlTag << " --- HV FINAL SPECTRUM RESULTS ---" << endl; + cout << " Centroid (Mu) : " << mu << " keV" << endl; + cout << " Fitted Gaussian FWHM : " << fwhm_fit << " keV" << endl; + cout << " Direct Histogram FWHM: " << m_DirectFWHM_HV << " keV" << endl; } delete fitFuncHV; } return; } -///////////////////////////////////////////////////////////////////////////////// - -MStripHit* MModuleTrappingCorrection::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; - 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; -} - ///////////////////////////////////////////////////////////////////////////////// @@ -459,129 +453,6 @@ double MModuleTrappingCorrection::Interpolate(double x, const std::vectorGetNStripHits() == 0) { - // Error if no strip hits listed. Bad grade is returned - if (g_Verbosity >= c_Error) cout << m_XmlTag << "ERROR in MModuleTrappingCorrection: HIT WITH NO STRIP HITS" << endl; - return -1; - } - - // Take a Hit and separate its activated p and n strips into separate vectors. - 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 == nullptr ) { - if (g_Verbosity >= c_Error) cout << m_XmlTag << "ERROR in MModuleTrappingCorrection: Trapping Correction: got NULL strip hit :( " << endl; - return -1; - } - if (SH->GetEnergy() == 0 ) { - if (g_Verbosity >= c_Error) cout << m_XmlTag << "ERROR in MModuleTrappingCorrection: Trapping Correction: got strip without energy :( " << endl; - return -1; - } - if (SH->IsLowVoltageStrip()) { - LVStrips.push_back(SH); - LVStripIDs.push_back(SH->GetStripID()); - } - else { - HVStrips.push_back(SH); - HVStripIDs.push_back(SH->GetStripID()); - } - } - - // If the same strip has multiple hits, this is a bad grade. - bool MultiHitX = H->GetStripHitMultipleTimesLV(); - bool MultiHitY = H->GetStripHitMultipleTimesHV(); - if (MultiHitX || MultiHitY) { - return 5; - } - - 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 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 ( ((HVmax - HVmin) >= (HVStrips.size())) || ((LVmax - LVmin) >= (LVStrips.size())) ) { - return 6; - } - } - else{ - return -1; - } - - int return_value; - // If 1 strip on each side, GRADE=0 - // This represents the center of the pixel - 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 ( (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 ( (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 ( (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 ( (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 ( (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 ( (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 ( (LVStrips.size() == 3) && (HVStrips.size() == 2) ) { - return_value = 1; - } - - else { - // If more complicated than the above cases, return 4 for now. - // TODO: Handle more complicated charge distributions. - return_value = 4; - } - - return return_value; -} - -///////////////////////////////////////////////////////////////////////////////// - - void MModuleTrappingCorrection::ShowOptionsGUI() { // Show the options GUI - or do nothing @@ -619,7 +490,7 @@ MXmlNode* MModuleTrappingCorrection::CreateXmlConfiguration() return Node; } -//////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// TF1* MModuleTrappingCorrection::GeneratePhotopeakFunction() @@ -678,6 +549,51 @@ TF1* MModuleTrappingCorrection::GeneratePhotopeakFunction() //////////////////////////////////////////////////////////////////////////////// +double MModuleTrappingCorrection::CalculateDirectFWHM(TH1D* hist) +{ + if (hist == nullptr || hist->GetEntries() == 0) return 0.0; + + // 1. Find the maximum bin and its half-maximum height + int maxBin = hist->GetMaximumBin(); + double halfMax = hist->GetBinContent(maxBin) / 2.0; + + if (halfMax <= 0.0) return 0.0; + + // 2. Search LEFT for the half-maximum crossing point + double xLeft = hist->GetBinCenter(1); + for (int b = maxBin; b >= 1; --b) { + if (hist->GetBinContent(b) <= halfMax) { + double x1 = hist->GetBinCenter(b); + double y1 = hist->GetBinContent(b); + double x2 = hist->GetBinCenter(b + 1); + double y2 = hist->GetBinContent(b + 1); + + // Linear interpolation between bins + xLeft = (y2 != y1) ? x1 + (halfMax - y1) * (x2 - x1) / (y2 - y1) : x1; + break; + } + } + + // 3. Search RIGHT for the half-maximum crossing point + double xRight = hist->GetBinCenter(hist->GetNbinsX()); + for (int b = maxBin; b <= hist->GetNbinsX(); ++b) { + if (hist->GetBinContent(b) <= halfMax) { + double x1 = hist->GetBinCenter(b - 1); + double y1 = hist->GetBinContent(b - 1); + double x2 = hist->GetBinCenter(b); + double y2 = hist->GetBinContent(b); + + // Linear interpolation between bins + xRight = (y2 != y1) ? x1 + (halfMax - y1) * (x2 - x1) / (y2 - y1) : x2; + break; + } + } + + // 4. Return total width at half maximum + return (xRight - xLeft); +} + +//////////////////////////////////////////////////////////////////////////////// // MModuleTrappingCorrection.cxx: the end... From d97007557a2423401826de83ec1b2417be5e1cb2 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:10:37 -0700 Subject: [PATCH 35/61] fixed compilation error with trapping app --- apps/TrappingCorrectionCs137.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 4017837c..de9b07ba 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -753,8 +753,8 @@ TF1* TrappingCorrectionCs137::GeneratePhotopeakFunction() //////////////////////////////////////////////////////////////////////////////// -// TrappingCorrectionCs137* g_Prg = 0; -// int g_NInterruptCatches = 1; +TrappingCorrectionCs137* g_Prg = 0; +int g_NInterruptCatches = 1; MStripHit* TrappingCorrectionCs137::GetDominantStrip(vector& Strips, double& EnergyFraction) { From 57a17db25809c99b7b34c0d7ee32bfb2733a2f1d Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Fri, 24 Jul 2026 12:00:57 -0700 Subject: [PATCH 36/61] removed duplicate code from trapping module and added depth cal getter function for detector IDs --- include/MModuleDepthCalibration.h | 2 ++ include/MModuleTrappingCorrection.h | 2 +- src/MModuleTrappingCorrection.cxx | 46 +++++------------------------ 3 files changed, 11 insertions(+), 39 deletions(-) diff --git a/include/MModuleDepthCalibration.h b/include/MModuleDepthCalibration.h index b3381de3..196678b0 100644 --- a/include/MModuleDepthCalibration.h +++ b/include/MModuleDepthCalibration.h @@ -126,6 +126,8 @@ class MModuleDepthCalibration : public MModule //! Determine the Grade (geometry of charge sharing) of the Hit int GetHitGrade(MHit* H); + const std::vector& GetDetectorIDs() const { return m_DetectorIDs; } + //! Finalize void Finalize(); diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index d25b83b3..1bf9f247 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -113,7 +113,7 @@ class MModuleTrappingCorrection : public MModule double m_SimCCE_Energy; MString m_SimCCEFile; - unordered_map m_Detectors; + // unordered_map m_Detectors; vector m_DetectorIDs; MModuleEnergyCalibration* m_EnergyCalibration; MGUIExpoTrappingCorrection* m_ExpoTrappingCorrection; diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index bc084b33..8c7af612 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -106,44 +106,6 @@ MModuleTrappingCorrection::~MModuleTrappingCorrection() bool MModuleTrappingCorrection::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. - vector DetList = m_Geometry->GetDetectorList(); - - // Look through the Geometry and get the names 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. - unsigned int DetID = i; - - 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); - - if (g_Verbosity >= c_Info) { - cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; - } - m_DetectorIDs.push_back(DetID); - m_Detectors[DetID] = det; - } else { - if (g_Verbosity >= c_Error) { - cout<<"ERROR in MModuleTrappingCorrection::Initialize: Found a duplicate detector: "< GetDetectorIDs(); + + if (m_DetectorIDs.empty()) { + cout << "ERROR in MModuleTrappingCorrection::Initialize: Depth Calibration has no registered detector IDs!" << endl; + return false; + } + return MModule::Initialize(); } From a017321782d7adaba7697b6ce2d0bc226051525c Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 28 Jul 2026 08:27:06 -0700 Subject: [PATCH 37/61] cleaning out output from Cs trapping app --- apps/TrappingCorrectionCs137.cxx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index de9b07ba..ab116377 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -67,14 +67,14 @@ using namespace std; double g_MinCTD = -250; double g_MaxCTD = 250; -int g_MinCounts = 1500; +int g_MinCounts = 400; int g_HVStrips = 64; int g_LVStrips = 64; double g_CsPhotopeak = 661.7; -const int NCTDBins = 50; +const int NCTDBins = 40; // We need NCTDBins + 1 edges to define the boundaries of NCTDBins double g_CTDBinEdges[NCTDBins + 1]; @@ -582,14 +582,14 @@ bool TrappingCorrectionCs137::Analyze() MasterFitFile << endl << endl; // Add spacing between different bin entries - ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); - coutbuf = cout.rdbuf(); - cout.rdbuf(LVFitFile.rdbuf()); - if (LVFit >= 0) { - LVFit->Print(); - } - cout.rdbuf(coutbuf); - LVFitFile.close(); + // ofstream LVFitFile(DetID + MString("_CTDbin_") + c + MString("_LVEnergyFitResult_.txt")); + // coutbuf = cout.rdbuf(); + // cout.rdbuf(LVFitFile.rdbuf()); + // if (LVFit >= 0) { + // LVFit->Print(); + // } + // cout.rdbuf(coutbuf); + // LVFitFile.close(); TFile HVHistFile(m_OutFile + MString("_Det") + DetID + MString("_CTDbin_") + c + MString("_HVEnergyHist_Illum.root"), "recreate"); TCanvas* HVHistCanvas = new TCanvas(); From 6c5153b92bbcf31e9378631fa9df9124758226bb Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 29 Jul 2026 16:38:49 -0700 Subject: [PATCH 38/61] updated trapping parameter file w corrected base cce simulations --- ...mmy_trapping_parameters_singledetector.csv | 304 +++++++++--------- 1 file changed, 152 insertions(+), 152 deletions(-) diff --git a/resource/dee/dummy_trapping_parameters_singledetector.csv b/resource/dee/dummy_trapping_parameters_singledetector.csv index 580a741a..4d4b330f 100644 --- a/resource/dee/dummy_trapping_parameters_singledetector.csv +++ b/resource/dee/dummy_trapping_parameters_singledetector.csv @@ -1,153 +1,153 @@ -1.0024045968768727,0.599438386875331,0.6343250169433193,1.0020865536682357,-21.933959500314355,21.073550128312775 +1.0004614708764512,26.97750073638292,-27.302528941860835,1.0001434796999964,12.90339574367257,-13.320294113438992 z_depth_mm,CCE_HV,CCE_LV -7.5,0.9997843655589124,0.9997843655589124 -7.4,0.9997848393262908,0.9997848393262908 -7.3,0.9997840856694716,0.9997840856694716 -7.2,0.9997806884891888,0.9997806884891888 -7.1,0.9997758754373276,0.9997758754373276 -7.0,0.9997707787718172,0.9997707787718172 -6.9,0.9997636051351584,0.9997636051351584 -6.8,0.999755204264947,0.999755204264947 -6.7,0.9997458590954548,0.9997458590954548 -6.6,0.9997364194692084,0.9997364194692084 -6.5,0.999725658069214,0.999725658069214 -6.4,0.9997145189366148,0.9997145189366148 -6.3,0.9997024356968855,0.9997024356968855 -6.2,0.9996912963246354,0.9996912963246354 -6.1,0.999677136109408,0.999677136109408 -6.0,0.9996661851507654,0.9996661851507654 -5.9,0.9996515526810562,0.9996515526810562 -5.8,0.9996379586807026,0.9996379586807026 -5.7,0.9996255913707786,0.9996255913707786 -5.6,0.9996102033709772,0.9996102033709772 -5.5,0.999594721202322,0.999594721202322 -5.4,0.9995798049527872,0.9995798049527872 -5.3,0.999564227855144,0.999564227855144 -5.2,0.9995502555243504,0.9995502555243504 -5.1,0.9995346787208024,0.9995346787208024 -5.0,0.999519667507766,0.999519667507766 -4.9,0.99950295752719,0.99950295752719 -4.8,0.9994871911622304,0.9994871911622304 -4.7,0.999469159716861,0.999469159716861 -4.6,0.9994526381252908,0.9994526381252908 -4.5,0.9994371547016008,0.9994371547016008 -4.4,0.9994213880406564,0.9994213880406564 -4.3,0.9994032619632196,0.9994032619632196 -4.2,0.9993852302143508,0.9993852302143508 -4.1,0.9993684250509454,0.9993684250509454 -4.0,0.9993520916352928,0.9993520916352928 -3.9,0.9993343424875064,0.9993343424875064 -3.8,0.9993164044582996,0.9993164044582996 -3.7,0.999297428814204,0.999297428814204 -3.6,0.99928015151698,0.99928015151698 -3.5,0.9992625909333068,0.9992625909333068 -3.4,0.9992452189127492,0.9992452189127492 -3.3,0.999225959366186,0.999225959366186 -3.2,0.9992082093201582,0.9992082093201582 -3.1,0.9991874396841024,0.9991874396841024 -3.0,0.9991689353863444,0.9991689353863444 -2.9,0.9991517517005,0.9991517517005 -2.8,0.9991346621171212,0.9991346621171212 -2.7,0.9991153079954752,0.9991153079954752 -2.6,0.9990968969979592,0.9990968969979592 -2.5,0.9990782980441476,0.9990782980441476 -2.4,0.9990586611355716,0.9990586611355716 -2.3,0.9990377963471704,0.9990377963471704 -2.2,0.99901910171742,0.99901910171742 -2.1,0.9989998419330156,0.9989998419330156 -2.0,0.9989818079232482,0.9989818079232482 -1.9,0.998961887197356,0.998961887197356 -1.8,0.9989437587198526,0.9989437587198526 -1.7,0.9989214776998088,0.9989214776998088 -1.6,0.9989018404721522,0.9989018404721522 -1.5,0.9988816364866144,0.9988816364866144 -1.4,0.9988633188339436,0.9988633188339436 -1.3,0.9988429259487488,0.9988429259487488 -1.2,0.9988224369491642,0.9988224369491642 -1.1,0.9988027045247908,0.9988027045247908 -1.0,0.9987834427982912,0.9987834427982912 -0.9,0.9987636159823396,0.9987636159823396 -0.8,0.9987405800150732,0.9987405800150732 -0.7,0.998719998337024,0.998719998337024 -0.6,0.9986995108170164,0.9986995108170164 -0.5,0.9986790214744364,0.9986790214744364 -0.4,0.9986574013277176,0.9986574013277176 -0.3,0.998636064024602,0.998636064024602 -0.2,0.9986158575897858,0.9986158575897858 -0.1,0.9985945199463312,0.9985945199463312 -0.0,0.998572711135827,0.998572711135827 --0.1,0.998552126990966,0.998552126990966 --0.2,0.9985306948245288,0.9985306948245288 --0.3,0.9985086027152572,0.9985086027152572 --0.4,0.9984850000393304,0.9984850000393304 --0.5,0.9984639454414344,0.9984639454414344 --0.6,0.998442419766231,0.998442419766231 --0.7,0.9984200416186334,0.9984200416186334 --0.8,0.9983979489884688,0.9983979489884688 --0.9,0.9983749120858002,0.9983749120858002 --1.0,0.9983546104679136,0.9983546104679136 --1.1,0.9983311017405946,0.9983311017405946 --1.2,0.9983087254562776,0.9983087254562776 --1.3,0.998286538765916,0.998286538765916 --1.4,0.998263876940509,0.998263876940509 --1.5,0.9982415952978057,0.9982415952978057 --1.6,0.9982173308397496,0.9982173308397496 --1.7,0.9981947664332018,0.9981947664332018 --1.8,0.9981699363282376,0.9981699363282376 --1.9,0.9981473713950654,0.9981473713950654 --2.0,0.9981231068687314,0.9981231068687314 --2.1,0.9980998811979256,0.9980998811979256 --2.2,0.9980762751630516,0.9980762751630516 --2.3,0.9980518220843966,0.9980518220843966 --2.4,0.998028690195372,0.998028690195372 --2.5,0.9980031991192292,0.9980031991192292 --2.6,0.9979819523802372,0.9979819523802372 --2.7,0.9979565550854832,0.9979565550854832 --2.8,0.997931535032997,0.997931535032997 --2.9,0.9979072710390456,0.9979072710390456 --3.0,0.9978819685120324,0.9978819685120324 --3.1,0.9978582671402304,0.9978582671402304 --3.2,0.9978335306200926,0.9978335306200926 --3.3,0.997808510435997,0.997808510435997 --3.4,0.9977822637104984,0.9977822637104984 --3.5,0.9977574333711066,0.9977574333711066 --3.6,0.99773118663829,0.99773118663829 --3.7,0.9977044680576383,0.9977044680576383 --3.8,0.9976782208784912,0.9976782208784912 --3.9,0.997653389420603,0.997653389420603 --4.0,0.9976263873592934,0.9976263873592934 --4.1,0.9975992911078352,0.9975992911078352 --4.2,0.9975741729180628,0.9975741729180628 --4.3,0.99754641549766,0.99754641549766 --4.4,0.9975196961366052,0.9975196961366052 --4.5,0.9974929774727094,0.9974929774727094 --4.6,0.9974665408455404,0.9974665408455404 --4.7,0.9974386889789368,0.9974386889789368 --4.8,0.997410742940092,0.997410742940092 --4.9,0.99738430228969,0.99738430228969 --5.0,0.9973561671196124,0.9973561671196124 --5.1,0.997328221022722,0.997328221022722 --5.2,0.9972992356196227,0.9972992356196227 --5.3,0.9972706286272036,0.9972706286272036 --5.4,0.9972419259134844,0.9972419259134844 --5.5,0.9972125636070748,0.9972125636070748 --5.6,0.9971824457327526,0.9971824457327526 --5.7,0.997152611360722,0.997152611360722 --5.8,0.9971225881635524,0.9971225881635524 --5.9,0.9970948253503598,0.9970948253503598 --6.0,0.9970650850558636,0.9970650850558636 --6.1,0.9970340232588428,0.9970340232588428 --6.2,0.9970027720667292,0.9970027720667292 --6.3,0.9969721823277168,0.9969721823277168 --6.4,0.9969408369958432,0.9969408369958432 --6.5,0.9969083575293533,0.9969083575293533 --6.6,0.996876918057559,0.996876918057559 --6.7,0.9968444400446544,0.9968444400446544 --6.8,0.9968114899676088,0.9968114899676088 --6.9,0.9967795781256784,0.9967795781256784 --7.0,0.9967453062658024,0.9967453062658024 --7.1,0.9967126394241572,0.9967126394241572 --7.2,0.996678461977118,0.996678461977118 --7.3,0.9966433404017078,0.9966433404017078 --7.4,0.9966101070830398,0.9966101070830398 --7.5,0.9965741357920954,0.9965741357920954 +-7.5,0.9960754005722672,0.9995680702824706 +-7.4,0.9961283655288202,0.9995866741854744 +-7.3,0.9961799143100644,0.9995983865132282 +-7.2,0.9962307077978106,0.9996045286163866 +-7.1,0.9962799906985604,0.9996057608966376 +-7.0,0.9963278574240018,0.9996047269442528 +-6.9,0.9963751576793192,0.9996001050566428 +-6.8,0.9964218918031278,0.999591518055102 +-6.7,0.9964676814671262,0.9995818918172162 +-6.6,0.9965126214260192,0.9995714155297944 +-6.5,0.9965546362530274,0.9995587675159084 +-6.4,0.9965983488394674,0.9995444199486776 +-6.3,0.9966398902762568,0.9995298831101098 +-6.2,0.9966814320191532,0.9995129860915468 +-6.1,0.996721840186966,0.999495616713339 +-6.0,0.9967618710147071,0.9994796627385392 +-5.9,0.9967992640603592,0.9994615374667511 +-5.8,0.9968375950968208,0.9994417130820838 +-5.7,0.996876209367542,0.9994230210184356 +-5.6,0.9969135965814632,0.9994053665715116 +-5.5,0.9969512667344292,0.9993843144597538 +-5.4,0.996988088607557,0.9993652439859948 +-5.3,0.9970243428533409,0.9993435308368304 +-5.2,0.9970605973698986,0.999323704737354 +-5.1,0.9970957186625464,0.9993027463873654 +-5.0,0.997128201852184,0.999282636650904 +-4.9,0.997163133975293,0.9992609227234652 +-4.8,0.9971971222513047,0.9992423227931412 +-4.7,0.99723045068752,0.9992186269132852 +-4.6,0.9972645330910304,0.999197667075865 +-4.5,0.997296633626106,0.9991773688108196 +-4.4,0.9973294889278216,0.9991549931844508 +-4.3,0.9973604607250754,0.9991340337966688 +-4.2,0.9973915219033234,0.9991119414267454 +-4.1,0.9974244715414337,0.9990898489050768 +-4.0,0.9974552506810508,0.9990700217057504 +-3.9,0.9974854628536703,0.9990474569336196 +-3.8,0.9975174681134844,0.9990248935438112 +-3.7,0.9975481518526584,0.9990028006276976 +-3.6,0.9975781747105746,0.9989815572118812 +-3.5,0.9976072543544832,0.9989599359560328 +-3.4,0.9976366167586318,0.9989363338697768 +-3.3,0.9976672058276272,0.9989159397325226 +-3.2,0.997695061527942,0.9988940349755416 +-3.1,0.9977239511469376,0.9988740181939894 +-3.0,0.997752558798022,0.9988500383554292 +-2.9,0.997780693740538,0.9988299272475998 +-2.8,0.9978092056932284,0.9988081166089234 +-2.7,0.997835456249908,0.9987879106491638 +-2.6,0.9978631196488936,0.9987651577047352 +-2.5,0.9978910656557696,0.9987429711607436 +-2.4,0.9979180669624028,0.998722576094638 +-2.3,0.9979432785028124,0.9987013316896338 +-2.2,0.9979700918809232,0.9986809377649604 +-2.1,0.9979968104506788,0.9986586552650168 +-2.0,0.9980241895067804,0.998636657700976 +-1.9,0.9980510965082604,0.998615223990674 +-1.8,0.9980778153994272,0.9985938865703976 +-1.7,0.998102929122216,0.998573491409772 +-1.6,0.9981270070969988,0.9985528125326696 +-1.5,0.9981534419639304,0.9985314750514952 +-1.4,0.9981795001983076,0.998508061349048 +-1.3,0.9982037637866816,0.9984868184846898 +-1.2,0.9982279362284424,0.9984672720418092 +-1.1,0.9982532388982888,0.9984440470528136 +-1.0,0.9982777857893338,0.9984245948332848 +-0.9,0.9983012968190556,0.998404388094939 +-0.8,0.998326221738846,0.9983826727803112 +-0.7,0.998350391055626,0.9983606751019626 +-0.6,0.9983754094394036,0.9983381100474218 +-0.5,0.9984005231104938,0.9983179033459608 +-0.4,0.9984234650599014,0.998297414896014 +-0.3,0.998446692485329,0.9982741897906248 +-0.2,0.9984699178682128,0.998254643282951 +-0.1,0.9984943702625176,0.9982339663680992 +0.0,0.9985161814851206,0.9982124374219222 +0.1,0.9985395955741484,0.9981915716005412 +0.2,0.9985621609993632,0.9981703289569462 +0.3,0.9985851980201632,0.9981474811588664 +0.4,0.9986075737591684,0.9981266154431652 +0.5,0.9986313647242406,0.9981062208760968 +0.6,0.9986542122070716,0.9980854482663012 +0.7,0.99867668285946,0.9980637327576776 +0.8,0.9986970764818612,0.9980423011850016 +0.9,0.9987209624540418,0.9980236038279624 +1.0,0.998741168166942,0.998000755289082 +1.1,0.9987643934066572,0.9979806436969496 +1.2,0.9987841268148946,0.9979609093234636 +1.3,0.9988048029530124,0.9979395712594462 +1.4,0.998828876892382,0.9979175730728168 +1.5,0.9988500249066732,0.9978968024202356 +1.6,0.998869946969749,0.9978761257767412 +1.7,0.998891850143693,0.9978545988167388 +1.8,0.99891148892525,0.997834579972524 +1.9,0.9989318815854488,0.9978137142289052 +2.0,0.9989531249377974,0.9977936977576536 +2.1,0.9989733286874388,0.9977710385783546 +2.2,0.998993815365242,0.9977511158435132 +2.3,0.9990143035084226,0.9977310033948454 +2.4,0.9990347901823036,0.9977111756403796 +2.5,0.99905395647878,0.9976897437334612 +2.6,0.9990734047525536,0.9976679343911176 +2.7,0.9990940815967804,0.9976490475941848 +2.8,0.9991140958375196,0.997628465336091 +2.9,0.9991339216016192,0.9976080712160224 +3.0,0.999152709686677,0.9975856951073382 +3.1,0.9991718745873368,0.997565679522037 +3.2,0.9991919847688816,0.9975445312202288 +3.3,0.9992100173710472,0.9975243265709302 +3.4,0.9992296540596812,0.9975034603209378 +3.5,0.999249007500204,0.9974817452942196 +3.6,0.9992667568609706,0.9974612576212276 +3.7,0.9992845061840244,0.9974406755321984 +3.8,0.9993048981091543,0.9974224491068971 +3.9,0.9993229305698542,0.9974012058404372 +4.0,0.9993420946956286,0.9973793965883082 +4.1,0.9993592774528276,0.9973595684941804 +4.2,0.9993779697426552,0.9973388921785016 +4.3,0.9993951523587272,0.9973189706537894 +4.4,0.9994116739654898,0.9972978222721152 +4.5,0.9994302716345286,0.9972778016754492 +4.6,0.9994466043364204,0.9972580691825388 +4.7,0.9994631256367906,0.99723758138497 +4.8,0.9994795524684096,0.997217187996138 +4.9,0.9994975835457,0.9971979264909168 +5.0,0.999513538277845,0.9971764948153332 +5.1,0.9995292097931202,0.9971548743144144 +5.2,0.9995450699181228,0.9971352359355208 +5.3,0.9995625342950276,0.9971147483827466 +5.4,0.9995779222113124,0.9970951077852024 +5.5,0.9995915167429508,0.9970763168645695 +5.6,0.9996074706089096,0.9970551681031228 +5.7,0.9996227638202354,0.9970336416861376 +5.8,0.9996349419674988,0.9970139093938633 +5.9,0.999648913194318,0.9969936103385107 +6.0,0.9996614686529788,0.9969733115670298 +6.1,0.9996746846124428,0.9969538610635932 +6.2,0.9996888444586154,0.9969332790437246 +6.3,0.9996975291349788,0.9969118473074394 +6.4,0.999710367136738,0.9968914541134416 +6.5,0.999721222617078,0.9968719103384752 +6.6,0.99973113405139,0.9968516112561766 +6.7,0.9997398180433936,0.9968314068842338 +6.8,0.9997463307291454,0.996811391338197 +6.9,0.9997552976144944,0.996791186966254 +7.0,0.9997603940398226,0.996769755225922 +7.1,0.9997629413906144,0.9967493620280732 +7.2,0.9997656772603496,0.9967296297208956 +7.3,0.9997665249985864,0.9967094253489528 +7.4,0.9997642575200192,0.9966895042158688 +7.5,0.9997587802114803,0.996669488669832 From a48ef40eb1557113cc00a04328d40793deb924b7 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 5 Aug 2026 15:57:20 -0700 Subject: [PATCH 39/61] updated sim CCE read in function to take four raw simulated CCE curves and four fitted trapping parameters --- include/MModuleTrappingCorrection.h | 12 ++++++------ src/MModuleTrappingCorrection.cxx | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 1bf9f247..19bde95b 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -121,14 +121,14 @@ class MModuleTrappingCorrection : public MModule bool m_SimCCEFileIsLoaded; double m_ParamA_HV; - double m_ParamB_HV; - double m_ParamC_HV; double m_ParamA_LV; - double m_ParamB_LV; - double m_ParamC_LV; + double m_ParamB; + double m_ParamC; std::vector m_Depths; - std::vector m_CCEs_HV; - std::vector m_CCEs_LV; + std::vector m_CCEs_HV_e; + std::vector m_CCEs_HV_h; + std::vector m_CCEs_LV_e; + std::vector m_CCEs_LV_h; diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 8c7af612..b2303b3a 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -195,7 +195,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) } // Get the dominant strip for the hit and its energy fraction for both LV and HV sides - //s.t we cna determine the depth anf energy to correct + //s.t we can determine the depth and energy to correct double LVEnergyFraction; double HVEnergyFraction; MStripHit* LVSH = m_DepthCalibration->GetDominantStrip(LVStrips, LVEnergyFraction); @@ -203,8 +203,6 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Get the position value (assumed from event/hit context H) double depth_val = H->GetPosition().GetZ(); - // cout<<"Depth value: "<(Zpos); // Correct the Low Voltage side energy if the hit pointer exists if (LVSH != nullptr) { @@ -220,7 +218,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Correct the High Voltage side energy if the hit pointer exists if (HVSH != nullptr) { double rawHVEnergy = HVSH->GetEnergy(); - double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV, m_ParamA_HV, m_ParamB_HV, m_ParamC_HV); + double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV_e, m_CCEs_HV_h, m_CCEs_LV_e, m_CCEs_LV_h, m_ParamA_HV, m_ParamA_LV, m_ParamB, m_ParamC); HVSH->SetEnergy(correctedHVEnergy); if (HasExpos() == true) { @@ -315,8 +313,10 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Clear existing array data before loading new files m_Depths.clear(); - m_CCEs_HV.clear(); - m_CCEs_LV.clear(); + m_CCEs_HV_e.clear(); + m_CCEs_HV_h.clear(); + m_CCEs_LV_e.clear(); + m_CCEs_LV_h.clear(); MString Line; int ValidLineCount = 0; @@ -338,14 +338,12 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Read parameters A, B, and C from the first line if (Tokens.size() == 6) { m_ParamA_HV = Tokens[0].ToDouble(); - m_ParamB_HV = Tokens[1].ToDouble(); - m_ParamC_HV = Tokens[2].ToDouble(); - m_ParamA_LV = Tokens[3].ToDouble(); - m_ParamB_LV = Tokens[4].ToDouble(); - m_ParamC_LV = Tokens[5].ToDouble(); + m_ParamA_LV = Tokens[1].ToDouble(); + m_ParamB = Tokens[2].ToDouble(); + m_ParamC = Tokens[3].ToDouble(); ValidLineCount++; } else { - cout << "ERROR in LoadSimCCEFile: Expected 6 parameters (A,B,C for HV, LV) on the first line." << endl; + cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B,and C) on the first line." << endl; SimCCEFile.Close(); return false; } @@ -358,8 +356,10 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Read the rest of the rows into your depth and CCE HV arrays if (Tokens.size() == 3) { m_Depths.push_back(Tokens[0].ToDouble()); - m_CCEs_HV.push_back(Tokens[1].ToDouble()); - m_CCEs_LV.push_back(Tokens[2].ToDouble()); + m_CCEs_HV_e.push_back(Tokens[1].ToDouble()); + m_CCEs_HV_h.push_back(Tokens[2].ToDouble()); + m_CCEs_LV_e.push_back(Tokens[3].ToDouble()); + m_CCEs_LV_h.push_back(Tokens[4].ToDouble()); ValidLineCount++; } } From 817766864036e50915c5d13d2ce87d863dbdb3aa Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 5 Aug 2026 16:16:31 -0700 Subject: [PATCH 40/61] updated function for corrected energy to scale HV,LV cce affected by e,h by fitted trapping parameters B,C --- include/MModuleTrappingCorrection.h | 2 +- src/MModuleTrappingCorrection.cxx | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 19bde95b..372ea306 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -95,7 +95,7 @@ class MModuleTrappingCorrection : public MModule bool LoadSimCCEFile(MString FName); //! Get the Sim-based corrected energy given the CTD value, uncorrected energy, and the sorted Sim CCE values - double GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted, double paramA, double paramB, double paramC); + double GetSimBasedCorrectedEnergy(double ctd_val, double uncorrected_energy, const std::vector& sim_cce_sorted_e, const std::vector& sim_cce_sorted_h, double paramA, double paramB, double paramC); //! Interpolate a value given x, xp, and fp double Interpolate(double x, const std::vector& xp, const std::vector& fp); diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index b2303b3a..234eee4e 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -207,7 +207,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Correct the Low Voltage side energy if the hit pointer exists if (LVSH != nullptr) { double rawLVEnergy = LVSH->GetEnergy(); - double correctedLVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawLVEnergy, m_CCEs_LV, m_ParamA_LV, m_ParamB_LV, m_ParamC_LV); + double correctedLVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawLVEnergy, m_CCEs_LV_e, m_CCEs_LV_h, m_ParamA_LV, m_ParamB, m_ParamC); LVSH->SetEnergy(correctedLVEnergy); if (HasExpos() == true) { @@ -218,7 +218,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) // Correct the High Voltage side energy if the hit pointer exists if (HVSH != nullptr) { double rawHVEnergy = HVSH->GetEnergy(); - double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV_e, m_CCEs_HV_h, m_CCEs_LV_e, m_CCEs_LV_h, m_ParamA_HV, m_ParamA_LV, m_ParamB, m_ParamC); + double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV_e, m_CCEs_HV_h, m_ParamA_HV, m_ParamB, m_ParamC); HVSH->SetEnergy(correctedHVEnergy); if (HasExpos() == true) { @@ -369,8 +369,8 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) // Print summary to console if verbose logging is enabled if (g_Verbosity >= c_Info) { - cout << m_XmlTag << "Loaded HV parameters: A=" << m_ParamA_HV - << ", B=" << m_ParamB_HV << ", C=" << m_ParamC_HV << endl; + cout << m_XmlTag << "Loaded parameters: A=" << m_ParamA_HV << ", " << m_ParamA_LV + << ", B=" << m_ParamB << ", C=" << m_ParamC << endl; cout << m_XmlTag << "Loaded " << m_Depths.size() << " data points into arrays." << endl; } @@ -380,13 +380,14 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) ///////////////////////////////////////////////////////////////////////////////// -double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double depth_val, double uncorrected_energy, const std::vector& sim_cce_sorted, double paramA, double paramB, double paramC) { +double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double depth_val, double uncorrected_energy, const std::vector& sim_cce_sorted_e, const std::vector& sim_cce_sorted_h, double paramA, double paramB, double paramC) { // Look up the simulation CCE baseline using the interpolate function - double cce_base = Interpolate(depth_val, m_Depths, sim_cce_sorted); + double cce_base_e = Interpolate(depth_val, m_Depths, sim_cce_sorted_e); + double cce_base_h = Interpolate(depth_val, m_Depths, sim_cce_sorted_h); // Evaluate the physical trapping function model using class global popt variables - double expected_centroid_scaled = paramA * (1.0 - paramB * (1.0 - cce_base)) * (1.0 - paramC * (1.0 - cce_base)); + double expected_centroid_scaled = paramA * (1.0 - paramB * (1.0 - cce_base_e)) * (1.0 - paramC * (1.0 - cce_base_h)); // Prevent division-by-zero or non-physical negative values if (expected_centroid_scaled <= 0.0) { From 30799b837e063592a51e6119bd697aeed997855d Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:28:28 -0700 Subject: [PATCH 41/61] updated dummy trapping parameter file --- .../dummy_trapping_params_singledetector.csv | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 resource/dee/dummy_trapping_params_singledetector.csv diff --git a/resource/dee/dummy_trapping_params_singledetector.csv b/resource/dee/dummy_trapping_params_singledetector.csv new file mode 100644 index 00000000..fffa7074 --- /dev/null +++ b/resource/dee/dummy_trapping_params_singledetector.csv @@ -0,0 +1,153 @@ +1.0009264205609762,1.288689028046797,0.3010529785474152,1.00084829470918,1.288689028046797,0.3010529785474152 +z_depth_mm,e_CCE_HV,h_CCE_HV,e_CCE_LV,h_CCE_LV +-7.5,0.9960754005722672,1.0,0.9995680702824706,1.0 +-7.4,0.9961283655288202,1.0,0.9995997923338564,0.9999868765995326 +-7.3,0.9961799143100644,1.0,0.9996279267722878,0.9999704487457096 +-7.2,0.9962307077978106,1.0,0.999652945652101,0.999951566155109 +-7.1,0.9962799906985604,1.0,0.9996737160428892,0.9999320226738372 +-7.0,0.9963278574240018,1.0,0.9996934479141384,0.9999112518241762 +-6.9,0.9963751576793192,1.0,0.9997102530485034,0.9998898200838444 +-6.8,0.9964219858762003,0.999999905589124,0.9997259252524616,0.9998655559549224 +-6.7,0.996467775544522,0.999999905589124,0.9997390483630052,0.9998428024332484 +-6.6,0.9965127155076576,0.999999905589124,0.9997533988148228,0.9998179718266084 +-6.5,0.996555200766925,0.9999994335347432,0.9997637840102168,0.9997949350660752 +-6.4,0.9965989133781268,0.9999994335347432,0.9997751133142831,0.9997692547428584 +-6.3,0.9966405489322088,0.9999993391238672,0.999784932044474,0.9997448962009834 +-6.2,0.9966822788979778,0.9999991503021148,0.9997933346116564,0.9997195935295784 +-6.1,0.9967226871001252,0.9999991503021148,0.9998014539462374,0.9996941020322672 +-6.0,0.9967628120672112,0.9999990558912386,0.9998102341568889,0.99966936583858 +-5.9,0.9968020873291114,0.999997167673716,0.9998177870262664,0.9996436855153632 +-5.8,0.9968404184741392,0.999997167673716,0.9998235460891668,0.999618099605099 +-5.7,0.9968790328542289,0.999997167673716,0.9998298716172704,0.9995930801725528 +-5.6,0.9969165142940712,0.99999707326284,0.9998377077192496,0.999567588675242 +-5.5,0.996954184557288,0.99999707326284,0.999842239440876,0.9995420027649778 +-5.4,0.996991477173756,0.9999966012084592,0.999848187325511,0.9995169833324316 +-5.3,0.9970278256733512,0.999996506797583,0.9998520581710671,0.9994913974221676 +-5.2,0.9970642685846338,0.9999963179758308,0.9998577228231004,0.9994659059248566 +-5.1,0.997099484143982,0.9999962235649548,0.9998614992577888,0.9994411697311696 +-5.0,0.997133944409832,0.999994240936556,0.9998669750880878,0.9994155838209052 +-4.9,0.9971688767341186,0.999994240936556,0.9998706571119091,0.9993901867365474 +-4.8,0.9972029593532196,0.9999941465256798,0.9998763217639424,0.9993659226076254 +-4.7,0.9972367587372588,0.9999936744712992,0.9998783988030212,0.9993401478714552 +-4.6,0.99727084135636,0.9999936744712992,0.9998830249355152,0.9993145619611912 +-4.5,0.99730322456509,0.9999933912386708,0.999886046083266,0.9992912419617992 +-4.4,0.9973361742439442,0.9999932968277946,0.9998896336962204,0.9992652783997232 +-4.3,0.9973690295111108,0.999991408610272,0.9998926548439714,0.99924129750966 +-4.2,0.9974000909562196,0.999991408610272,0.9998956759917224,0.9992161836641612 +-4.1,0.9974331350467608,0.9999913141993956,0.9998986971394734,0.999191069818662 +-4.0,0.997464385315244,0.9999908421450152,0.999902001519826,0.999167938645176 +-3.9,0.9974948802902291,0.9999905589123866,0.99990492825671,0.999142447147865 +-3.8,0.9975268858522104,0.9999905589123866,0.9999059667762494,0.999118843909614 +-3.7,0.9975576640622574,0.9999904645015104,0.999908799102266,0.999093918890021 +-3.6,0.9975877813904936,0.9999903700906344,0.9999116314282824,0.999069843587005 +-3.5,0.997617332248606,0.9999898980362538,0.9999145581651664,0.999045296219224 +-3.4,0.997646977518406,0.9999896148036254,0.9999155022738384,0.9990207488514428 +-3.3,0.997677566905078,0.9999896148036254,0.9999183345998552,0.9989975232650038 +-3.2,0.9977074009982526,0.9999876321752268,0.9999211669258716,0.9989727870713168 +-3.1,0.9977362909745544,0.9999876321752268,0.9999239992518882,0.99894993913669 +-3.0,0.9977654641859178,0.9999870657099698,0.999924754538826,0.9989252029430028 +-2.9,0.9977938821037832,0.9999867824773414,0.9999273036322408,0.998902543834282 +-2.8,0.997822394433336,0.9999867824773414,0.9999299471365232,0.998878090879454 +-2.7,0.997850717939514,0.9999847054380664,0.9999326850516724,0.9988551485318738 +-2.6,0.997878947034005,0.9999841389728096,0.9999335347494774,0.9988315452936228 +-2.5,0.997907176128496,0.9999838557401812,0.9999343844472824,0.99880850853309 +-2.4,0.9979341778710524,0.9999838557401812,0.9999371223624318,0.998785377359604 +-2.3,0.9979613684369836,0.9999818731117824,0.9999394826341124,0.9987617741213528 +-2.2,0.9979886534146016,0.999981401057402,0.999941087618855,0.998739775903303 +-2.1,0.9980156551571582,0.9999811178247736,0.9999429758361996,0.998715606187334 +-2.0,0.9980431289581512,0.9999810234138974,0.9999434478905356,0.9986931359045192 +-1.9,0.9980701307007076,0.9999809290030212,0.9999459025730832,0.9986692494274092 +-1.8,0.9980973212666384,0.9999804569486404,0.9999468466817554,0.9986469679705 +-1.7,0.9981228124221988,0.999980079305136,0.9999491125425686,0.9986243088617792 +-1.6,0.9981487756361956,0.9999781910876132,0.9999516616359836,0.9986010832753404 +-1.5,0.9981753053203158,0.9999780966767372,0.9999525113337884,0.9985788962313844 +-1.4,0.9982020238278104,0.9999774358006044,0.9999527945663902,0.9985551985801804 +-1.3,0.998226476454811,0.999977246978852,0.9999534554424608,0.9985332947750832 +-1.2,0.9982527229038692,0.9999751699395772,0.9999560989467428,0.9985111077311274 +-1.1,0.9982785917061788,0.9999746034743202,0.9999563821793446,0.9984875989058294 +-1.0,0.9983034219799284,0.999974320241692,0.9999590256836268,0.9984655062748266 +-0.9,0.9983288187238014,0.9999724320241692,0.9999611027227056,0.9984432248179176 +-0.8,0.9983543098793618,0.9999718655589124,0.9999618580096432,0.9984207545351028 +-0.7,0.9983788569180494,0.999971487915408,0.9999620468313778,0.9983985674911467 +-0.6,0.9984038760151736,0.999971487915408,0.9999628021183156,0.9983752474917548 +-0.5,0.9984295559941084,0.9999709214501512,0.99996469033566,0.9983531548607518 +-0.4,0.9984528756808618,0.9999705438066464,0.9999656344443322,0.9983317231204198 +-0.3,0.998477989189673,0.9999686555891238,0.9999658232660666,0.9983083087080749 +-0.2,0.9985017809348627,0.9999680891238673,0.9999679947160126,0.998286593728884 +-0.1,0.9985266112086122,0.9999677114803625,0.999968655592083,0.9982652564015052 +0.0,0.9985504029538018,0.9999657288519638,0.9999706382202947,0.9982417475762072 +0.1,0.9985743835223662,0.9999651623867069,0.9999712990963652,0.9982202214229224 +0.2,0.9985982696792428,0.9999638406344412,0.9999714879180998,0.9981987896825903 +0.3,0.9986223446594944,0.9999628021148036,0.9999717711507012,0.9981756585091044 +0.4,0.9986454755228732,0.9999620468277944,0.9999723376159048,0.9981542267687724 +0.5,0.9986693616797502,0.9999619524169184,0.999973376135444,0.9981327950284404 +0.6,0.9986927757781908,0.9999613859516616,0.999974603476718,0.9981107968103904 +0.7,0.9987164731116932,0.999960158610272,0.9999751699419211,0.9980885153534818 +0.8,0.9987380933880756,0.9999589312688822,0.9999753587636556,0.9980668947872436 +0.9,0.9987626404267635,0.9999582703927492,0.9999774358027346,0.9980461239375829 +1.0,0.998784921584957,0.9999561933534744,0.999978002267938,0.998022709525238 +1.1,0.9988089965652084,0.9999553436555892,0.9999790407874772,0.998001561023765 +1.2,0.9988307112532784,0.9999533610271902,0.9999802681287512,0.9979806013481982 +1.3,0.9988522371179738,0.9999525113293052,0.9999808345939544,0.9979586975431012 +1.4,0.9988764065099124,0.9999524169184292,0.999981023415689,0.9979365104991452 +1.5,0.9988983100213568,0.99995166163142,0.999981117826556,0.9979156452365314 +1.6,0.9989203079444886,0.999949584592145,0.9999814010591578,0.9978946855609646 +1.7,0.9989429667494312,0.999948829305136,0.999981967524361,0.9978725929299616 +1.8,0.9989647758491884,0.9999466578549848,0.999983666919971,0.9978508779507708 +1.9,0.998986018478822,0.9999458081570995,0.99998404456344,0.9978296350363448 +2.0,0.999009243753888,0.999943825528701,0.9999846110286432,0.9978090530125898 +2.1,0.9990302975601472,0.9999429758308158,0.9999847998503776,0.9977862050779628 +2.2,0.9990513513664064,0.9999424093655588,0.9999856495481826,0.997765434228302 +2.3,0.999074104583036,0.9999401435045318,0.9999868768894564,0.9977440969009232 +2.4,0.9990952528009824,0.9999394826283988,0.9999874433546598,0.9977237037030744 +2.5,0.9991166842539904,0.9999372167673716,0.9999876321763944,0.9977020831368364 +2.6,0.9991369827667516,0.9999363670694864,0.9999877265872616,0.9976801793317396 +2.7,0.9991602080418176,0.9999338179758308,0.9999896148046058,0.9976594084820788 +2.8,0.9991806009662658,0.9999334403323265,0.9999898036263404,0.9976386376324176 +2.9,0.999201277125776,0.9999325906344412,0.9999902756806764,0.997617772369804 +3.0,0.9992220476969732,0.9999306080060424,0.9999904645024108,0.997595207674036 +3.1,0.9992421573863596,0.9999296638972812,0.999990558913278,0.9975750977150462 +3.2,0.999265099426364,0.999926831570997,0.999990558913278,0.9975539492135732 +3.3,0.9992851147040632,0.999924848942598,0.9999907477350124,0.9975335560157244 +3.4,0.9993056020401988,0.999923999244713,0.9999912197893484,0.9975122186883454 +3.5,0.9993258061412724,0.9999231495468278,0.9999913142002156,0.9974904092962016 +3.6,0.9993458214189718,0.9999208836858008,0.999991408611083,0.9974698272724468 +3.7,0.9993659311083584,0.9999185234138972,0.9999915030219504,0.9974491508357388 +3.8,0.999387551384741,0.9999172960725076,0.9999933912392946,0.9974290408767488 +3.9,0.9994081331325636,0.999914746978852,0.9999935800610292,0.9974076091364172 +4.0,0.9994276763518268,0.9999143693353476,0.9999935800610292,0.997385799744273 +4.1,0.9994475972178388,0.9999116314199396,0.9999941465262324,0.9973654065464244 +4.2,0.9994672348487889,0.9999106873111784,0.9999941465262324,0.9973447301097164 +4.3,0.9994872501264882,0.9999078549848942,0.9999943353479668,0.9973246201507264 +4.4,0.999506415699002,0.9999052114803626,0.9999943353479668,0.9973034716492536 +4.5,0.9995258645065777,0.9999043617824774,0.9999962235653111,0.9972815678441568 +4.6,0.9995450300790916,0.9999015294561934,0.9999963179761784,0.997261741124026 +4.7,0.999564101239918,0.9998989803625378,0.9999964123870456,0.997241159100271 +4.8,0.9995831724007448,0.999896336858006,0.9999965067979129,0.9972206714894692 +4.9,0.9996022435615716,0.9998952983383684,0.999996978852249,0.9972009391822914 +5.0,0.9996211258990236,0.9998923716012084,0.999996978852249,0.9971795074419594 +5.1,0.9996401026481628,0.9998890672205438,0.999996978852249,0.9971578868757216 +5.2,0.999658984985615,0.9998860460725076,0.9999971676739834,0.9971380601555908 +5.3,0.9996773952646308,0.999885101963746,0.9999971676739834,0.9971175725447888 +5.4,0.9996957111319592,0.9998821752265862,0.9999981117826556,0.997096990521034 +5.5,0.999714121410975,0.9998773602719034,0.9999990558913278,0.997077258213856 +5.6,0.9997316819848056,0.9998757552870092,0.999999150302195,0.9970560152994304 +5.7,0.9997500922638216,0.9998726397280968,0.9999992447130622,0.9970343947331924 +5.8,0.9997674640142772,0.9998674471299092,0.9999992447130622,0.9970146624260146 +5.9,0.9997830419426754,0.9998658421450152,0.9999993391239296,0.9969942692281656 +6.0,0.9998008857515676,0.9998605551359516,0.9999993391239296,0.99697397044327 +6.1,0.9998173133851508,0.9998573451661632,0.9999998111782656,0.996954049310186 +6.2,0.9998351571940431,0.999853663141994,0.9999998111782656,0.9969334672864312 +6.3,0.9998495077705069,0.999847998489426,0.9999998111782656,0.9969120355460992 +6.4,0.9998661242274646,0.9998442220543808,0.9999998111782656,0.9968916423482505 +6.5,0.9998827406844224,0.9998384629909366,0.9999999055891328,0.9968720044540256 +6.6,0.9998965247907624,0.999834592145015,1.0,0.9968516112561766 +6.7,0.9999117250724114,0.999828077794562,1.0,0.9968314068842338 +6.8,0.9999250371203152,0.9998212802114804,1.0,0.996811391338197 +6.9,0.9999396709318406,0.9998156155589124,1.0,0.996791186966254 +7.0,0.9999515668044354,0.9998088179758308,1.0,0.996769755225922 +7.1,0.9999628962069066,0.9998000377643504,1.0,0.9967493620280732 +7.2,0.9999747920795016,0.9997908799093655,1.0,0.9967296297208956 +7.3,0.9999852717767874,0.99978125,1.0,0.9967094253489528 +7.4,0.9999932967702044,0.9997709592145017,1.0,0.9966895042158688 +7.5,1.0,0.9997587802114803,1.0,0.996669488669832 From f5426c50eb9ce34c3cd2fd0736ea9b9f93b2099f Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Sun, 9 Aug 2026 19:34:46 -0700 Subject: [PATCH 42/61] added gaurd against nullptr for domminant strip energies --- apps/TrappingCorrectionAm241.cxx | 2 +- apps/TrappingCorrectionCs137.cxx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index e650d358..df137bf4 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -479,7 +479,7 @@ bool TrappingCorrectionAm241::Analyze() MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); - if ((LVSH->HasCalibratedTiming()==true) && (HVSH->HasCalibratedTiming()==true)) { + if ((LVSH->HasCalibratedTiming()==true) && (HVSH->HasCalibratedTiming()==true)&& (LVSH != nullptr) && (HVSH != nullptr)) { double CTD = LVSH->GetTiming() - HVSH->GetTiming(); diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index ab116377..8babb609 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -67,8 +67,7 @@ using namespace std; double g_MinCTD = -250; double g_MaxCTD = 250; -int g_MinCounts = 400; - +int g_MinCounts = 1200; int g_HVStrips = 64; int g_LVStrips = 64; @@ -494,7 +493,7 @@ bool TrappingCorrectionCs137::Analyze() MStripHit* HVSH = GetDominantStrip(HVStrips, HVEnergyFraction); MStripHit* LVSH = GetDominantStrip(LVStrips, LVEnergyFraction); - if ((LVSH->HasCalibratedTiming() == true) && (HVSH->HasCalibratedTiming() == true)) { + if ((LVSH->HasCalibratedTiming() == true) && (HVSH->HasCalibratedTiming() == true) && (LVSH != nullptr) && (HVSH != nullptr)) { double CTD = LVSH->GetTiming() - HVSH->GetTiming(); int CTDBin = GetCTDBin(CTD); From 2f7b072ff2615e1a09edb4b2d30ee35bdbcc64df Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Sun, 9 Aug 2026 19:41:28 -0700 Subject: [PATCH 43/61] updated trapping param file to show depth in cm --- ...mmy_trapping_parameters_singledetector.csv | 306 +++++++++--------- .../dummy_trapping_params_singledetector.csv | 153 --------- 2 files changed, 153 insertions(+), 306 deletions(-) delete mode 100644 resource/dee/dummy_trapping_params_singledetector.csv diff --git a/resource/dee/dummy_trapping_parameters_singledetector.csv b/resource/dee/dummy_trapping_parameters_singledetector.csv index 4d4b330f..4c11419f 100644 --- a/resource/dee/dummy_trapping_parameters_singledetector.csv +++ b/resource/dee/dummy_trapping_parameters_singledetector.csv @@ -1,153 +1,153 @@ -1.0004614708764512,26.97750073638292,-27.302528941860835,1.0001434796999964,12.90339574367257,-13.320294113438992 -z_depth_mm,CCE_HV,CCE_LV --7.5,0.9960754005722672,0.9995680702824706 --7.4,0.9961283655288202,0.9995866741854744 --7.3,0.9961799143100644,0.9995983865132282 --7.2,0.9962307077978106,0.9996045286163866 --7.1,0.9962799906985604,0.9996057608966376 --7.0,0.9963278574240018,0.9996047269442528 --6.9,0.9963751576793192,0.9996001050566428 --6.8,0.9964218918031278,0.999591518055102 --6.7,0.9964676814671262,0.9995818918172162 --6.6,0.9965126214260192,0.9995714155297944 --6.5,0.9965546362530274,0.9995587675159084 --6.4,0.9965983488394674,0.9995444199486776 --6.3,0.9966398902762568,0.9995298831101098 --6.2,0.9966814320191532,0.9995129860915468 --6.1,0.996721840186966,0.999495616713339 --6.0,0.9967618710147071,0.9994796627385392 --5.9,0.9967992640603592,0.9994615374667511 --5.8,0.9968375950968208,0.9994417130820838 --5.7,0.996876209367542,0.9994230210184356 --5.6,0.9969135965814632,0.9994053665715116 --5.5,0.9969512667344292,0.9993843144597538 --5.4,0.996988088607557,0.9993652439859948 --5.3,0.9970243428533409,0.9993435308368304 --5.2,0.9970605973698986,0.999323704737354 --5.1,0.9970957186625464,0.9993027463873654 --5.0,0.997128201852184,0.999282636650904 --4.9,0.997163133975293,0.9992609227234652 --4.8,0.9971971222513047,0.9992423227931412 --4.7,0.99723045068752,0.9992186269132852 --4.6,0.9972645330910304,0.999197667075865 --4.5,0.997296633626106,0.9991773688108196 --4.4,0.9973294889278216,0.9991549931844508 --4.3,0.9973604607250754,0.9991340337966688 --4.2,0.9973915219033234,0.9991119414267454 --4.1,0.9974244715414337,0.9990898489050768 --4.0,0.9974552506810508,0.9990700217057504 --3.9,0.9974854628536703,0.9990474569336196 --3.8,0.9975174681134844,0.9990248935438112 --3.7,0.9975481518526584,0.9990028006276976 --3.6,0.9975781747105746,0.9989815572118812 --3.5,0.9976072543544832,0.9989599359560328 --3.4,0.9976366167586318,0.9989363338697768 --3.3,0.9976672058276272,0.9989159397325226 --3.2,0.997695061527942,0.9988940349755416 --3.1,0.9977239511469376,0.9988740181939894 --3.0,0.997752558798022,0.9988500383554292 --2.9,0.997780693740538,0.9988299272475998 --2.8,0.9978092056932284,0.9988081166089234 --2.7,0.997835456249908,0.9987879106491638 --2.6,0.9978631196488936,0.9987651577047352 --2.5,0.9978910656557696,0.9987429711607436 --2.4,0.9979180669624028,0.998722576094638 --2.3,0.9979432785028124,0.9987013316896338 --2.2,0.9979700918809232,0.9986809377649604 --2.1,0.9979968104506788,0.9986586552650168 --2.0,0.9980241895067804,0.998636657700976 --1.9,0.9980510965082604,0.998615223990674 --1.8,0.9980778153994272,0.9985938865703976 --1.7,0.998102929122216,0.998573491409772 --1.6,0.9981270070969988,0.9985528125326696 --1.5,0.9981534419639304,0.9985314750514952 --1.4,0.9981795001983076,0.998508061349048 --1.3,0.9982037637866816,0.9984868184846898 --1.2,0.9982279362284424,0.9984672720418092 --1.1,0.9982532388982888,0.9984440470528136 --1.0,0.9982777857893338,0.9984245948332848 --0.9,0.9983012968190556,0.998404388094939 --0.8,0.998326221738846,0.9983826727803112 --0.7,0.998350391055626,0.9983606751019626 --0.6,0.9983754094394036,0.9983381100474218 --0.5,0.9984005231104938,0.9983179033459608 --0.4,0.9984234650599014,0.998297414896014 --0.3,0.998446692485329,0.9982741897906248 --0.2,0.9984699178682128,0.998254643282951 --0.1,0.9984943702625176,0.9982339663680992 -0.0,0.9985161814851206,0.9982124374219222 -0.1,0.9985395955741484,0.9981915716005412 -0.2,0.9985621609993632,0.9981703289569462 -0.3,0.9985851980201632,0.9981474811588664 -0.4,0.9986075737591684,0.9981266154431652 -0.5,0.9986313647242406,0.9981062208760968 -0.6,0.9986542122070716,0.9980854482663012 -0.7,0.99867668285946,0.9980637327576776 -0.8,0.9986970764818612,0.9980423011850016 -0.9,0.9987209624540418,0.9980236038279624 -1.0,0.998741168166942,0.998000755289082 -1.1,0.9987643934066572,0.9979806436969496 -1.2,0.9987841268148946,0.9979609093234636 -1.3,0.9988048029530124,0.9979395712594462 -1.4,0.998828876892382,0.9979175730728168 -1.5,0.9988500249066732,0.9978968024202356 -1.6,0.998869946969749,0.9978761257767412 -1.7,0.998891850143693,0.9978545988167388 -1.8,0.99891148892525,0.997834579972524 -1.9,0.9989318815854488,0.9978137142289052 -2.0,0.9989531249377974,0.9977936977576536 -2.1,0.9989733286874388,0.9977710385783546 -2.2,0.998993815365242,0.9977511158435132 -2.3,0.9990143035084226,0.9977310033948454 -2.4,0.9990347901823036,0.9977111756403796 -2.5,0.99905395647878,0.9976897437334612 -2.6,0.9990734047525536,0.9976679343911176 -2.7,0.9990940815967804,0.9976490475941848 -2.8,0.9991140958375196,0.997628465336091 -2.9,0.9991339216016192,0.9976080712160224 -3.0,0.999152709686677,0.9975856951073382 -3.1,0.9991718745873368,0.997565679522037 -3.2,0.9991919847688816,0.9975445312202288 -3.3,0.9992100173710472,0.9975243265709302 -3.4,0.9992296540596812,0.9975034603209378 -3.5,0.999249007500204,0.9974817452942196 -3.6,0.9992667568609706,0.9974612576212276 -3.7,0.9992845061840244,0.9974406755321984 -3.8,0.9993048981091543,0.9974224491068971 -3.9,0.9993229305698542,0.9974012058404372 -4.0,0.9993420946956286,0.9973793965883082 -4.1,0.9993592774528276,0.9973595684941804 -4.2,0.9993779697426552,0.9973388921785016 -4.3,0.9993951523587272,0.9973189706537894 -4.4,0.9994116739654898,0.9972978222721152 -4.5,0.9994302716345286,0.9972778016754492 -4.6,0.9994466043364204,0.9972580691825388 -4.7,0.9994631256367906,0.99723758138497 -4.8,0.9994795524684096,0.997217187996138 -4.9,0.9994975835457,0.9971979264909168 -5.0,0.999513538277845,0.9971764948153332 -5.1,0.9995292097931202,0.9971548743144144 -5.2,0.9995450699181228,0.9971352359355208 -5.3,0.9995625342950276,0.9971147483827466 -5.4,0.9995779222113124,0.9970951077852024 -5.5,0.9995915167429508,0.9970763168645695 -5.6,0.9996074706089096,0.9970551681031228 -5.7,0.9996227638202354,0.9970336416861376 -5.8,0.9996349419674988,0.9970139093938633 -5.9,0.999648913194318,0.9969936103385107 -6.0,0.9996614686529788,0.9969733115670298 -6.1,0.9996746846124428,0.9969538610635932 -6.2,0.9996888444586154,0.9969332790437246 -6.3,0.9996975291349788,0.9969118473074394 -6.4,0.999710367136738,0.9968914541134416 -6.5,0.999721222617078,0.9968719103384752 -6.6,0.99973113405139,0.9968516112561766 -6.7,0.9997398180433936,0.9968314068842338 -6.8,0.9997463307291454,0.996811391338197 -6.9,0.9997552976144944,0.996791186966254 -7.0,0.9997603940398226,0.996769755225922 -7.1,0.9997629413906144,0.9967493620280732 -7.2,0.9997656772603496,0.9967296297208956 -7.3,0.9997665249985864,0.9967094253489528 -7.4,0.9997642575200192,0.9966895042158688 -7.5,0.9997587802114803,0.996669488669832 +1.0009264205609762,1.00084829470918,1.288689028046797,0.3010529785474152 +z_depth_cm,e_CCE_HV,h_CCE_HV,e_CCE_LV,h_CCE_LV +-0.75,0.9960754005722672,1.0,0.9995680702824706,1.0 +-0.74,0.9961283655288202,1.0,0.9995997923338564,0.9999868765995326 +-0.73,0.9961799143100644,1.0,0.9996279267722878,0.9999704487457096 +-0.72,0.9962307077978106,1.0,0.999652945652101,0.999951566155109 +-0.71,0.9962799906985604,1.0,0.9996737160428892,0.9999320226738372 +-0.7,0.9963278574240018,1.0,0.9996934479141384,0.9999112518241762 +-0.6900000000000001,0.9963751576793192,1.0,0.9997102530485034,0.9998898200838444 +-0.6799999999999999,0.9964219858762003,0.999999905589124,0.9997259252524616,0.9998655559549224 +-0.67,0.996467775544522,0.999999905589124,0.9997390483630052,0.9998428024332484 +-0.6599999999999999,0.9965127155076576,0.999999905589124,0.9997533988148228,0.9998179718266084 +-0.65,0.996555200766925,0.9999994335347432,0.9997637840102168,0.9997949350660752 +-0.64,0.9965989133781268,0.9999994335347432,0.9997751133142831,0.9997692547428584 +-0.63,0.9966405489322088,0.9999993391238672,0.999784932044474,0.9997448962009834 +-0.62,0.9966822788979778,0.9999991503021148,0.9997933346116564,0.9997195935295784 +-0.61,0.9967226871001252,0.9999991503021148,0.9998014539462374,0.9996941020322672 +-0.6,0.9967628120672112,0.9999990558912386,0.9998102341568889,0.99966936583858 +-0.5900000000000001,0.9968020873291114,0.999997167673716,0.9998177870262664,0.9996436855153632 +-0.58,0.9968404184741392,0.999997167673716,0.9998235460891668,0.999618099605099 +-0.5700000000000001,0.9968790328542289,0.999997167673716,0.9998298716172704,0.9995930801725528 +-0.5599999999999999,0.9969165142940712,0.99999707326284,0.9998377077192496,0.999567588675242 +-0.55,0.996954184557288,0.99999707326284,0.999842239440876,0.9995420027649778 +-0.54,0.996991477173756,0.9999966012084592,0.999848187325511,0.9995169833324316 +-0.53,0.9970278256733512,0.999996506797583,0.9998520581710671,0.9994913974221676 +-0.52,0.9970642685846338,0.9999963179758308,0.9998577228231004,0.9994659059248566 +-0.51,0.997099484143982,0.9999962235649548,0.9998614992577888,0.9994411697311696 +-0.5,0.997133944409832,0.999994240936556,0.9998669750880878,0.9994155838209052 +-0.49000000000000005,0.9971688767341186,0.999994240936556,0.9998706571119091,0.9993901867365474 +-0.48,0.9972029593532196,0.9999941465256798,0.9998763217639424,0.9993659226076254 +-0.47000000000000003,0.9972367587372588,0.9999936744712992,0.9998783988030212,0.9993401478714552 +-0.45999999999999996,0.99727084135636,0.9999936744712992,0.9998830249355152,0.9993145619611912 +-0.45,0.99730322456509,0.9999933912386708,0.999886046083266,0.9992912419617992 +-0.44000000000000006,0.9973361742439442,0.9999932968277946,0.9998896336962204,0.9992652783997232 +-0.43,0.9973690295111108,0.999991408610272,0.9998926548439714,0.99924129750966 +-0.42000000000000004,0.9974000909562196,0.999991408610272,0.9998956759917224,0.9992161836641612 +-0.41,0.9974331350467608,0.9999913141993956,0.9998986971394734,0.999191069818662 +-0.4,0.997464385315244,0.9999908421450152,0.999902001519826,0.999167938645176 +-0.39,0.9974948802902291,0.9999905589123866,0.99990492825671,0.999142447147865 +-0.38,0.9975268858522104,0.9999905589123866,0.9999059667762494,0.999118843909614 +-0.37,0.9975576640622574,0.9999904645015104,0.999908799102266,0.999093918890021 +-0.36,0.9975877813904936,0.9999903700906344,0.9999116314282824,0.999069843587005 +-0.35,0.997617332248606,0.9999898980362538,0.9999145581651664,0.999045296219224 +-0.33999999999999997,0.997646977518406,0.9999896148036254,0.9999155022738384,0.9990207488514428 +-0.32999999999999996,0.997677566905078,0.9999896148036254,0.9999183345998552,0.9989975232650038 +-0.32,0.9977074009982526,0.9999876321752268,0.9999211669258716,0.9989727870713168 +-0.31,0.9977362909745544,0.9999876321752268,0.9999239992518882,0.99894993913669 +-0.3,0.9977654641859178,0.9999870657099698,0.999924754538826,0.9989252029430028 +-0.29,0.9977938821037832,0.9999867824773414,0.9999273036322408,0.998902543834282 +-0.27999999999999997,0.997822394433336,0.9999867824773414,0.9999299471365232,0.998878090879454 +-0.27,0.997850717939514,0.9999847054380664,0.9999326850516724,0.9988551485318738 +-0.26,0.997878947034005,0.9999841389728096,0.9999335347494774,0.9988315452936228 +-0.25,0.997907176128496,0.9999838557401812,0.9999343844472824,0.99880850853309 +-0.24,0.9979341778710524,0.9999838557401812,0.9999371223624318,0.998785377359604 +-0.22999999999999998,0.9979613684369836,0.9999818731117824,0.9999394826341124,0.9987617741213528 +-0.22000000000000003,0.9979886534146016,0.999981401057402,0.999941087618855,0.998739775903303 +-0.21000000000000002,0.9980156551571582,0.9999811178247736,0.9999429758361996,0.998715606187334 +-0.2,0.9980431289581512,0.9999810234138974,0.9999434478905356,0.9986931359045192 +-0.19,0.9980701307007076,0.9999809290030212,0.9999459025730832,0.9986692494274092 +-0.18,0.9980973212666384,0.9999804569486404,0.9999468466817554,0.9986469679705 +-0.16999999999999998,0.9981228124221988,0.999980079305136,0.9999491125425686,0.9986243088617792 +-0.16,0.9981487756361956,0.9999781910876132,0.9999516616359836,0.9986010832753404 +-0.15,0.9981753053203158,0.9999780966767372,0.9999525113337884,0.9985788962313844 +-0.13999999999999999,0.9982020238278104,0.9999774358006044,0.9999527945663902,0.9985551985801804 +-0.13,0.998226476454811,0.999977246978852,0.9999534554424608,0.9985332947750832 +-0.12,0.9982527229038692,0.9999751699395772,0.9999560989467428,0.9985111077311274 +-0.11000000000000001,0.9982785917061788,0.9999746034743202,0.9999563821793446,0.9984875989058294 +-0.1,0.9983034219799284,0.999974320241692,0.9999590256836268,0.9984655062748266 +-0.09,0.9983288187238014,0.9999724320241692,0.9999611027227056,0.9984432248179176 +-0.08,0.9983543098793618,0.9999718655589124,0.9999618580096432,0.9984207545351028 +-0.06999999999999999,0.9983788569180494,0.999971487915408,0.9999620468313778,0.9983985674911467 +-0.06,0.9984038760151736,0.999971487915408,0.9999628021183156,0.9983752474917548 +-0.05,0.9984295559941084,0.9999709214501512,0.99996469033566,0.9983531548607518 +-0.04,0.9984528756808618,0.9999705438066464,0.9999656344443322,0.9983317231204198 +-0.03,0.998477989189673,0.9999686555891238,0.9999658232660666,0.9983083087080749 +-0.02,0.9985017809348627,0.9999680891238673,0.9999679947160126,0.998286593728884 +-0.01,0.9985266112086122,0.9999677114803625,0.999968655592083,0.9982652564015052 +0.0,0.9985504029538018,0.9999657288519638,0.9999706382202947,0.9982417475762072 +0.01,0.9985743835223662,0.9999651623867069,0.9999712990963652,0.9982202214229224 +0.02,0.9985982696792428,0.9999638406344412,0.9999714879180998,0.9981987896825903 +0.03,0.9986223446594944,0.9999628021148036,0.9999717711507012,0.9981756585091044 +0.04,0.9986454755228732,0.9999620468277944,0.9999723376159048,0.9981542267687724 +0.05,0.9986693616797502,0.9999619524169184,0.999973376135444,0.9981327950284404 +0.06,0.9986927757781908,0.9999613859516616,0.999974603476718,0.9981107968103904 +0.06999999999999999,0.9987164731116932,0.999960158610272,0.9999751699419211,0.9980885153534818 +0.08,0.9987380933880756,0.9999589312688822,0.9999753587636556,0.9980668947872436 +0.09,0.9987626404267635,0.9999582703927492,0.9999774358027346,0.9980461239375829 +0.1,0.998784921584957,0.9999561933534744,0.999978002267938,0.998022709525238 +0.11000000000000001,0.9988089965652084,0.9999553436555892,0.9999790407874772,0.998001561023765 +0.12,0.9988307112532784,0.9999533610271902,0.9999802681287512,0.9979806013481982 +0.13,0.9988522371179738,0.9999525113293052,0.9999808345939544,0.9979586975431012 +0.13999999999999999,0.9988764065099124,0.9999524169184292,0.999981023415689,0.9979365104991452 +0.15,0.9988983100213568,0.99995166163142,0.999981117826556,0.9979156452365314 +0.16,0.9989203079444886,0.999949584592145,0.9999814010591578,0.9978946855609646 +0.16999999999999998,0.9989429667494312,0.999948829305136,0.999981967524361,0.9978725929299616 +0.18,0.9989647758491884,0.9999466578549848,0.999983666919971,0.9978508779507708 +0.19,0.998986018478822,0.9999458081570995,0.99998404456344,0.9978296350363448 +0.2,0.999009243753888,0.999943825528701,0.9999846110286432,0.9978090530125898 +0.21000000000000002,0.9990302975601472,0.9999429758308158,0.9999847998503776,0.9977862050779628 +0.22000000000000003,0.9990513513664064,0.9999424093655588,0.9999856495481826,0.997765434228302 +0.22999999999999998,0.999074104583036,0.9999401435045318,0.9999868768894564,0.9977440969009232 +0.24,0.9990952528009824,0.9999394826283988,0.9999874433546598,0.9977237037030744 +0.25,0.9991166842539904,0.9999372167673716,0.9999876321763944,0.9977020831368364 +0.26,0.9991369827667516,0.9999363670694864,0.9999877265872616,0.9976801793317396 +0.27,0.9991602080418176,0.9999338179758308,0.9999896148046058,0.9976594084820788 +0.27999999999999997,0.9991806009662658,0.9999334403323265,0.9999898036263404,0.9976386376324176 +0.29,0.999201277125776,0.9999325906344412,0.9999902756806764,0.997617772369804 +0.3,0.9992220476969732,0.9999306080060424,0.9999904645024108,0.997595207674036 +0.31,0.9992421573863596,0.9999296638972812,0.999990558913278,0.9975750977150462 +0.32,0.999265099426364,0.999926831570997,0.999990558913278,0.9975539492135732 +0.32999999999999996,0.9992851147040632,0.999924848942598,0.9999907477350124,0.9975335560157244 +0.33999999999999997,0.9993056020401988,0.999923999244713,0.9999912197893484,0.9975122186883454 +0.35,0.9993258061412724,0.9999231495468278,0.9999913142002156,0.9974904092962016 +0.36,0.9993458214189718,0.9999208836858008,0.999991408611083,0.9974698272724468 +0.37,0.9993659311083584,0.9999185234138972,0.9999915030219504,0.9974491508357388 +0.38,0.999387551384741,0.9999172960725076,0.9999933912392946,0.9974290408767488 +0.39,0.9994081331325636,0.999914746978852,0.9999935800610292,0.9974076091364172 +0.4,0.9994276763518268,0.9999143693353476,0.9999935800610292,0.997385799744273 +0.41,0.9994475972178388,0.9999116314199396,0.9999941465262324,0.9973654065464244 +0.42000000000000004,0.9994672348487889,0.9999106873111784,0.9999941465262324,0.9973447301097164 +0.43,0.9994872501264882,0.9999078549848942,0.9999943353479668,0.9973246201507264 +0.44000000000000006,0.999506415699002,0.9999052114803626,0.9999943353479668,0.9973034716492536 +0.45,0.9995258645065777,0.9999043617824774,0.9999962235653111,0.9972815678441568 +0.45999999999999996,0.9995450300790916,0.9999015294561934,0.9999963179761784,0.997261741124026 +0.47000000000000003,0.999564101239918,0.9998989803625378,0.9999964123870456,0.997241159100271 +0.48,0.9995831724007448,0.999896336858006,0.9999965067979129,0.9972206714894692 +0.49000000000000005,0.9996022435615716,0.9998952983383684,0.999996978852249,0.9972009391822914 +0.5,0.9996211258990236,0.9998923716012084,0.999996978852249,0.9971795074419594 +0.51,0.9996401026481628,0.9998890672205438,0.999996978852249,0.9971578868757216 +0.52,0.999658984985615,0.9998860460725076,0.9999971676739834,0.9971380601555908 +0.53,0.9996773952646308,0.999885101963746,0.9999971676739834,0.9971175725447888 +0.54,0.9996957111319592,0.9998821752265862,0.9999981117826556,0.997096990521034 +0.55,0.999714121410975,0.9998773602719034,0.9999990558913278,0.997077258213856 +0.5599999999999999,0.9997316819848056,0.9998757552870092,0.999999150302195,0.9970560152994304 +0.5700000000000001,0.9997500922638216,0.9998726397280968,0.9999992447130622,0.9970343947331924 +0.58,0.9997674640142772,0.9998674471299092,0.9999992447130622,0.9970146624260146 +0.5900000000000001,0.9997830419426754,0.9998658421450152,0.9999993391239296,0.9969942692281656 +0.6,0.9998008857515676,0.9998605551359516,0.9999993391239296,0.99697397044327 +0.61,0.9998173133851508,0.9998573451661632,0.9999998111782656,0.996954049310186 +0.62,0.9998351571940431,0.999853663141994,0.9999998111782656,0.9969334672864312 +0.63,0.9998495077705069,0.999847998489426,0.9999998111782656,0.9969120355460992 +0.64,0.9998661242274646,0.9998442220543808,0.9999998111782656,0.9968916423482505 +0.65,0.9998827406844224,0.9998384629909366,0.9999999055891328,0.9968720044540256 +0.6599999999999999,0.9998965247907624,0.999834592145015,1.0,0.9968516112561766 +0.67,0.9999117250724114,0.999828077794562,1.0,0.9968314068842338 +0.6799999999999999,0.9999250371203152,0.9998212802114804,1.0,0.996811391338197 +0.6900000000000001,0.9999396709318406,0.9998156155589124,1.0,0.996791186966254 +0.7,0.9999515668044354,0.9998088179758308,1.0,0.996769755225922 +0.71,0.9999628962069066,0.9998000377643504,1.0,0.9967493620280732 +0.72,0.9999747920795016,0.9997908799093655,1.0,0.9967296297208956 +0.73,0.9999852717767874,0.99978125,1.0,0.9967094253489528 +0.74,0.9999932967702044,0.9997709592145017,1.0,0.9966895042158688 +0.75,1.0,0.9997587802114803,1.0,0.996669488669832 diff --git a/resource/dee/dummy_trapping_params_singledetector.csv b/resource/dee/dummy_trapping_params_singledetector.csv deleted file mode 100644 index fffa7074..00000000 --- a/resource/dee/dummy_trapping_params_singledetector.csv +++ /dev/null @@ -1,153 +0,0 @@ -1.0009264205609762,1.288689028046797,0.3010529785474152,1.00084829470918,1.288689028046797,0.3010529785474152 -z_depth_mm,e_CCE_HV,h_CCE_HV,e_CCE_LV,h_CCE_LV --7.5,0.9960754005722672,1.0,0.9995680702824706,1.0 --7.4,0.9961283655288202,1.0,0.9995997923338564,0.9999868765995326 --7.3,0.9961799143100644,1.0,0.9996279267722878,0.9999704487457096 --7.2,0.9962307077978106,1.0,0.999652945652101,0.999951566155109 --7.1,0.9962799906985604,1.0,0.9996737160428892,0.9999320226738372 --7.0,0.9963278574240018,1.0,0.9996934479141384,0.9999112518241762 --6.9,0.9963751576793192,1.0,0.9997102530485034,0.9998898200838444 --6.8,0.9964219858762003,0.999999905589124,0.9997259252524616,0.9998655559549224 --6.7,0.996467775544522,0.999999905589124,0.9997390483630052,0.9998428024332484 --6.6,0.9965127155076576,0.999999905589124,0.9997533988148228,0.9998179718266084 --6.5,0.996555200766925,0.9999994335347432,0.9997637840102168,0.9997949350660752 --6.4,0.9965989133781268,0.9999994335347432,0.9997751133142831,0.9997692547428584 --6.3,0.9966405489322088,0.9999993391238672,0.999784932044474,0.9997448962009834 --6.2,0.9966822788979778,0.9999991503021148,0.9997933346116564,0.9997195935295784 --6.1,0.9967226871001252,0.9999991503021148,0.9998014539462374,0.9996941020322672 --6.0,0.9967628120672112,0.9999990558912386,0.9998102341568889,0.99966936583858 --5.9,0.9968020873291114,0.999997167673716,0.9998177870262664,0.9996436855153632 --5.8,0.9968404184741392,0.999997167673716,0.9998235460891668,0.999618099605099 --5.7,0.9968790328542289,0.999997167673716,0.9998298716172704,0.9995930801725528 --5.6,0.9969165142940712,0.99999707326284,0.9998377077192496,0.999567588675242 --5.5,0.996954184557288,0.99999707326284,0.999842239440876,0.9995420027649778 --5.4,0.996991477173756,0.9999966012084592,0.999848187325511,0.9995169833324316 --5.3,0.9970278256733512,0.999996506797583,0.9998520581710671,0.9994913974221676 --5.2,0.9970642685846338,0.9999963179758308,0.9998577228231004,0.9994659059248566 --5.1,0.997099484143982,0.9999962235649548,0.9998614992577888,0.9994411697311696 --5.0,0.997133944409832,0.999994240936556,0.9998669750880878,0.9994155838209052 --4.9,0.9971688767341186,0.999994240936556,0.9998706571119091,0.9993901867365474 --4.8,0.9972029593532196,0.9999941465256798,0.9998763217639424,0.9993659226076254 --4.7,0.9972367587372588,0.9999936744712992,0.9998783988030212,0.9993401478714552 --4.6,0.99727084135636,0.9999936744712992,0.9998830249355152,0.9993145619611912 --4.5,0.99730322456509,0.9999933912386708,0.999886046083266,0.9992912419617992 --4.4,0.9973361742439442,0.9999932968277946,0.9998896336962204,0.9992652783997232 --4.3,0.9973690295111108,0.999991408610272,0.9998926548439714,0.99924129750966 --4.2,0.9974000909562196,0.999991408610272,0.9998956759917224,0.9992161836641612 --4.1,0.9974331350467608,0.9999913141993956,0.9998986971394734,0.999191069818662 --4.0,0.997464385315244,0.9999908421450152,0.999902001519826,0.999167938645176 --3.9,0.9974948802902291,0.9999905589123866,0.99990492825671,0.999142447147865 --3.8,0.9975268858522104,0.9999905589123866,0.9999059667762494,0.999118843909614 --3.7,0.9975576640622574,0.9999904645015104,0.999908799102266,0.999093918890021 --3.6,0.9975877813904936,0.9999903700906344,0.9999116314282824,0.999069843587005 --3.5,0.997617332248606,0.9999898980362538,0.9999145581651664,0.999045296219224 --3.4,0.997646977518406,0.9999896148036254,0.9999155022738384,0.9990207488514428 --3.3,0.997677566905078,0.9999896148036254,0.9999183345998552,0.9989975232650038 --3.2,0.9977074009982526,0.9999876321752268,0.9999211669258716,0.9989727870713168 --3.1,0.9977362909745544,0.9999876321752268,0.9999239992518882,0.99894993913669 --3.0,0.9977654641859178,0.9999870657099698,0.999924754538826,0.9989252029430028 --2.9,0.9977938821037832,0.9999867824773414,0.9999273036322408,0.998902543834282 --2.8,0.997822394433336,0.9999867824773414,0.9999299471365232,0.998878090879454 --2.7,0.997850717939514,0.9999847054380664,0.9999326850516724,0.9988551485318738 --2.6,0.997878947034005,0.9999841389728096,0.9999335347494774,0.9988315452936228 --2.5,0.997907176128496,0.9999838557401812,0.9999343844472824,0.99880850853309 --2.4,0.9979341778710524,0.9999838557401812,0.9999371223624318,0.998785377359604 --2.3,0.9979613684369836,0.9999818731117824,0.9999394826341124,0.9987617741213528 --2.2,0.9979886534146016,0.999981401057402,0.999941087618855,0.998739775903303 --2.1,0.9980156551571582,0.9999811178247736,0.9999429758361996,0.998715606187334 --2.0,0.9980431289581512,0.9999810234138974,0.9999434478905356,0.9986931359045192 --1.9,0.9980701307007076,0.9999809290030212,0.9999459025730832,0.9986692494274092 --1.8,0.9980973212666384,0.9999804569486404,0.9999468466817554,0.9986469679705 --1.7,0.9981228124221988,0.999980079305136,0.9999491125425686,0.9986243088617792 --1.6,0.9981487756361956,0.9999781910876132,0.9999516616359836,0.9986010832753404 --1.5,0.9981753053203158,0.9999780966767372,0.9999525113337884,0.9985788962313844 --1.4,0.9982020238278104,0.9999774358006044,0.9999527945663902,0.9985551985801804 --1.3,0.998226476454811,0.999977246978852,0.9999534554424608,0.9985332947750832 --1.2,0.9982527229038692,0.9999751699395772,0.9999560989467428,0.9985111077311274 --1.1,0.9982785917061788,0.9999746034743202,0.9999563821793446,0.9984875989058294 --1.0,0.9983034219799284,0.999974320241692,0.9999590256836268,0.9984655062748266 --0.9,0.9983288187238014,0.9999724320241692,0.9999611027227056,0.9984432248179176 --0.8,0.9983543098793618,0.9999718655589124,0.9999618580096432,0.9984207545351028 --0.7,0.9983788569180494,0.999971487915408,0.9999620468313778,0.9983985674911467 --0.6,0.9984038760151736,0.999971487915408,0.9999628021183156,0.9983752474917548 --0.5,0.9984295559941084,0.9999709214501512,0.99996469033566,0.9983531548607518 --0.4,0.9984528756808618,0.9999705438066464,0.9999656344443322,0.9983317231204198 --0.3,0.998477989189673,0.9999686555891238,0.9999658232660666,0.9983083087080749 --0.2,0.9985017809348627,0.9999680891238673,0.9999679947160126,0.998286593728884 --0.1,0.9985266112086122,0.9999677114803625,0.999968655592083,0.9982652564015052 -0.0,0.9985504029538018,0.9999657288519638,0.9999706382202947,0.9982417475762072 -0.1,0.9985743835223662,0.9999651623867069,0.9999712990963652,0.9982202214229224 -0.2,0.9985982696792428,0.9999638406344412,0.9999714879180998,0.9981987896825903 -0.3,0.9986223446594944,0.9999628021148036,0.9999717711507012,0.9981756585091044 -0.4,0.9986454755228732,0.9999620468277944,0.9999723376159048,0.9981542267687724 -0.5,0.9986693616797502,0.9999619524169184,0.999973376135444,0.9981327950284404 -0.6,0.9986927757781908,0.9999613859516616,0.999974603476718,0.9981107968103904 -0.7,0.9987164731116932,0.999960158610272,0.9999751699419211,0.9980885153534818 -0.8,0.9987380933880756,0.9999589312688822,0.9999753587636556,0.9980668947872436 -0.9,0.9987626404267635,0.9999582703927492,0.9999774358027346,0.9980461239375829 -1.0,0.998784921584957,0.9999561933534744,0.999978002267938,0.998022709525238 -1.1,0.9988089965652084,0.9999553436555892,0.9999790407874772,0.998001561023765 -1.2,0.9988307112532784,0.9999533610271902,0.9999802681287512,0.9979806013481982 -1.3,0.9988522371179738,0.9999525113293052,0.9999808345939544,0.9979586975431012 -1.4,0.9988764065099124,0.9999524169184292,0.999981023415689,0.9979365104991452 -1.5,0.9988983100213568,0.99995166163142,0.999981117826556,0.9979156452365314 -1.6,0.9989203079444886,0.999949584592145,0.9999814010591578,0.9978946855609646 -1.7,0.9989429667494312,0.999948829305136,0.999981967524361,0.9978725929299616 -1.8,0.9989647758491884,0.9999466578549848,0.999983666919971,0.9978508779507708 -1.9,0.998986018478822,0.9999458081570995,0.99998404456344,0.9978296350363448 -2.0,0.999009243753888,0.999943825528701,0.9999846110286432,0.9978090530125898 -2.1,0.9990302975601472,0.9999429758308158,0.9999847998503776,0.9977862050779628 -2.2,0.9990513513664064,0.9999424093655588,0.9999856495481826,0.997765434228302 -2.3,0.999074104583036,0.9999401435045318,0.9999868768894564,0.9977440969009232 -2.4,0.9990952528009824,0.9999394826283988,0.9999874433546598,0.9977237037030744 -2.5,0.9991166842539904,0.9999372167673716,0.9999876321763944,0.9977020831368364 -2.6,0.9991369827667516,0.9999363670694864,0.9999877265872616,0.9976801793317396 -2.7,0.9991602080418176,0.9999338179758308,0.9999896148046058,0.9976594084820788 -2.8,0.9991806009662658,0.9999334403323265,0.9999898036263404,0.9976386376324176 -2.9,0.999201277125776,0.9999325906344412,0.9999902756806764,0.997617772369804 -3.0,0.9992220476969732,0.9999306080060424,0.9999904645024108,0.997595207674036 -3.1,0.9992421573863596,0.9999296638972812,0.999990558913278,0.9975750977150462 -3.2,0.999265099426364,0.999926831570997,0.999990558913278,0.9975539492135732 -3.3,0.9992851147040632,0.999924848942598,0.9999907477350124,0.9975335560157244 -3.4,0.9993056020401988,0.999923999244713,0.9999912197893484,0.9975122186883454 -3.5,0.9993258061412724,0.9999231495468278,0.9999913142002156,0.9974904092962016 -3.6,0.9993458214189718,0.9999208836858008,0.999991408611083,0.9974698272724468 -3.7,0.9993659311083584,0.9999185234138972,0.9999915030219504,0.9974491508357388 -3.8,0.999387551384741,0.9999172960725076,0.9999933912392946,0.9974290408767488 -3.9,0.9994081331325636,0.999914746978852,0.9999935800610292,0.9974076091364172 -4.0,0.9994276763518268,0.9999143693353476,0.9999935800610292,0.997385799744273 -4.1,0.9994475972178388,0.9999116314199396,0.9999941465262324,0.9973654065464244 -4.2,0.9994672348487889,0.9999106873111784,0.9999941465262324,0.9973447301097164 -4.3,0.9994872501264882,0.9999078549848942,0.9999943353479668,0.9973246201507264 -4.4,0.999506415699002,0.9999052114803626,0.9999943353479668,0.9973034716492536 -4.5,0.9995258645065777,0.9999043617824774,0.9999962235653111,0.9972815678441568 -4.6,0.9995450300790916,0.9999015294561934,0.9999963179761784,0.997261741124026 -4.7,0.999564101239918,0.9998989803625378,0.9999964123870456,0.997241159100271 -4.8,0.9995831724007448,0.999896336858006,0.9999965067979129,0.9972206714894692 -4.9,0.9996022435615716,0.9998952983383684,0.999996978852249,0.9972009391822914 -5.0,0.9996211258990236,0.9998923716012084,0.999996978852249,0.9971795074419594 -5.1,0.9996401026481628,0.9998890672205438,0.999996978852249,0.9971578868757216 -5.2,0.999658984985615,0.9998860460725076,0.9999971676739834,0.9971380601555908 -5.3,0.9996773952646308,0.999885101963746,0.9999971676739834,0.9971175725447888 -5.4,0.9996957111319592,0.9998821752265862,0.9999981117826556,0.997096990521034 -5.5,0.999714121410975,0.9998773602719034,0.9999990558913278,0.997077258213856 -5.6,0.9997316819848056,0.9998757552870092,0.999999150302195,0.9970560152994304 -5.7,0.9997500922638216,0.9998726397280968,0.9999992447130622,0.9970343947331924 -5.8,0.9997674640142772,0.9998674471299092,0.9999992447130622,0.9970146624260146 -5.9,0.9997830419426754,0.9998658421450152,0.9999993391239296,0.9969942692281656 -6.0,0.9998008857515676,0.9998605551359516,0.9999993391239296,0.99697397044327 -6.1,0.9998173133851508,0.9998573451661632,0.9999998111782656,0.996954049310186 -6.2,0.9998351571940431,0.999853663141994,0.9999998111782656,0.9969334672864312 -6.3,0.9998495077705069,0.999847998489426,0.9999998111782656,0.9969120355460992 -6.4,0.9998661242274646,0.9998442220543808,0.9999998111782656,0.9968916423482505 -6.5,0.9998827406844224,0.9998384629909366,0.9999999055891328,0.9968720044540256 -6.6,0.9998965247907624,0.999834592145015,1.0,0.9968516112561766 -6.7,0.9999117250724114,0.999828077794562,1.0,0.9968314068842338 -6.8,0.9999250371203152,0.9998212802114804,1.0,0.996811391338197 -6.9,0.9999396709318406,0.9998156155589124,1.0,0.996791186966254 -7.0,0.9999515668044354,0.9998088179758308,1.0,0.996769755225922 -7.1,0.9999628962069066,0.9998000377643504,1.0,0.9967493620280732 -7.2,0.9999747920795016,0.9997908799093655,1.0,0.9967296297208956 -7.3,0.9999852717767874,0.99978125,1.0,0.9967094253489528 -7.4,0.9999932967702044,0.9997709592145017,1.0,0.9966895042158688 -7.5,1.0,0.9997587802114803,1.0,0.996669488669832 From cd9e87976d3766c37dea8748aef0ef09f8b85e1e Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Sun, 9 Aug 2026 19:48:09 -0700 Subject: [PATCH 44/61] added local position and corresponding getter/setter --- include/MHit.h | 12 ++++++++++++ src/MHit.cxx | 2 ++ 2 files changed, 14 insertions(+) diff --git a/include/MHit.h b/include/MHit.h index a44ac6b6..75f28518 100644 --- a/include/MHit.h +++ b/include/MHit.h @@ -73,6 +73,14 @@ class MHit //! Return the position resolution of the hit MVector GetPositionResolution() const { return m_PositionResolution; } + // Local Position: + + //! Set the local/raw position of the hit + void SetLocalPosition(const MVector& Position) { m_LocalPosition = Position; } + + //! Return the local/raw position of the hit + MVector GetLocalPosition() const { return m_LocalPosition; } + // Energy: @@ -178,6 +186,10 @@ class MHit //! Position resolution of the hit MVector m_PositionResolution; + + //! Local/raw position resolution of the hit + MVector m_LocalPosition; + //! Energy of the hit double m_Energy; //! Energy resolution of the hit diff --git a/src/MHit.cxx b/src/MHit.cxx index 260352c4..8e4e4cca 100644 --- a/src/MHit.cxx +++ b/src/MHit.cxx @@ -74,6 +74,8 @@ void MHit::Clear() m_Position = g_VectorNotDefined; m_Energy = g_DoubleNotDefined; + m_LocalPosition = g_VectorNotDefined; + m_LVEnergy = g_DoubleNotDefined; m_HVEnergy = g_DoubleNotDefined; From c601dfa3b0620d58becd42296ec085b5ac1135f4 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Sun, 9 Aug 2026 19:52:29 -0700 Subject: [PATCH 45/61] write local position in depth cal and access local pos in trapping correction --- src/MModuleDepthCalibration.cxx | 43 +++++++++++++++++++----- src/MModuleTrappingCorrection.cxx | 56 +++++++++++++++++++++++-------- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/MModuleDepthCalibration.cxx b/src/MModuleDepthCalibration.cxx index adcb9044..3b28d6e2 100644 --- a/src/MModuleDepthCalibration.cxx +++ b/src/MModuleDepthCalibration.cxx @@ -365,11 +365,13 @@ bool MModuleDepthCalibration::AnalyzeEvent(MReadOutAssembly* Event) // Make sure XYZ resolution are correctly mapped to the global coord system. MVector PositionResolution(Xsigma, Ysigma, Zsigma); MVector GlobalResolution = ((m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(PositionResolution)) - (m_Detectors[DetID]->GetSensitiveVolume(0)->GetPositionInWorldVolume(LocalOrigin))).Abs(); - + H->SetPosition(GlobalPosition); H->SetPositionResolution(GlobalResolution); + H->SetLocalPosition(LocalPosition); + } @@ -440,23 +442,45 @@ bool MModuleDepthCalibration::LoadDetectorDimensions(MDGeometryQuest* Geometry) // ie DetID=0 should be the 0th detector in m_Detectors, DetID=1 should the 1st, etc. vector DetList = Geometry->GetDetectorList(); - // Look through the Geometry and get the names and thicknesses of all the detectors. + // Look through the Geometry and get the names and thicknesses of all Strip3D detectors. + vector DetectorNames; + unsigned int DetID = 0; + 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 == true) { DetID = 11; } 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); + MString DetectorName = det->GetName(); + string DetName = DetectorName.GetString(); + + // Check that the DetID agrees with the naming scheme GeD_X + if (DetectorName.BeginsWith("GeD_") == true) { + DetectorName.RemoveAllInPlace("GeD_"); // The number after GeD is the COSI detector ID + if (DetID != DetectorName.ToUnsignedInt()) { + if (g_Verbosity >= c_Error) { + cout << "ERROR in MModuleDepthCalibration::Initialize: Non-matching DetID="<GetName() == "COSI-SMEX-Payload"){ + return false; + } + } + } else if (Geometry->GetName() == "COSI-SMEX-Payload") { + if (g_Verbosity >= c_Error) { + cout << "ERROR in MModuleDepthCalibration::Initialize: COSI-SMEX-Payload expects all Strip3D detectors to follow the name scheme GeD_X"<GetStructuralSize().GetZ()); MDStrip3D* strip = dynamic_cast(det); m_XPitches[DetID] = strip->GetPitchX(); @@ -465,7 +489,7 @@ bool MModuleDepthCalibration::LoadDetectorDimensions(MDGeometryQuest* Geometry) m_NYStrips[DetID] = strip->GetNStripsY(); if (g_Verbosity >= c_Info) { - cout << "Found detector " << det_name << " corresponding to DetID=" << DetID << "." << endl; + cout << "Found detector " << DetName << " 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; @@ -474,9 +498,10 @@ bool MModuleDepthCalibration::LoadDetectorDimensions(MDGeometryQuest* Geometry) } m_DetectorIDs.push_back(DetID); m_Detectors[DetID] = det; + DetID += 1; } else { if (g_Verbosity >= c_Error) { - cout<<"ERROR in MModuleDepthCalibration::Initialize: Found a duplicate detector: "<GetDominantStrip(LVStrips, LVEnergyFraction); MStripHit* HVSH = m_DepthCalibration->GetDominantStrip(HVStrips, HVEnergyFraction); - // Get the position value (assumed from event/hit context H) - double depth_val = H->GetPosition().GetZ(); + // Get the position value in mm(assumed from event/hit context H) + double depth_val = H->GetLocalPosition().GetZ(); // Correct the Low Voltage side energy if the hit pointer exists if (LVSH != nullptr) { double rawLVEnergy = LVSH->GetEnergy(); double correctedLVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawLVEnergy, m_CCEs_LV_e, m_CCEs_LV_h, m_ParamA_LV, m_ParamB, m_ParamC); + LVSH->SetEnergy(correctedLVEnergy); if (HasExpos() == true) { @@ -219,6 +220,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) if (HVSH != nullptr) { double rawHVEnergy = HVSH->GetEnergy(); double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV_e, m_CCEs_HV_h, m_ParamA_HV, m_ParamB, m_ParamC); + HVSH->SetEnergy(correctedHVEnergy); if (HasExpos() == true) { @@ -335,32 +337,57 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) } if (ValidLineCount == 0) { - // Read parameters A, B, and C from the first line - if (Tokens.size() == 6) { + // 1. Read parameters A_HV, A_LV, B, and C from the first line + if (Tokens.size() == 4) { m_ParamA_HV = Tokens[0].ToDouble(); m_ParamA_LV = Tokens[1].ToDouble(); - m_ParamB = Tokens[2].ToDouble(); - m_ParamC = Tokens[3].ToDouble(); + m_ParamB = Tokens[2].ToDouble(); + m_ParamC = Tokens[3].ToDouble(); + + cout << "\n--- Trapping File Sanity Check ---" << endl; + cout << "Loaded Parameters -> A_HV: " << m_ParamA_HV + << " | A_LV: " << m_ParamA_LV + << " | B: " << m_ParamB + << " | C: " << m_ParamC << endl; + ValidLineCount++; } else { - cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B,and C) on the first line." << endl; + cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B, and C) on the first line." << endl; SimCCEFile.Close(); return false; } } else if (ValidLineCount == 1) { - // Skip the second line which is the column header (z_depth_mm,CCE_HV) + // 2. Print column headers line + cout << "Loaded Column Headers: "; + for (size_t i = 0; i < Tokens.size(); ++i) { + cout << Tokens[i] << (i + 1 < Tokens.size() ? " | " : "\n"); + } ValidLineCount++; } else { - // Read the rest of the rows into your depth and CCE HV arrays - if (Tokens.size() == 3) { + // 3. Read the 5 data columns into depth and CCE arrays + if (Tokens.size() == 5) { + // Print the first 3 data rows to terminal for verification + if (ValidLineCount <= 4) { + cout << "Data Row " << (ValidLineCount - 1) << ": "; + for (size_t i = 0; i < Tokens.size(); ++i) { + cout << Tokens[i] << (i + 1 < Tokens.size() ? " | " : "\n"); + } + if (ValidLineCount == 4) { + cout << "-----------------------------------\n" << endl; + } + } + m_Depths.push_back(Tokens[0].ToDouble()); m_CCEs_HV_e.push_back(Tokens[1].ToDouble()); m_CCEs_HV_h.push_back(Tokens[2].ToDouble()); m_CCEs_LV_e.push_back(Tokens[3].ToDouble()); m_CCEs_LV_h.push_back(Tokens[4].ToDouble()); + ValidLineCount++; + } else { + cout << "ERROR in LoadSimCCEFile: Expected 5 columns on line " << (ValidLineCount + 1) << endl; } } } @@ -368,8 +395,8 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) SimCCEFile.Close(); // Print summary to console if verbose logging is enabled - if (g_Verbosity >= c_Info) { - cout << m_XmlTag << "Loaded parameters: A=" << m_ParamA_HV << ", " << m_ParamA_LV + if (g_Verbosity >= 1) { + cout << m_XmlTag << "Loaded parameters: A_HV=" << m_ParamA_HV << ", A_LV=" << m_ParamA_LV << ", B=" << m_ParamB << ", C=" << m_ParamC << endl; cout << m_XmlTag << "Loaded " << m_Depths.size() << " data points into arrays." << endl; } @@ -377,14 +404,15 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) return true; } - ///////////////////////////////////////////////////////////////////////////////// double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double depth_val, double uncorrected_energy, const std::vector& sim_cce_sorted_e, const std::vector& sim_cce_sorted_h, double paramA, double paramB, double paramC) { // Look up the simulation CCE baseline using the interpolate function + double cce_base_e = Interpolate(depth_val, m_Depths, sim_cce_sorted_e); double cce_base_h = Interpolate(depth_val, m_Depths, sim_cce_sorted_h); + // Evaluate the physical trapping function model using class global popt variables double expected_centroid_scaled = paramA * (1.0 - paramB * (1.0 - cce_base_e)) * (1.0 - paramC * (1.0 - cce_base_h)); @@ -403,7 +431,7 @@ double MModuleTrappingCorrection::GetSimBasedCorrectedEnergy(double depth_val, d double MModuleTrappingCorrection::Interpolate(double x, const std::vector& xp, const std::vector& fp) { - // need an interpolation function to get continuour CCE values from the discrete simulation data + // need an interpolation function to get continuous CCE values from the discrete simulation data if (xp.empty()) return 0.0; if (x <= xp.front()) return fp.front(); if (x >= xp.back()) return fp.back(); From 2a10c00114160fd1c1edd5fce821fe42c4db8b76 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:26:58 -0700 Subject: [PATCH 46/61] added HV,LV photopeak fitting and readout at end of anlaysis --- src/MModuleTrappingCorrection.cxx | 127 +++++++++++++++++++----------- 1 file changed, 80 insertions(+), 47 deletions(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 94c8d7e8..d0e7e5f9 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -250,58 +250,63 @@ void MModuleTrappingCorrection::Finalize() return; } - // Locate the histograms dynamically from ROOT's global memory map - TH1D* histLV = (TH1D*) gDirectory->Get("EnergyHistogramLVFinal"); - TH1D* histHV = (TH1D*) gDirectory->Get("EnergyHistogramHVFinal"); + if (g_Verbosity >= c_Info){ + cout << "INFO: Finalizing Trapping Correction Module..." << endl; + } - if (histLV == nullptr) histLV = (TH1D*) gDirectory->Get("m_EnergyHistogramLVFinal"); - if (histHV == nullptr) histHV = (TH1D*) gDirectory->Get("m_EnergyHistogramHVFinal"); + TH1D* histLV = m_ExpoSpectrum->GetEnergyHistogramLVFinal(); + TH1D* histHV = m_ExpoSpectrum->GetEnergyHistogramHVFinal(); - // Perform the photopeak fit and direct calculation for the LV peak + // --- LV side --- if (histLV != nullptr && histLV->GetEntries() > 0) { - // Calculate raw FWHM directly from the histogram + m_DirectFWHM_LV = CalculateDirectFWHM(histLV); TF1* fitFuncLV = GeneratePhotopeakFunction(); fitFuncLV->SetParameter("Amplitude", histLV->GetBinContent(histLV->GetMaximumBin())); histLV->Fit(fitFuncLV, "RQ"); - double mu = fitFuncLV->GetParameter("x0 (Mu)"); - double fwhm_fit = 2.35482 * fitFuncLV->GetParameter("Sigma Gauss"); - - if (g_Verbosity >= c_Info) { - cout << m_XmlTag << " --- LV FINAL SPECTRUM RESULTS ---" << endl; - cout << " Centroid (Mu) : " << mu << " keV" << endl; - cout << " Fitted Gaussian FWHM : " << fwhm_fit << " keV" << endl; - cout << " Direct Histogram FWHM: " << m_DirectFWHM_LV << " keV" << endl; - } + double mu_lv = fitFuncLV->GetParameter("x0 (Mu)"); + double fwhm_fit_lv = 2.35482 * fitFuncLV->GetParameter("Sigma Gauss"); + + + cout << m_XmlTag << " --- LV FINAL SPECTRUM RESULTS ---" << endl; + cout << " Centroid (Mu) : " << mu_lv << " keV" << endl; + cout << " Fitted Gaussian FWHM : " << fwhm_fit_lv << " keV" << endl; + cout << " Direct Histogram FWHM: " << m_DirectFWHM_LV << " keV" << endl; + + delete fitFuncLV; + } else { + cout << "WARNING: histLV is null or has 0 entries." << endl; } - // Perform the photopeak fit and direct calculation for the HV peak + // --- HV side --- if (histHV != nullptr && histHV->GetEntries() > 0) { - // Calculate raw FWHM directly from the histogram + m_DirectFWHM_HV = CalculateDirectFWHM(histHV); TF1* fitFuncHV = GeneratePhotopeakFunction(); fitFuncHV->SetParameter("Amplitude", histHV->GetBinContent(histHV->GetMaximumBin())); histHV->Fit(fitFuncHV, "RQ"); - double mu = fitFuncHV->GetParameter("x0 (Mu)"); - double fwhm_fit = 2.35482 * fitFuncHV->GetParameter("Sigma Gauss"); + double mu_hv = fitFuncHV->GetParameter("x0 (Mu)"); + double fwhm_fit_hv = 2.35482 * fitFuncHV->GetParameter("Sigma Gauss"); - if (g_Verbosity >= c_Info) { - cout << m_XmlTag << " --- HV FINAL SPECTRUM RESULTS ---" << endl; - cout << " Centroid (Mu) : " << mu << " keV" << endl; - cout << " Fitted Gaussian FWHM : " << fwhm_fit << " keV" << endl; - cout << " Direct Histogram FWHM: " << m_DirectFWHM_HV << " keV" << endl; - } + + cout << m_XmlTag << " --- HV FINAL SPECTRUM RESULTS ---" << endl; + cout << " Centroid (Mu) : " << mu_hv << " keV" << endl; + cout << " Fitted Gaussian FWHM : " << fwhm_fit_hv << " keV" << endl; + cout << " Direct Histogram FWHM: " << m_DirectFWHM_HV << " keV" << endl; + + delete fitFuncHV; + } else { + cout << "WARNING: histHV is null or has 0 entries." << endl; } return; } - ///////////////////////////////////////////////////////////////////////////////// @@ -313,7 +318,6 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) return false; } - // Clear existing array data before loading new files m_Depths.clear(); m_CCEs_HV_e.clear(); m_CCEs_HV_h.clear(); @@ -395,7 +399,7 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) SimCCEFile.Close(); // Print summary to console if verbose logging is enabled - if (g_Verbosity >= 1) { + if (g_Verbosity >= c_Info) { cout << m_XmlTag << "Loaded parameters: A_HV=" << m_ParamA_HV << ", A_LV=" << m_ParamA_LV << ", B=" << m_ParamB << ", C=" << m_ParamC << endl; cout << m_XmlTag << "Loaded " << m_Depths.size() << " data points into arrays." << endl; @@ -547,51 +551,80 @@ TF1* MModuleTrappingCorrection::GeneratePhotopeakFunction() //////////////////////////////////////////////////////////////////////////////// - double MModuleTrappingCorrection::CalculateDirectFWHM(TH1D* hist) { if (hist == nullptr || hist->GetEntries() == 0) return 0.0; - // 1. Find the maximum bin and its half-maximum height + //Locate the peak bin int maxBin = hist->GetMaximumBin(); - double halfMax = hist->GetBinContent(maxBin) / 2.0; - if (halfMax <= 0.0) return 0.0; + if (g_Verbosity >= c_Info){ + cout << "INFO: Maximum bin located at: " << maxBin << " with content: " << hist->GetBinContent(maxBin) << endl; + } + + double peakHeight = hist->GetBinContent(maxBin); + if (peakHeight <= 0.0) return 0.0; - // 2. Search LEFT for the half-maximum crossing point - double xLeft = hist->GetBinCenter(1); - for (int b = maxBin; b >= 1; --b) { - if (hist->GetBinContent(b) <= halfMax) { + //Define a local search window (depends on binning you set on the GUI) + // Set the binning in the GUI to 0.1 keV before finalize function is called + const int searchWindowBins = 150; + + int minSearchBin = std::max(1, maxBin - searchWindowBins); + int maxSearchBin = std::min(hist->GetNbinsX(), maxBin + searchWindowBins); + + //Estimate local background level from the window edges + double bgLeft = hist->GetBinContent(minSearchBin); + double bgRight = hist->GetBinContent(maxSearchBin); + double localBG = 0.0; // assume the background is zero for now + //(bgLeft + bgRight) / 2.0; + + // Calculate net peak height above background + double netPeakHeight = peakHeight - localBG; + if (netPeakHeight <= 0.0) return 0.0; + + // Target level is half-maximum relative to local background + double targetHalfMax = localBG + (netPeakHeight / 2.0); + + //Search left within the restricted window + double xLeft = -1.0; + for (int b = maxBin; b >= minSearchBin; --b) { + if (hist->GetBinContent(b) <= targetHalfMax) { double x1 = hist->GetBinCenter(b); double y1 = hist->GetBinContent(b); double x2 = hist->GetBinCenter(b + 1); double y2 = hist->GetBinContent(b + 1); - // Linear interpolation between bins - xLeft = (y2 != y1) ? x1 + (halfMax - y1) * (x2 - x1) / (y2 - y1) : x1; + // Linear interpolation between adjacent bins + xLeft = (y2 != y1) ? x1 + (targetHalfMax - y1) * (x2 - x1) / (y2 - y1) : x1; break; } } - // 3. Search RIGHT for the half-maximum crossing point - double xRight = hist->GetBinCenter(hist->GetNbinsX()); - for (int b = maxBin; b <= hist->GetNbinsX(); ++b) { - if (hist->GetBinContent(b) <= halfMax) { + //Search right within the restricted window + double xRight = -1.0; + for (int b = maxBin; b <= maxSearchBin; ++b) { + if (hist->GetBinContent(b) <= targetHalfMax) { double x1 = hist->GetBinCenter(b - 1); double y1 = hist->GetBinContent(b - 1); double x2 = hist->GetBinCenter(b); double y2 = hist->GetBinContent(b); - // Linear interpolation between bins - xRight = (y2 != y1) ? x1 + (halfMax - y1) * (x2 - x1) / (y2 - y1) : x2; + // Linear interpolation between adjacent bins + xRight = (y2 != y1) ? x1 + (targetHalfMax - y1) * (x2 - x1) / (y2 - y1) : x2; break; } } - // 4. Return total width at half maximum + // Ensure valid crossing points were found on both sides + if (xLeft < 0.0 || xRight < 0.0) { + if (g_Verbosity >= c_Warning) { + cout << "WARNING in CalculateDirectFWHM: Peak did not cross half-maximum inside local window." << endl; + } + return 0.0; + } + return (xRight - xLeft); } - //////////////////////////////////////////////////////////////////////////////// From 3a8b9f71e5b6c57b52c7052bd3ef75f8422c56ca Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:28:43 -0700 Subject: [PATCH 47/61] changed comment from mm to cm --- src/MModuleTrappingCorrection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index d0e7e5f9..2a916a5e 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -201,7 +201,7 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) MStripHit* LVSH = m_DepthCalibration->GetDominantStrip(LVStrips, LVEnergyFraction); MStripHit* HVSH = m_DepthCalibration->GetDominantStrip(HVStrips, HVEnergyFraction); - // Get the position value in mm(assumed from event/hit context H) + // Get the position value in cm(assumed from event/hit context H) double depth_val = H->GetLocalPosition().GetZ(); // Correct the Low Voltage side energy if the hit pointer exists From fb8b087b78a4680ab141fc1ca72a0c759067198c Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Wed, 12 Aug 2026 16:33:41 -0700 Subject: [PATCH 48/61] added getter for expo histogram for outputting photopeak fit params --- include/MGUIExpoPlotSpectrum.h | 4 ++++ src/MGUIExpoTrappingCorrection.cxx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/MGUIExpoPlotSpectrum.h b/include/MGUIExpoPlotSpectrum.h index 80d964d3..6293f508 100644 --- a/include/MGUIExpoPlotSpectrum.h +++ b/include/MGUIExpoPlotSpectrum.h @@ -66,6 +66,9 @@ class MGUIExpoPlotSpectrum : public MGUIExpo //! Update the frame virtual void Update(); + TH1D* GetEnergyHistogramLVFinal() const { return m_EnergyHistogramLVFinal; } + TH1D* GetEnergyHistogramHVFinal() const { return m_EnergyHistogramHVFinal; } + protected: //! Update the histogram range @@ -100,6 +103,7 @@ class MGUIExpoPlotSpectrum : public MGUIExpo TH1D* m_EnergyHistogramHVFinal; TH1D* m_EnergyHistogramNearestNeighborLVFinal; TH1D* m_EnergyHistogramNearestNeighborHVFinal; + // Data buffers (to hold data Initial window opens) std::vector m_DataBufferLVInitial; diff --git a/src/MGUIExpoTrappingCorrection.cxx b/src/MGUIExpoTrappingCorrection.cxx index e5e55b2d..6b9df141 100644 --- a/src/MGUIExpoTrappingCorrection.cxx +++ b/src/MGUIExpoTrappingCorrection.cxx @@ -2,7 +2,7 @@ * MGUIExpoTrappingCorrection.cxx * * - * Copyright (C) by Andreas Zoglauer. + * Copyright (C) by Andreas Zoglauer * All rights reserved. * * From a480b7513aee55faa74f54431e6ef445db6df980 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:05:37 -0700 Subject: [PATCH 49/61] updating trapping correction gui to compare corrected/uncorrected energies --- include/MGUIExpoTrappingCorrection.h | 50 ++++- include/MModuleTrappingCorrection.h | 2 +- src/MGUIExpoTrappingCorrection.cxx | 291 ++++++++++++++++++++------- src/MModuleTrappingCorrection.cxx | 166 ++++++++------- 4 files changed, 341 insertions(+), 168 deletions(-) diff --git a/include/MGUIExpoTrappingCorrection.h b/include/MGUIExpoTrappingCorrection.h index 89ca23d1..225f3be1 100644 --- a/include/MGUIExpoTrappingCorrection.h +++ b/include/MGUIExpoTrappingCorrection.h @@ -28,6 +28,11 @@ #include #include #include +#include +#include +#include +#include +#include // MEGAlib libs: #include "MGlobal.h" @@ -66,8 +71,23 @@ class MGUIExpoTrappingCorrection : public MGUIExpo //! Set the energy histogram parameters void SetEnergyHistogramParameters(int NBins, double Min, double Max); - //! Add data to the energy histogram - void AddEnergy(double Energy); + //! Add data to the uncorrected energy histogram + void AddEnergyInitial(double Energy, bool IsNearestNeighbor, bool IsLV); + + //! Add data to the corrected energy histogram + void AddEnergyFinal(double Energy, bool IsNearestNeighbor, bool IsLV); + + // //! Add data to the energy histogram + // void AddEnergy(double Energy); + + // Callback slot for the Apply button + void OnApply(); + + // Getters for Finalize analysis + TH1D* GetEnergyHistogramLVInitial() const { return m_EnergyLVInitial; } + TH1D* GetEnergyHistogramLVFinal() const { return m_EnergyLVFinal; } + TH1D* GetEnergyHistogramHVInitial() const { return m_EnergyHVInitial; } + TH1D* GetEnergyHistogramHVFinal() const { return m_EnergyHVFinal; } // protected methods: protected: @@ -78,10 +98,28 @@ class MGUIExpoTrappingCorrection : public MGUIExpo // private members: private: - //! Energy canvas - TRootEmbeddedCanvas* m_EnergyCanvas; - //! Energy histogram - TH1D* m_Energy; + // //! Energy canvas + // TRootEmbeddedCanvas* m_EnergyCanvas; + // //! Energy histogram + // TH1D* m_Energy; + + //! Energy Histograms + TH1D* m_EnergyLVInitial; + TH1D* m_EnergyLVFinal; + TH1D* m_EnergyHVInitial; + TH1D* m_EnergyHVFinal; + + //! Canvases & Display elements + TRootEmbeddedCanvas* m_CanvasLV; + TRootEmbeddedCanvas* m_CanvasHV; + TLegend* m_LegendLV; + TLegend* m_LegendHV; + + //! Interactive Control Widgets + TGNumberEntry* m_EntryNBins; + TGNumberEntry* m_EntryMinEnergy; + TGNumberEntry* m_EntryMaxEnergy; + TGTextButton* m_ButtonApply; diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 372ea306..2ead7701 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -138,7 +138,7 @@ class MModuleTrappingCorrection : public MModule MModuleDepthCalibration* m_DepthCalibration = nullptr; //! Updated GUI to display the energy histogram - MGUIExpoPlotSpectrum* m_ExpoSpectrum; + MGUIExpoTrappingCorrection* m_ExpoSpectrum; TF1* GeneratePhotopeakFunction(); diff --git a/src/MGUIExpoTrappingCorrection.cxx b/src/MGUIExpoTrappingCorrection.cxx index 6b9df141..7d9b52f4 100644 --- a/src/MGUIExpoTrappingCorrection.cxx +++ b/src/MGUIExpoTrappingCorrection.cxx @@ -27,6 +27,8 @@ #include #include #include +#include +#include // MEGAlib libs: #include "MStreams.h" @@ -40,150 +42,287 @@ ClassImp(MGUIExpoTrappingCorrection) #endif - //////////////////////////////////////////////////////////////////////////////// - MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIExpo(Module) { - // standard constructor - - // Set the new title of the tab here: m_TabTitle = "Trapping Correction"; - // Add all histograms and canvases below - m_Energy = new TH1D("", "Spectrum combined hits", 200, 0, 1000); - m_Energy->SetXTitle("Energy [keV]"); - m_Energy->SetYTitle("counts"); - m_Energy->SetFillColor(kAzure+7); - - m_EnergyCanvas = 0; + // Default parameters: 200 bins, 0 to 1000 keV + m_EnergyLVInitial = new TH1D("EnergyLVInitial", "LV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + m_EnergyLVInitial->SetXTitle("Energy [keV]"); + m_EnergyLVInitial->SetYTitle("Counts"); + m_EnergyLVInitial->GetYaxis()->SetNoExponent(kTRUE); + m_EnergyLVInitial->SetLineColor(kGray+2); + m_EnergyLVInitial->SetLineWidth(2); + m_EnergyLVInitial->SetLineStyle(2); + + m_EnergyLVFinal = new TH1D("EnergyLVFinal", "LV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + m_EnergyLVFinal->SetXTitle("Energy [keV]"); + m_EnergyLVFinal->SetYTitle("Counts"); + m_EnergyLVFinal->GetYaxis()->SetNoExponent(kTRUE); + m_EnergyLVFinal->SetLineColor(kAzure+1); + m_EnergyLVFinal->SetLineWidth(2); + m_EnergyLVFinal->SetFillColorAlpha(kAzure-9, 0.35); + + m_EnergyHVInitial = new TH1D("EnergyHVInitial", "HV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + m_EnergyHVInitial->SetXTitle("Energy [keV]"); + m_EnergyHVInitial->SetYTitle("Counts"); + m_EnergyHVInitial->GetYaxis()->SetNoExponent(kTRUE); + m_EnergyHVInitial->SetLineColor(kGray+2); + m_EnergyHVInitial->SetLineWidth(2); + m_EnergyHVInitial->SetLineStyle(2); + + m_EnergyHVFinal = new TH1D("EnergyHVFinal", "HV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + m_EnergyHVFinal->SetXTitle("Energy [keV]"); + m_EnergyHVFinal->SetYTitle("Counts"); + m_EnergyHVFinal->GetYaxis()->SetNoExponent(kTRUE); + m_EnergyHVFinal->SetLineColor(kOrange+7); + m_EnergyHVFinal->SetLineWidth(2); + m_EnergyHVFinal->SetFillColorAlpha(kOrange-9, 0.35); + + m_CanvasLV = nullptr; + m_CanvasHV = nullptr; + m_LegendLV = nullptr; + m_LegendHV = nullptr; + + m_EntryNBins = nullptr; + m_EntryMinEnergy = nullptr; + m_EntryMaxEnergy = nullptr; + m_ButtonApply = nullptr; - // use hierarchical cleaning SetCleanup(kDeepCleanup); } - //////////////////////////////////////////////////////////////////////////////// - MGUIExpoTrappingCorrection::~MGUIExpoTrappingCorrection() { - // kDeepCleanup is activated + // kDeepCleanup handles memory deletion for embedded GUI widgets } - //////////////////////////////////////////////////////////////////////////////// - -void MGUIExpoTrappingCorrection::Reset() +void MGUIExpoTrappingCorrection::Create() { - //! Reset the data in the UI + if (m_IsCreated == true) return; m_Mutex.Lock(); - m_Energy->Reset(); + // 1. Top Control Bar Frame for parameters + TGHorizontalFrame* ControlFrame = new TGHorizontalFrame(this, 800, 30); + // Binning Entry + TGLabel* LabelBins = new TGLabel(ControlFrame, "Bins:"); + ControlFrame->AddFrame(LabelBins, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 2, 2, 2)); + + m_EntryNBins = new TGNumberEntry(ControlFrame, 200, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAPositive); + ControlFrame->AddFrame(m_EntryNBins, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 2, 2)); + + // Min Energy Entry + TGLabel* LabelMin = new TGLabel(ControlFrame, "Min Energy [keV]:"); + ControlFrame->AddFrame(LabelMin, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 2, 2, 2)); + + m_EntryMinEnergy = new TGNumberEntry(ControlFrame, 0, 6, -1, TGNumberFormat::kNESRealOne); + ControlFrame->AddFrame(m_EntryMinEnergy, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 2, 2)); + + // Max Energy Entry + TGLabel* LabelMax = new TGLabel(ControlFrame, "Max Energy [keV]:"); + ControlFrame->AddFrame(LabelMax, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 2, 2, 2)); + + m_EntryMaxEnergy = new TGNumberEntry(ControlFrame, 1000, 6, -1, TGNumberFormat::kNESRealOne); + ControlFrame->AddFrame(m_EntryMaxEnergy, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 2, 2)); + + // Apply Button + m_ButtonApply = new TGTextButton(ControlFrame, " Apply Range "); + ControlFrame->AddFrame(m_ButtonApply, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 10, 5, 2, 2)); + + // Connect the Apply button click to the OnApply method slot + m_ButtonApply->Connect("Clicked()", "MGUIExpoTrappingCorrection", this, "OnApply()"); + + // Add the control bar at the top of the tab + AddFrame(ControlFrame, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 5, 5, 5, 2)); + + // 2. Main Canvas Frame (Side-by-Side Plots) + TGLayoutHints* CanvasLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2); + TGHorizontalFrame* HFrame = new TGHorizontalFrame(this); + AddFrame(HFrame, CanvasLayout); + + // LV Canvas + m_CanvasLV = new TRootEmbeddedCanvas("CanvasLV", HFrame, 100, 100); + HFrame->AddFrame(m_CanvasLV, CanvasLayout); + + m_CanvasLV->GetCanvas()->cd(); + m_CanvasLV->GetCanvas()->SetGridx(); + m_CanvasLV->GetCanvas()->SetGridy(); + + m_EnergyLVInitial->Draw("HIST"); + m_EnergyLVFinal->Draw("HIST SAME"); + + m_LegendLV = new TLegend(0.55, 0.72, 0.88, 0.88); + m_LegendLV->AddEntry(m_EnergyLVInitial, "LV Uncorrected", "l"); + m_LegendLV->AddEntry(m_EnergyLVFinal, "LV Corrected", "f"); + m_LegendLV->Draw(); + + // HV Canvas + m_CanvasHV = new TRootEmbeddedCanvas("CanvasHV", HFrame, 100, 100); + HFrame->AddFrame(m_CanvasHV, CanvasLayout); + + m_CanvasHV->GetCanvas()->cd(); + m_CanvasHV->GetCanvas()->SetGridx(); + m_CanvasHV->GetCanvas()->SetGridy(); + + m_EnergyHVInitial->Draw("HIST"); + m_EnergyHVFinal->Draw("HIST SAME"); + + m_LegendHV = new TLegend(0.55, 0.72, 0.88, 0.88); + m_LegendHV->AddEntry(m_EnergyHVInitial, "HV Uncorrected", "l"); + m_LegendHV->AddEntry(m_EnergyHVFinal, "HV Corrected", "f"); + m_LegendHV->Draw(); + + MapSubwindows(); + Layout(); + + m_IsCreated = true; + m_Mutex.UnLock(); } - //////////////////////////////////////////////////////////////////////////////// +void MGUIExpoTrappingCorrection::OnApply() +{ + //! Called when the user clicks "Apply Range" in the GUI + + if (m_EntryNBins == nullptr || m_EntryMinEnergy == nullptr || m_EntryMaxEnergy == nullptr) return; + + int nBins = m_EntryNBins->GetIntNumber(); + double minE = m_EntryMinEnergy->GetNumber(); + double maxE = m_EntryMaxEnergy->GetNumber(); + + if (maxE <= minE || nBins <= 0) { + cout << "WARNING in MGUIExpoTrappingCorrection: Invalid histogram parameters (" + << nBins << " bins, min=" << minE << ", max=" << maxE << ")" << endl; + return; + } + + SetEnergyHistogramParameters(nBins, minE, maxE); + Update(); +} + +//////////////////////////////////////////////////////////////////////////////// void MGUIExpoTrappingCorrection::SetEnergyHistogramParameters(int NBins, double Min, double Max) { - // Set the energy histogram parameters - m_Mutex.Lock(); - m_Energy->SetBins(NBins, Min, Max); - + m_EnergyLVInitial->SetBins(NBins, Min, Max); + m_EnergyLVFinal->SetBins(NBins, Min, Max); + m_EnergyHVInitial->SetBins(NBins, Min, Max); + m_EnergyHVFinal->SetBins(NBins, Min, Max); + + // Keep entry controls in sync if set programmatically from code (e.g., CreateExpos) + if (m_EntryNBins != nullptr) m_EntryNBins->SetIntNumber(NBins); + if (m_EntryMinEnergy != nullptr) m_EntryMinEnergy->SetNumber(Min); + if (m_EntryMaxEnergy != nullptr) m_EntryMaxEnergy->SetNumber(Max); + m_Mutex.UnLock(); } - //////////////////////////////////////////////////////////////////////////////// - -void MGUIExpoTrappingCorrection::AddEnergy(double Energy) +void MGUIExpoTrappingCorrection::Update() { - // Add data to the energy histogram - m_Mutex.Lock(); - m_Energy->Fill(Energy); - - m_Mutex.UnLock(); -} + if (m_CanvasLV != nullptr && m_CanvasLV->GetCanvas() != nullptr) { + m_CanvasLV->GetCanvas()->cd(); + double maxLV = std::max(m_EnergyLVInitial->GetMaximum(), m_EnergyLVFinal->GetMaximum()); + if (maxLV > 0.0) { + m_EnergyLVInitial->SetMaximum(maxLV * 1.15); + } -//////////////////////////////////////////////////////////////////////////////// + m_CanvasLV->GetCanvas()->Modified(); + m_CanvasLV->GetCanvas()->Update(); + } + if (m_CanvasHV != nullptr && m_CanvasHV->GetCanvas() != nullptr) { + m_CanvasHV->GetCanvas()->cd(); -void MGUIExpoTrappingCorrection::Export(const MString& FileName) -{ - // Add data to the energy histogram + double maxHV = std::max(m_EnergyHVInitial->GetMaximum(), m_EnergyHVFinal->GetMaximum()); + if (maxHV > 0.0) { + m_EnergyHVInitial->SetMaximum(maxHV * 1.15); + } - m_Mutex.Lock(); + m_CanvasHV->GetCanvas()->Modified(); + m_CanvasHV->GetCanvas()->Update(); + } - m_EnergyCanvas->GetCanvas()->SaveAs(FileName); - m_Mutex.UnLock(); } - //////////////////////////////////////////////////////////////////////////////// - -void MGUIExpoTrappingCorrection::Create() +void MGUIExpoTrappingCorrection::Reset() { - // Add the GUI options here + m_Mutex.Lock(); - // Do not create it twice! - if (m_IsCreated == true) return; + m_EnergyLVInitial->Reset(); + m_EnergyLVFinal->Reset(); + m_EnergyHVInitial->Reset(); + m_EnergyHVFinal->Reset(); + + m_Mutex.UnLock(); +} + +//////////////////////////////////////////////////////////////////////////////// +void MGUIExpoTrappingCorrection::AddEnergyInitial(double Energy, bool IsNearestNeighbor, bool IsLV) +{ m_Mutex.Lock(); - - TGLayoutHints* CanvasLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, - 2, 2, 2, 2); - TGHorizontalFrame* HFrame = new TGHorizontalFrame(this); - AddFrame(HFrame, CanvasLayout); + if (IsLV == true) { + m_EnergyLVInitial->Fill(Energy); + } else { + m_EnergyHVInitial->Fill(Energy); + } - - m_EnergyCanvas = new TRootEmbeddedCanvas("Energy", HFrame, 100, 100); - HFrame->AddFrame(m_EnergyCanvas, CanvasLayout); - - m_EnergyCanvas->GetCanvas()->cd(); - m_EnergyCanvas->GetCanvas()->SetGridy(); - m_EnergyCanvas->GetCanvas()->SetGridx(); - m_Energy->Draw(); - m_EnergyCanvas->GetCanvas()->Update(); - - m_IsCreated = true; - m_Mutex.UnLock(); } - //////////////////////////////////////////////////////////////////////////////// - -void MGUIExpoTrappingCorrection::Update() +void MGUIExpoTrappingCorrection::AddEnergyFinal(double Energy, bool IsNearestNeighbor, bool IsLV) { - //! Update the frame - m_Mutex.Lock(); - if (m_EnergyCanvas != 0) { - m_EnergyCanvas->GetCanvas()->Modified(); - m_EnergyCanvas->GetCanvas()->Update(); + if (IsLV == true) { + m_EnergyLVFinal->Fill(Energy); + } else { + m_EnergyHVFinal->Fill(Energy); } - + m_Mutex.UnLock(); } - -// MGUIExpoTrappingCorrection: the end... //////////////////////////////////////////////////////////////////////////////// + +void MGUIExpoTrappingCorrection::Export(const MString& FileName) +{ + m_Mutex.Lock(); + + if (m_CanvasLV != nullptr && m_CanvasLV->GetCanvas() != nullptr) { + MString nameLV = FileName; + nameLV.ReplaceAll(".png", "_LV.png"); + m_CanvasLV->GetCanvas()->SaveAs(nameLV); + } + + if (m_CanvasHV != nullptr && m_CanvasHV->GetCanvas() != nullptr) { + MString nameHV = FileName; + nameHV.ReplaceAll(".png", "_HV.png"); + m_CanvasHV->GetCanvas()->SaveAs(nameHV); + } + + m_Mutex.UnLock(); +} \ No newline at end of file diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 2a916a5e..dbf7568c 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -144,12 +144,10 @@ void MModuleTrappingCorrection::CreateExpos() if (HasExpos() == true) return; - // Set the histogram display - m_ExpoSpectrum = new MGUIExpoPlotSpectrum(this); + // Set the histogram display using the new double-canvas GUI class + m_ExpoSpectrum = new MGUIExpoTrappingCorrection(this); m_ExpoSpectrum->SetEnergyHistogramParameters(200, 0, 2000); m_Expos.push_back(m_ExpoSpectrum); - - } @@ -158,34 +156,19 @@ void MModuleTrappingCorrection::CreateExpos() bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) { - if (Event->GetGuardRingVeto() == true) { - //Right now we cannot use events w GR veto - - // Event->SetTrappingCorrectionError("GR Veto"); + // Right now we cannot use events w GR veto 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. + for (unsigned int i = 0; i < Event->GetNHits(); ++i) { MHit* H = Event->GetHit(i); int Grade = m_DepthCalibration->GetHitGrade(H); - // Handle different grades differently - // Get the position from the depth cal. If error is thrown, record and no depth. - - // GRADE=-1 is an error. Break from the loop and continue. - if (Grade < 0){ - H->SetNoDepth(); - } 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. + if (Grade < 0 || Grade > 4) { H->SetNoDepth(); - } else { // If the Grade is 0-4, we can handle it. + } else { // If Grade is 0-4, proceed with analysis - // Take a Hit and separate its activated X- and Y-strips into separate vectors. vector LVStrips; vector HVStrips; @@ -194,51 +177,59 @@ bool MModuleTrappingCorrection::AnalyzeEvent(MReadOutAssembly* Event) if (SH->IsLowVoltageStrip()) LVStrips.push_back(SH); else HVStrips.push_back(SH); } - // Get the dominant strip for the hit and its energy fraction for both LV and HV sides - //s.t we can determine the depth and energy to correct double LVEnergyFraction; double HVEnergyFraction; MStripHit* LVSH = m_DepthCalibration->GetDominantStrip(LVStrips, LVEnergyFraction); MStripHit* HVSH = m_DepthCalibration->GetDominantStrip(HVStrips, HVEnergyFraction); - // Get the position value in cm(assumed from event/hit context H) + // Local Z depth position double depth_val = H->GetLocalPosition().GetZ(); - // Correct the Low Voltage side energy if the hit pointer exists + // --- Low Voltage Side --- if (LVSH != nullptr) { - double rawLVEnergy = LVSH->GetEnergy(); - double correctedLVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawLVEnergy, m_CCEs_LV_e, m_CCEs_LV_h, m_ParamA_LV, m_ParamB, m_ParamC); - - LVSH->SetEnergy(correctedLVEnergy); + double rawLVEnergy = LVSH->GetEnergy(); + + // --- 1. FILL UNCORRECTED (RAW) --- + if (HasExpos() == true) { + m_ExpoSpectrum->AddEnergyInitial(rawLVEnergy, LVSH->IsNearestNeighbor(), LVSH->IsLowVoltageStrip()); + } + + // --- 2. CALCULATE CORRECTION --- + double correctedLVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawLVEnergy, m_CCEs_LV_e, m_CCEs_LV_h, m_ParamA_LV, m_ParamB, m_ParamC); + LVSH->SetEnergy(correctedLVEnergy); + + // --- 3. FILL CORRECTED (FINAL) --- + if (HasExpos() == true) { + m_ExpoSpectrum->AddEnergyFinal(correctedLVEnergy, LVSH->IsNearestNeighbor(), LVSH->IsLowVoltageStrip()); + } + } + // --- High Voltage Side --- + if (HVSH != nullptr) { + double rawHVEnergy = HVSH->GetEnergy(); + + // 1. Record UNCORRECTED (raw) HV energy to expo spectrum if (HasExpos() == true) { - m_ExpoSpectrum->AddEnergyFinal(correctedLVEnergy, LVSH->IsNearestNeighbor(), LVSH->IsLowVoltageStrip()); + m_ExpoSpectrum->AddEnergyInitial(rawHVEnergy, HVSH->IsNearestNeighbor(), HVSH->IsLowVoltageStrip()); } - } - // Correct the High Voltage side energy if the hit pointer exists - if (HVSH != nullptr) { - double rawHVEnergy = HVSH->GetEnergy(); + // 2. Compute trapping correction double correctedHVEnergy = GetSimBasedCorrectedEnergy(depth_val, rawHVEnergy, m_CCEs_HV_e, m_CCEs_HV_h, m_ParamA_HV, m_ParamB, m_ParamC); - HVSH->SetEnergy(correctedHVEnergy); + // 3. Record CORRECTED (final) HV energy to expo spectrum if (HasExpos() == true) { m_ExpoSpectrum->AddEnergyFinal(correctedHVEnergy, HVSH->IsNearestNeighbor(), HVSH->IsLowVoltageStrip()); } } - - } } } Event->SetAnalysisProgress(MAssembly::c_TrappingCorrection); - return true; } - ///////////////////////////////////////////////////////////////////////////////// void MModuleTrappingCorrection::Finalize() @@ -250,63 +241,68 @@ void MModuleTrappingCorrection::Finalize() return; } - if (g_Verbosity >= c_Info){ + if (g_Verbosity >= c_Info) { cout << "INFO: Finalizing Trapping Correction Module..." << endl; } - TH1D* histLV = m_ExpoSpectrum->GetEnergyHistogramLVFinal(); - TH1D* histHV = m_ExpoSpectrum->GetEnergyHistogramHVFinal(); + // Retrieve both uncorrected (Initial) and corrected (Final) histograms + TH1D* histLVInit = m_ExpoSpectrum->GetEnergyHistogramLVInitial(); + TH1D* histLVFinal = m_ExpoSpectrum->GetEnergyHistogramLVFinal(); - // --- LV side --- - if (histLV != nullptr && histLV->GetEntries() > 0) { + TH1D* histHVInit = m_ExpoSpectrum->GetEnergyHistogramHVInitial(); + TH1D* histHVFinal = m_ExpoSpectrum->GetEnergyHistogramHVFinal(); - m_DirectFWHM_LV = CalculateDirectFWHM(histLV); + // Helper lambda to perform fit, output results, and return {mu, fwhm} + auto FitAndPrintSpectrum = [&](TH1D* hist, const string& titleLabel) -> std::pair { + if (hist == nullptr || hist->GetEntries() <= 0) { + cout << "WARNING: " << titleLabel << " histogram is null or has 0 entries." << endl; + return std::make_pair(0.0, 0.0); + } - TF1* fitFuncLV = GeneratePhotopeakFunction(); - fitFuncLV->SetParameter("Amplitude", histLV->GetBinContent(histLV->GetMaximumBin())); - histLV->Fit(fitFuncLV, "RQ"); - - double mu_lv = fitFuncLV->GetParameter("x0 (Mu)"); - double fwhm_fit_lv = 2.35482 * fitFuncLV->GetParameter("Sigma Gauss"); - - - cout << m_XmlTag << " --- LV FINAL SPECTRUM RESULTS ---" << endl; - cout << " Centroid (Mu) : " << mu_lv << " keV" << endl; - cout << " Fitted Gaussian FWHM : " << fwhm_fit_lv << " keV" << endl; - cout << " Direct Histogram FWHM: " << m_DirectFWHM_LV << " keV" << endl; - + double directFWHM = CalculateDirectFWHM(hist); - delete fitFuncLV; - } else { - cout << "WARNING: histLV is null or has 0 entries." << endl; - } + TF1* fitFunc = GeneratePhotopeakFunction(); + fitFunc->SetParameter("Amplitude", hist->GetBinContent(hist->GetMaximumBin())); + hist->Fit(fitFunc, "RQ"); - // --- HV side --- - if (histHV != nullptr && histHV->GetEntries() > 0) { - - m_DirectFWHM_HV = CalculateDirectFWHM(histHV); + double mu = fitFunc->GetParameter("x0 (Mu)"); + double fwhm = 2.35482 * fitFunc->GetParameter("Sigma Gauss"); - TF1* fitFuncHV = GeneratePhotopeakFunction(); - fitFuncHV->SetParameter("Amplitude", histHV->GetBinContent(histHV->GetMaximumBin())); - histHV->Fit(fitFuncHV, "RQ"); - - double mu_hv = fitFuncHV->GetParameter("x0 (Mu)"); - double fwhm_fit_hv = 2.35482 * fitFuncHV->GetParameter("Sigma Gauss"); - - - cout << m_XmlTag << " --- HV FINAL SPECTRUM RESULTS ---" << endl; - cout << " Centroid (Mu) : " << mu_hv << " keV" << endl; - cout << " Fitted Gaussian FWHM : " << fwhm_fit_hv << " keV" << endl; - cout << " Direct Histogram FWHM: " << m_DirectFWHM_HV << " keV" << endl; - + cout << "\n" << m_XmlTag << " --- " << titleLabel << " ---" << endl; + cout << " Centroid (Mu) : " << mu << " keV" << endl; + cout << " Fitted Gaussian FWHM : " << fwhm << " keV" << endl; + cout << " Direct Histogram FWHM: " << directFWHM << " keV" << endl; - delete fitFuncHV; - } else { - cout << "WARNING: histHV is null or has 0 entries." << endl; - } + delete fitFunc; + return std::make_pair(mu, fwhm); + }; + + cout << "\n========================================================" << endl; + cout << " TRAPPING CORRECTION SPECTRUM FIT RESULTS " << endl; + cout << "========================================================" << endl; + + // --- Fit Uncorrected and Corrected Spectra --- + std::pair lv_raw = FitAndPrintSpectrum(histLVInit, "LV UNCORRECTED (RAW) SPECTRUM"); + std::pair lv_corr = FitAndPrintSpectrum(histLVFinal, "LV CORRECTED SPECTRUM"); + + std::pair hv_raw = FitAndPrintSpectrum(histHVInit, "HV UNCORRECTED (RAW) SPECTRUM"); + std::pair hv_corr = FitAndPrintSpectrum(histHVFinal, "HV CORRECTED SPECTRUM"); + + // Summary Comparison Output + cout << "\n========================================================" << endl; + cout << " SUMMARY COMPARISON " << endl; + cout << "========================================================" << endl; + cout << " LV Side: " << endl; + cout << " Raw Centroid: " << lv_raw.first << " keV | Corrected Centroid: " << lv_corr.first << " keV" << endl; + cout << " Raw FWHM : " << lv_raw.second << " keV | Corrected FWHM : " << lv_corr.second << " keV" << endl; + cout << " HV Side: " << endl; + cout << " Raw Centroid: " << hv_raw.first << " keV | Corrected Centroid: " << hv_corr.first << " keV" << endl; + cout << " Raw FWHM : " << hv_raw.second << " keV | Corrected FWHM : " << hv_corr.second << " keV" << endl; + cout << "========================================================\n" << endl; return; } + ///////////////////////////////////////////////////////////////////////////////// From 962421c16ad62acffa4412cb0e42b850e6c1b570 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Sun, 16 Aug 2026 15:47:54 -0700 Subject: [PATCH 50/61] fixed hist inputted energy range + scaled peak height --- include/MGUIExpoTrappingCorrection.h | 2 +- src/MGUIExpoTrappingCorrection.cxx | 134 ++++++++++++++++----------- 2 files changed, 83 insertions(+), 53 deletions(-) diff --git a/include/MGUIExpoTrappingCorrection.h b/include/MGUIExpoTrappingCorrection.h index 225f3be1..023ef66c 100644 --- a/include/MGUIExpoTrappingCorrection.h +++ b/include/MGUIExpoTrappingCorrection.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -121,6 +120,7 @@ class MGUIExpoTrappingCorrection : public MGUIExpo TGNumberEntry* m_EntryMaxEnergy; TGTextButton* m_ButtonApply; + TGCheckButton* m_CheckLogY; #ifdef ___CLING___ diff --git a/src/MGUIExpoTrappingCorrection.cxx b/src/MGUIExpoTrappingCorrection.cxx index 7d9b52f4..a935a0e1 100644 --- a/src/MGUIExpoTrappingCorrection.cxx +++ b/src/MGUIExpoTrappingCorrection.cxx @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include // MEGAlib libs: #include "MStreams.h" @@ -48,8 +51,8 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx { m_TabTitle = "Trapping Correction"; - // Default parameters: 200 bins, 0 to 1000 keV - m_EnergyLVInitial = new TH1D("EnergyLVInitial", "LV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + // LV Histograms + m_EnergyLVInitial = new TH1D("EnergyLVInitial", "LV Spectrum (Uncorrected vs Corrected)", 200, 620, 700); m_EnergyLVInitial->SetXTitle("Energy [keV]"); m_EnergyLVInitial->SetYTitle("Counts"); m_EnergyLVInitial->GetYaxis()->SetNoExponent(kTRUE); @@ -57,7 +60,7 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx m_EnergyLVInitial->SetLineWidth(2); m_EnergyLVInitial->SetLineStyle(2); - m_EnergyLVFinal = new TH1D("EnergyLVFinal", "LV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + m_EnergyLVFinal = new TH1D("EnergyLVFinal", "LV Spectrum (Uncorrected vs Corrected)", 200, 620, 700); m_EnergyLVFinal->SetXTitle("Energy [keV]"); m_EnergyLVFinal->SetYTitle("Counts"); m_EnergyLVFinal->GetYaxis()->SetNoExponent(kTRUE); @@ -65,7 +68,8 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx m_EnergyLVFinal->SetLineWidth(2); m_EnergyLVFinal->SetFillColorAlpha(kAzure-9, 0.35); - m_EnergyHVInitial = new TH1D("EnergyHVInitial", "HV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + // HV Histograms + m_EnergyHVInitial = new TH1D("EnergyHVInitial", "HV Spectrum (Uncorrected vs Corrected)", 200, 620, 700); m_EnergyHVInitial->SetXTitle("Energy [keV]"); m_EnergyHVInitial->SetYTitle("Counts"); m_EnergyHVInitial->GetYaxis()->SetNoExponent(kTRUE); @@ -73,7 +77,7 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx m_EnergyHVInitial->SetLineWidth(2); m_EnergyHVInitial->SetLineStyle(2); - m_EnergyHVFinal = new TH1D("EnergyHVFinal", "HV Spectrum (Uncorrected vs Corrected)", 100, 620, 700); + m_EnergyHVFinal = new TH1D("EnergyHVFinal", "HV Spectrum (Uncorrected vs Corrected)", 200, 620, 700); m_EnergyHVFinal->SetXTitle("Energy [keV]"); m_EnergyHVFinal->SetYTitle("Counts"); m_EnergyHVFinal->GetYaxis()->SetNoExponent(kTRUE); @@ -81,6 +85,7 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx m_EnergyHVFinal->SetLineWidth(2); m_EnergyHVFinal->SetFillColorAlpha(kOrange-9, 0.35); + // Initialize canvases and buttons m_CanvasLV = nullptr; m_CanvasHV = nullptr; m_LegendLV = nullptr; @@ -89,6 +94,7 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx m_EntryNBins = nullptr; m_EntryMinEnergy = nullptr; m_EntryMaxEnergy = nullptr; + m_CheckLogY = nullptr; m_ButtonApply = nullptr; SetCleanup(kDeepCleanup); @@ -98,7 +104,7 @@ MGUIExpoTrappingCorrection::MGUIExpoTrappingCorrection(MModule* Module) : MGUIEx MGUIExpoTrappingCorrection::~MGUIExpoTrappingCorrection() { - // kDeepCleanup handles memory deletion for embedded GUI widgets + // Memory cleanup handled by ROOT's kDeepCleanup } //////////////////////////////////////////////////////////////////////////////// @@ -109,46 +115,49 @@ void MGUIExpoTrappingCorrection::Create() m_Mutex.Lock(); - // 1. Top Control Bar Frame for parameters + // Create labels and buttons on GUI + // Top frame TGHorizontalFrame* ControlFrame = new TGHorizontalFrame(this, 800, 30); - // Binning Entry + // Binning entry TGLabel* LabelBins = new TGLabel(ControlFrame, "Bins:"); ControlFrame->AddFrame(LabelBins, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 2, 2, 2)); m_EntryNBins = new TGNumberEntry(ControlFrame, 200, 5, -1, TGNumberFormat::kNESInteger, TGNumberFormat::kNEAPositive); ControlFrame->AddFrame(m_EntryNBins, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 2, 2)); - // Min Energy Entry + // Min Energy entry TGLabel* LabelMin = new TGLabel(ControlFrame, "Min Energy [keV]:"); ControlFrame->AddFrame(LabelMin, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 2, 2, 2)); m_EntryMinEnergy = new TGNumberEntry(ControlFrame, 0, 6, -1, TGNumberFormat::kNESRealOne); ControlFrame->AddFrame(m_EntryMinEnergy, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 2, 2)); - // Max Energy Entry + // Max Energy entry TGLabel* LabelMax = new TGLabel(ControlFrame, "Max Energy [keV]:"); ControlFrame->AddFrame(LabelMax, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 2, 2, 2)); m_EntryMaxEnergy = new TGNumberEntry(ControlFrame, 1000, 6, -1, TGNumberFormat::kNESRealOne); ControlFrame->AddFrame(m_EntryMaxEnergy, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 10, 2, 2)); + // Log Y Checkbox + m_CheckLogY = new TGCheckButton(ControlFrame, "Log Y Scale"); + ControlFrame->AddFrame(m_CheckLogY, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 10, 10, 2, 2)); + m_CheckLogY->Connect("Clicked()", "MGUIExpoTrappingCorrection", this, "OnApply()"); + // Apply Button m_ButtonApply = new TGTextButton(ControlFrame, " Apply Range "); - ControlFrame->AddFrame(m_ButtonApply, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 10, 5, 2, 2)); - - // Connect the Apply button click to the OnApply method slot + ControlFrame->AddFrame(m_ButtonApply, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 5, 2, 2)); m_ButtonApply->Connect("Clicked()", "MGUIExpoTrappingCorrection", this, "OnApply()"); - // Add the control bar at the top of the tab AddFrame(ControlFrame, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 5, 5, 5, 2)); - // 2. Main Canvas Frame (Side-by-Side Plots) + // Main Canvas Frame (Side-by-Side Plots) TGLayoutHints* CanvasLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2); TGHorizontalFrame* HFrame = new TGHorizontalFrame(this); AddFrame(HFrame, CanvasLayout); - // LV Canvas + // LV Canvas setup m_CanvasLV = new TRootEmbeddedCanvas("CanvasLV", HFrame, 100, 100); HFrame->AddFrame(m_CanvasLV, CanvasLayout); @@ -164,7 +173,7 @@ void MGUIExpoTrappingCorrection::Create() m_LegendLV->AddEntry(m_EnergyLVFinal, "LV Corrected", "f"); m_LegendLV->Draw(); - // HV Canvas + // HV Canvas setup m_CanvasHV = new TRootEmbeddedCanvas("CanvasHV", HFrame, 100, 100); HFrame->AddFrame(m_CanvasHV, CanvasLayout); @@ -183,6 +192,7 @@ void MGUIExpoTrappingCorrection::Create() MapSubwindows(); Layout(); + // Signal that the canvas has been created so we know when we can start to fill it m_IsCreated = true; m_Mutex.UnLock(); @@ -192,19 +202,15 @@ void MGUIExpoTrappingCorrection::Create() void MGUIExpoTrappingCorrection::OnApply() { - //! Called when the user clicks "Apply Range" in the GUI - + //Create function has already been run + if (m_IsCreated == false) return; if (m_EntryNBins == nullptr || m_EntryMinEnergy == nullptr || m_EntryMaxEnergy == nullptr) return; int nBins = m_EntryNBins->GetIntNumber(); double minE = m_EntryMinEnergy->GetNumber(); double maxE = m_EntryMaxEnergy->GetNumber(); - if (maxE <= minE || nBins <= 0) { - cout << "WARNING in MGUIExpoTrappingCorrection: Invalid histogram parameters (" - << nBins << " bins, min=" << minE << ", max=" << maxE << ")" << endl; - return; - } + if (maxE <= minE || nBins <= 0) return; SetEnergyHistogramParameters(nBins, minE, maxE); Update(); @@ -216,47 +222,71 @@ void MGUIExpoTrappingCorrection::SetEnergyHistogramParameters(int NBins, double { m_Mutex.Lock(); - m_EnergyLVInitial->SetBins(NBins, Min, Max); - m_EnergyLVFinal->SetBins(NBins, Min, Max); - m_EnergyHVInitial->SetBins(NBins, Min, Max); - m_EnergyHVFinal->SetBins(NBins, Min, Max); + // 1. Zoom the X-axis view without altering underlying data/binning + if (m_EnergyLVInitial != nullptr) m_EnergyLVInitial->GetXaxis()->SetRangeUser(Min, Max); + if (m_EnergyLVFinal != nullptr) m_EnergyLVFinal->GetXaxis()->SetRangeUser(Min, Max); + if (m_EnergyHVInitial != nullptr) m_EnergyHVInitial->GetXaxis()->SetRangeUser(Min, Max); + if (m_EnergyHVFinal != nullptr) m_EnergyHVFinal->GetXaxis()->SetRangeUser(Min, Max); - // Keep entry controls in sync if set programmatically from code (e.g., CreateExpos) + // 2. Update entry boxes if (m_EntryNBins != nullptr) m_EntryNBins->SetIntNumber(NBins); if (m_EntryMinEnergy != nullptr) m_EntryMinEnergy->SetNumber(Min); if (m_EntryMaxEnergy != nullptr) m_EntryMaxEnergy->SetNumber(Max); m_Mutex.UnLock(); } - //////////////////////////////////////////////////////////////////////////////// void MGUIExpoTrappingCorrection::Update() { + if (m_IsCreated == false) return; + m_Mutex.Lock(); - if (m_CanvasLV != nullptr && m_CanvasLV->GetCanvas() != nullptr) { - m_CanvasLV->GetCanvas()->cd(); + bool isLog = (m_CheckLogY != nullptr && m_CheckLogY->IsOn()); - double maxLV = std::max(m_EnergyLVInitial->GetMaximum(), m_EnergyLVFinal->GetMaximum()); - if (maxLV > 0.0) { - m_EnergyLVInitial->SetMaximum(maxLV * 1.15); + // --- Update LV Canvas --- + if (m_CanvasLV != nullptr && m_CanvasLV->GetCanvas() != nullptr) { + TCanvas* canvasLV = m_CanvasLV->GetCanvas(); + canvasLV->cd(); + canvasLV->SetLogy(isLog ? 1 : 0); + + double maxLVInitial = m_EnergyLVInitial->GetBinContent(m_EnergyLVInitial->GetMaximumBin()); + double maxLVFinal = m_EnergyLVFinal->GetBinContent(m_EnergyLVFinal->GetMaximumBin()); + double realMaxLV = std::max(maxLVInitial, maxLVFinal); + + if (isLog) { + m_EnergyLVInitial->SetMinimum(0.1); + m_EnergyLVInitial->SetMaximum(realMaxLV > 0 ? realMaxLV * 5.0 : 10.0); + } else { + m_EnergyLVInitial->SetMinimum(-1111); + m_EnergyLVInitial->SetMaximum(realMaxLV > 0 ? realMaxLV * 1.15 : 10.0); } - m_CanvasLV->GetCanvas()->Modified(); - m_CanvasLV->GetCanvas()->Update(); + canvasLV->Modified(); + canvasLV->Update(); } + // --- Update HV Canvas --- if (m_CanvasHV != nullptr && m_CanvasHV->GetCanvas() != nullptr) { - m_CanvasHV->GetCanvas()->cd(); - - double maxHV = std::max(m_EnergyHVInitial->GetMaximum(), m_EnergyHVFinal->GetMaximum()); - if (maxHV > 0.0) { - m_EnergyHVInitial->SetMaximum(maxHV * 1.15); + TCanvas* canvasHV = m_CanvasHV->GetCanvas(); + canvasHV->cd(); + canvasHV->SetLogy(isLog ? 1 : 0); + + double maxHVInitial = m_EnergyHVInitial->GetBinContent(m_EnergyHVInitial->GetMaximumBin()); + double maxHVFinal = m_EnergyHVFinal->GetBinContent(m_EnergyHVFinal->GetMaximumBin()); + double realMaxHV = std::max(maxHVInitial, maxHVFinal); + + if (isLog) { + m_EnergyHVInitial->SetMinimum(0.1); + m_EnergyHVInitial->SetMaximum(realMaxHV > 0 ? realMaxHV * 5.0 : 10.0); + } else { + m_EnergyHVInitial->SetMinimum(-1111); + m_EnergyHVInitial->SetMaximum(realMaxHV > 0 ? realMaxHV * 1.15 : 10.0); } - m_CanvasHV->GetCanvas()->Modified(); - m_CanvasHV->GetCanvas()->Update(); + canvasHV->Modified(); + canvasHV->Update(); } m_Mutex.UnLock(); @@ -268,10 +298,10 @@ void MGUIExpoTrappingCorrection::Reset() { m_Mutex.Lock(); - m_EnergyLVInitial->Reset(); - m_EnergyLVFinal->Reset(); - m_EnergyHVInitial->Reset(); - m_EnergyHVFinal->Reset(); + if (m_EnergyLVInitial != nullptr) m_EnergyLVInitial->Reset(); + if (m_EnergyLVFinal != nullptr) m_EnergyLVFinal->Reset(); + if (m_EnergyHVInitial != nullptr) m_EnergyHVInitial->Reset(); + if (m_EnergyHVFinal != nullptr) m_EnergyHVFinal->Reset(); m_Mutex.UnLock(); } @@ -283,9 +313,9 @@ void MGUIExpoTrappingCorrection::AddEnergyInitial(double Energy, bool IsNearestN m_Mutex.Lock(); if (IsLV == true) { - m_EnergyLVInitial->Fill(Energy); + if (m_EnergyLVInitial != nullptr) m_EnergyLVInitial->Fill(Energy); } else { - m_EnergyHVInitial->Fill(Energy); + if (m_EnergyHVInitial != nullptr) m_EnergyHVInitial->Fill(Energy); } m_Mutex.UnLock(); @@ -298,9 +328,9 @@ void MGUIExpoTrappingCorrection::AddEnergyFinal(double Energy, bool IsNearestNei m_Mutex.Lock(); if (IsLV == true) { - m_EnergyLVFinal->Fill(Energy); + if (m_EnergyLVFinal != nullptr) m_EnergyLVFinal->Fill(Energy); } else { - m_EnergyHVFinal->Fill(Energy); + if (m_EnergyHVFinal != nullptr) m_EnergyHVFinal->Fill(Energy); } m_Mutex.UnLock(); From cf10a9de6daa32c2183921dfb80c9ca549a09168 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Sun, 16 Aug 2026 15:49:28 -0700 Subject: [PATCH 51/61] added outputted hist fit statistics --- include/MModuleTrappingCorrection.h | 2 ++ src/MModuleTrappingCorrection.cxx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 2ead7701..63d30d9b 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -147,6 +147,8 @@ class MModuleTrappingCorrection : public MModule double m_DirectFWHM_LV = 0.0; double m_DirectFWHM_HV = 0.0; + TGCheckButton* m_LogYButton; + #ifdef ___CLING___ public: diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index dbf7568c..70d76318 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -245,7 +245,7 @@ void MModuleTrappingCorrection::Finalize() cout << "INFO: Finalizing Trapping Correction Module..." << endl; } - // Retrieve both uncorrected (Initial) and corrected (Final) histograms + // Retrieve both uncorrected and corrected histograms TH1D* histLVInit = m_ExpoSpectrum->GetEnergyHistogramLVInitial(); TH1D* histLVFinal = m_ExpoSpectrum->GetEnergyHistogramLVFinal(); From 3e57639c6db3d28b42c2b1a6cf89d83781d4cbb0 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Mon, 17 Aug 2026 16:42:07 -0700 Subject: [PATCH 52/61] corrected erroneous change --- src/MGUIOptionsLoaderMeasurementsHDF.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/MGUIOptionsLoaderMeasurementsHDF.cxx b/src/MGUIOptionsLoaderMeasurementsHDF.cxx index 5126b5b8..5c2f2bcf 100644 --- a/src/MGUIOptionsLoaderMeasurementsHDF.cxx +++ b/src/MGUIOptionsLoaderMeasurementsHDF.cxx @@ -86,6 +86,11 @@ void MGUIOptionsLoaderMeasurementsHDF::Create() m_FileSelectorStripMap->SetFileType("Strip map file", "*.map"); m_OptionsFrame->AddFrame(m_FileSelectorStripMap, LabelLayout); + // Nearest neighbor checkbox + m_IncludeNearestNeighbor = new TGCheckButton(m_OptionsFrame, "Include Nearest Neighbors"); + m_IncludeNearestNeighbor->SetOn(dynamic_cast(m_Module)->GetIncludeNearestNeighbor()); + m_IncludeNearestNeighbor->Associate(this); + m_OptionsFrame->AddFrame(m_IncludeNearestNeighbor, LabelLayout); PostCreate(); } From be838f7f6c9ae921197ebed618cbff3957b53e34 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Mon, 17 Aug 2026 16:43:46 -0700 Subject: [PATCH 53/61] added verbosity qualifiers for output and deleted unnecessary output --- src/MModuleTrappingCorrection.cxx | 57 ++++++++++++------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 70d76318..fa7d9087 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -114,22 +114,28 @@ bool MModuleTrappingCorrection::Initialize() MSupervisor* S = MSupervisor::GetSupervisor(); m_EnergyCalibration = (MModuleEnergyCalibration*) S->GetAvailableModuleByXmlTag("EnergyCalibration"); if (m_EnergyCalibration == nullptr) { - cout << "MModuleTrappingCorrection: couldn't resolve pointer to Energy Calibration Module... need access to this module for energy resolution lookup!" << endl; - return false; + if (g_Verbosity >= c_Error) { + cout << "ERROR in MModuleTrappingCorrection::Initialize: couldn't resolve pointer to Energy Calibration Module... need access to this module for energy resolution lookup!" << endl; + } + return false; } m_DepthCalibration = (MModuleDepthCalibration*) S->GetAvailableModuleByXmlTag("DepthCalibration"); if (m_DepthCalibration == nullptr) { - cout << "MModuleTrappingCorrection: couldn't resolve pointer to Depth Calibration Module... need access to this module for depth resolution lookup!" << endl; - return false; + if (g_Verbosity >= c_Error) { + cout << "ERROR in MModuleTrappingCorrection::Initialize: couldn't resolve pointer to Depth Calibration Module... need access to this module for depth resolution lookup!" << endl; + } + return false; } m_DetectorIDs = m_DepthCalibration-> GetDetectorIDs(); if (m_DetectorIDs.empty()) { - cout << "ERROR in MModuleTrappingCorrection::Initialize: Depth Calibration has no registered detector IDs!" << endl; - return false; + if (g_Verbosity >= c_Error) { + cout << "ERROR in MModuleTrappingCorrection::Initialize: Depth Calibration has no registered detector IDs!" << endl; + } + return false; } return MModule::Initialize(); @@ -337,48 +343,25 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) } if (ValidLineCount == 0) { - // 1. Read parameters A_HV, A_LV, B, and C from the first line + //Read parameters A_HV, A_LV, B, and C from the first line if (Tokens.size() == 4) { m_ParamA_HV = Tokens[0].ToDouble(); m_ParamA_LV = Tokens[1].ToDouble(); m_ParamB = Tokens[2].ToDouble(); m_ParamC = Tokens[3].ToDouble(); - cout << "\n--- Trapping File Sanity Check ---" << endl; - cout << "Loaded Parameters -> A_HV: " << m_ParamA_HV - << " | A_LV: " << m_ParamA_LV - << " | B: " << m_ParamB - << " | C: " << m_ParamC << endl; - ValidLineCount++; } else { - cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B, and C) on the first line." << endl; + if (g_Verbosity >= c_Error) { + cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B, and C) on the first line." << endl; + } SimCCEFile.Close(); return false; } - } - else if (ValidLineCount == 1) { - // 2. Print column headers line - cout << "Loaded Column Headers: "; - for (size_t i = 0; i < Tokens.size(); ++i) { - cout << Tokens[i] << (i + 1 < Tokens.size() ? " | " : "\n"); - } - ValidLineCount++; - } + } else { - // 3. Read the 5 data columns into depth and CCE arrays + //Read the 5 data columns into depth and CCE arrays if (Tokens.size() == 5) { - // Print the first 3 data rows to terminal for verification - if (ValidLineCount <= 4) { - cout << "Data Row " << (ValidLineCount - 1) << ": "; - for (size_t i = 0; i < Tokens.size(); ++i) { - cout << Tokens[i] << (i + 1 < Tokens.size() ? " | " : "\n"); - } - if (ValidLineCount == 4) { - cout << "-----------------------------------\n" << endl; - } - } - m_Depths.push_back(Tokens[0].ToDouble()); m_CCEs_HV_e.push_back(Tokens[1].ToDouble()); m_CCEs_HV_h.push_back(Tokens[2].ToDouble()); @@ -387,7 +370,9 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) ValidLineCount++; } else { - cout << "ERROR in LoadSimCCEFile: Expected 5 columns on line " << (ValidLineCount + 1) << endl; + if (g_Verbosity >= c_Error) { + cout << "ERROR in LoadSimCCEFile: Expected 5 columns on line " << (ValidLineCount + 1) << endl; + } } } } From c19ab79a17d83f09ebbc12c9c0ff78a9d0d5e7a5 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Mon, 17 Aug 2026 20:33:19 -0700 Subject: [PATCH 54/61] adding nn back --- src/MGUIOptionsLoaderMeasurementsHDF.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MGUIOptionsLoaderMeasurementsHDF.cxx b/src/MGUIOptionsLoaderMeasurementsHDF.cxx index 5c2f2bcf..eedb6add 100644 --- a/src/MGUIOptionsLoaderMeasurementsHDF.cxx +++ b/src/MGUIOptionsLoaderMeasurementsHDF.cxx @@ -137,6 +137,7 @@ bool MGUIOptionsLoaderMeasurementsHDF::OnApply() dynamic_cast(m_Module)->SetFileName(m_FileSelectorHDF->GetFileName()); dynamic_cast(m_Module)->SetLoadContinuationFiles(m_LoadContinuationFiles->IsOn()); dynamic_cast(m_Module)->SetFileNameStripMap(m_FileSelectorStripMap->GetFileName()); + dynamic_cast(m_Module)->SetIncludeNearestNeighbor(m_IncludeNearestNeighbor->IsOn()); return true; } From 43116c991f973af2c4cb60624525cd9e709d64c4 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Mon, 17 Aug 2026 20:50:47 -0700 Subject: [PATCH 55/61] close file and exit after error --- src/MModuleTrappingCorrection.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index fa7d9087..42fbfcda 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -372,7 +372,9 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) } else { if (g_Verbosity >= c_Error) { cout << "ERROR in LoadSimCCEFile: Expected 5 columns on line " << (ValidLineCount + 1) << endl; - } + } + SimCCEFile.Close(); + return false; } } } From e55d0643bcebc84fdc7e59027ba107af40a5cbcf Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 18 Aug 2026 13:41:06 -0700 Subject: [PATCH 56/61] changed cce filename _ removed unused variable --- include/MModuleTrappingCorrection.h | 7 +++---- src/MModuleTrappingCorrection.cxx | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/MModuleTrappingCorrection.h b/include/MModuleTrappingCorrection.h index 63d30d9b..b7ad1271 100644 --- a/include/MModuleTrappingCorrection.h +++ b/include/MModuleTrappingCorrection.h @@ -69,10 +69,10 @@ class MModuleTrappingCorrection : public MModule virtual void ShowOptionsGUI(); //! Set filename for SimCCE file - void SetSimCCEFileName( const MString& FileName) { m_SimCCEFile = FileName; } + void SetSimCCEFileName( const MString& FileName) { m_SimCCEFileName = FileName; } //! Get filename for SimCCE file - MString GetSimCCEFileName() const { return m_SimCCEFile; } + MString GetSimCCEFileName() const { return m_SimCCEFileName; } //! Finalize the module virtual void Finalize(); @@ -109,9 +109,8 @@ class MModuleTrappingCorrection : public MModule // protected members: protected: - unordered_map> m_SimCCE; double m_SimCCE_Energy; - MString m_SimCCEFile; + MString m_SimCCEFileName; // unordered_map m_Detectors; vector m_DetectorIDs; diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 42fbfcda..31de87b8 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -106,7 +106,7 @@ MModuleTrappingCorrection::~MModuleTrappingCorrection() bool MModuleTrappingCorrection::Initialize() { - m_SimCCEFileIsLoaded = LoadSimCCEFile(m_SimCCEFile); + m_SimCCEFileIsLoaded = LoadSimCCEFile(m_SimCCEFileName); if (m_SimCCEFileIsLoaded == false) { return false; } @@ -457,7 +457,7 @@ bool MModuleTrappingCorrection::ReadXmlConfiguration(MXmlNode* Node) MXmlNode* SimCCEFileNameNode = Node->GetNode("SimCCEFileName"); if (SimCCEFileNameNode != nullptr) { - m_SimCCEFile = SimCCEFileNameNode->GetValue(); + m_SimCCEFileName = SimCCEFileNameNode->GetValue(); } return true; @@ -471,7 +471,7 @@ MXmlNode* MModuleTrappingCorrection::CreateXmlConfiguration() //! Create an XML node tree from the configuration MXmlNode* Node = new MXmlNode(0,m_XmlTag); - new MXmlNode(Node, "SimCCEFileName", m_SimCCEFile); + new MXmlNode(Node, "SimCCEFileName", m_SimCCEFileName); return Node; } From 0513b47af46d61b0946fe42d704265224c437824 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Tue, 18 Aug 2026 14:59:23 -0700 Subject: [PATCH 57/61] updated local position description --- include/MHit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/MHit.h b/include/MHit.h index 75f28518..1dd21e38 100644 --- a/include/MHit.h +++ b/include/MHit.h @@ -187,7 +187,7 @@ class MHit MVector m_PositionResolution; - //! Local/raw position resolution of the hit + //! Position of the hit in local detector coordinates MVector m_LocalPosition; //! Energy of the hit From 87e4ae84fef950608bb728c53bdc07774b7ae80f Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 20 Aug 2026 14:44:59 -0700 Subject: [PATCH 58/61] update for param file with commented headers --- ...mmy_trapping_parameters_singledetector.csv | 3 +- src/MModuleTrappingCorrection.cxx | 73 +++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/resource/dee/dummy_trapping_parameters_singledetector.csv b/resource/dee/dummy_trapping_parameters_singledetector.csv index 4c11419f..a4ff0a52 100644 --- a/resource/dee/dummy_trapping_parameters_singledetector.csv +++ b/resource/dee/dummy_trapping_parameters_singledetector.csv @@ -1,5 +1,6 @@ +# A_HV,A_LV,B,C 1.0009264205609762,1.00084829470918,1.288689028046797,0.3010529785474152 -z_depth_cm,e_CCE_HV,h_CCE_HV,e_CCE_LV,h_CCE_LV +# z_depth_cm,e_CCE_HV,h_CCE_HV,e_CCE_LV,h_CCE_LV -0.75,0.9960754005722672,1.0,0.9995680702824706,1.0 -0.74,0.9961283655288202,1.0,0.9995997923338564,0.9999868765995326 -0.73,0.9961799143100644,1.0,0.9996279267722878,0.9999704487457096 diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 31de87b8..1eec0278 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -316,7 +316,9 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) { MFile SimCCEFile; if (SimCCEFile.Open(FileName) == false) { - cout << "ERROR in MModuleTrappingCorrection::LoadSimCCEFile: failed to open file." << endl; + if (g_Verbosity >= c_Error) { + cout << "ERROR in MModuleTrappingCorrection::LoadSimCCEFile: failed to open file " << FileName << endl; + } return false; } @@ -327,65 +329,62 @@ bool MModuleTrappingCorrection::LoadSimCCEFile(MString FileName) m_CCEs_LV_h.clear(); MString Line; - int ValidLineCount = 0; + bool ParsedHeaderParameters = false; while (SimCCEFile.ReadLine(Line)) { - // Skip comment lines - if (Line.BeginsWith('#') == true) { + + // Skip empty lines or pure comment lines + if (Line.IsEmpty() == true || Line.BeginsWith('#') == true) { continue; } std::vector Tokens = Line.Tokenize(","); - - // Skip empty lines safely - if (Tokens.size() == 0) { - continue; - } - if (ValidLineCount == 0) { - //Read parameters A_HV, A_LV, B, and C from the first line + // Read parameters (A_HV, A_LV, B, C) + if (ParsedHeaderParameters == false) { if (Tokens.size() == 4) { - m_ParamA_HV = Tokens[0].ToDouble(); - m_ParamA_LV = Tokens[1].ToDouble(); - m_ParamB = Tokens[2].ToDouble(); - m_ParamC = Tokens[3].ToDouble(); + m_ParamA_HV = Tokens[0].Strip().ToDouble(); + m_ParamA_LV = Tokens[1].Strip().ToDouble(); + m_ParamB = Tokens[2].Strip().ToDouble(); + m_ParamC = Tokens[3].Strip().ToDouble(); - ValidLineCount++; + ParsedHeaderParameters = true; } else { if (g_Verbosity >= c_Error) { - cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B, and C) on the first line." << endl; + cout << "ERROR in LoadSimCCEFile: Expected 4 parameters (A_HV, A_LV, B, C) on first data line, found " + << Tokens.size() << " tokens." << endl; } SimCCEFile.Close(); return false; } - } + } + // Read CCE curves else { - //Read the 5 data columns into depth and CCE arrays if (Tokens.size() == 5) { - m_Depths.push_back(Tokens[0].ToDouble()); - m_CCEs_HV_e.push_back(Tokens[1].ToDouble()); - m_CCEs_HV_h.push_back(Tokens[2].ToDouble()); - m_CCEs_LV_e.push_back(Tokens[3].ToDouble()); - m_CCEs_LV_h.push_back(Tokens[4].ToDouble()); - - ValidLineCount++; - } else { - if (g_Verbosity >= c_Error) { - cout << "ERROR in LoadSimCCEFile: Expected 5 columns on line " << (ValidLineCount + 1) << endl; - } - SimCCEFile.Close(); - return false; - } + m_Depths.push_back(Tokens[0].Strip().ToDouble()); + m_CCEs_HV_e.push_back(Tokens[1].Strip().ToDouble()); + m_CCEs_HV_h.push_back(Tokens[2].Strip().ToDouble()); + m_CCEs_LV_e.push_back(Tokens[3].Strip().ToDouble()); + m_CCEs_LV_h.push_back(Tokens[4].Strip().ToDouble()); + } } } SimCCEFile.Close(); - // Print summary to console if verbose logging is enabled + if (ParsedHeaderParameters == false || m_Depths.size() == 0) { + if (g_Verbosity >= c_Error) { + cout << "ERROR in LoadSimCCEFile: No valid CCE data points were loaded!" << endl; + } + return false; + } + + // Console output on successful load if (g_Verbosity >= c_Info) { - cout << m_XmlTag << "Loaded parameters: A_HV=" << m_ParamA_HV << ", A_LV=" << m_ParamA_LV - << ", B=" << m_ParamB << ", C=" << m_ParamC << endl; - cout << m_XmlTag << "Loaded " << m_Depths.size() << " data points into arrays." << endl; + cout << m_XmlTag << "Loaded CCE simulation parameters from " << FileName << ":" << endl; + cout << m_XmlTag << " A_HV = " << m_ParamA_HV << ", A_LV = " << m_ParamA_LV + << ", B = " << m_ParamB << ", C = " << m_ParamC << endl; + cout << m_XmlTag << " Loaded " << m_Depths.size() << " depth grid points." << endl; } return true; From 675aab7c40c9169e8da8fdb3c1d00f8faeeac94b Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 20 Aug 2026 14:51:20 -0700 Subject: [PATCH 59/61] a bit of comment cleanup --- apps/TrappingCorrectionCs137.cxx | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/apps/TrappingCorrectionCs137.cxx b/apps/TrappingCorrectionCs137.cxx index 8babb609..11f092ca 100644 --- a/apps/TrappingCorrectionCs137.cxx +++ b/apps/TrappingCorrectionCs137.cxx @@ -2,12 +2,12 @@ * TrappingCorrectionCs137.cxx * * - * Copyright (C) by Sean Pike. + * Copyright (C) by Sophie Haight. * All rights reserved. * * * This code implementation is the intellectual property of - * Sean Pike. + * Sophie Haight. * * By copying, distributing or modifying the Program (or any work * based on the Program) you indicate your acceptance of this statement, @@ -67,13 +67,13 @@ using namespace std; double g_MinCTD = -250; double g_MaxCTD = 250; -int g_MinCounts = 1200; +int g_MinCounts = 1000; int g_HVStrips = 64; int g_LVStrips = 64; double g_CsPhotopeak = 661.7; -const int NCTDBins = 40; +const int NCTDBins = 10; // We need NCTDBins + 1 edges to define the boundaries of NCTDBins double g_CTDBinEdges[NCTDBins + 1]; @@ -132,7 +132,7 @@ class TrappingCorrectionCs137 void Interrupt() { m_Interrupt = true; } //! Produce functions for fitting - // TF1* GenerateCTDFunction(double CTDFitMin, double CTDFitMax, double CTDGuess); + TF1* GeneratePhotopeakFunction(); MStripHit* GetDominantStrip(vector& Strips, double& EnergyFraction); @@ -190,8 +190,8 @@ bool TrappingCorrectionCs137::ParseCommandLine(int argc, char** argv) Usage<<" Usage: TrappingCorrection "< HDFNames; From d8e1b98f47a3d550f06297d437252464ce9592d9 Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 20 Aug 2026 14:59:45 -0700 Subject: [PATCH 60/61] cout cleanup --- apps/TrappingCorrectionAm241.cxx | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/apps/TrappingCorrectionAm241.cxx b/apps/TrappingCorrectionAm241.cxx index df137bf4..d2283cb5 100644 --- a/apps/TrappingCorrectionAm241.cxx +++ b/apps/TrappingCorrectionAm241.cxx @@ -274,16 +274,13 @@ bool TrappingCorrectionAm241::Analyze() // Store the HV and LV input files vector FileNames; FileNames.push_back(m_HVFileName); - cout<<"HV file names stored"< IllumSide; IllumSide.push_back(MString("HV")); IllumSide.push_back(MString("LV")); - cout<<"HV and LV integers mapped"<SetFileNameStripMap(m_StripMapFile); Loader->SetFileName(File); @@ -367,21 +361,18 @@ bool TrappingCorrectionAm241::Analyze() 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"<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; - - 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(); // Pass Events through each module. Once calibrated, add the Event to the histograms - cout<<"Analyzing..."<Clear(); From e37fd74a9b6cf9a132d98e47bda4e6b9d1cb91aa Mon Sep 17 00:00:00 2001 From: sophieehaight <144858596+sophieehaight@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:01:16 -0700 Subject: [PATCH 61/61] added TO DO --- src/MModuleTrappingCorrection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MModuleTrappingCorrection.cxx b/src/MModuleTrappingCorrection.cxx index 1eec0278..9b28f606 100644 --- a/src/MModuleTrappingCorrection.cxx +++ b/src/MModuleTrappingCorrection.cxx @@ -128,7 +128,7 @@ bool MModuleTrappingCorrection::Initialize() return false; } - +// TO DO: remove this check once we successfully process multiple detectors m_DetectorIDs = m_DepthCalibration-> GetDetectorIDs(); if (m_DetectorIDs.empty()) {