diff --git a/.gitignore b/.gitignore index 0c448d557..1117cb01c 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ UserTools/ImportedTools UserTools/InactiveTools UserTools/MyFactory +.vscode/ diff --git a/BeamFetcherV2 b/BeamFetcherV2 new file mode 120000 index 000000000..ed84c9a56 --- /dev/null +++ b/BeamFetcherV2 @@ -0,0 +1 @@ +configfiles/BeamFetcherV2/ToolChainConfig \ No newline at end of file diff --git a/DataModel/ADCPulse.h b/DataModel/ADCPulse.h index 422a7cd81..e78f8d5e1 100755 --- a/DataModel/ADCPulse.h +++ b/DataModel/ADCPulse.h @@ -98,6 +98,6 @@ class ADCPulse : public Hit { std::vector trace_y_ = {}; // y points of the pulse (baseline-subtracted) [ADC] }; -// (From Andrew Sutton) Need to increment the class version since we added time as a new variable +// Need to increment the class version since we added time as a new variable // the version number ensures backward compatibility when serializing -BOOST_CLASS_VERSION(ADCPulse, 1) +BOOST_CLASS_VERSION(ADCPulse, 1) \ No newline at end of file diff --git a/DataModel/Channel.h b/DataModel/Channel.h index 80f4b2626..3c44cb804 100644 --- a/DataModel/Channel.h +++ b/DataModel/Channel.h @@ -14,8 +14,9 @@ class Channel : public SerialisableObject{ public: Channel() : ChannelID(-1), channelrelposition(Position(-1,-1,-1)), stripside(2), stripnum(-1), signal_crate(-1), signal_card(-1), signal_channel(-1), level2_crate(-1), level2_card(-1), level2_channel(-1), hv_crate(-1), hv_card(-1), hv_channel(-1), status(channelstatus::OFF) - {serialise=true;} - Channel(unsigned long chnID, Position chanpos, int strp, int strpnm, unsigned int sig_crt, unsigned int sig_crd, unsigned int sig_chn, unsigned int lv2_crt, unsigned int lv2_crd, unsigned int lv2_ch, unsigned int hv_crt, unsigned int hv_crd, unsigned int hv_chn, channelstatus chanstat) : ChannelID(chnID), channelrelposition(chanpos), stripside(strp), stripnum(strpnm), signal_crate(sig_crt), signal_card(sig_crd), signal_channel(sig_chn), level2_crate(lv2_crt), level2_card(lv2_crd), level2_channel(lv2_ch), hv_crate(hv_crt), hv_card(hv_crd), hv_channel(hv_chn), status(chanstat) {serialise=true;} + {channelType = 0; serialise=true;} + Channel(unsigned long chnID, Position chanpos, int strp, int strpnm, unsigned int sig_crt, unsigned int sig_crd, unsigned int sig_chn, unsigned int lv2_crt, unsigned int lv2_crd, unsigned int lv2_ch, unsigned int hv_crt, unsigned int hv_crd, unsigned int hv_chn, channelstatus chanstat) : ChannelID(chnID), channelrelposition(chanpos), stripside(strp), stripnum(strpnm), signal_crate(sig_crt), signal_card(sig_crd), signal_channel(sig_chn), level2_crate(lv2_crt), level2_card(lv2_crd), level2_channel(lv2_ch), hv_crate(hv_crt), hv_card(hv_crd), hv_channel(hv_chn), status(chanstat) {channelType=0; serialise=true;} + Channel(unsigned long chnID, Position chanpos, int strp, int strpnm, unsigned int sig_crt, unsigned int sig_crd, unsigned int sig_chn, unsigned int lv2_crt, unsigned int lv2_crd, unsigned int lv2_ch, unsigned int hv_crt, unsigned int hv_crd, unsigned int hv_chn, channelstatus chanstat, int channelPMTType) : ChannelID(chnID), channelrelposition(chanpos), stripside(strp), stripnum(strpnm), signal_crate(sig_crt), signal_card(sig_crd), signal_channel(sig_chn), level2_crate(lv2_crt), level2_card(lv2_crd), level2_channel(lv2_ch), hv_crate(hv_crt), hv_card(hv_crd), hv_channel(hv_chn), status(chanstat), channelType(channelPMTType) {serialise=true;} virtual ~Channel(){} unsigned long GetChannelID(){return ChannelID;} @@ -32,6 +33,7 @@ class Channel : public SerialisableObject{ unsigned int GetHvCard(){return hv_card;} unsigned int GetHvChannel(){return hv_channel;} channelstatus GetStatus(){return status;} + int GetChannelType(){return channelType;} void SetChannelID(unsigned long channelIDin){ChannelID=channelIDin;} void SetRelPos(Position pos){ channelrelposition=pos;} @@ -47,6 +49,7 @@ class Channel : public SerialisableObject{ void SetHvCard(unsigned int cardin){hv_card=cardin;} void SetHvChannel(unsigned int chanin){hv_channel=chanin;} void SetStatus(channelstatus stat){status=stat;} + void SetChannelType(int type){channelType=type;} bool Print(){ std::cout<<"ChannelID : "< void serialize(Archive & ar, const unsigned int version){ if(serialise){ ar & ChannelID; @@ -97,6 +101,7 @@ class Channel : public SerialisableObject{ ar & hv_card; ar & hv_channel; ar & status; + ar & channelType; } } diff --git a/DataModel/LAPPDPulse.h b/DataModel/LAPPDPulse.h index 8aff68195..497ae30cb 100755 --- a/DataModel/LAPPDPulse.h +++ b/DataModel/LAPPDPulse.h @@ -28,6 +28,10 @@ class LAPPDPulse : public Hit{ inline double GetHalfEndTime(){return halfEndTime;} inline void SetBaseline(double base){baseline=base;} inline double GetBaseline(){return baseline;} + inline void SetPulseFollowTime(double pulseFollow){pulseFollowTime=pulseFollow;} + inline double GetPulseFollowTime(){return pulseFollowTime;} + inline void SetPulseFollowCharge(double pulseFollow){pulseFollowCharge=pulseFollow;} + inline double GetPulseFollowCharge(){return pulseFollowCharge;} bool Print() { cout<<"TubeId : "<CStore.Get("AuxChannelNumToTypeMap", AuxChannelNumToTypeMap); + m_data->CStore.Get("ChannelNumToTankPMTSPEChargeMap", ChannelKeyToSPEMap); + m_data->CStore.Get("pmt_tubeid_to_channelkey_data", pmtid_to_channelkey); + m_data->CStore.Get("channelkey_to_pmtid", channelkey_to_pmtid); + m_data->CStore.Get("channelkey_to_mrdpmtid", channelkey_to_mrdpmtid); + m_data->CStore.Get("mrdpmtid_to_channelkey_data", mrdpmtid_to_channelkey_data); + m_data->CStore.Get("channelkey_to_faccpmtid", channelkey_to_faccpmtid); + + auto get_geometry = m_data->Stores.at("ANNIEEvent")->Header->Get("AnnieGeometry", geom); + if (!get_geometry) + { + Log("ANNIEEventTreeMaker Tool: Error retrieving Geometry from ANNIEEvent!", v_error, ANNIEEventTreeMakerVerbosity); + return false; + } + + // general information in an event + fANNIETree->Branch("runNumber", &fRunNumber, "runNumber/I"); + fANNIETree->Branch("subrunNumber", &fSubrunNumber, "subrunNumber/I"); + fANNIETree->Branch("partFileNumber", &fPartFileNumber, "partFileNumber/I"); + fANNIETree->Branch("runType", &fRunType, "runType/I"); + fANNIETree->Branch("eventNumber", &fEventNumber, "eventNumber/I"); // + fANNIETree->Branch("PrimaryTriggerWord", &fPrimaryTriggerWord, "PrimaryTriggerWord/I"); + fANNIETree->Branch("GroupedTriggerTime", &fGroupedTriggerTime); + fANNIETree->Branch("GroupedTriggerWord", &fGroupedTriggerWord); + fANNIETree->Branch("trigword", &fTriggerword, "trigword/I"); // keep for trigger 5 or 14 + + // flags from event selector + fANNIETree->Branch("Extended", &fExtended, "Extended/I"); + fANNIETree->Branch("HasTank", &fHasTank, "HasTank/I"); + fANNIETree->Branch("HasMRD", &fHasMRD, "HasMRD/I"); + fANNIETree->Branch("HasLAPPD", &fHasLAPPD, "HasLAPPD/I"); + fANNIETree->Branch("TankMRDCoinc", &fTankMRDCoinc, "TankMRDCoinc/I"); + fANNIETree->Branch("NoVeto", &fNoVeto, "NoVeto/I"); + fANNIETree->Branch("MRDTriggerType", &fMRDTriggerTypeInt, "MRDTriggerType/I"); + //fANNIETree->Branch("MRDTriggerTypeString", &fMRDTriggerType); + + // event information of data + fANNIETree->Branch("eventTimeTank", &fEventTimeTank, "eventTimeTank/l"); + fANNIETree->Branch("eventTimeMRD", &fEventTimeMRD, "eventTimeMRD/l"); + + // beam information + if (BeamInfo_fill) + { + fANNIETree->Branch("beam_pot_875", &fPot, "beam_pot_875/D"); + fANNIETree->Branch("beam_ok", &fBeamok, "beam_ok/I"); + fANNIETree->Branch("BunchRotationOn", &fBunchRotationOn, "BunchRotationOn/I"); + fANNIETree->Branch("beam_E_TOR860", &beam_E_TOR860, "beam_E_TOR860/D"); + fANNIETree->Branch("beam_E_TOR875", &beam_E_TOR875, "beam_E_TOR875/D"); + fANNIETree->Branch("beam_THCURR", &beam_THCURR, "beam_THCURR/D"); + fANNIETree->Branch("beam_BTJT2", &beam_BTJT2, "beam_BTJT2/D"); + fANNIETree->Branch("beam_HP875", &beam_HP875, "beam_HP875/D"); + fANNIETree->Branch("beam_VP875", &beam_VP875, "beam_VP875/D"); + fANNIETree->Branch("beam_HPTG1", &beam_HPTG1, "beam_HPTG1/D"); + fANNIETree->Branch("beam_VPTG1", &beam_VPTG1, "beam_VPTG1/D"); + fANNIETree->Branch("beam_HPTG2", &beam_HPTG2, "beam_HPTG2/D"); + fANNIETree->Branch("beam_VPTG2", &beam_VPTG2, "beam_VPTG2/D"); + fANNIETree->Branch("beam_BTH2T2", &beam_BTH2T2, "beam_BTH2T2/D"); + fANNIETree->Branch("beam_B_BRRMPL", &beam_B_BRRMPL, "beam_B_BRRMPL/D"); + fANNIETree->Branch("beam_B_BRRMPQ", &beam_B_BRRMPQ, "beam_B_BRRMPQ/D"); + fANNIETree->Branch("beam_B_BRRMPS", &beam_B_BRRMPS, "beam_B_BRRMPS/D"); + fANNIETree->Branch("beam_B_BRRMP", &beam_B_BRRMP, "beam_B_BRRMP/D"); + fANNIETree->Branch("BeamInfoTime", &fBeamInfoTime, "BeamInfoTime/l"); + fANNIETree->Branch("BeamInfoTimeToTriggerDiff", &fBeamInfoTimeToTriggerDiff, "BeamInfoTimeToTriggerDiff/L"); + } + + if (RWMBRF_fill) + { + fANNIETree->Branch("RWMRisingStart", &fRWMRisingStart, "fRWMRisingStart/D"); + fANNIETree->Branch("RWMRisingEnd", &fRWMRisingEnd, "fRWMRisingEnd/D"); + fANNIETree->Branch("RWMHalfRising", &fRWMHalfRising, "fRWMHalfRising/D"); + fANNIETree->Branch("RWMFHWM", &fRWMFHWM, "fRWMFHWM/D"); + fANNIETree->Branch("RWMFirstPeak", &fRWMFirstPeak, "fRWMFirstPeak/D"); + + fANNIETree->Branch("BRFFirstPeak", &fBRFFirstPeak, "fBRFFirstPeak/D"); + fANNIETree->Branch("BRFAveragePeak", &fBRFAveragePeak, "fBRFAveragePeak/D"); + fANNIETree->Branch("BRFFirstPeakFit", &fBRFFirstPeakFit, "fBRFFirstPeakFit/D"); + } + + //********************************************************// + + // Tank cluster information + + fANNIETree->Branch("numberOfClusters", &fNumberOfClusters, "fNumberOfClusters/I"); + fANNIETree->Branch("clusterTime", &fClusterTimeV); + fANNIETree->Branch("clusterCharge", &fClusterChargeV); + fANNIETree->Branch("clusterPE", &fClusterPEV); + fANNIETree->Branch("clusterMaxPE", &fClusterMaxPEV); + fANNIETree->Branch("clusterChargePointX", &fClusterChargePointXV); + fANNIETree->Branch("clusterChargePointY", &fClusterChargePointYV); + fANNIETree->Branch("clusterChargePointZ", &fClusterChargePointZV); + fANNIETree->Branch("clusterChargeBalance", &fClusterChargeBalanceV); + fANNIETree->Branch("clusterHits", &fClusterHits); + fANNIETree->Branch("Cluster_HitX", &fCluster_HitX); + fANNIETree->Branch("Cluster_HitY", &fCluster_HitY); + fANNIETree->Branch("Cluster_HitZ", &fCluster_HitZ); + fANNIETree->Branch("Cluster_HitT", &fCluster_HitT); + fANNIETree->Branch("Cluster_HitQ", &fCluster_HitQ); + fANNIETree->Branch("Cluster_HitPE", &fCluster_HitPE); + fANNIETree->Branch("Cluster_HitType", &fCluster_HitType); + fANNIETree->Branch("Cluster_HitDetID", &fCluster_HitDetID); + fANNIETree->Branch("Cluster_HitChankey", &fCluster_HitChankey); + fANNIETree->Branch("Cluster_HitChankeyMC", &fCluster_HitChankeyMC); + fANNIETree->Branch("Cluster_HitPMTType", &fCluster_HitPMTType); + + // MRD cluster information + fANNIETree->Branch("eventTimeMRD", &fEventTimeMRD_Tree); + fANNIETree->Branch("MRDClusterNumber", &fMRDClusterNumber); + fANNIETree->Branch("MRDClusterTime", &fMRDClusterTime); + fANNIETree->Branch("MRDClusterTimeSigma", &fMRDClusterTimeSigma); + fANNIETree->Branch("MRDClusterHitNumber", &fMRDClusterHitNumber); + + if (TankHitInfo_fill) + { + // Tank Hit information + fANNIETree->Branch("nhits", &fNHits, "nhits/I"); + fANNIETree->Branch("filter", &fIsFiltered); + fANNIETree->Branch("hitX", &fHitX); + fANNIETree->Branch("hitY", &fHitY); + fANNIETree->Branch("hitZ", &fHitZ); + fANNIETree->Branch("hitT", &fHitT); + fANNIETree->Branch("hitQ", &fHitQ); + fANNIETree->Branch("hitPE", &fHitPE); + fANNIETree->Branch("hitType", &fHitType); + fANNIETree->Branch("hitDetID", &fHitDetID); + fANNIETree->Branch("hitChankey", &fHitChankey); + fANNIETree->Branch("hitChankeyMC", &fHitChankeyMC); + fANNIETree->Branch("hitPMTType", &fHitPMTType); + } + + if (SiPMPulseInfo_fill) + { + fANNIETree->Branch("SiPMhitQ", &fSiPMHitQ); + fANNIETree->Branch("SiPMhitT", &fSiPMHitT); + fANNIETree->Branch("SiPMhitAmplitude", &fSiPMHitAmplitude); + fANNIETree->Branch("SiPMNum", &fSiPMNum); + fANNIETree->Branch("SiPM1NPulses", &fSiPM1NPulses, "SiPM1NPulses/I"); + fANNIETree->Branch("SiPM2NPulses", &fSiPM2NPulses, "SiPM2NPulses/I"); + } + + if (LAPPDData_fill) + { + fANNIETree->Branch("LAPPD_ID", &fLAPPD_ID); + fANNIETree->Branch("LAPPD_Position", &fLAPPD_Position); + fANNIETree->Branch("LAPPD_Count", &fLAPPD_Count); + fANNIETree->Branch("LAPPD_Beamgate_ns", &fLAPPD_Beamgate_ns); + fANNIETree->Branch("LAPPD_Timestamp_ns", &fLAPPD_Timestamp_ns); + fANNIETree->Branch("LAPPD_Beamgate_Raw", &fLAPPD_Beamgate_Raw); + fANNIETree->Branch("LAPPD_Timestamp_Raw", &fLAPPD_Timestamp_Raw); + fANNIETree->Branch("LAPPD_Offset", &fLAPPD_Offset); + fANNIETree->Branch("LAPPD_TSCorrection", &fLAPPD_TSCorrection); + fANNIETree->Branch("LAPPD_BGCorrection", &fLAPPD_BGCorrection); + fANNIETree->Branch("LAPPD_OSInMinusPS", &fLAPPD_OSInMinusPS); + if (LAPPD_PPS_fill) + { + fANNIETree->Branch("LAPPD_BGPPSBefore", &fLAPPD_BGPPSBefore); + fANNIETree->Branch("LAPPD_BGPPSAfter", &fLAPPD_BGPPSAfter); + fANNIETree->Branch("LAPPD_BGPPSDiff", &fLAPPD_BGPPSDiff); + fANNIETree->Branch("LAPPD_BGPPSMissing", &fLAPPD_BGPPSMissing); + fANNIETree->Branch("LAPPD_TSPPSBefore", &fLAPPD_TSPPSBefore); + fANNIETree->Branch("LAPPD_TSPPSAfter", &fLAPPD_TSPPSAfter); + fANNIETree->Branch("LAPPD_TSPPSDiff", &fLAPPD_TSPPSDiff); + fANNIETree->Branch("LAPPD_TSPPSMissing", &fLAPPD_TSPPSMissing); + } + fANNIETree->Branch("LAPPD_BG_switchBit0", &fLAPPD_BG_switchBit0); + fANNIETree->Branch("LAPPD_BG_switchBit1", &fLAPPD_BG_switchBit1); + + // load the ID conversion table + string ACCIDConfigFile = "LAPPDIDConfig.csv"; + m_variables.Get("ACCIDConfigFile", ACCIDConfigFile); + idConfigRecords = LoadIDConfig(ACCIDConfigFile); + //print the loaded records + if (ANNIEEventTreeMakerVerbosity > 1) + { + // print the ACCID config records for debug + cout << "Loaded LAPPD ID Config Records from " << ACCIDConfigFile << ":" << endl; + for (const auto& record : idConfigRecords) { + cout << "RunNumber: " << record.RunNumber + << ", ACCID: " << record.ACCID + << ", ManufacturerID: " << record.ManufacturerID + << ", Position: " << record.Position << endl; + } + + int testRunNum = 4950; + int testACCID = 1; // example ACCID to query + auto result = queryNearestID(idConfigRecords, testRunNum, testACCID); + int nearestManuID = std::get<0>(result); + std::string position = std::get<1>(result); + cout << "Querying nearest ID for RunNumber: " << testRunNum << ", ACCID: " << testACCID << endl; + cout << "Nearest ManufacturerID: " << nearestManuID << ", Position: " << position << endl; + + int testRunNum2 = 5000; + int testACCID2 = 2; // example ACCID to query + auto result2 = queryNearestID(idConfigRecords, testRunNum2, testACCID2); + int nearestManuID2 = std::get<0>(result2); + std::string position2 = std::get<1>(result2); + cout << "Querying nearest ID for RunNumber: " << testRunNum2 << ", ACCID: " << testACCID2 << endl; + cout << "Nearest ManufacturerID: " << nearestManuID2 << ", Position: " << position2 << endl; + + int testRunNum3 = 5907; + int testManuID3 = 39; // example ManufacturerID to query + auto result3 = queryNearestACCID(idConfigRecords, testRunNum3, testManuID3); + int nearestACCID3 = std::get<0>(result3); + std::string position3 = std::get<1>(result3); + cout << "Querying nearest ACCID for RunNumber: " << testRunNum3 << ", ManufacturerID: " << testManuID3 << endl; + cout << "Nearest ACCID: " << nearestACCID3 << ", Position: " << position3 << endl; + } + } + + // LAPPD reconstruction information + if (LAPPDReco_fill) + { + // fANNIETree->Branch("LAPPDPulseTimeStampUL", &fLAPPDPulseTimeStampUL, "LAPPDPulseTimeStampUL/l"); + // fANNIETree->Branch("LAPPDPulseBeamgateUL", &fLAPPDPulseBeamgateUL, "LAPPDPulseBeamgateUL/l"); + // actually we don't need these two for pulse and hit, because it is impossible to have multiple events from one LAPPD in one ANNIEEvent due to the dead time and the trigger scheme + // LAPPD ID is enough to find the corresponding unix timestamp + // but leave them there in case + + fANNIETree->Branch("LAPPD_PulseIDs", &fLAPPD_IDs); + fANNIETree->Branch("LAPPD_ChannelID", &fChannelID); + fANNIETree->Branch("LAPPD_PeakTime", &fPulsePeakTime); + fANNIETree->Branch("LAPPD_PulseHalfHeightTime", &fPulseHalfHeightTime); + fANNIETree->Branch("LAPPD_PeakAmp", &fPulsePeakAmp); + fANNIETree->Branch("LAPPD_Charge", &fPulseCharge); + fANNIETree->Branch("LAPPD_PulseStart", &fPulseStart); + fANNIETree->Branch("LAPPD_PulseEnd", &fPulseEnd); + fANNIETree->Branch("LAPPD_PulseWidth", &fPulseWidth); + fANNIETree->Branch("LAPPD_PulseSide", &fPulseSide); + fANNIETree->Branch("LAPPD_PulseStripNum", &fPulseStripNum); + fANNIETree->Branch("LAPPD_PulseBaseline", &fPulseBaseline); + fANNIETree->Branch("LAPPD_PulseFollowTime", &fPulseFollowTime); + fANNIETree->Branch("LAPPD_PulseFollowCharge", &fPulseFollowCharge); + + // fANNIETree->Branch("LAPPDHitTimeStampUL", &fLAPPDHitTimeStampUL, "LAPPDHitTimeStampUL/l"); + // fANNIETree->Branch("LAPPDHitBeamgateUL", &fLAPPDHitBeamgateUL, "LAPPDHitBeamgateUL/l"); + + fANNIETree->Branch("LAPPDID_Hit", &fLAPPDHit_IDs); + fANNIETree->Branch("LAPPDHitChannel", &fLAPPDHitChannel); + fANNIETree->Branch("LAPPDHitStrip", &fLAPPDHitStrip); + fANNIETree->Branch("LAPPDHitTime", &fLAPPDHitTime); + fANNIETree->Branch("LAPPDHitAmp", &fLAPPDHitAmp); + fANNIETree->Branch("LAPPDHitParallelPos", &fLAPPDHitParallelPos); + fANNIETree->Branch("LAPPDHitTransversePos", &fLAPPDHitTransversePos); + fANNIETree->Branch("LAPPDHitP1StartTime", &fLAPPDHitP1StartTime); + fANNIETree->Branch("LAPPDHitP2StartTime", &fLAPPDHitP2StartTime); + fANNIETree->Branch("LAPPDHitP1EndTime", &fLAPPDHitP1EndTime); + fANNIETree->Branch("LAPPDHitP2EndTime", &fLAPPDHitP2EndTime); + + fANNIETree->Branch("LAPPDHitP1PeakTime", &fLAPPDHitP1PeakTime); + fANNIETree->Branch("LAPPDHitP2PeakTime", &fLAPPDHitP2PeakTime); + fANNIETree->Branch("LAPPDHitP1PeakAmp", &fLAPPDHitP1PeakAmp); + fANNIETree->Branch("LAPPDHitP2PeakAmp", &fLAPPDHitP2PeakAmp); + fANNIETree->Branch("LAPPDHitP1HalfHeightTime", &fLAPPDHitP1HalfHeightTime); + fANNIETree->Branch("LAPPDHitP2HalfHeightTime", &fLAPPDHitP2HalfHeightTime); + fANNIETree->Branch("LAPPDHitP1HalfEndTime", &fLAPPDHitP1HalfEndTime); + fANNIETree->Branch("LAPPDHitP2HalfEndTime", &fLAPPDHitP2HalfEndTime); + fANNIETree->Branch("LAPPDHitP1Charge", &fLAPPDHitP1Charge); + fANNIETree->Branch("LAPPDHitP2Charge", &fLAPPDHitP2Charge); + fANNIETree->Branch("LAPPDHitP1Baseline", &fLAPPDHitP1Baseline); + fANNIETree->Branch("LAPPDHitP2Baseline", &fLAPPDHitP2Baseline); + fANNIETree->Branch("LAPPDHitP1FollowTime", &fLAPPDHitP1FollowTime); + fANNIETree->Branch("LAPPDHitP2FollowTime", &fLAPPDHitP2FollowTime); + fANNIETree->Branch("LAPPDHitP1FollowCharge", &fLAPPDHitP1FollowCharge); + fANNIETree->Branch("LAPPDHitP2FollowCharge", &fLAPPDHitP2FollowCharge); + + /* + fANNIETree->Branch("LAPPDWaveformChankey", &LAPPDWaveformChankey, "LAPPDWaveformChankey/I"); + fANNIETree->Branch("WaveformMax", &waveformMaxValue, "WaveformMax/D"); + fANNIETree->Branch("WaveformRMS", &waveformRMSValue, "WaveformRMS/D"); + fANNIETree->Branch("WaveformMaxTimeBin", &waveformMaxTimeBinValue, "WaveformMaxTimeBin/I"); + fANNIETree->Branch("waveformMaxFoundNear", &waveformMaxFoundNear, "waveformMaxFoundNear/O"); // O is boolean + fANNIETree->Branch("WaveformMaxNearing", &waveformMaxNearingValue, "WaveformMaxNearing/D"); + */ + } + + LAPPDWaveformInputLabel = "BLsubtractedLAPPDData"; + m_variables.Get("LAPPDWaveformInputLabel", LAPPDWaveformInputLabel); + if (LAPPD_Waveform_fill) + { + // Log("ANNIEEventTreeMaker Tool: LAPPDWaveformInputLabel = " + LAPPDWaveformInputLabel, 0, ANNIEEventTreeMakerVerbosity); + fANNIETree->Branch("LAPPDWaveform", &fLAPPDWaveforms); + } + + if (LAPPD_MC_fill) + { + fANNIETree->Branch("LAPPDMCHitTubeIDs", &fLAPPDMCHitTubeIDs); + fANNIETree->Branch("LAPPDMCHitChankeys", &fLAPPDMCHitChankeys); + fANNIETree->Branch("LAPPDMCHitTime", &fLAPPDMCHitTime); + fANNIETree->Branch("LAPPDMCHitCharge", &fLAPPDMCHitCharge); + fANNIETree->Branch("LAPPDMCHitX", &fLAPPDMCHitX); + fANNIETree->Branch("LAPPDMCHitY", &fLAPPDMCHitY); + fANNIETree->Branch("LAPPDMCHitZ", &fLAPPDMCHitZ); + fANNIETree->Branch("LAPPDMCHitParallelPos", &fLAPPDMCHitParallelPos); + fANNIETree->Branch("LAPPDMCHitTransversePos", &fLAPPDMCHitTransversePos); + } + + if (MRDHitInfo_fill) + { + fANNIETree->Branch("MRDHitClusterIndex", &fMRDHitClusterIndex); + fANNIETree->Branch("MRDhitT", &fMRDHitT); + fANNIETree->Branch("MRDHitCharge", &fMRDHitCharge); + fANNIETree->Branch("MRDHitDigitPMT", &fMRDHitDigitPMT); + + fANNIETree->Branch("MRDhitDetID", &fMRDHitDetID); + fANNIETree->Branch("MRDhitChankey", &fMRDHitChankey); + fANNIETree->Branch("MRDhitChankeyMC", &fMRDHitChankeyMC); + fANNIETree->Branch("FMVhitT", &fFMVHitT); + fANNIETree->Branch("FMVhitDetID", &fFMVHitDetID); + fANNIETree->Branch("FMVhitChankey", &fFMVHitChankey); + fANNIETree->Branch("FMVhitChankeyMC", &fFMVHitChankeyMC); + fANNIETree->Branch("vetoHit", &fVetoHit, "vetoHit/I"); + } + + if (MRDReco_fill) + { + fANNIETree->Branch("MRDClusterIndex", &fMRDClusterIndex); + fANNIETree->Branch("NumClusterTracks", &fNumClusterTracks); + fANNIETree->Branch("MRDTrackAngle", &fMRDTrackAngle); + fANNIETree->Branch("MRDTrackAngleError", &fMRDTrackAngleError); + fANNIETree->Branch("MRDPenetrationDepth", &fMRDPenetrationDepth); + fANNIETree->Branch("MRDTrackLength", &fMRDTrackLength); + fANNIETree->Branch("MRDEntryPointRadius", &fMRDEntryPointRadius); + fANNIETree->Branch("MRDEnergyLoss", &fMRDEnergyLoss); + fANNIETree->Branch("MRDEnergyLossError", &fMRDEnergyLossError); + fANNIETree->Branch("MRDTrackStartX", &fMRDTrackStartX); + fANNIETree->Branch("MRDTrackStartY", &fMRDTrackStartY); + fANNIETree->Branch("MRDTrackStartZ", &fMRDTrackStartZ); + fANNIETree->Branch("MRDTrackStopX", &fMRDTrackStopX); + fANNIETree->Branch("MRDTrackStopY", &fMRDTrackStopY); + fANNIETree->Branch("MRDTrackStopZ", &fMRDTrackStopZ); + fANNIETree->Branch("MRDSide", &fMRDSide); + fANNIETree->Branch("MRDStop", &fMRDStop); + fANNIETree->Branch("MRDThrough", &fMRDThrough); + } + + fANNIETree->Branch("eventStatusApplied", &fEventStatusApplied, "eventStatusApplied/I"); + fANNIETree->Branch("eventStatusFlagged", &fEventStatusFlagged, "eventStatusFlagged/I"); + + // MC truth information for muons + // Output to tree when MCTruth_fill = 1 in config + if (MCTruth_fill) + { + fTrueNeutCapVtxX = new std::vector; + fTrueNeutCapVtxY = new std::vector; + fTrueNeutCapVtxZ = new std::vector; + fTrueNeutCapNucleus = new std::vector; + fTrueNeutCapTime = new std::vector; + fTrueNeutCapGammas = new std::vector; + fTrueNeutCapE = new std::vector; + fTrueNeutCapGammaE = new std::vector; + fTruePrimaryPdgs = new std::vector; + fANNIETree->Branch("triggerNumber", &fiMCTriggerNum, "triggerNumber/I"); + fANNIETree->Branch("mcEntryNumber", &fMCEventNum, "mcEntryNumber/I"); + fANNIETree->Branch("trueVtxX", &fTrueVtxX, "trueVtxX/D"); + fANNIETree->Branch("trueVtxY", &fTrueVtxY, "trueVtxY/D"); + fANNIETree->Branch("trueVtxZ", &fTrueVtxZ, "trueVtxZ/D"); + fANNIETree->Branch("trueVtxTime", &fTrueVtxTime, "trueVtxTime/D"); + fANNIETree->Branch("trueDirX", &fTrueDirX, "trueDirX/D"); + fANNIETree->Branch("trueDirY", &fTrueDirY, "trueDirY/D"); + fANNIETree->Branch("trueDirZ", &fTrueDirZ, "trueDirZ/D"); + fANNIETree->Branch("trueAngle", &fTrueAngle, "trueAngle/D"); + fANNIETree->Branch("truePhi", &fTruePhi, "truePhi/D"); + fANNIETree->Branch("trueMuonEnergy", &fTrueMuonEnergy, "trueMuonEnergy/D"); + fANNIETree->Branch("truePrimaryPdg", &fTruePrimaryPdg, "truePrimaryPdg/I"); + fANNIETree->Branch("trueTrackLengthInWater", &fTrueTrackLengthInWater, "trueTrackLengthInWater/D"); + fANNIETree->Branch("trueTrackLengthInMRD", &fTrueTrackLengthInMRD, "trueTrackLengthInMRD/D"); + fANNIETree->Branch("trueMultiRing", &fTrueMultiRing, "trueMultiRing/I"); + fANNIETree->Branch("Pi0Count", &fPi0Count, "Pi0Count/I"); + fANNIETree->Branch("PiPlusCount", &fPiPlusCount, "PiPlusCount/I"); + fANNIETree->Branch("PiMinusCount", &fPiMinusCount, "PiMinusCount/I"); + fANNIETree->Branch("K0Count", &fK0Count, "K0Count/I"); + fANNIETree->Branch("KPlusCount", &fKPlusCount, "KPlusCount/I"); + fANNIETree->Branch("KMinusCount", &fKMinusCount, "KMinusCount/I"); + fANNIETree->Branch("truePrimaryPdgs", &fTruePrimaryPdgs); + fANNIETree->Branch("trueNeutCapVtxX", &fTrueNeutCapVtxX); + fANNIETree->Branch("trueNeutCapVtxY", &fTrueNeutCapVtxY); + fANNIETree->Branch("trueNeutCapVtxZ", &fTrueNeutCapVtxZ); + fANNIETree->Branch("trueNeutCapNucleus", &fTrueNeutCapNucleus); + fANNIETree->Branch("trueNeutCapTime", &fTrueNeutCapTime); + fANNIETree->Branch("trueNeutCapGammas", &fTrueNeutCapGammas); + fANNIETree->Branch("trueNeutCapE", &fTrueNeutCapE); + fANNIETree->Branch("trueNeutCapGammaE", &fTrueNeutCapGammaE); + fANNIETree->Branch("trueNeutrinoEnergy", &fTrueNeutrinoEnergy, "trueNeutrinoEnergy/D"); + fANNIETree->Branch("trueNeutrinoMomentum_X", &fTrueNeutrinoMomentum_X, "trueNeutrinoMomentum_X/D"); + fANNIETree->Branch("trueNeutrinoMomentum_Y", &fTrueNeutrinoMomentum_Y, "trueNeutrinoMomentum_Y/D"); + fANNIETree->Branch("trueNeutrinoMomentum_Z", &fTrueNeutrinoMomentum_Z, "trueNeutrinoMomentum_Z/D"); + fANNIETree->Branch("trueNuIntxVtx_X", &fTrueNuIntxVtx_X, "trueNuIntxVtx_X/D"); + fANNIETree->Branch("trueNuIntxVtx_Y", &fTrueNuIntxVtx_Y, "trueNuIntxVtx_Y/D"); + fANNIETree->Branch("trueNuIntxVtx_Z", &fTrueNuIntxVtx_Z, "trueNuIntxVtx_Z/D"); + fANNIETree->Branch("trueNuIntxVtx_T", &fTrueNuIntxVtx_T, "trueNuIntxVtx_T/D"); + fANNIETree->Branch("trueFSLVtx_X", &fTrueFSLVtx_X, "trueFSLVtx_X/D"); + fANNIETree->Branch("trueFSLVtx_Y", &fTrueFSLVtx_Y, "trueFSLVtx_Y/D"); + fANNIETree->Branch("trueFSLVtx_Z", &fTrueFSLVtx_Z, "trueFSLVtx_Z/D"); + fANNIETree->Branch("trueFSLMomentum_X", &fTrueFSLMomentum_X, "trueFSLMomentum_X/D"); + fANNIETree->Branch("trueFSLMomentum_Y", &fTrueFSLMomentum_Y, "trueFSLMomentum_Y/D"); + fANNIETree->Branch("trueFSLMomentum_Z", &fTrueFSLMomentum_Z, "trueFSLMomentum_Z/D"); + fANNIETree->Branch("trueFSLTime", &fTrueFSLTime, "trueFSLTime/D"); + fANNIETree->Branch("trueFSLMass", &fTrueFSLMass, "trueFSLMass/D"); + fANNIETree->Branch("trueFSLPdg", &fTrueFSLPdg, "trueFSLPdg/I"); + fANNIETree->Branch("trueFSLEnergy", &fTrueFSLEnergy, "trueFSLEnergy/D"); + fANNIETree->Branch("trueQ2", &fTrueQ2, "trueQ2/D"); + fANNIETree->Branch("trueCC", &fTrueCC, "trueCC/I"); + fANNIETree->Branch("trueNC", &fTrueNC, "trueNC/I"); + fANNIETree->Branch("trueQEL", &fTrueQEL, "trueQEL/I"); + fANNIETree->Branch("trueRES", &fTrueRES, "trueRES/I"); + fANNIETree->Branch("trueDIS", &fTrueDIS, "trueDIS/I"); + fANNIETree->Branch("trueCOH", &fTrueCOH, "trueCOH/I"); + fANNIETree->Branch("trueMEC", &fTrueMEC, "trueMEC/I"); + fANNIETree->Branch("trueNeutrons", &fTrueNeutrons, "trueNeutrons/I"); + fANNIETree->Branch("trueProtons", &fTrueProtons, "trueProtons/I"); + fANNIETree->Branch("truePi0", &fTruePi0, "truePi0/I"); + fANNIETree->Branch("truePiPlus", &fTruePiPlus, "truePiPlus/I"); + fANNIETree->Branch("truePiPlusCher", &fTruePiPlusCher, "truePiPlusCher/I"); + fANNIETree->Branch("truePiMinus", &fTruePiMinus, "truePiMinus/I"); + fANNIETree->Branch("truePiMinusCher", &fTruePiMinusCher, "truePiMinusCher/I"); + fANNIETree->Branch("trueKPlus", &fTrueKPlus, "trueKPlus/I"); + fANNIETree->Branch("trueKPlusCher", &fTrueKPlusCher, "trueKPlusCher/I"); + fANNIETree->Branch("trueKMinus", &fTrueKMinus, "trueKMinus/I"); + fANNIETree->Branch("trueKMinusCher", &fTrueKMinusCher, "trueKMinusCher/I"); + } + + // Reconstructed variables after full Muon Reco Analysis + if (TankReco_fill) + { + fANNIETree->Branch("recoVtxX", &fRecoVtxX, "recoVtxX/D"); + fANNIETree->Branch("recoVtxY", &fRecoVtxY, "recoVtxY/D"); + fANNIETree->Branch("recoVtxZ", &fRecoVtxZ, "recoVtxZ/D"); + fANNIETree->Branch("recoVtxTime", &fRecoVtxTime, "recoVtxTime/D"); + fANNIETree->Branch("recoDirX", &fRecoDirX, "recoDirX/D"); + fANNIETree->Branch("recoDirY", &fRecoDirY, "recoDirY/D"); + fANNIETree->Branch("recoDirZ", &fRecoDirZ, "recoDirZ/D"); + fANNIETree->Branch("recoAngle", &fRecoAngle, "recoAngle/D"); + fANNIETree->Branch("recoPhi", &fRecoPhi, "recoPhi/D"); + fANNIETree->Branch("recoVtxFOM", &fRecoVtxFOM, "recoVtxFOM/D"); + fANNIETree->Branch("recoStatus", &fRecoStatus, "recoStatus/I"); + } + + // fill ring counting info + if (RingCounting_fill) + { + fANNIETree->Branch("RC_singleRingP", &fRC_singleRingP, "RC_singleRingP/D"); + fANNIETree->Branch("RC_multiRingP", &fRC_multiRingP, "RC_multiRingP/D"); + } + + // Reconstructed variables from each step in Muon Reco Analysis + // Currently output when RecoDebug_fill = 1 in config + if (RecoDebug_fill) + { + fANNIETree->Branch("seedVtxX", &fSeedVtxX); + fANNIETree->Branch("seedVtxY", &fSeedVtxY); + fANNIETree->Branch("seedVtxZ", &fSeedVtxZ); + fANNIETree->Branch("seedVtxFOM", &fSeedVtxFOM); + fANNIETree->Branch("seedVtxTime", &fSeedVtxTime, "seedVtxTime/D"); + + fANNIETree->Branch("pointPosX", &fPointPosX, "pointPosX/D"); + fANNIETree->Branch("pointPosY", &fPointPosY, "pointPosY/D"); + fANNIETree->Branch("pointPosZ", &fPointPosZ, "pointPosZ/D"); + fANNIETree->Branch("pointPosTime", &fPointPosTime, "pointPosTime/D"); + fANNIETree->Branch("pointPosFOM", &fPointPosFOM, "pointPosFOM/D"); + fANNIETree->Branch("pointPosStatus", &fPointPosStatus, "pointPosStatus/I"); + + fANNIETree->Branch("pointDirX", &fPointDirX, "pointDirX/D"); + fANNIETree->Branch("pointDirY", &fPointDirY, "pointDirY/D"); + fANNIETree->Branch("pointDirZ", &fPointDirZ, "pointDirZ/D"); + fANNIETree->Branch("pointDirTime", &fPointDirTime, "pointDirTime/D"); + fANNIETree->Branch("pointDirStatus", &fPointDirStatus, "pointDirStatus/I"); + fANNIETree->Branch("pointDirFOM", &fPointDirFOM, "pointDirFOM/D"); + + fANNIETree->Branch("pointVtxPosX", &fPointVtxPosX, "pointVtxPosX/D"); + fANNIETree->Branch("pointVtxPosY", &fPointVtxPosY, "pointVtxPosY/D"); + fANNIETree->Branch("pointVtxPosZ", &fPointVtxPosZ, "pointVtxPosZ/D"); + fANNIETree->Branch("pointVtxTime", &fPointVtxTime, "pointVtxTime/D"); + fANNIETree->Branch("pointVtxDirX", &fPointVtxDirX, "pointVtxDirX/D"); + fANNIETree->Branch("pointVtxDirY", &fPointVtxDirY, "pointVtxDirY/D"); + fANNIETree->Branch("pointVtxDirZ", &fPointVtxDirZ, "pointVtxDirZ/D"); + fANNIETree->Branch("pointVtxFOM", &fPointVtxFOM, "pointVtxFOM/D"); + fANNIETree->Branch("pointVtxStatus", &fPointVtxStatus, "pointVtxStatus/I"); + } + + // Difference in MC Truth and Muon Reconstruction Analysis + // Output to tree when muonTruthRecoDiff_fill = 1 in config + if (muonTruthRecoDiff_fill) + { + fANNIETree->Branch("deltaVtxX", &fDeltaVtxX, "deltaVtxX/D"); + fANNIETree->Branch("deltaVtxY", &fDeltaVtxY, "deltaVtxY/D"); + fANNIETree->Branch("deltaVtxZ", &fDeltaVtxZ, "deltaVtxZ/D"); + fANNIETree->Branch("deltaVtxR", &fDeltaVtxR, "deltaVtxR/D"); + fANNIETree->Branch("deltaVtxT", &fDeltaVtxT, "deltaVtxT/D"); + fANNIETree->Branch("deltaParallel", &fDeltaParallel, "deltaParallel/D"); + fANNIETree->Branch("deltaPerpendicular", &fDeltaPerpendicular, "deltaPerpendicular/D"); + fANNIETree->Branch("deltaAzimuth", &fDeltaAzimuth, "deltaAzimuth/D"); + fANNIETree->Branch("deltaZenith", &fDeltaZenith, "deltaZenith/D"); + fANNIETree->Branch("deltaAngle", &fDeltaAngle, "deltaAngle/D"); + } + + return true; +} + +bool ANNIEEventTreeMaker::Execute() +{ + //****************************** Reset Variables *************************************// + ResetVariables(); + + //****************************** fillCleanEventsOnly *************************************// + // If only clean events are built, return true for dirty events + auto get_flagsapp = m_data->Stores.at("RecoEvent")->Get("EventFlagApplied", fEventStatusApplied); + auto get_flags = m_data->Stores.at("RecoEvent")->Get("EventFlagged", fEventStatusFlagged); + + if (fillCleanEventsOnly) + { + // auto get_cutstatus = m_data->Stores.at("RecoEvent")->Get("EventCutStatus",fEventCutStatus); + if (!get_flagsapp || !get_flags) + { + Log("PhaseITreeMaker tool: No Event status applied or flagged bitmask!!", v_error, ANNIEEventTreeMakerVerbosity); + return false; + } + // check if event passes the cut + if ((fEventStatusFlagged) != 0) + { + // if (!fEventCutStatus){ + Log("ANNIEEventTreeMaker Tool: Event was flagged with one of the active cuts.", v_debug, ANNIEEventTreeMakerVerbosity); + return true; + } + } + // done + + //****************************** Fill Event Info *************************************// + bool keepLoading = LoadEventInfo(); + if (!keepLoading) + return false; + LoadBeamInfo(); + // done + + //****************************** Fill RWM BRF Info *************************************// + if (RWMBRF_fill) + { + LoadRWMBRFInfo(); + } + + //****************************** Fill Hit Info *************************************// + if (TankHitInfo_fill) + { + // this will fill all hits in this event + LoadAllTankHits(); + } + if (SiPMPulseInfo_fill) + { + LoadSiPMHits(); + } + // done + //****************************** Fill Cluster Info *************************************// + if (TankCluster_fill) + { + LoadClusterInfo(); + } + + //****************************** Fill LAPPD Info *************************************// + if (LAPPDData_fill) + { + LoadLAPPDInfo(); + } + if (LAPPD_Waveform_fill) + { + FillLAPPDWaveform(); + } + + if (LAPPD_MC_fill) + { + FillLAPPDMCHitInfo(); + } + + //****************************** Fill MRD Info *************************************// + if (MRDHitInfo_fill) + { + LoadMRDCluster(); + } + + //****************************** Fill Reco Info *************************************// + bool got_reco = false; + if (TankReco_fill) + { + got_reco = FillTankRecoInfo(); + } + + if (RingCounting_fill) + { + bool got_srFlag = m_data->Stores.at("RecoEvent")->Get("RingCountingSRPrediction", fRC_singleRingP); + bool got_mrFlag = m_data->Stores.at("RecoEvent")->Get("RingCountingMRPrediction", fRC_multiRingP); + if(ANNIEEventTreeMakerVerbosity>1) + cout<<"Printing ring counting: got_srFlag = "<FillTruthRecoDiffInfo(gotmctruth, got_reco); + + //****************************** Fill Reco Summary *************************************// + if (got_reco && gotmctruth && (ANNIEEventTreeMakerVerbosity > 4)) + { + RecoSummary(); + } + + //****************************** Fill Tree *************************************// + fANNIETree->Fill(); + + processedEvents++; + return true; +} + +bool ANNIEEventTreeMaker::Finalise() +{ + Log("ANNIEEventTreeMaker Tool: Got " + std::to_string(processedEvents) + " events", 0, ANNIEEventTreeMakerVerbosity); + fOutput_tfile->cd(); + fANNIETree->Write(); + fOutput_tfile->Close(); + Log("ANNIEEventTreeMaker Tool: Tree written to file", 0, ANNIEEventTreeMakerVerbosity); + + return true; +} + +void ANNIEEventTreeMaker::ResetVariables() +{ + // Reset all variables + + // Event Info + fRunNumber = 0; + fSubrunNumber = 0; + fPartFileNumber = 0; + fEventNumber = 0; + fPrimaryTriggerWord = 0; + fPrimaryTriggerTime = 0; + fTriggerword = 0; + fExtended = 0; + fTankMRDCoinc = 0; + fNoVeto = 0; + fHasTank = 0; + fHasMRD = 0; + fHasLAPPD = 0; + fGroupedTriggerTime.clear(); + fGroupedTriggerWord.clear(); + fDataStreams.clear(); + fEventTimeTank = 0; + fEventTimeMRD = 0; + fMRDTriggerType = ""; + fMRDTriggerTypeInt = -9999; + + // beam info + fPot = -9999; + fBeamok = 0; + fBunchRotationOn = 0; + beam_E_TOR860 = -9999; + beam_E_TOR875 = -9999; + beam_THCURR = -9999; + beam_BTJT2 = -9999; + beam_HP875 = -9999; + beam_VP875 = -9999; + beam_HPTG1 = -9999; + beam_VPTG1 = -9999; + beam_HPTG2 = -9999; + beam_VPTG2 = -9999; + beam_BTH2T2 = -9999; + beam_B_BRRMPL = -9999; + beam_B_BRRMPQ = -9999; + beam_B_BRRMPS = -9999; + beam_B_BRRMP = -9999; + fBeamInfoTime = 0; + fBeamInfoTimeToTriggerDiff = -9999; + + // RWM BRF info + fRWMRisingStart = -9999; + fRWMRisingEnd = -9999; + fRWMHalfRising = -9999; + fRWMFHWM = -9999; + fRWMFirstPeak = -9999; + fBRFFirstPeak = -9999; + fBRFAveragePeak = -9999; + fBRFFirstPeakFit = -9999; + + // TankHitInfo + fNHits = 0; + fIsFiltered.clear(); + fHitX.clear(); + fHitY.clear(); + fHitZ.clear(); + fHitT.clear(); + fHitQ.clear(); + fHitPE.clear(); + fHitType.clear(); + fHitDetID.clear(); + fHitChankey.clear(); + fHitChankeyMC.clear(); + fHitPMTType.clear(); + + // SiPMPulse Info + fSiPM1NPulses = 0; + fSiPM2NPulses = 0; + fSiPMHitQ.clear(); + fSiPMHitT.clear(); + fSiPMHitAmplitude.clear(); + fSiPMNum.clear(); + + // LAPPDData_fill + fLAPPD_Count = 0; + fLAPPD_ID.clear(); + fLAPPD_Position.clear(); + fLAPPD_Beamgate_ns.clear(); + fLAPPD_Timestamp_ns.clear(); + fLAPPD_Beamgate_Raw.clear(); + fLAPPD_Timestamp_Raw.clear(); + fLAPPD_Offset.clear(); + fLAPPD_TSCorrection.clear(); + fLAPPD_BGCorrection.clear(); + fLAPPD_OSInMinusPS.clear(); + fLAPPD_BG_switchBit0.clear(); + fLAPPD_BG_switchBit1.clear(); + // LAPPD_PPS_fill + fLAPPD_BGPPSBefore.clear(); + fLAPPD_BGPPSAfter.clear(); + fLAPPD_BGPPSDiff.clear(); + fLAPPD_BGPPSMissing.clear(); + fLAPPD_TSPPSBefore.clear(); + fLAPPD_TSPPSAfter.clear(); + fLAPPD_TSPPSDiff.clear(); + fLAPPD_TSPPSMissing.clear(); + + // LAPPD Reco Fill + fLAPPDPulseTimeStampUL.clear(); + fLAPPDPulseBeamgateUL.clear(); + fLAPPD_IDs.clear(); + fChannelID.clear(); + fPulsePeakTime.clear(); + fPulseHalfHeightTime.clear(); + fPulseCharge.clear(); + fPulsePeakAmp.clear(); + fPulseStart.clear(); + fPulseEnd.clear(); + fPulseWidth.clear(); + fPulseSide.clear(); + fPulseStripNum.clear(); + fPulseBaseline.clear(); + fPulseFollowTime.clear(); + fPulseFollowCharge.clear(); + + fLAPPDHitTimeStampUL.clear(); + fLAPPDHitBeamgateUL.clear(); + fLAPPDHit_IDs.clear(); + fLAPPDHitChannel.clear(); + fLAPPDHitStrip.clear(); + fLAPPDHitTime.clear(); + fLAPPDHitAmp.clear(); + fLAPPDHitParallelPos.clear(); + fLAPPDHitTransversePos.clear(); + fLAPPDHitP1StartTime.clear(); + fLAPPDHitP2StartTime.clear(); + fLAPPDHitP1EndTime.clear(); + fLAPPDHitP2EndTime.clear(); + fLAPPDHitP1PeakTime.clear(); + fLAPPDHitP2PeakTime.clear(); + fLAPPDHitP1PeakAmp.clear(); + fLAPPDHitP2PeakAmp.clear(); + fLAPPDHitP1HalfHeightTime.clear(); + fLAPPDHitP2HalfHeightTime.clear(); + fLAPPDHitP1HalfEndTime.clear(); + fLAPPDHitP2HalfEndTime.clear(); + fLAPPDHitP1Charge.clear(); + fLAPPDHitP2Charge.clear(); + fLAPPDHitP1Baseline.clear(); + fLAPPDHitP2Baseline.clear(); + fLAPPDHitP1FollowTime.clear(); + fLAPPDHitP2FollowTime.clear(); + fLAPPDHitP1FollowCharge.clear(); + fLAPPDHitP2FollowCharge.clear(); + + LAPPDWaveformChankey.clear(); + waveformMaxValue.clear(); + waveformRMSValue.clear(); + waveformMaxFoundNear.clear(); + waveformMaxNearingValue.clear(); + waveformMaxTimeBinValue.clear(); + + // LAPPD waveform fill + fLAPPDWaveforms.clear(); + + // LAPPD MC fill + fLAPPDMCHitTubeIDs.clear(); + fLAPPDMCHitChankeys.clear(); + fLAPPDMCHitTime.clear(); + fLAPPDMCHitCharge.clear(); + fLAPPDMCHitX.clear(); + fLAPPDMCHitY.clear(); + fLAPPDMCHitZ.clear(); + fLAPPDMCHitParallelPos.clear(); + fLAPPDMCHitTransversePos.clear(); + + // tank cluster information + fNumberOfClusters = 0; + + fClusterHits.clear(); + fClusterChargeV.clear(); + fClusterTimeV.clear(); + fClusterPEV.clear(); + + fCluster_HitX.clear(); + fCluster_HitY.clear(); + fCluster_HitZ.clear(); + fCluster_HitT.clear(); + fCluster_HitQ.clear(); + fCluster_HitPE.clear(); + fCluster_HitType.clear(); + fCluster_HitDetID.clear(); + fCluster_HitChankey.clear(); + fCluster_HitChankeyMC.clear(); + fCluster_HitPMTType.clear(); + + fClusterMaxPEV.clear(); + fClusterChargePointXV.clear(); + fClusterChargePointYV.clear(); + fClusterChargePointZV.clear(); + fClusterChargeBalanceV.clear(); + + // MRD cluster information + fEventTimeMRD_Tree = 0; + fMRDClusterNumber = 0; + fMRDClusterHitNumber.clear(); + fMRDClusterTime.clear(); + fMRDClusterTimeSigma.clear(); + + fVetoHit = 0; + fMRDHitClusterIndex.clear(); + fMRDHitT.clear(); + fMRDHitCharge.clear(); + fMRDHitDigitPMT.clear(); + fMRDHitDetID.clear(); + fMRDHitChankey.clear(); + fMRDHitChankeyMC.clear(); + fFMVHitT.clear(); + fFMVHitDetID.clear(); + fFMVHitChankey.clear(); + fFMVHitChankeyMC.clear(); + + fNumMRDClusterTracks = 0; + fMRDTrackAngle.clear(); + fMRDTrackAngleError.clear(); + fMRDPenetrationDepth.clear(); + fMRDTrackLength.clear(); + fMRDEntryPointRadius.clear(); + fMRDEnergyLoss.clear(); + fMRDEnergyLossError.clear(); + fMRDTrackStartX.clear(); + fMRDTrackStartY.clear(); + fMRDTrackStartZ.clear(); + fMRDTrackStopX.clear(); + fMRDTrackStopY.clear(); + fMRDTrackStopZ.clear(); + fMRDSide.clear(); + fMRDStop.clear(); + fMRDThrough.clear(); + fMRDClusterIndex.clear(); + fNumClusterTracks.clear(); + + // fillCleanEventsOnly + fEventStatusApplied = 0; + fEventStatusFlagged = 0; + + // MCTruth_fill + if (MCTruth_fill) + { + fMCEventNum = 0; + fMCTriggerNum = 0; + fiMCTriggerNum = -9999; + + fTrueVtxX = -9999; + fTrueVtxY = -9999; + fTrueVtxZ = -9999; + fTrueVtxTime = -9999; + fTrueDirX = -9999; + fTrueDirY = -9999; + fTrueDirZ = -9999; + fTrueAngle = -9999; + fTruePhi = -9999; + fTrueMuonEnergy = -9999; + fTruePrimaryPdg = -9999; + fTrueTrackLengthInWater = -9999; + fTrueTrackLengthInMRD = -9999; + fTruePrimaryPdgs->clear(); + fTrueNeutCapVtxX->clear(); + fTrueNeutCapVtxY->clear(); + fTrueNeutCapVtxZ->clear(); + fTrueNeutCapNucleus->clear(); + fTrueNeutCapTime->clear(); + fTrueNeutCapGammas->clear(); + fTrueNeutCapE->clear(); + fTrueNeutCapGammaE->clear(); + fTrueMultiRing = -9999; + } + + // Genie information for event + fTrueNeutrinoEnergy = -9999; + fTrueNeutrinoMomentum_X = -9999; + fTrueNeutrinoMomentum_Y = -9999; + fTrueNeutrinoMomentum_Z = -9999; + fTrueNuIntxVtx_X = -9999; + fTrueNuIntxVtx_Y = -9999; + fTrueNuIntxVtx_Z = -9999; + fTrueNuIntxVtx_T = -9999; + fTrueFSLVtx_X = -9999; + fTrueFSLVtx_Y = -9999; + fTrueFSLVtx_Z = -9999; + fTrueFSLMomentum_X = -9999; + fTrueFSLMomentum_Y = -9999; + fTrueFSLMomentum_Z = -9999; + fTrueFSLTime = -9999; + fTrueFSLMass = -9999; + fTrueFSLPdg = -9999; + fTrueFSLEnergy = -9999; + fTrueQ2 = -9999; + fTrueCC = -9999; + fTrueNC = -9999; + fTrueQEL = -9999; + fTrueRES = -9999; + fTrueDIS = -9999; + fTrueCOH = -9999; + fTrueMEC = -9999; + fTrueNeutrons = -9999; + fTrueProtons = -9999; + fTruePi0 = -9999; + fTruePiPlus = -9999; + fTruePiPlusCher = -9999; + fTruePiMinus = -9999; + fTruePiMinusCher = -9999; + fTrueKPlus = -9999; + fTrueKPlusCher = -9999; + fTrueKMinus = -9999; + fTrueKMinusCher = -9999; + + // TankReco_fill + fRecoVtxX = -9999; + fRecoVtxY = -9999; + fRecoVtxZ = -9999; + fRecoVtxTime = -9999; + fRecoVtxFOM = -9999; + fRecoDirX = -9999; + fRecoDirY = -9999; + fRecoDirZ = -9999; + fRecoAngle = -9999; + fRecoPhi = -9999; + fRecoStatus = -9999; + + // RingCounting_fill + fRC_singleRingP = -9999; + fRC_multiRingP = -9999; + + // RecoDebug_fill + fSeedVtxX.clear(); + fSeedVtxY.clear(); + fSeedVtxZ.clear(); + fSeedVtxFOM.clear(); + fSeedVtxTime = -9999; + + // Reco vertex + // Point Position Vertex + fPointVtxPosX = -9999; + fPointVtxPosY = -9999; + fPointVtxPosZ = -9999; + fPointVtxTime = -9999; + fPointPosFOM = -9999; + fPointPosStatus = -9999; + fPointVtxDirX = -9999; + fPointVtxDirY = -9999; + fPointVtxDirZ = -9999; + fPointDirTime = -9999; + fPointDirFOM = -9999; + fPointDirStatus = -9999; + + // Point Vertex Finder + fPointVtxPosX = -9999; + fPointVtxPosY = -9999; + fPointVtxPosZ = -9999; + fPointVtxTime = -9999; + fPointVtxDirX = -9999; + fPointVtxDirY = -9999; + fPointVtxDirZ = -9999; + fPointVtxFOM = -9999; + fPointVtxStatus = -9999; + + // Difference between MC and Truth + fDeltaVtxX = -9999; + fDeltaVtxY = -9999; + fDeltaVtxZ = -9999; + fDeltaVtxR = -9999; + fDeltaVtxT = -9999; + fDeltaParallel = -9999; + fDeltaPerpendicular = -9999; + fDeltaAzimuth = -9999; + fDeltaZenith = -9999; + fDeltaAngle = -9999; + + // Pion and kaon counts for event + fPi0Count = 0; + fPiPlusCount = 0; + fPiMinusCount = 0; + fK0Count = 0; + fKPlusCount = 0; + fKMinusCount = 0; + + // Event Info + fDataStreams.clear(); + GroupedTrigger.clear(); + + // LAPPDData_fill + LAPPDDataMap.clear(); + LAPPDBeamgate_ns.clear(); + LAPPDTimeStamps_ns.clear(); + LAPPDTimeStampsRaw.clear(); + LAPPDBeamgatesRaw.clear(); + LAPPDOffsets.clear(); + LAPPDTSCorrection.clear(); + LAPPDBGCorrection.clear(); + LAPPDOSInMinusPS.clear(); + SwitchBitBG.clear(); + // LAPPD_PPS_fill + LAPPDBG_PPSBefore.clear(); + LAPPDBG_PPSAfter.clear(); + LAPPDBG_PPSDiff.clear(); + LAPPDBG_PPSMissing.clear(); + LAPPDTS_PPSBefore.clear(); + LAPPDTS_PPSAfter.clear(); + LAPPDTS_PPSDiff.clear(); + LAPPDTS_PPSMissing.clear(); + + // LAPPD Reco Fill + lappdPulses.clear(); + lappdHits.clear(); + + waveformMax.clear(); + waveformRMS.clear(); + waveformMaxLast.clear(); + waveformMaxNearing.clear(); + waveformMaxTimeBin.clear(); +} + +bool ANNIEEventTreeMaker::LoadEventInfo() +{ + Log("ANNIEEventTreeMaker Tool: LoadEventInfo", v_warning, ANNIEEventTreeMakerVerbosity); + m_data->Stores["ANNIEEvent"]->Get("RunNumber", fRunNumber); + m_data->Stores["ANNIEEvent"]->Get("SubRunNumber", fSubrunNumber); + m_data->Stores["ANNIEEvent"]->Get("PartNumber", fPartFileNumber); + bool gotEventNumber = m_data->Stores["ANNIEEvent"]->Get("EventNumber", fEventNumber); + if (!gotEventNumber) + { + uint32_t enm = 9998; + m_data->CStore.Get("EventNumberTree", enm); + cout << "ANNIEEventTreeMaker Tool: Not get the event number from ANNIEEvent, get from CStore: " << enm << endl; + fEventNumber = static_cast(enm); + } + + m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerWord", fPrimaryTriggerWord); + if (fPrimaryTriggerWord == 14) + trigword = 5; + else + trigword = fPrimaryTriggerWord; + m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerTime", fPrimaryTriggerTime); + m_data->Stores["ANNIEEvent"]->Get("GroupedTrigger", GroupedTrigger); + m_data->Stores["ANNIEEvent"]->Get("TriggerWord", fTriggerword); + m_data->Stores["ANNIEEvent"]->Get("TriggerExtended", fExtended); + m_data->Stores["ANNIEEvent"]->Get("DataStreams", fDataStreams); + + bool pmtmrdcoinc, noveto; + m_data->Stores["RecoEvent"]->Get("PMTMRDCoinc", pmtmrdcoinc); + m_data->Stores["RecoEvent"]->Get("NoVeto", noveto); + if (pmtmrdcoinc) + fTankMRDCoinc = 1; + else + fTankMRDCoinc = 0; + + if (noveto) + fNoVeto = 1; + else + fNoVeto = 0; + + if (fDataStreams["Tank"] == 1) + fHasTank = 1; + else + fHasTank = 0; + + if (fDataStreams["MRD"] == 1) + { + fHasMRD = 1; + m_data->Stores["ANNIEEvent"]->Get("MRDTriggerType", fMRDTriggerType); + Log("ANNIEEventTreeMaker Tool: MRD Trigger Type: " + fMRDTriggerType, v_debug, ANNIEEventTreeMakerVerbosity); + bool cosmic = fMRDTriggerType == "Cosmic"; + Log("ANNIEEventTreeMaker Tool: Cosmic Trigger: " + std::to_string(cosmic), v_debug, ANNIEEventTreeMakerVerbosity); + if (fMRDTriggerType == "Beam") + fMRDTriggerTypeInt = 1; + else if (fMRDTriggerType == "Cosmic") + fMRDTriggerTypeInt = 2; + else + fMRDTriggerTypeInt = 0; + } + else + fHasMRD = 0; + + if (fDataStreams["LAPPD"] == 1) + fHasLAPPD = 1; + else + fHasLAPPD = 0; + + for (std::map::iterator it = GroupedTrigger.begin(); it != GroupedTrigger.end(); ++it) + { + uint64_t key = it->first; + uint32_t value = it->second; + + fGroupedTriggerTime.push_back(key); + fGroupedTriggerWord.push_back(value); + } + + bool gotETT = m_data->Stores["ANNIEEvent"]->Get("EventTimeTank", fEventTimeTank); + if (!gotETT) + fEventTimeTank = 0; + + TimeClass tm; + bool gotETMRD = m_data->Stores["ANNIEEvent"]->Get("EventTimeMRD", tm); + fEventTimeMRD = (ULong64_t)tm.GetNs(); + + if (!gotETMRD) + fEventTimeMRD = 0; + + if (fillAllTriggers) + return true; + else if (fill_singleTrigger) + { + if (fPrimaryTriggerWord == fill_singleTriggerWord) + return true; + else + return false; + } + else if (fill_TriggerWord.size() > 0) + { + for (auto trig : fill_TriggerWord) + { + if (fPrimaryTriggerWord == trig) + return true; + } + return false; + } + else + return true; +} + +void ANNIEEventTreeMaker::LoadBeamInfo() +{ + Log("ANNIEEventTreeMaker Tool: LoadBeamInfo", v_debug, ANNIEEventTreeMakerVerbosity); + + m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR860", beam_E_TOR860); + m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR875", beam_E_TOR875); + m_data->Stores["ANNIEEvent"]->Get("beam_THCURR", beam_THCURR); + m_data->Stores["ANNIEEvent"]->Get("beam_BTJT2", beam_BTJT2); + m_data->Stores["ANNIEEvent"]->Get("beam_HP875", beam_HP875); + m_data->Stores["ANNIEEvent"]->Get("beam_VP875", beam_VP875); + m_data->Stores["ANNIEEvent"]->Get("beam_HPTG1", beam_HPTG1); + m_data->Stores["ANNIEEvent"]->Get("beam_VPTG1", beam_VPTG1); + m_data->Stores["ANNIEEvent"]->Get("beam_HPTG2", beam_HPTG2); + m_data->Stores["ANNIEEvent"]->Get("beam_VPTG2", beam_VPTG2); + m_data->Stores["ANNIEEvent"]->Get("beam_BTH2T2", beam_BTH2T2); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMPL", beam_B_BRRMPL); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMPQ", beam_B_BRRMPQ); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMPS", beam_B_BRRMPS); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMP", beam_B_BRRMP); + + m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR875", fPot); + m_data->Stores["ANNIEEvent"]->Get("beam_good", fBeamok); + m_data->Stores["ANNIEEvent"]->Get("bunch_rotation_on", fBunchRotationOn); + + m_data->Stores["ANNIEEvent"]->Get("BeamInfoTime", fBeamInfoTime); + m_data->Stores["ANNIEEvent"]->Get("BeamInfoTimeToTriggerDiff", fBeamInfoTimeToTriggerDiff); +} + +void ANNIEEventTreeMaker::LoadRWMBRFInfo() +{ + Log("ANNIEEventTreeMaker Tool: LoadRWMBRFInfo", v_debug, ANNIEEventTreeMakerVerbosity); + m_data->Stores["ANNIEEvent"]->Get("RWMRisingStart", fRWMRisingStart); + m_data->Stores["ANNIEEvent"]->Get("RWMRisingEnd", fRWMRisingEnd); + m_data->Stores["ANNIEEvent"]->Get("RWMHalfRising", fRWMHalfRising); + m_data->Stores["ANNIEEvent"]->Get("RWMFHWM", fRWMFHWM); + m_data->Stores["ANNIEEvent"]->Get("RWMFirstPeak", fRWMFirstPeak); + + m_data->Stores["ANNIEEvent"]->Get("BRFFirstPeak", fBRFFirstPeak); + m_data->Stores["ANNIEEvent"]->Get("BRFAveragePeak", fBRFAveragePeak); + m_data->Stores["ANNIEEvent"]->Get("BRFFirstPeakFit", fBRFFirstPeakFit); +} + +void ANNIEEventTreeMaker::LoadAllTankHits() +{ + Log("ANNIEEventTreeMaker Tool: LoadAllTankHits", v_debug, ANNIEEventTreeMakerVerbosity); + std::map> *Hits = nullptr; + std::map> *MCHits = nullptr; + bool got_hits = false; + if (isData) + got_hits = m_data->Stores["ANNIEEvent"]->Get("Hits", Hits); + else + got_hits = m_data->Stores["ANNIEEvent"]->Get("MCHits", MCHits); + if (!got_hits) + { + std::cout << "No Hits store in ANNIEEvent. Continuing to build tree " << std::endl; + return; + } + + Position detector_center = geom->GetTankCentre(); + double tank_center_x = detector_center.X(); + double tank_center_y = detector_center.Y(); + double tank_center_z = detector_center.Z(); + fNHits = 0; + + std::map>::iterator it_tank_data; + std::map>::iterator it_tank_mc; + if (isData) + it_tank_data = (*Hits).begin(); + else + it_tank_mc = (*MCHits).begin(); + bool loop_tank = true; + int hits_size = (isData) ? Hits->size() : MCHits->size(); + if (hits_size == 0) + loop_tank = false; + + while (loop_tank) + { + // start to fill tank info to vectors + unsigned long channel_key; + if (isData) + channel_key = it_tank_data->first; + else + channel_key = it_tank_mc->first; + Detector *this_detector = geom->ChannelToDetector(channel_key); + Position det_position = this_detector->GetDetectorPosition(); + unsigned long detkey = this_detector->GetDetectorID(); + unsigned long channel_key_data = channel_key; + if (!isData) + { + int wcsimid = channelkey_to_pmtid.at(channel_key); + channel_key_data = pmtid_to_channelkey[wcsimid]; + } + std::map::iterator it = ChannelKeyToSPEMap.find(channel_key); + std::map::iterator it_mc = ChannelKeyToSPEMap.find(channel_key_data); + bool SPE_available = true; + if (isData) + SPE_available = (it != ChannelKeyToSPEMap.end()); + else + SPE_available = (it_mc != ChannelKeyToSPEMap.end()); + if (SPE_available) + { // Charge to SPE conversion is available + if (isData) + { + std::vector ThisPMTHits = it_tank_data->second; + fNHits += ThisPMTHits.size(); + for (Hit &ahit : ThisPMTHits) + { + double hit_charge = ahit.GetCharge(); + double hit_PE = hit_charge / ChannelKeyToSPEMap.at(channel_key); + fHitX.push_back((det_position.X() - tank_center_x)); + fHitY.push_back((det_position.Y() - tank_center_y)); + fHitZ.push_back((det_position.Z() - tank_center_z)); + fHitT.push_back(ahit.GetTime()); + fHitQ.push_back(hit_charge); + fHitPE.push_back(hit_PE); + fHitDetID.push_back(detkey); + fHitChankey.push_back(channel_key); + fHitChankeyMC.push_back(channel_key); + Channel *thisHitChannel = geom->GetChannel(channel_key); + fHitPMTType.push_back(thisHitChannel->GetChannelType()); + fHitType.push_back(RecoDigit::PMT8inch); // 0 For PMTs + } + } + else + { + std::vector ThisPMTHits = it_tank_mc->second; + fNHits += ThisPMTHits.size(); + for (MCHit &ahit : ThisPMTHits) + { + double hit_PE = ahit.GetCharge(); + double hit_charge = hit_PE * ChannelKeyToSPEMap.at(channel_key_data); + fHitX.push_back((det_position.X() - tank_center_x)); + fHitY.push_back((det_position.Y() - tank_center_y)); + fHitZ.push_back((det_position.Z() - tank_center_z)); + fHitT.push_back(ahit.GetTime()); + fHitQ.push_back(hit_charge); + fHitPE.push_back(hit_PE); + fHitDetID.push_back(detkey); + fHitChankey.push_back(channel_key_data); + fHitChankeyMC.push_back(channel_key); + Channel *thisHitChannel = geom->GetChannel(channel_key); + fHitPMTType.push_back(thisHitChannel->GetChannelType()); + fHitType.push_back(RecoDigit::PMT8inch); // 0 For PMTs + } + } + } + + if (isData) + { + it_tank_data++; + if (it_tank_data == (*Hits).end()) + loop_tank = false; + } + else + { + it_tank_mc++; + if (it_tank_mc == (*MCHits).end()) + loop_tank = false; + } + } + return; +} + +void ANNIEEventTreeMaker::LoadSiPMHits() +{ + Log("ANNIEEventTreeMaker Tool: LoadSiPMHits", v_debug, ANNIEEventTreeMakerVerbosity); + std::map>> aux_pulse_map; + m_data->Stores.at("ANNIEEvent")->Get("RecoADCAuxHits", aux_pulse_map); + fSiPM1NPulses = 0; + fSiPM2NPulses = 0; + for (const auto &temp_pair : aux_pulse_map) + { + const auto &channel_key = temp_pair.first; + // For now, only calibrate the SiPM waveforms + int sipm_number = -1; + if (AuxChannelNumToTypeMap->at(channel_key) == "SiPM1") + { + sipm_number = 1; + } + else if (AuxChannelNumToTypeMap->at(channel_key) == "SiPM2") + { + sipm_number = 2; + } + else + continue; + + std::vector> sipm_minibuffers = temp_pair.second; + size_t num_minibuffers = sipm_minibuffers.size(); // Should be size 1 in FrankDAQ mode + for (size_t mb = 0; mb < num_minibuffers; ++mb) + { + std::vector thisbuffer_pulses = sipm_minibuffers.at(mb); + if (sipm_number == 1) + fSiPM1NPulses += thisbuffer_pulses.size(); + if (sipm_number == 2) + fSiPM2NPulses += thisbuffer_pulses.size(); + for (size_t i = 0; i < thisbuffer_pulses.size(); i++) + { + ADCPulse apulse = thisbuffer_pulses.at(i); + fSiPMHitAmplitude.push_back(apulse.amplitude()); + fSiPMHitT.push_back(apulse.peak_time()); + fSiPMHitQ.push_back(apulse.charge()); + fSiPMNum.push_back(sipm_number); + } + } + } +} + +void ANNIEEventTreeMaker::LoadLAPPDInfo() +{ + m_data->Stores["ANNIEEvent"]->Get("LAPPDDataMap", LAPPDDataMap); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + m_data->Stores["ANNIEEvent"]->Get("LAPPDOffsets", LAPPDOffsets); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTSCorrection", LAPPDTSCorrection); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBGCorrection", LAPPDBGCorrection); + m_data->Stores["ANNIEEvent"]->Get("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + m_data->Stores["ANNIEEvent"]->Get("SwitchBitBG", SwitchBitBG); + + if (LAPPDDataMap.size() != 0) + { + FillLAPPDInfo(); + // print the content of fDataStreams, and the size of data map + // cout<<"Found LAPPDData, LAPPDDataMap Size: "<::iterator it = LAPPDDataMap.begin(); it != LAPPDDataMap.end(); ++it) + { + uint64_t key = it->first; + PsecData psecData = it->second; + int LAPPD_IDInit = psecData.LAPPD_ID; + // now check what ID should be used + // the Incom ID is implemented first in run 5887, all runs before that use the ACC ID (i.e., 0,1,2) in the psecData. + // So for those runs, we need to map the ACC ID to Incom ID using the config. + // also for positions, we use string for now, to avoid confusion with int IDs, can be changed later. + string position; + auto config = queryNearestID(idConfigRecords, fRunNumber, LAPPD_IDInit); + position = std::get<1>(config); + if (LAPPD_IDInit < 20) + { + LAPPD_IDInit = std::get<0>(config); + } + if (ANNIEEventTreeMakerVerbosity > 3) + cout << "ANNIEEventTreeMaker: Filling LAPPD Info, Original LAPPD_ID: " << psecData.LAPPD_ID << ", Mapped LAPPD_ID: " << LAPPD_IDInit << ", Position: " << position << ", using run number: " << fRunNumber << endl; + + fLAPPD_ID.push_back(psecData.LAPPD_ID); + fLAPPD_Position.push_back(position); + fLAPPD_Beamgate_ns.push_back(LAPPDBeamgate_ns[key]); + fLAPPD_Timestamp_ns.push_back(LAPPDTimeStamps_ns[key]); + fLAPPD_Beamgate_Raw.push_back(LAPPDBeamgatesRaw[key]); + fLAPPD_Timestamp_Raw.push_back(LAPPDTimeStampsRaw[key]); + fLAPPD_Offset.push_back(LAPPDOffsets[key]); + fLAPPD_TSCorrection.push_back(LAPPDTSCorrection[key]); + fLAPPD_BGCorrection.push_back(LAPPDBGCorrection[key]); + fLAPPD_OSInMinusPS.push_back(LAPPDOSInMinusPS[key]); + fLAPPD_BGPPSBefore.push_back(LAPPDBG_PPSBefore[key]); + fLAPPD_BGPPSAfter.push_back(LAPPDBG_PPSAfter[key]); + fLAPPD_BGPPSDiff.push_back(LAPPDBG_PPSDiff[key]); + fLAPPD_BGPPSMissing.push_back(LAPPDBG_PPSMissing[key]); + fLAPPD_TSPPSBefore.push_back(LAPPDTS_PPSBefore[key]); + fLAPPD_TSPPSAfter.push_back(LAPPDTS_PPSAfter[key]); + fLAPPD_TSPPSDiff.push_back(LAPPDTS_PPSDiff[key]); + fLAPPD_TSPPSMissing.push_back(LAPPDTS_PPSMissing[key]); + // check if SwitchBitBG has the key + if (SwitchBitBG.find(psecData.LAPPD_ID) != SwitchBitBG.end()) + { + if (SwitchBitBG[psecData.LAPPD_ID].size() != 2) + { + cout << "ANNIEEventTreeMaker: SwitchBitBG size is not 2, LAPPD_ID: " << psecData.LAPPD_ID << ", size: " << SwitchBitBG[psecData.LAPPD_ID].size() << endl; + continue; + } + fLAPPD_BG_switchBit0.push_back(SwitchBitBG[psecData.LAPPD_ID][0]); + fLAPPD_BG_switchBit1.push_back(SwitchBitBG[psecData.LAPPD_ID][1]); + continue; + } + } +} + +void ANNIEEventTreeMaker::FillLAPPDPulse() +{ + bool gotPulse = m_data->Stores["ANNIEEvent"]->Get("LAPPDPulses", lappdPulses); + if (gotPulse) + { + + std::map>>::iterator it; + for (it = lappdPulses.begin(); it != lappdPulses.end(); it++) + { + int stripno = it->first; + vector> stripPulses = it->second; + + vector pulse0 = stripPulses.at(0); + vector pulse1 = stripPulses.at(1); + for (int i = 0; i < pulse0.size(); i++) + { + fPulseSide.push_back(0); + LAPPDPulse thisPulse = pulse0.at(i); + fLAPPD_IDs.push_back(thisPulse.GetTubeId()); + fChannelID.push_back(thisPulse.GetChannelID()); + fPulseStripNum.push_back(stripno); + fPulsePeakTime.push_back(thisPulse.GetTime()); + fPulseHalfHeightTime.push_back(thisPulse.GetHalfHeightTime()); + fPulseCharge.push_back(thisPulse.GetCharge()); + fPulsePeakAmp.push_back(thisPulse.GetPeak()); + fPulseStart.push_back(thisPulse.GetLowRange()); + fPulseEnd.push_back(thisPulse.GetHiRange()); + fPulseWidth.push_back(thisPulse.GetHiRange() - thisPulse.GetLowRange()); + fPulseBaseline.push_back(thisPulse.GetBaseline()); + fPulseFollowTime.push_back(thisPulse.GetPulseFollowTime()); + fPulseFollowCharge.push_back(thisPulse.GetPulseFollowCharge()); + } + for (int i = 0; i < pulse1.size(); i++) + { + fPulseSide.push_back(1); + LAPPDPulse thisPulse = pulse1.at(i); + fLAPPD_IDs.push_back(thisPulse.GetTubeId()); + fChannelID.push_back(thisPulse.GetChannelID()); + fPulseStripNum.push_back(stripno); + fPulsePeakTime.push_back(thisPulse.GetTime()); + fPulseHalfHeightTime.push_back(thisPulse.GetHalfHeightTime()); + fPulseCharge.push_back(thisPulse.GetCharge()); + fPulsePeakAmp.push_back(thisPulse.GetPeak()); + fPulseStart.push_back(thisPulse.GetLowRange()); + fPulseEnd.push_back(thisPulse.GetHiRange()); + fPulseWidth.push_back(thisPulse.GetHiRange() - thisPulse.GetLowRange()); + fPulseBaseline.push_back(thisPulse.GetBaseline()); + fPulseFollowTime.push_back(thisPulse.GetPulseFollowTime()); + fPulseFollowCharge.push_back(thisPulse.GetPulseFollowCharge()); + } + } + } +} + +void ANNIEEventTreeMaker::FillLAPPDHit() +{ + bool gotHit = m_data->Stores["ANNIEEvent"]->Get("LAPPDHits", lappdHits); + + if (gotHit) + { + std::map>::iterator it; + for (it = lappdHits.begin(); it != lappdHits.end(); it++) + { + int stripno = it->first; + vector stripHits = it->second; + for (int i = 0; i < stripHits.size(); i++) + { + LAPPDHit thisHit = stripHits.at(i); + LAPPDPulse p1 = thisHit.GetPulse1(); + LAPPDPulse p2 = thisHit.GetPulse2(); + fLAPPDHit_IDs.push_back(thisHit.GetTubeId()); + fLAPPDHitStrip.push_back(stripno); + fLAPPDHitTime.push_back(thisHit.GetTime()); + fLAPPDHitAmp.push_back(thisHit.GetCharge()); + vector position = thisHit.GetPosition(); + /* + XPosTank = position.at(0); + YPosTank = position.at(1); + ZPosTank = position.at(2);*/ + vector localPosition = thisHit.GetLocalPosition(); + fLAPPDHitParallelPos.push_back(localPosition.at(0)); + fLAPPDHitTransversePos.push_back(localPosition.at(1)); + // fLAPPDHitP1StartTime.push_back(thisHit.GetPulse1StartTime()); + // fLAPPDHitP2StartTime.push_back(thisHit.GetPulse2StartTime()); + // fLAPPDHitP1EndTime.push_back(thisHit.GetPulse1LastTime()); + // fLAPPDHitP2EndTime.push_back(thisHit.GetPulse2LastTime()); + // cout<<"Pulse 1 start time: "<> *m_all_clusters = nullptr; + std::map> *m_all_clusters_MC = nullptr; + std::map> *m_all_clusters_detkeys = nullptr; + + bool get_clusters = false; + if (isData) + { + get_clusters = m_data->CStore.Get("ClusterMap", m_all_clusters); + if (!get_clusters) + { + std::cout << "ANNIEEventTreeMaker tool: No clusters found!" << std::endl; + return false; + } + } + else + { + get_clusters = m_data->CStore.Get("ClusterMapMC", m_all_clusters_MC); + if (!get_clusters) + { + std::cout << "ANNIEEventTreeMaker tool: No clusters found (MC)!" << std::endl; + return false; + } + } + get_clusters = m_data->CStore.Get("ClusterMapDetkey", m_all_clusters_detkeys); + if (!get_clusters) + { + std::cout << "ANNIEEventTreeMaker tool: No cluster detkeys found!" << std::endl; + return false; + } + Log("ANNIEEventTreeMaker Tool: Accessing pairs in all_clusters map", v_debug, ANNIEEventTreeMakerVerbosity); + + int cluster_num = 0; + int cluster_size = 0; + if (isData) + cluster_size = (int)m_all_clusters->size(); + else + cluster_size = (int)m_all_clusters_MC->size(); + + std::map>::iterator it_cluster_pair; + std::map>::iterator it_cluster_pair_mc; + bool loop_map = true; + if (isData) + it_cluster_pair = (*m_all_clusters).begin(); + else + it_cluster_pair_mc = (*m_all_clusters_MC).begin(); + if (cluster_size == 0) + loop_map = false; + + fNumberOfClusters = cluster_size; + while (loop_map) + { + if (isData) + { + std::vector cluster_hits = it_cluster_pair->second; + double thisClusterTime = it_cluster_pair->first; + if (cluster_TankHitInfo_fill) + { + Log("ANNIEEventTreeMaker Tool: Loading tank cluster hits into cluster tree", v_debug, ANNIEEventTreeMakerVerbosity); + fClusterTimeV.push_back(thisClusterTime); + this->LoadTankClusterHits(cluster_hits); + } + + bool good_class = this->LoadTankClusterClassifiers(it_cluster_pair->first); + if (!good_class) + { + if (ANNIEEventTreeMakerVerbosity > 3) + Log("ANNIEEventTreeMaker Tool: No cluster classifiers. Continuing tree", v_debug, ANNIEEventTreeMakerVerbosity); + } + } + else + { + std::vector cluster_hits = it_cluster_pair_mc->second; + double thisClusterTime = it_cluster_pair_mc->first; + std::vector cluster_detkeys = m_all_clusters_detkeys->at(it_cluster_pair_mc->first); + if (cluster_TankHitInfo_fill) + { + Log("ANNIEEventTreeMaker Tool: Loading tank cluster hits into cluster tree", v_debug, ANNIEEventTreeMakerVerbosity); + fClusterTimeV.push_back(thisClusterTime); + this->LoadTankClusterHitsMC(cluster_hits, cluster_detkeys); + } + bool good_class = this->LoadTankClusterClassifiers(it_cluster_pair_mc->first); + if (!good_class) + { + if (ANNIEEventTreeMakerVerbosity > 3) + Log("ANNIEEventTreeMaker Tool: No cluster classifiers. Continuing tree", v_debug, ANNIEEventTreeMakerVerbosity); + } + } + + if (isData) + { + it_cluster_pair++; + if (it_cluster_pair == (*m_all_clusters).end()) + loop_map = false; + } + else + { + it_cluster_pair_mc++; + if (it_cluster_pair_mc == (*m_all_clusters_MC).end()) + loop_map = false; + } + } + + return true; +} + +void ANNIEEventTreeMaker::LoadTankClusterHits(std::vector cluster_hits) +{ + Position detector_center = geom->GetTankCentre(); + double tank_center_x = detector_center.X(); + double tank_center_y = detector_center.Y(); + double tank_center_z = detector_center.Z(); + + double ClusterCharge = 0; + double ClusterPE = 0; + int ClusterHitNum = 0; + vector HitXV; + vector HitYV; + vector HitZV; + vector HitTV; + vector HitQV; + vector HitPEV; + vector HitTypeV; + vector HitDetIDV; + vector HitChankeyV; + vector HitCKMC; + vector HitPMTType; + + for (int i = 0; i < (int)cluster_hits.size(); i++) + { + int channel_key = cluster_hits.at(i).GetTubeId(); + std::map::iterator it = ChannelKeyToSPEMap.find(channel_key); + if (it != ChannelKeyToSPEMap.end()) + { // Charge to SPE conversion is available + Detector *this_detector = geom->ChannelToDetector(channel_key); + unsigned long detkey = this_detector->GetDetectorID(); + Position det_position = this_detector->GetDetectorPosition(); + double hit_charge = cluster_hits.at(i).GetCharge(); + double hit_PE = hit_charge / ChannelKeyToSPEMap.at(channel_key); + HitXV.push_back((det_position.X() - tank_center_x)); + HitYV.push_back((det_position.Y() - tank_center_y)); + HitZV.push_back((det_position.Z() - tank_center_z)); + HitQV.push_back(hit_charge); + HitPEV.push_back(hit_PE); + HitTV.push_back(cluster_hits.at(i).GetTime()); + HitDetIDV.push_back(detkey); + + HitChankeyV.push_back(channel_key); + HitCKMC.push_back(channel_key); + Channel* thisHitChannel = geom->GetChannel(channel_key); + HitPMTType.push_back(thisHitChannel->GetChannelType()); + HitTypeV.push_back(RecoDigit::PMT8inch); + ClusterCharge += hit_charge; + ClusterPE += hit_PE; + ClusterHitNum += 1; + } + else + { + if (ANNIEEventTreeMakerVerbosity > 4) + { + std::cout << "FOUND A HIT FOR CHANNELKEY " << channel_key << "BUT NO CONVERSION " << "TO PE AVAILABLE. SKIPPING PE." << std::endl; + } + } + } + fClusterHits.push_back(ClusterHitNum); + fClusterChargeV.push_back(ClusterCharge); + fClusterPEV.push_back(ClusterPE); + + fCluster_HitX.push_back(HitXV); + fCluster_HitY.push_back(HitYV); + fCluster_HitZ.push_back(HitZV); + fCluster_HitT.push_back(HitTV); + fCluster_HitQ.push_back(HitQV); + fCluster_HitPE.push_back(HitPEV); + fCluster_HitType.push_back(HitTypeV); + fCluster_HitDetID.push_back(HitDetIDV); + fCluster_HitChankey.push_back(HitChankeyV); + fCluster_HitChankeyMC.push_back(HitCKMC); + fCluster_HitPMTType.push_back(HitPMTType); + + return; +} + +void ANNIEEventTreeMaker::LoadTankClusterHitsMC(std::vector cluster_hits, std::vector cluster_detkeys) +{ + Position detector_center = geom->GetTankCentre(); + double tank_center_x = detector_center.X(); + double tank_center_y = detector_center.Y(); + double tank_center_z = detector_center.Z(); + + double ClusterCharge = 0; + double ClusterPE = 0; + int ClusterHitNum = 0; + vector HitXV; + vector HitYV; + vector HitZV; + vector HitTV; + vector HitQV; + vector HitPEV; + vector HitTypeV; + vector HitDetIDV; + vector HitChankeyV; + vector HitCKMC; + vector HitPMTType; + + for (int i = 0; i < (int)cluster_hits.size(); i++) + { + unsigned long detkey = cluster_detkeys.at(i); + int channel_key = (int)detkey; + int tubeid = cluster_hits.at(i).GetTubeId(); + unsigned long utubeid = (unsigned long)tubeid; + int wcsimid = channelkey_to_pmtid.at(utubeid); + unsigned long detkey_data = pmtid_to_channelkey[wcsimid]; + int channel_key_data = (int)detkey_data; + std::map::iterator it = ChannelKeyToSPEMap.find(channel_key_data); + if (it != ChannelKeyToSPEMap.end()) + { // Charge to SPE conversion is available + Detector *this_detector = geom->ChannelToDetector(tubeid); + Position det_position = this_detector->GetDetectorPosition(); + unsigned long detkey = this_detector->GetDetectorID(); + double hit_PE = cluster_hits.at(i).GetCharge(); + double hit_charge = hit_PE * ChannelKeyToSPEMap.at(channel_key_data); + HitXV.push_back((det_position.X() - tank_center_x)); + HitYV.push_back((det_position.Y() - tank_center_y)); + HitZV.push_back((det_position.Z() - tank_center_z)); + HitQV.push_back(hit_charge); + HitPEV.push_back(hit_PE); + HitTV.push_back(cluster_hits.at(i).GetTime()); + HitDetIDV.push_back(detkey); + HitChankeyV.push_back(channel_key_data); + HitCKMC.push_back(channel_key); + Channel* thisHitChannel = geom->GetChannel(channel_key_data); + HitPMTType.push_back(thisHitChannel->GetChannelType()); + HitTypeV.push_back(RecoDigit::PMT8inch); + ClusterCharge += hit_charge; + ClusterPE += hit_PE; + ClusterHitNum += 1; + } + else + { + if (ANNIEEventTreeMakerVerbosity > 4) + { + std::cout << "FOUND A HIT FOR CHANNELKEY " << channel_key_data << "(MC detkey: " << channel_key << ", chankey = " << utubeid << ", wcsimid = " << wcsimid << ") BUT NO CONVERSION " << "TO PE AVAILABLE. SKIPPING PE." << std::endl; + } + } + } + fClusterHits.push_back(ClusterHitNum); + fClusterChargeV.push_back(ClusterCharge); + fClusterPEV.push_back(ClusterPE); + + fCluster_HitX.push_back(HitXV); + fCluster_HitY.push_back(HitYV); + fCluster_HitZ.push_back(HitZV); + fCluster_HitT.push_back(HitTV); + fCluster_HitQ.push_back(HitQV); + fCluster_HitPE.push_back(HitPEV); + fCluster_HitType.push_back(HitTypeV); + fCluster_HitDetID.push_back(HitDetIDV); + fCluster_HitChankey.push_back(HitChankeyV); + fCluster_HitChankeyMC.push_back(HitCKMC); + fCluster_HitPMTType.push_back(HitPMTType); + + return; +} + +bool ANNIEEventTreeMaker::LoadTankClusterClassifiers(double cluster_time) +{ + // Save classifiers to ANNIEEvent + Log("PhaseITreeMaker tool: Getting cluster classifiers", v_debug, ANNIEEventTreeMakerVerbosity); + std::map ClusterMaxPEs; + std::map ClusterChargePoints; + std::map ClusterChargeBalances; + + bool got_ccp = m_data->Stores.at("ANNIEEvent")->Get("ClusterChargePoints", ClusterChargePoints); + bool got_ccb = m_data->Stores.at("ANNIEEvent")->Get("ClusterChargeBalances", ClusterChargeBalances); + bool got_cmpe = m_data->Stores.at("ANNIEEvent")->Get("ClusterMaxPEs", ClusterMaxPEs); + bool good_classifiers = got_ccp && got_ccb && got_cmpe; + if (!good_classifiers) + { + Log("PhaseITreeMaker tool: One of the charge cluster classifiers is not available", v_debug, ANNIEEventTreeMakerVerbosity); + } + else + { + Log("PhaseITreeMaker tool: Setting fCluster variables to classifier parameters", v_debug, ANNIEEventTreeMakerVerbosity); + fClusterMaxPEV.push_back(ClusterMaxPEs.at(cluster_time)); + Position ClusterChargePoint = ClusterChargePoints.at(cluster_time); + fClusterChargePointXV.push_back(ClusterChargePoint.X()); + fClusterChargePointYV.push_back(ClusterChargePoint.Y()); + fClusterChargePointZV.push_back(ClusterChargePoint.Z()); + fClusterChargeBalanceV.push_back(ClusterChargeBalances.at(cluster_time)); + } + return good_classifiers; +} + +void ANNIEEventTreeMaker::LoadMRDCluster() +{ + std::vector mrddigittimesthisevent; + std::vector mrddigitchargesthisevent; + ; + std::vector mrddigitpmtsthisevent; + std::vector mrddigitchankeysthisevent; + std::vector> MrdTimeClusters; + + bool get_clusters = m_data->CStore.Get("MrdTimeClusters", MrdTimeClusters); + if (!get_clusters) + { + std::cout << "ANNIEEventTreeMaker tool: No MRD clusters found! Did you run the TimeClustering tool?" << std::endl; + return; + } + + int num_mrd_clusters; + m_data->CStore.Get("NumMrdTimeClusters", num_mrd_clusters); + + if (num_mrd_clusters > 0) + { + m_data->CStore.Get("MrdDigitTimes", mrddigittimesthisevent); + m_data->CStore.Get("MrdDigitPmts", mrddigitpmtsthisevent); + m_data->CStore.Get("MrdDigitChankeys", mrddigitchankeysthisevent); + m_data->CStore.Get("MrdDigitCharges", mrddigitchargesthisevent); + m_data->CStore.Get("MrdDigitPmts", mrddigitpmtsthisevent); + } + + std::map> *TDCData = nullptr; + std::map> *TDCData_MC = nullptr; + + int TrigHasVetoHit = 0; + bool has_tdc = false; + if (isData) + has_tdc = m_data->Stores["ANNIEEvent"]->Get("TDCData", TDCData); // a std::map> + else + has_tdc = m_data->Stores["ANNIEEvent"]->Get("TDCData", TDCData_MC); + if (!has_tdc) + { + std::cout << "No TDCData store in ANNIEEvent." << std::endl; + } + + int cluster_num = 0; + for (int i = 0; i < (int)MrdTimeClusters.size(); i++) + { + int tdcdata_size = (isData) ? TDCData->size() : TDCData_MC->size(); + int fMRDClusterHits = 0; + if (has_tdc && tdcdata_size > 0) + { + Log("ANNIEEventTreeMaker tool: Looping over FACC/MRD hits... looking for Veto activity", v_debug, ANNIEEventTreeMakerVerbosity); + if (isData) + { + for (auto &&anmrdpmt : (*TDCData)) + { + unsigned long chankey = anmrdpmt.first; + std::vector mrdhits = anmrdpmt.second; + Detector *thedetector = geom->ChannelToDetector(chankey); + unsigned long detkey = thedetector->GetDetectorID(); + if (thedetector->GetDetectorElement() == "Veto") + { + TrigHasVetoHit = 1; // this is a veto hit, not an MRD hit. + for (int j = 0; j < (int)mrdhits.size(); j++) + { + fFMVHitT.push_back(mrdhits.at(j).GetTime()); + fFMVHitDetID.push_back(detkey); + fFMVHitChankey.push_back(chankey); + fFMVHitChankeyMC.push_back(chankey); + } + } + } + } + else + { + for (auto &&anmrdpmt : (*TDCData_MC)) + { + unsigned long chankey = anmrdpmt.first; + Detector *thedetector = geom->ChannelToDetector(chankey); + unsigned long detkey = thedetector->GetDetectorID(); + if (thedetector->GetDetectorElement() == "Veto") + { + TrigHasVetoHit = 1; // this is a veto hit, not an MRD hit. + int wcsimid = channelkey_to_faccpmtid.at(chankey) - 1; + unsigned long chankey_data = wcsimid; + std::vector mrdhits = anmrdpmt.second; + for (int j = 0; j < (int)mrdhits.size(); j++) + { + fFMVHitT.push_back(mrdhits.at(j).GetTime()); + fFMVHitDetID.push_back(detkey); + fFMVHitChankey.push_back(chankey_data); + fFMVHitChankeyMC.push_back(chankey); + } + } + } + } + } + + fVetoHit = TrigHasVetoHit; + std::vector ThisClusterIndices = MrdTimeClusters.at(i); + for (int j = 0; j < (int)ThisClusterIndices.size(); j++) + { + Detector *thedetector = geom->ChannelToDetector(mrddigitchankeysthisevent.at(ThisClusterIndices.at(j))); + unsigned long detkey = thedetector->GetDetectorID(); + + fMRDHitT.push_back(mrddigittimesthisevent.at(ThisClusterIndices.at(j))); + fMRDHitClusterIndex.push_back(i); + fMRDHitCharge.push_back(mrddigitchargesthisevent.at(ThisClusterIndices.at(j))); + fMRDHitDigitPMT.push_back(mrddigitpmtsthisevent.at(ThisClusterIndices.at(j))); + fMRDHitDetID.push_back(detkey); + if (isData) + fMRDHitChankey.push_back(mrddigitchankeysthisevent.at(ThisClusterIndices.at(j))); + else + { + int wcsimid = channelkey_to_mrdpmtid.at(mrddigitchankeysthisevent.at(ThisClusterIndices.at(j))) - 1; + unsigned long chankey_data = mrdpmtid_to_channelkey_data[wcsimid]; + fMRDHitChankey.push_back(chankey_data); + } + fMRDHitChankeyMC.push_back(mrddigitchankeysthisevent.at(ThisClusterIndices.at(j))); + fMRDClusterHits += 1; + } + + double MRDThisClusterTime = 0; + double MRDThisClusterTimeSigma = 0; + ComputeMeanAndVariance(fMRDHitT, MRDThisClusterTime, MRDThisClusterTimeSigma); + // FIXME: calculate fMRDClusterTime + + // Standard run level information + Log("ANNIEEventTreeMaker Tool: MRD cluster, Getting run level information from ANNIEEvent", v_debug, ANNIEEventTreeMakerVerbosity); + + if (MRDReco_fill) + { + int ThisMRDClusterTrackNum = this->LoadMRDTrackReco(i); + fNumClusterTracks.push_back(ThisMRDClusterTrackNum); + // Get the track info + } + cluster_num++; + + fMRDClusterHitNumber.push_back(fMRDClusterHits); + fMRDClusterTime.push_back(MRDThisClusterTime); + fMRDClusterTimeSigma.push_back(MRDThisClusterTimeSigma); + } + fMRDClusterNumber = cluster_num; + Log("ANNIEEventTreeMaker Tool: MRD cluster, Finished loading MRD cluster info", v_debug, ANNIEEventTreeMakerVerbosity); +} + +int ANNIEEventTreeMaker::LoadMRDTrackReco(int SubEventID) +{ + std::vector *theMrdTracks; // the reconstructed tracks + int numtracksinev; + + // Check for valid track criteria + m_data->Stores["MRDTracks"]->Get("MRDTracks", theMrdTracks); + m_data->Stores["MRDTracks"]->Get("NumMrdTracks", numtracksinev); + // Loop over reconstructed tracks + + Position StartVertex; + Position StopVertex; + double TrackLength = -9999; + double TrackAngle = -9999; + double TrackAngleError = -9999; + double PenetrationDepth = -9999; + Position MrdEntryPoint; + double EnergyLoss = -9999; // in MeV + double EnergyLossError = -9999; + double EntryPointRadius = -9999; + bool IsMrdPenetrating; + bool IsMrdStopped; + bool IsMrdSideExit; + + int NumClusterTracks = 0; + for (int tracki = 0; tracki < numtracksinev; tracki++) + { + BoostStore *thisTrackAsBoostStore = &(theMrdTracks->at(tracki)); + int TrackEventID = -1; + // get track properties that are needed for the through-going muon selection + thisTrackAsBoostStore->Get("MrdSubEventID", TrackEventID); + if (TrackEventID != SubEventID) + continue; + + // If we're here, this track is associated with this cluster + thisTrackAsBoostStore->Get("StartVertex", StartVertex); + thisTrackAsBoostStore->Get("StopVertex", StopVertex); + thisTrackAsBoostStore->Get("TrackAngle", TrackAngle); + thisTrackAsBoostStore->Get("TrackAngleError", TrackAngleError); + thisTrackAsBoostStore->Get("PenetrationDepth", PenetrationDepth); + thisTrackAsBoostStore->Get("MrdEntryPoint", MrdEntryPoint); + thisTrackAsBoostStore->Get("EnergyLoss", EnergyLoss); + thisTrackAsBoostStore->Get("EnergyLossError", EnergyLossError); + thisTrackAsBoostStore->Get("IsMrdPenetrating", IsMrdPenetrating); // bool + thisTrackAsBoostStore->Get("IsMrdStopped", IsMrdStopped); // bool + thisTrackAsBoostStore->Get("IsMrdSideExit", IsMrdSideExit); + TrackLength = sqrt(pow((StopVertex.X() - StartVertex.X()), 2) + pow(StopVertex.Y() - StartVertex.Y(), 2) + pow(StopVertex.Z() - StartVertex.Z(), 2)) * 100.0; + EntryPointRadius = sqrt(pow(MrdEntryPoint.X(), 2) + pow(MrdEntryPoint.Y(), 2)) * 100.0; // convert to cm + PenetrationDepth = PenetrationDepth * 100.0; + + // Push back some properties + fMRDTrackAngle.push_back(TrackAngle); + fMRDTrackAngleError.push_back(TrackAngleError); + fMRDTrackLength.push_back(TrackLength); + fMRDPenetrationDepth.push_back(PenetrationDepth); + fMRDEntryPointRadius.push_back(EntryPointRadius); + fMRDEnergyLoss.push_back(EnergyLoss); + fMRDEnergyLossError.push_back(EnergyLossError); + fMRDTrackStartX.push_back(StartVertex.X()); + fMRDTrackStartY.push_back(StartVertex.Y()); + fMRDTrackStartZ.push_back(StartVertex.Z()); + fMRDTrackStopX.push_back(StopVertex.X()); + fMRDTrackStopY.push_back(StopVertex.Y()); + fMRDTrackStopZ.push_back(StopVertex.Z()); + fMRDStop.push_back(IsMrdStopped); + fMRDSide.push_back(IsMrdSideExit); + fMRDThrough.push_back(IsMrdPenetrating); + NumClusterTracks += 1; + fMRDClusterIndex.push_back(SubEventID); + } + return NumClusterTracks; +} + +// MC and tank reco information below + +bool ANNIEEventTreeMaker::FillTankRecoInfo() +{ + bool got_reco_info = true; + auto *reco_event = m_data->Stores["RecoEvent"]; + if (!reco_event) + { + Log("Error: The PhaseITreeMaker tool could not find the RecoEvent Store", v_error, ANNIEEventTreeMakerVerbosity); + got_reco_info = false; + } + // Read reconstructed Vertex + RecoVertex *recovtx = 0; + auto get_extendedvtx = m_data->Stores.at("RecoEvent")->Get("ExtendedVertex", recovtx); + if (!get_extendedvtx) + { + Log("Warning: The PhaseITreeMaker tool could not find ExtendedVertex. Continuing to build tree", v_message, ANNIEEventTreeMakerVerbosity); + got_reco_info = false; + } + else + { + fRecoVtxX = recovtx->GetPosition().X(); + fRecoVtxY = recovtx->GetPosition().Y(); + fRecoVtxZ = recovtx->GetPosition().Z(); + fRecoVtxTime = recovtx->GetTime(); + fRecoVtxFOM = recovtx->GetFOM(); + fRecoDirX = recovtx->GetDirection().X(); + fRecoDirY = recovtx->GetDirection().Y(); + fRecoDirZ = recovtx->GetDirection().Z(); + fRecoAngle = TMath::ACos(fRecoDirZ); + if (fRecoDirX > 0.0) + { + fRecoPhi = atan(fRecoDirY / fRecoDirX); + } + if (fRecoDirX < 0.0) + { + fRecoPhi = atan(fRecoDirY / fRecoDirX); + if (fRecoDirY > 0.0) + fRecoPhi += TMath::Pi(); + if (fRecoDirY <= 0.0) + fRecoPhi -= TMath::Pi(); + } + if (fRecoDirX == 0.0) + { + if (fRecoDirY > 0.0) + fRecoPhi = 0.5 * TMath::Pi(); + else if (fRecoDirY < 0.0) + fRecoPhi = -0.5 * TMath::Pi(); + else + fRecoPhi = 0; + } + fRecoStatus = recovtx->GetStatus(); + } + return got_reco_info; +} + +void ANNIEEventTreeMaker::FillRecoDebugInfo() +{ + // Read Seed candidates + std::vector *seedvtxlist = 0; + auto get_seedvtxlist = m_data->Stores.at("RecoEvent")->Get("vSeedVtxList", seedvtxlist); ///> Get List of seeds from "RecoEvent" + if (get_seedvtxlist) + { + for (auto &seed : *seedvtxlist) + { + fSeedVtxX.push_back(seed.GetPosition().X()); + fSeedVtxY.push_back(seed.GetPosition().Y()); + fSeedVtxZ.push_back(seed.GetPosition().Z()); + fSeedVtxTime = seed.GetTime(); + } + } + else + { + Log("ANNIEEventTreeMaker Tool: No Seed List found. Continuing to build tree ", v_message, ANNIEEventTreeMakerVerbosity); + } + std::vector *seedfomlist = 0; + auto get_seedfomlist = m_data->Stores.at("RecoEvent")->Get("vSeedFOMList", seedfomlist); ///> Get List of seed FOMs from "RecoEvent" + if (get_seedfomlist) + { + for (auto &seedFOM : *seedfomlist) + { + fSeedVtxFOM.push_back(seedFOM); + } + } + else + { + Log("ANNIEEventTreeMaker Tool: No Seed FOM List found. Continuing to build tree ", v_message, ANNIEEventTreeMakerVerbosity); + } + + // Read PointPosition-fitted Vertex + RecoVertex *pointposvtx = 0; + auto get_pointposdata = m_data->Stores.at("RecoEvent")->Get("PointPosition", pointposvtx); + if (get_pointposdata) + { + fPointPosX = pointposvtx->GetPosition().X(); + fPointPosY = pointposvtx->GetPosition().Y(); + fPointPosZ = pointposvtx->GetPosition().Z(); + fPointPosTime = pointposvtx->GetTime(); + fPointPosFOM = pointposvtx->GetFOM(); + fPointPosStatus = pointposvtx->GetStatus(); + } + else + { + Log("ANNIEEventTreeMaker Tool: No PointPosition Tool data found. Continuing to build remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + } + + // Read PointDirection-fitted Vertex + RecoVertex *pointdirvtx = 0; + auto get_pointdirdata = m_data->Stores.at("RecoEvent")->Get("PointDirection", pointdirvtx); + if (get_pointdirdata) + { + fPointDirX = pointdirvtx->GetDirection().X(); + fPointDirY = pointdirvtx->GetDirection().Y(); + fPointDirZ = pointdirvtx->GetDirection().Z(); + fPointDirTime = pointdirvtx->GetTime(); + fPointDirFOM = pointdirvtx->GetFOM(); + fPointDirStatus = pointdirvtx->GetStatus(); + } + else + { + Log("ANNIEEventTreeMaker Tool: No PointDirection Tool data found. Continuing to build remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + } + + // Read PointVertex Tool's fitted Vertex + RecoVertex *pointvtx = 0; + auto get_pointvtxdata = m_data->Stores.at("RecoEvent")->Get("PointVertex", pointvtx); + if (get_pointvtxdata) + { + fPointVtxPosX = pointvtx->GetPosition().X(); + fPointVtxPosY = pointvtx->GetPosition().Y(); + fPointVtxPosZ = pointvtx->GetPosition().Z(); + fPointVtxDirX = pointvtx->GetDirection().X(); + fPointVtxDirY = pointvtx->GetDirection().Y(); + fPointVtxDirZ = pointvtx->GetDirection().Z(); + fPointVtxTime = pointvtx->GetTime(); + fPointVtxFOM = pointvtx->GetFOM(); + fPointVtxStatus = pointvtx->GetStatus(); + } + else + { + Log("ANNIEEventTreeMaker Tool: No PointVertex Tool data found. Continuing to build remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + } +} + +bool ANNIEEventTreeMaker::FillMCTruthInfo() +{ + bool successful_load = true; + // MC entry number + m_data->Stores.at("ANNIEEvent")->Get("MCEventNum", fMCEventNum); + // MC trigger number + m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum", fMCTriggerNum); + std::string logmessage = " Retriving information for MCEntry " + to_string(fMCEventNum) + + ", MCTrigger " + to_string(fMCTriggerNum) + ", EventNumber " + to_string(fEventNumber); + Log(logmessage, v_message, ANNIEEventTreeMakerVerbosity); + + fiMCTriggerNum = (int)fMCTriggerNum; + + std::map> MCNeutCap; + bool get_neutcap = m_data->Stores.at("ANNIEEvent")->Get("MCNeutCap", MCNeutCap); + if (!get_neutcap) + { + Log("ANNIEEventTreeMaker: Did not find MCNeutCap in ANNIEEvent Store!", v_warning, ANNIEEventTreeMakerVerbosity); + } + std::map>> MCNeutCapGammas; + bool get_neutcap_gammas = m_data->Stores.at("ANNIEEvent")->Get("MCNeutCapGammas", MCNeutCapGammas); + if (!get_neutcap_gammas) + { + Log("ANNIEEventTreeMaker: Did not find MCNeutCapGammas in ANNIEEvent Store!", v_warning, ANNIEEventTreeMakerVerbosity); + } + + for (std::map>>::iterator it = MCNeutCapGammas.begin(); it != MCNeutCapGammas.end(); it++) + { + std::vector> mcneutgammas = it->second; + for (int i_cap = 0; i_cap < (int)mcneutgammas.size(); i_cap++) + { + std::vector capgammas = mcneutgammas.at(i_cap); + if (ANNIEEventTreeMakerVerbosity > 1) + { + for (int i_gamma = 0; i_gamma < (int)capgammas.size(); i_gamma++) + { + std::cout << "gamma # " << i_gamma << ", energy: " << capgammas.at(i_gamma) << std::endl; + } + } + } + } + + RecoVertex *truevtx = 0; + auto get_muonMC = m_data->Stores.at("RecoEvent")->Get("TrueVertex", truevtx); + auto get_muonMCEnergy = m_data->Stores.at("RecoEvent")->Get("TrueMuonEnergy", fTrueMuonEnergy); + auto get_pdg = m_data->Stores.at("RecoEvent")->Get("PdgPrimary", fTruePrimaryPdg); + if (get_muonMC && get_muonMCEnergy) + { + fTrueVtxX = truevtx->GetPosition().X(); + fTrueVtxY = truevtx->GetPosition().Y(); + fTrueVtxZ = truevtx->GetPosition().Z(); + fTrueVtxTime = truevtx->GetTime(); + fTrueDirX = truevtx->GetDirection().X(); + fTrueDirY = truevtx->GetDirection().Y(); + fTrueDirZ = truevtx->GetDirection().Z(); + double TrueAngRad = TMath::ACos(fTrueDirZ); + fTrueAngle = TrueAngRad / (TMath::Pi() / 180.0); // radians->degrees + if (fTrueDirX > 0.0) + { + fTruePhi = atan(fTrueDirY / fTrueDirX); + } + if (fTrueDirX < 0.0) + { + fTruePhi = atan(fTrueDirY / fTrueDirX); + if (fTrueDirY > 0.0) + fTruePhi += TMath::Pi(); + if (fTrueDirY <= 0.0) + fTruePhi -= TMath::Pi(); + } + if (fTrueDirX == 0.0) + { + if (fTrueDirY > 0.0) + fTruePhi = 0.5 * TMath::Pi(); + else if (fTrueDirY < 0.0) + fTruePhi = -0.5 * TMath::Pi(); + else + fTruePhi = 0; + } + } + else + { + Log("ANNIEEventTreeMaker Tool: Missing MC Energy/Vertex info; is this MC? Continuing to build remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + successful_load = false; + } + double waterT, MRDT; + auto get_tankTrackLength = m_data->Stores.at("RecoEvent")->Get("TrueTrackLengthInWater", waterT); + auto get_MRDTrackLength = m_data->Stores.at("RecoEvent")->Get("TrueTrackLengthInMRD", MRDT); + if (get_tankTrackLength && get_MRDTrackLength) + { + fTrueTrackLengthInWater = waterT; + fTrueTrackLengthInMRD = MRDT; + } + else + { + Log("ANNIEEventTreeMaker Tool: True track lengths missing. Continuing to build tree", v_message, ANNIEEventTreeMakerVerbosity); + successful_load = false; + } + + bool IsMultiRing = false; + bool get_multi = m_data->Stores.at("RecoEvent")->Get("MCMultiRingEvent", IsMultiRing); + if (get_multi) + { + fTrueMultiRing = (IsMultiRing) ? 1 : 0; + } + else + { + Log("ANNIEEventTreeMaker Tool: True Multi Ring information missing. Continuing to build tree", v_message, ANNIEEventTreeMakerVerbosity); + successful_load = false; + } + + std::vector primary_pdgs; + bool has_primaries = m_data->Stores.at("RecoEvent")->Get("PrimaryPdgs", primary_pdgs); + if (has_primaries) + { + for (int i_part = 0; i_part < (int)primary_pdgs.size(); i_part++) + { + fTruePrimaryPdgs->push_back(primary_pdgs.at(i_part)); + } + } + else + { + Log("ANNIEEventTreeMaker Tool: Primary Pdgs information missing. Continuing to build tree", v_message, ANNIEEventTreeMakerVerbosity); + successful_load = false; + } + + int pi0count, pipcount, pimcount, K0count, Kpcount, Kmcount; + auto get_pi0 = m_data->Stores.at("RecoEvent")->Get("MCPi0Count", pi0count); + auto get_pim = m_data->Stores.at("RecoEvent")->Get("MCPiMinusCount", pimcount); + auto get_pip = m_data->Stores.at("RecoEvent")->Get("MCPiPlusCount", pipcount); + auto get_k0 = m_data->Stores.at("RecoEvent")->Get("MCK0Count", K0count); + auto get_km = m_data->Stores.at("RecoEvent")->Get("MCKMinusCount", Kmcount); + auto get_kp = m_data->Stores.at("RecoEvent")->Get("MCKPlusCount", Kpcount); + if (get_pi0 && get_pim && get_pip && get_k0 && get_km && get_kp) + { + // set values in tree to thouse grabbed from the RecoEvent Store + fPi0Count = pi0count; + fPiPlusCount = pipcount; + fPiMinusCount = pimcount; + fK0Count = K0count; + fKPlusCount = Kpcount; + fKMinusCount = Kmcount; + } + else + { + Log("ANNIEEventTreeMaker Tool: Missing MC Pion/Kaon count information. Continuing to build remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + successful_load = false; + } + + if (MCNeutCap.count("CaptVtxX") > 0) + { + std::vector n_vtxx = MCNeutCap["CaptVtxX"]; + std::vector n_vtxy = MCNeutCap["CaptVtxY"]; + std::vector n_vtxz = MCNeutCap["CaptVtxZ"]; + std::vector n_parent = MCNeutCap["CaptParent"]; + std::vector n_ngamma = MCNeutCap["CaptNGamma"]; + std::vector n_totale = MCNeutCap["CaptTotalE"]; + std::vector n_time = MCNeutCap["CaptTime"]; + std::vector n_nuc = MCNeutCap["CaptNucleus"]; + + for (int i_cap = 0; i_cap < (int)n_vtxx.size(); i_cap++) + { + fTrueNeutCapVtxX->push_back(n_vtxx.at(i_cap)); + fTrueNeutCapVtxY->push_back(n_vtxy.at(i_cap)); + fTrueNeutCapVtxZ->push_back(n_vtxz.at(i_cap)); + fTrueNeutCapNucleus->push_back(n_nuc.at(i_cap)); + fTrueNeutCapTime->push_back(n_time.at(i_cap)); + fTrueNeutCapGammas->push_back(n_ngamma.at(i_cap)); + fTrueNeutCapE->push_back(n_totale.at(i_cap)); + } + } + + if (ANNIEEventTreeMakerVerbosity > 1) + std::cout << "MCNeutCapGammas count CaptGammas: " << MCNeutCapGammas.count("CaptGammas") << std::endl; + if (MCNeutCapGammas.count("CaptGammas") > 0) + { + std::vector> cap_energies = MCNeutCapGammas["CaptGammas"]; + if (ANNIEEventTreeMakerVerbosity > 1) + std::cout << "cap_energies size: " << cap_energies.size() << std::endl; + for (int i_cap = 0; i_cap < (int)cap_energies.size(); i_cap++) + { + for (int i_gamma = 0; i_gamma < cap_energies.at(i_cap).size(); i_gamma++) + { + if (ANNIEEventTreeMakerVerbosity > 1) + std::cout << "gamma energy: " << cap_energies.at(i_cap).at(i_gamma) << std::endl; + fTrueNeutCapGammaE->push_back(cap_energies.at(i_cap).at(i_gamma)); + } + } + } + + // Load genie information + if (hasGenie) + { + double TrueNeutrinoEnergy, TrueQ2, TrueNuIntxVtx_X, TrueNuIntxVtx_Y, TrueNuIntxVtx_Z, TrueNuIntxVtx_T; + double TrueFSLeptonMass, TrueFSLeptonEnergy, TrueFSLeptonTime; + bool TrueCC, TrueNC, TrueQEL, TrueDIS, TrueCOH, TrueMEC, TrueRES; + int fsNeutrons, fsProtons, fsPi0, fsPiPlus, fsPiPlusCher, fsPiMinus, fsPiMinusCher; + int fsKPlus, fsKPlusCher, fsKMinus, fsKMinusCher, TrueNuPDG, TrueFSLeptonPdg; + Position TrueFSLeptonVtx; + Direction TrueFSLeptonMomentum; + Direction TrueNeutrinoMomentum; + bool get_neutrino_energy = m_data->Stores["GenieInfo"]->Get("NeutrinoEnergy", TrueNeutrinoEnergy); + bool get_neutrino_mom = m_data->Stores["GenieInfo"]->Get("NeutrinoMomentum", TrueNeutrinoMomentum); + bool get_neutrino_vtxx = m_data->Stores["GenieInfo"]->Get("NuIntxVtx_X", TrueNuIntxVtx_X); + bool get_neutrino_vtxy = m_data->Stores["GenieInfo"]->Get("NuIntxVtx_Y", TrueNuIntxVtx_Y); + bool get_neutrino_vtxz = m_data->Stores["GenieInfo"]->Get("NuIntxVtx_Z", TrueNuIntxVtx_Z); + bool get_neutrino_vtxt = m_data->Stores["GenieInfo"]->Get("NuIntxVtx_T", TrueNuIntxVtx_T); + bool get_q2 = m_data->Stores["GenieInfo"]->Get("EventQ2", TrueQ2); + bool get_cc = m_data->Stores["GenieInfo"]->Get("IsWeakCC", TrueCC); + bool get_nc = m_data->Stores["GenieInfo"]->Get("IsWeakNC", TrueNC); + bool get_qel = m_data->Stores["GenieInfo"]->Get("IsQuasiElastic", TrueQEL); + bool get_res = m_data->Stores["GenieInfo"]->Get("IsResonant", TrueRES); + bool get_dis = m_data->Stores["GenieInfo"]->Get("IsDeepInelastic", TrueDIS); + bool get_coh = m_data->Stores["GenieInfo"]->Get("IsCoherent", TrueCOH); + bool get_mec = m_data->Stores["GenieInfo"]->Get("IsMEC", TrueMEC); + bool get_n = m_data->Stores["GenieInfo"]->Get("NumFSNeutrons", fsNeutrons); + bool get_p = m_data->Stores["GenieInfo"]->Get("NumFSProtons", fsProtons); + bool get_pi0 = m_data->Stores["GenieInfo"]->Get("NumFSPi0", fsPi0); + bool get_piplus = m_data->Stores["GenieInfo"]->Get("NumFSPiPlus", fsPiPlus); + bool get_pipluscher = m_data->Stores["GenieInfo"]->Get("NumFSPiPlusCher", fsPiPlusCher); + bool get_piminus = m_data->Stores["GenieInfo"]->Get("NumFSPiMinus", fsPiMinus); + bool get_piminuscher = m_data->Stores["GenieInfo"]->Get("NumFSPiMinusCher", fsPiMinusCher); + bool get_kplus = m_data->Stores["GenieInfo"]->Get("NumFSKPlus", fsKPlus); + bool get_kpluscher = m_data->Stores["GenieInfo"]->Get("NumFSKPlusCher", fsKPlusCher); + bool get_kminus = m_data->Stores["GenieInfo"]->Get("NumFSKMinus", fsKMinus); + bool get_kminuscher = m_data->Stores["GenieInfo"]->Get("NumFSKMinusCher", fsKMinusCher); + bool get_fsl_vtx = m_data->Stores["GenieInfo"]->Get("FSLeptonVertex", TrueFSLeptonVtx); + bool get_fsl_momentum = m_data->Stores["GenieInfo"]->Get("FSLeptonMomentum", TrueFSLeptonMomentum); + bool get_fsl_time = m_data->Stores["GenieInfo"]->Get("FSLeptonTime", TrueFSLeptonTime); + bool get_fsl_mass = m_data->Stores["GenieInfo"]->Get("FSLeptonMass", TrueFSLeptonMass); + bool get_fsl_pdg = m_data->Stores["GenieInfo"]->Get("FSLeptonPdg", TrueFSLeptonPdg); + bool get_fsl_energy = m_data->Stores["GenieInfo"]->Get("FSLeptonEnergy", TrueFSLeptonEnergy); + if (ANNIEEventTreeMakerVerbosity > 1) + { + std::cout << "get_neutrino_energy: " << get_neutrino_energy << "get_neutrino_vtxx: " << get_neutrino_vtxx << "get_neutrino_vtxy: " << get_neutrino_vtxy << "get_neutrino_vtxz: " << get_neutrino_vtxz << "get_neutrino_time: " << get_neutrino_vtxt << std::endl; + std::cout << "get_q2: " << get_q2 << ", get_cc: " << get_cc << ", get_qel: " << get_qel << ", get_res: " << get_res << ", get_dis: " << get_dis << ", get_coh: " << get_coh << ", get_mec: " << get_mec << std::endl; + std::cout << "get_n: " << get_n << ", get_p: " << get_p << ", get_pi0: " << get_pi0 << ", get_piplus: " << get_piplus << ", get_pipluscher: " << get_pipluscher << ", get_piminus: " << get_piminus << ", get_piminuscher: " << get_piminuscher << ", get_kplus: " << get_kplus << ", get_kpluscher: " << get_kpluscher << ", get_kminus: " << get_kminus << ", get_kminuscher: " << get_kminuscher << std::endl; + std::cout << "get_fsl_vtx: " << get_fsl_vtx << ", get_fsl_momentum: " << get_fsl_momentum << ", get_fsl_time: " << get_fsl_time << ", get_fsl_mass: " << get_fsl_mass << ", get_fsl_pdg: " << get_fsl_pdg << ", get_fsl_energy: " << get_fsl_energy << std::endl; + } + if (get_neutrino_energy && get_neutrino_mom && get_neutrino_vtxx && get_neutrino_vtxy && get_neutrino_vtxz && get_neutrino_vtxt && get_q2 && get_cc && get_nc && get_qel && get_res && get_dis && get_coh && get_mec && get_n && get_p && get_pi0 && get_piplus && get_pipluscher && get_piminus && get_piminuscher && get_kplus && get_kpluscher && get_kminus && get_kminuscher && get_fsl_vtx && get_fsl_momentum && get_fsl_time && get_fsl_mass && get_fsl_pdg && get_fsl_energy) + { + fTrueNeutrinoEnergy = TrueNeutrinoEnergy; + fTrueNeutrinoMomentum_X = TrueNeutrinoMomentum.X(); + fTrueNeutrinoMomentum_Y = TrueNeutrinoMomentum.Y(); + fTrueNeutrinoMomentum_Z = TrueNeutrinoMomentum.Z(); + fTrueNuIntxVtx_X = TrueNuIntxVtx_X; + fTrueNuIntxVtx_Y = TrueNuIntxVtx_Y; + fTrueNuIntxVtx_Z = TrueNuIntxVtx_Z; + fTrueNuIntxVtx_T = TrueNuIntxVtx_T; + fTrueFSLVtx_X = TrueFSLeptonVtx.X(); + fTrueFSLVtx_Y = TrueFSLeptonVtx.Y(); + fTrueFSLVtx_Z = TrueFSLeptonVtx.Z(); + fTrueFSLMomentum_X = TrueFSLeptonMomentum.X(); + fTrueFSLMomentum_Y = TrueFSLeptonMomentum.Y(); + fTrueFSLMomentum_Z = TrueFSLeptonMomentum.Z(); + fTrueFSLTime = TrueFSLeptonTime; + fTrueFSLMass = TrueFSLeptonMass; + fTrueFSLPdg = TrueFSLeptonPdg; + fTrueFSLEnergy = TrueFSLeptonEnergy; + fTrueQ2 = TrueQ2; + fTrueCC = (TrueCC) ? 1 : 0; + fTrueNC = (TrueNC) ? 1 : 0; + fTrueQEL = (TrueQEL) ? 1 : 0; + fTrueRES = (TrueRES) ? 1 : 0; + fTrueDIS = (TrueDIS) ? 1 : 0; + fTrueCOH = (TrueCOH) ? 1 : 0; + fTrueMEC = (TrueMEC) ? 1 : 0; + fTrueNeutrons = fsNeutrons; + fTrueProtons = fsProtons; + fTruePi0 = fsPi0; + fTruePiPlus = fsPiPlus; + fTruePiPlusCher = fsPiPlusCher; + fTruePiMinus = fsPiMinus; + fTruePiMinusCher = fsPiMinusCher; + fTrueKPlus = fsKPlus; + fTrueKPlusCher = fsKPlusCher; + fTrueKMinus = fsKMinus; + fTrueKMinusCher = fsKMinusCher; + } + else + { + Log("ANNIEEventTreeMaker tool: Did not find GENIE information. Continuing building remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + successful_load = false; + } + } // end if hasGenie + + return successful_load; +} + +void ANNIEEventTreeMaker::FillTruthRecoDiffInfo(bool successful_mcload, bool successful_recoload) +{ + if (!successful_mcload || !successful_recoload) + { + Log("ANNIEEventTreeMaker Tool: Error loading True Muon Vertex or Extended Vertex information. Continuing to build remaining tree", v_message, ANNIEEventTreeMakerVerbosity); + } + else + { + // Make sure MCTruth Information is loaded from store + // Let's fill in stuff from the RecoSummary + fDeltaVtxX = fRecoVtxX - fTrueVtxX; + fDeltaVtxY = fRecoVtxY - fTrueVtxY; + fDeltaVtxZ = fRecoVtxZ - fTrueVtxZ; + fDeltaVtxT = fRecoVtxTime - fTrueVtxTime; + fDeltaVtxR = sqrt(pow(fDeltaVtxX, 2) + pow(fDeltaVtxY, 2) + pow(fDeltaVtxZ, 2)); + fDeltaParallel = fDeltaVtxX * fRecoDirX + fDeltaVtxY * fRecoDirY + fDeltaVtxZ * fRecoDirZ; + fDeltaPerpendicular = sqrt(pow(fDeltaVtxR, 2) - pow(fDeltaParallel, 2)); + fDeltaAzimuth = (fRecoAngle - fTrueAngle) / (TMath::Pi() / 180.0); + fDeltaZenith = (fRecoPhi - fTruePhi) / (TMath::Pi() / 180.0); + double cosphi = fTrueDirX * fRecoDirX + fTrueDirY * fRecoDirY + fTrueDirZ * fRecoDirZ; + double phi = TMath::ACos(cosphi); // radians + double TheAngle = phi / (TMath::Pi() / 180.0); // radians->degrees + fDeltaAngle = TheAngle; + } +} + +void ANNIEEventTreeMaker::RecoSummary() +{ + + // get reconstruction output + double dx = fRecoVtxX - fTrueVtxX; + double dy = fRecoVtxY - fTrueVtxY; + double dz = fRecoVtxZ - fTrueVtxZ; + double dt = fRecoVtxTime - fTrueVtxTime; + double deltaR = sqrt(dx * dx + dy * dy + dz * dz); + double cosphi = 0., phi = 0., DeltaAngle = 0.; + cosphi = fTrueDirX * fRecoDirX + fTrueDirY * fRecoDirY + fTrueDirZ * fRecoDirZ; + phi = TMath::ACos(cosphi); // radians + DeltaAngle = phi / (TMath::Pi() / 180.0); // radians->degrees + std::cout << "============================================================================" << std::endl; + std::cout << " Event number " << fEventNumber << std::endl; + std::cout << " trueVtx=(" << fTrueVtxX << ", " << fTrueVtxY << ", " << fTrueVtxZ << ", " << fTrueVtxTime << std::endl + << " TrueMuonEnergy= " << fTrueMuonEnergy << " Primary Pdg = " << fTruePrimaryPdg << std::endl + << " " << fTrueDirX << ", " << fTrueDirY << ", " << fTrueDirZ << ") " << std::endl; + std::cout << " recoVtx=(" << fRecoVtxX << ", " << fRecoVtxY << ", " << fRecoVtxZ << ", " << fRecoVtxTime << std::endl + << " " << fRecoDirX << ", " << fRecoDirY << ", " << fRecoDirZ << ") " << std::endl; + std::cout << " DeltaR = " << deltaR << "[cm]" << "\t" << " DeltaAngle = " << DeltaAngle << " [degree]" << std::endl; + std::cout << " FOM = " << fRecoVtxFOM << std::endl; + std::cout << " RecoStatus = " << fRecoStatus << std::endl; + std::cout << std::endl; +} + +void ANNIEEventTreeMaker::FillLAPPDWaveform() +{ + // Log("ANNIEEventTreeMaker: Filling LAPPD Waveform", 0, ANNIEEventTreeMakerVerbosity); + + fLAPPDWaveforms = std::vector>(60 * 3, std::vector(256, 0.0)); + + // m_data->Stores["ANNIEEvent"]->Print(false); + + // cout<<"LAPPDWaveformInputLabel: "<>> lappdData; // waveform data + m_data->Stores["ANNIEEvent"]->Get(LAPPDWaveformInputLabel, lappdData); + + std::map>>::iterator it; + for (it = lappdData.begin(); it != lappdData.end(); it++) + { + + // get the waveforms from channel number + unsigned long channel = it->first; + channel = channel % 1000 + 1000; + if ((channel % 1000) % 30 == 5) + continue; + Waveform waveforms = it->second.at(0); + vector wav = *waveforms.GetSamples(); + vector wave = wav; + if (wave.size() != 256) + { + cout << "ANNIEEventTreeMaker: Found a bug waveform at channel " << channel << ", size is " << wave.size() << endl; + continue; + } + + for (int i = 0; i < wave.size(); i++) + { + wave.at(i) = -wave.at(i); + } + + int LAPPD_ID = static_cast((channel - 1000) / 60); + Channel *chan = geom->GetChannel(channel); + int stripno = chan->GetStripNum(); + int stripSide = chan->GetStripSide(); + + // fill this waveform to fLAPPDWaveforms[LAPPD_ID][stripno+stripSide*30][n] + for (int n = 0; n < 256; n++) + { + fLAPPDWaveforms[LAPPD_ID * 60 + stripno + stripSide * 30][n] = wave.at(n); + } + } +} + +void ANNIEEventTreeMaker::FillLAPPDMCHitInfo() +{ + std::map> *MCLAPPDHits = nullptr; + m_data->Stores.at("ANNIEEvent")->Get("MCLAPPDHits", MCLAPPDHits); + + int HitCount = MCLAPPDHits->size(); + Log("ANNIEEventTreeMaker: Filling LAPPD MC Hit Info, got " + to_string(HitCount) + " MC hits", v_message, ANNIEEventTreeMakerVerbosity); + + Position detector_center = geom->GetTankCentre(); + double tank_center_x = detector_center.X(); + double tank_center_y = detector_center.Y(); + double tank_center_z = detector_center.Z(); + + for (std::pair> &&apair : *MCLAPPDHits) + { + unsigned long chankey = apair.first; + std::vector hits = apair.second; + + for (MCLAPPDHit &ahit : hits) + { + std::vector pos = ahit.GetPosition(); + double x = pos.at(0) - tank_center_x; + double y = pos.at(1) - tank_center_y; + double z = pos.at(2) - tank_center_z; + + std::vector local_pos = ahit.GetLocalPosition(); + // double local_x = local_pos.at(1); + // double local_y = local_pos.at(0); + double parallel = local_pos.at(0); + double transverse = local_pos.at(1); + + int tubeID = ahit.GetTubeId(); + double hitTime = ahit.GetTime(); + double hitCharge = ahit.GetCharge(); + + fLAPPDMCHitTubeIDs.push_back(tubeID); + fLAPPDMCHitChankeys.push_back(chankey); + fLAPPDMCHitTime.push_back(hitTime); + fLAPPDMCHitCharge.push_back(hitCharge); + fLAPPDMCHitX.push_back(x); + fLAPPDMCHitY.push_back(y); + fLAPPDMCHitZ.push_back(z); + fLAPPDMCHitParallelPos.push_back(parallel); + fLAPPDMCHitTransversePos.push_back(transverse); + } + } +} + + + + +vector ANNIEEventTreeMaker::LoadIDConfig(const string& filename) { + vector data; + ifstream file(filename); + if (!file.is_open()) { + cerr << "ANNIEEventTreeMaker::LoadIDConfig: Can't open file: " << filename << endl; + return data; + } + + string line; + getline(file, line); // skip header + + while (getline(file, line)) { + if (line.empty()) continue; + replace(line.begin(), line.end(), '\t', ','); // support tab or comma + stringstream ss(line); + string token; + IDConfigRecord r; + getline(ss, token, ','); r.RunNumber = stoi(token); + getline(ss, token, ','); r.ACCID = stoi(token); + getline(ss, token, ','); r.ManufacturerID = stoi(token); + getline(ss, token, ','); r.Position = token; + + data.push_back(r); + } + + return data; +} + +tuple ANNIEEventTreeMaker::queryNearestID(const vector& data, int targetRun, int accid) { + int bestRun = -1; + int bestManufacturer = -1; + string bestPosition; + + for (const auto& r : data) { + if (r.ACCID == accid && r.RunNumber <= targetRun) { + if (r.RunNumber > bestRun) { // find the nearest run not exceeding targetRun + bestRun = r.RunNumber; + bestManufacturer = r.ManufacturerID; + bestPosition = r.Position; + } + } + } + + if (bestRun == -1) + return {-1, ""}; + return {bestManufacturer, bestPosition}; +} + + + +tuple ANNIEEventTreeMaker::queryNearestACCID(const vector& data, int targetRun, int manufacturerID) { + int bestRun = -1; + int bestACCID = -1; + string bestPosition; + + for (const auto& r : data) { + if (r.ManufacturerID == manufacturerID && r.RunNumber <= targetRun) { + if (r.RunNumber > bestRun) { // find the nearest run not exceeding targetRun + bestRun = r.RunNumber; + bestACCID = r.ACCID; + bestPosition = r.Position; + } + } + } + + if (bestRun == -1) + return {-1, ""}; + return {bestACCID, bestPosition}; +} + diff --git a/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.h b/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.h new file mode 100644 index 000000000..a8386e13c --- /dev/null +++ b/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.h @@ -0,0 +1,605 @@ +#ifndef ANNIEEventTreeMaker_H +#define ANNIEEventTreeMaker_H + +#include +#include + +#include "Tool.h" +// ROOT includes +#include "TApplication.h" +#include +#include +#include "TFile.h" +#include "TTree.h" +#include "TH1D.h" +#include "TMath.h" +#include "ADCPulse.h" +#include "Waveform.h" +#include "CalibratedADCWaveform.h" +#include "Hit.h" +#include "RecoDigit.h" +#include "ANNIEalgorithms.h" +#include "TimeClass.h" +#include "BeamStatus.h" +#include "PsecData.h" +#include "LAPPDPulse.h" +#include "LAPPDHit.h" +#include "Geometry.h" + +/** + * \class ANNIEEventTreeMaker + * + * + * $Author: Yue Feng $ + * $Date: 2024/8 $ + * Contact: yuef@iastate.edu + */ +struct IDConfigRecord { + int RunNumber; + int ACCID; + int ManufacturerID; + string Position; +}; + +class ANNIEEventTreeMaker : public Tool +{ + +public: + ANNIEEventTreeMaker(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + bool LoadEventInfo(); + void LoadBeamInfo(); + + void LoadRWMBRFInfo(); + + void LoadAllTankHits(); + void LoadSiPMHits(); + + void LoadLAPPDInfo(); + void FillLAPPDInfo(); + void FillLAPPDHit(); + void FillLAPPDPulse(); + + bool LoadClusterInfo(); + + void LoadMRDCluster(); + + void LoadMRDInfo(); + void LoadLAPPDRecoInfo(); + void FillLAPPDRecoInfo(); + void FillLAPPDWaveform(); + void FillLAPPDMCHitInfo(); + + bool FillMCTruthInfo(); + bool FillTankRecoInfo(); + int LoadMRDTrackReco(int SubEventNumber); + void LoadAllMRDHits(bool isData); + void FillRecoDebugInfo(); + void FillTruthRecoDiffInfo(bool got_mc, bool got_reco); + + void RecoSummary(); + void LoadTankClusterHits(std::vector cluster_hits); + void LoadTankClusterHitsMC(std::vector cluster_hits, std::vector cluster_detkeys); + bool LoadTankClusterClassifiers(double cluster_time); + + vector LoadIDConfig(const string& filename); + tuple queryNearestID(const vector& data, int targetRun, int accid); + tuple queryNearestACCID(const vector& data, int targetRun, int manufacturerID); + + void ResetVariables(); + +private: + // General variables + bool isData = 1; + bool hasGenie; + + int ANNIEEventTreeMakerVerbosity = 0; + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + + int EventNumberIndex = 0; + + // What events will be filled - Triggers + bool fillAllTriggers; // if true, fill all events with any major trigger + // if fillAllTriggers = false: + bool fill_singleTrigger; // if true, only fill events with selected trigger, for example 14 + int fill_singleTriggerWord; + // if fillAllTriggers = false and fill_singleTrigger = false: + vector fill_TriggerWord; // fill events with any of these triggers in this vector + + // What events will be filled - status + bool fillCleanEventsOnly = 0; // Only output events not flagged by EventSelector tool + bool fillLAPPDEventsOnly = 0; // Only fill events with LAPPD data + + // What information will be filled + bool TankHitInfo_fill = 1; + bool TankCluster_fill = 1; + bool cluster_TankHitInfo_fill = 1; + bool MRDHitInfo_fill = 1; + bool LAPPDData_fill = 1; + bool RWMBRF_fill = 1; + bool LAPPD_PPS_fill = 1; + bool LAPPD_Waveform_fill = 1; + bool LAPPD_MC_fill = 0; + + // What reco information will be filled + bool MCTruth_fill = 0; // Output the MC truth information + bool TankReco_fill = 0; + bool MRDReco_fill = 1; + bool RecoDebug_fill = 0; // Outputs results of Reconstruction at each step (best fits, FOMs, etc.) + bool muonTruthRecoDiff_fill = 0; // Output difference in tmuonruth and reconstructed values + bool SiPMPulseInfo_fill = 0; + bool LAPPDReco_fill = 1; + bool BeamInfo_fill = 1; + bool RingCounting_fill = 0; + + TFile *fOutput_tfile = nullptr; + TTree *fANNIETree = nullptr; + Geometry *geom = nullptr; + + int processedEvents = 0; + + // Variables for filling the tree + + // EventInfo + int fRunNumber; + int fSubrunNumber; + int fPartFileNumber; + int fRunType = 0; + int fEventNumber; + int fPrimaryTriggerWord; + int trigword; + uint64_t fPrimaryTriggerTime; + vector fGroupedTriggerTime; + vector fGroupedTriggerWord; + int fTriggerword; + int fExtended; + int fTankMRDCoinc; + int fNoVeto; + int fHasTank; + int fHasMRD; + int fHasLAPPD; + std::string fMRDTriggerType; + int fMRDTriggerTypeInt; + + ULong64_t fEventTimeTank; + ULong64_t fEventTimeMRD; + + // beam information + double fPot; + int fBeamok; + int fBunchRotationOn; + double beam_E_TOR860; + double beam_E_TOR875; + double beam_THCURR; + double beam_BTJT2; + double beam_HP875; + double beam_VP875; + double beam_HPTG1; + double beam_VPTG1; + double beam_HPTG2; + double beam_VPTG2; + double beam_BTH2T2; + double beam_B_BRRMPL; + double beam_B_BRRMPQ; + double beam_B_BRRMPS; + double beam_B_BRRMP; + uint64_t fBeamInfoTime; + int64_t fBeamInfoTimeToTriggerDiff; + + // RWM and BRF information + double fRWMRisingStart; // start of the rising of the waveform + double fRWMRisingEnd; // maximum of the rising of the waveform + double fRWMHalfRising; // half of the rising of the waveform, from start to maximum + double fRWMFHWM; // full width at half maximum of the waveform + double fRWMFirstPeak; // first peak of the waveform + + double fBRFFirstPeak; // first peak of the waveform + double fBRFAveragePeak; // average peak of the waveform + double fBRFFirstPeakFit; // first peak of the waveform, Gaussian fit + + // TankHitInfo_fill + int fNHits = 0; + std::vector fIsFiltered; + std::vector fHitX; + std::vector fHitY; + std::vector fHitZ; + std::vector fHitT; + std::vector fHitQ; + std::vector fHitPE; + std::vector fHitType; + std::vector fHitDetID; + std::vector fHitChankey; + std::vector fHitChankeyMC; + std::vector fHitPMTType; + + // SiPMPulseInfo_fill + int fSiPM1NPulses; + int fSiPM2NPulses; + std::vector fSiPMHitQ; + std::vector fSiPMHitT; + std::vector fSiPMHitAmplitude; + std::vector fSiPMNum; + + // LAPPDData_fill + vector idConfigRecords; // save the conversion table between RunNumber, ACCID and ManufacturerID + int fLAPPD_Count; + vector fLAPPD_ID; + vector fLAPPD_Position; + vector fLAPPD_Beamgate_ns; + vector fLAPPD_Timestamp_ns; + vector fLAPPD_Beamgate_Raw; + vector fLAPPD_Timestamp_Raw; + vector fLAPPD_Offset; + vector fLAPPD_TSCorrection; + vector fLAPPD_BGCorrection; + vector fLAPPD_OSInMinusPS; + vector fLAPPD_BGPPSBefore; + vector fLAPPD_BGPPSAfter; + vector fLAPPD_BGPPSDiff; + vector fLAPPD_BGPPSMissing; + vector fLAPPD_TSPPSBefore; + vector fLAPPD_TSPPSAfter; + vector fLAPPD_TSPPSDiff; + vector fLAPPD_TSPPSMissing; + vector fLAPPD_BG_switchBit0; + vector fLAPPD_BG_switchBit1; + + // LAPPD Reco Fill + vector fLAPPDPulseTimeStampUL; + vector fLAPPDPulseBeamgateUL; + vector fLAPPD_IDs; + vector fChannelID; + vector fPulsePeakTime; + vector fPulseHalfHeightTime; + vector fPulseCharge; + vector fPulsePeakAmp; + vector fPulseStart; + vector fPulseEnd; + vector fPulseWidth; + vector fPulseSide; + vector fPulseStripNum; + vector fPulseBaseline; + vector fPulseFollowTime; + vector fPulseFollowCharge; + + vector fLAPPDHitTimeStampUL; + vector fLAPPDHitBeamgateUL; + vector fLAPPDHit_IDs; + vector fLAPPDHitChannel; + vector fLAPPDHitStrip; + vector fLAPPDHitTime; + vector fLAPPDHitAmp; + vector fLAPPDHitParallelPos; + vector fLAPPDHitTransversePos; + vector fLAPPDHitP1StartTime; + vector fLAPPDHitP2StartTime; + vector fLAPPDHitP1EndTime; + vector fLAPPDHitP2EndTime; + vector fLAPPDHitP1PeakTime; + vector fLAPPDHitP2PeakTime; + vector fLAPPDHitP1PeakAmp; + vector fLAPPDHitP2PeakAmp; + vector fLAPPDHitP1HalfHeightTime; + vector fLAPPDHitP2HalfHeightTime; + vector fLAPPDHitP1HalfEndTime; + vector fLAPPDHitP2HalfEndTime; + vector fLAPPDHitP1Charge; + vector fLAPPDHitP2Charge; + vector fLAPPDHitP1Baseline; + vector fLAPPDHitP2Baseline; + vector fLAPPDHitP1FollowTime; + vector fLAPPDHitP2FollowTime; + vector fLAPPDHitP1FollowCharge; + vector fLAPPDHitP2FollowCharge; + + // waveform + vector LAPPDWaveformChankey; + vector waveformMaxValue; + vector waveformRMSValue; + vector waveformMaxFoundNear; + vector waveformMaxNearingValue; + vector waveformMaxTimeBinValue; + + // LAPPD waveform Fill + string LAPPDWaveformInputLabel; + vector> fLAPPDWaveforms; + + // LAPPD MC Hit info, loaded from WCSim + vector fLAPPDMCHitTubeIDs; + vector fLAPPDMCHitChankeys; + vector fLAPPDMCHitTime; + vector fLAPPDMCHitCharge; + vector fLAPPDMCHitX; + vector fLAPPDMCHitY; + vector fLAPPDMCHitZ; + vector fLAPPDMCHitParallelPos; + vector fLAPPDMCHitTransversePos; + + // finished **************************************************** + + // tank cluster information + + int fNumberOfClusters; // how many clusters in this event + // vector fClusterIndex; // index of which cluster this data belongs to + vector fClusterHits; // how many hits in this cluster + vector fClusterChargeV; + vector fClusterTimeV; + vector fClusterPEV; + + vector> fCluster_HitX; // each vector is a cluster, each element is a hit in that cluster + vector> fCluster_HitY; + vector> fCluster_HitZ; + vector> fCluster_HitT; + vector> fCluster_HitQ; + vector> fCluster_HitPE; + vector> fCluster_HitType; + vector> fCluster_HitDetID; + vector> fCluster_HitChankey; + vector> fCluster_HitChankeyMC; + vector> fCluster_HitPMTType; + + vector fClusterMaxPEV; + vector fClusterChargePointXV; + vector fClusterChargePointYV; + vector fClusterChargePointZV; + vector fClusterChargeBalanceV; + + // MRD cluster information + ULong64_t fEventTimeMRD_Tree; + int fMRDClusterNumber; + std::vector fMRDClusterHitNumber; + std::vector fMRDClusterTime; + std::vector fMRDClusterTimeSigma; + + // MRDHitInfo_fill + int fVetoHit; + std::vector fMRDHitClusterIndex; + std::vector fMRDHitT; + std::vector fMRDHitCharge; + std::vector fMRDHitDigitPMT; + std::vector fMRDHitDetID; + std::vector fMRDHitChankey; + std::vector fMRDHitChankeyMC; + + std::vector fFMVHitT; + std::vector fFMVHitDetID; + std::vector fFMVHitChankey; + std::vector fFMVHitChankeyMC; + + // MRDReco_fill + int fNumMRDClusterTracks; + std::vector fMRDTrackAngle; + std::vector fMRDTrackAngleError; + std::vector fMRDPenetrationDepth; + std::vector fMRDTrackLength; + std::vector fMRDEntryPointRadius; + std::vector fMRDEnergyLoss; + std::vector fMRDEnergyLossError; + std::vector fMRDTrackStartX; + std::vector fMRDTrackStartY; + std::vector fMRDTrackStartZ; + std::vector fMRDTrackStopX; + std::vector fMRDTrackStopY; + std::vector fMRDTrackStopZ; + std::vector fMRDSide; + std::vector fMRDStop; + std::vector fMRDThrough; + std::vector fMRDClusterIndex; + + std::vector fNumClusterTracks; + + // fillCleanEventsOnly + int fEventStatusApplied; + int fEventStatusFlagged; + + // MCTruth_fill + // ************ MC Truth Information **************** // + uint64_t fMCEventNum; + uint16_t fMCTriggerNum; + int fiMCTriggerNum; + // True muon + double fTrueVtxX; + double fTrueVtxY; + double fTrueVtxZ; + double fTrueVtxTime; + double fTrueDirX; + double fTrueDirY; + double fTrueDirZ; + double fTrueAngle; + double fTruePhi; + double fTrueMuonEnergy; + int fTruePrimaryPdg; + double fTrueTrackLengthInWater; + double fTrueTrackLengthInMRD; + std::vector *fTruePrimaryPdgs = nullptr; + std::vector *fTrueNeutCapVtxX = nullptr; + std::vector *fTrueNeutCapVtxY = nullptr; + std::vector *fTrueNeutCapVtxZ = nullptr; + std::vector *fTrueNeutCapNucleus = nullptr; + std::vector *fTrueNeutCapTime = nullptr; + std::vector *fTrueNeutCapGammas = nullptr; + std::vector *fTrueNeutCapE = nullptr; + std::vector *fTrueNeutCapGammaE = nullptr; + int fTrueMultiRing; + + // Genie information for event + double fTrueNeutrinoEnergy; + double fTrueNeutrinoMomentum_X; + double fTrueNeutrinoMomentum_Y; + double fTrueNeutrinoMomentum_Z; + double fTrueNuIntxVtx_X; + double fTrueNuIntxVtx_Y; + double fTrueNuIntxVtx_Z; + double fTrueNuIntxVtx_T; + double fTrueFSLVtx_X; + double fTrueFSLVtx_Y; + double fTrueFSLVtx_Z; + double fTrueFSLMomentum_X; + double fTrueFSLMomentum_Y; + double fTrueFSLMomentum_Z; + double fTrueFSLTime; + double fTrueFSLMass; + int fTrueFSLPdg; + double fTrueFSLEnergy; + double fTrueQ2; + int fTrueCC; + int fTrueNC; + int fTrueQEL; + int fTrueRES; + int fTrueDIS; + int fTrueCOH; + int fTrueMEC; + int fTrueNeutrons; + int fTrueProtons; + int fTruePi0; + int fTruePiPlus; + int fTruePiPlusCher; + int fTruePiMinus; + int fTruePiMinusCher; + int fTrueKPlus; + int fTrueKPlusCher; + int fTrueKMinus; + int fTrueKMinusCher; + + // TankReco_fill + double fRecoVtxX; + double fRecoVtxY; + double fRecoVtxZ; + double fRecoVtxTime; + double fRecoVtxFOM; + double fRecoDirX; + double fRecoDirY; + double fRecoDirZ; + double fRecoAngle; + double fRecoPhi; + int fRecoStatus; + + // RingCounting_fill + double fRC_singleRingP; + double fRC_multiRingP; + + // RecoDebug_fill + // **************** Full reco chain information ************* // + // seed vertices + std::vector fSeedVtxX; + std::vector fSeedVtxY; + std::vector fSeedVtxZ; + std::vector fSeedVtxFOM; + double fSeedVtxTime; + + // Reco vertex + // Point Position Vertex + double fPointPosX; + double fPointPosY; + double fPointPosZ; + double fPointPosTime; + double fPointPosFOM; + int fPointPosStatus; + double fPointDirX; + double fPointDirY; + double fPointDirZ; + double fPointDirTime; + double fPointDirFOM; + int fPointDirStatus; + + // Point Vertex Finder + double fPointVtxPosX; + double fPointVtxPosY; + double fPointVtxPosZ; + double fPointVtxTime; + double fPointVtxDirX; + double fPointVtxDirY; + double fPointVtxDirZ; + double fPointVtxFOM; + int fPointVtxStatus; + + // muonTruthRecoDiff_fill + // ************* Difference between MC and Truth *********** // + double fDeltaVtxX; + double fDeltaVtxY; + double fDeltaVtxZ; + double fDeltaVtxR; + double fDeltaVtxT; + double fDeltaParallel; + double fDeltaPerpendicular; + double fDeltaAzimuth; + double fDeltaZenith; + double fDeltaAngle; + + // Pion and kaon counts for event + int fPi0Count; + int fPiPlusCount; + int fPiMinusCount; + int fK0Count; + int fKPlusCount; + int fKMinusCount; + + //******************************************************************************************************************** + + // data variables for filling the tree + // Event Info + std::map fDataStreams; + std::map GroupedTrigger; + + // LAPPDData_fill + std::map LAPPDDataMap; + std::map LAPPDBeamgate_ns; + std::map LAPPDTimeStamps_ns; // data and key are the same + std::map LAPPDTimeStampsRaw; + std::map LAPPDBeamgatesRaw; + std::map LAPPDOffsets; + std::map LAPPDTSCorrection; + std::map LAPPDBGCorrection; + std::map LAPPDOSInMinusPS; + std::map LAPPDBG_PPSBefore; + std::map LAPPDBG_PPSAfter; + std::map LAPPDBG_PPSDiff; + std::map LAPPDBG_PPSMissing; + std::map LAPPDTS_PPSBefore; + std::map LAPPDTS_PPSAfter; + std::map LAPPDTS_PPSDiff; + std::map LAPPDTS_PPSMissing; + std::map> SwitchBitBG; + + std::map>> lappdPulses; + std::map> lappdHits; + + //******************************************************************************************************************** + + // detector maps, don't clear + std::map *AuxChannelNumToTypeMap; + std::map ChannelKeyToSPEMap; + + std::map pmtid_to_channelkey; + std::map channelkey_to_pmtid; + std::map channelkey_to_mrdpmtid; + std::map mrdpmtid_to_channelkey_data; + std::map channelkey_to_faccpmtid; + std::map faccpmtid_to_channelkey_data; + + //******************************************************************************************************************** + // some left not used objects + + // left for raw data + std::vector fADCWaveformChankeys; + std::vector fADCWaveformSamples; + + // ************ Muon reconstruction level information ******** // + std::string MRDTriggertype; + + // ************* LAPPD RecoInfo *********** // + // left for LAPPD waveforms if needed + std::map> waveformMax; // strip number+30*side, value + std::map> waveformRMS; + std::map> waveformMaxLast; + std::map> waveformMaxNearing; + std::map> waveformMaxTimeBin; +}; + +#endif diff --git a/UserTools/ANNIEEventTreeMaker/README.md b/UserTools/ANNIEEventTreeMaker/README.md new file mode 100644 index 000000000..cb2e852ff --- /dev/null +++ b/UserTools/ANNIEEventTreeMaker/README.md @@ -0,0 +1,20 @@ +# ANNIEEventTreeMaker + +ANNIEEventTreeMaker + +## Data + +Describe any data formats ANNIEEventTreeMaker creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for ANNIEEventTreeMaker. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/BeamFetcherV2/BeamFetcherV2.cpp b/UserTools/BeamFetcherV2/BeamFetcherV2.cpp index 79c8c26e0..26f6892f8 100644 --- a/UserTools/BeamFetcherV2/BeamFetcherV2.cpp +++ b/UserTools/BeamFetcherV2/BeamFetcherV2.cpp @@ -71,6 +71,15 @@ bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) fSaveROOT = false; } + if (!got_deletectcdata) { + logmessage = ("Warning (BeamFetcherV2): DeleteCTCData was not set in the " + "config file. If you're not running downstream tools that " + "remove the CTC from the CStore then you probably want to " + " set this to true to save memory. Using default \"false\""); + Log(logmessage, v_warning, verbosity); + fDeleteCTCData = false; + } + if (!got_deletectcdata) { logmessage = ("Warning (BeamFetcherV2): DeleteCTCData was not set in the " @@ -114,19 +123,21 @@ bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) bool BeamFetcherV2::Execute() { m_data->CStore.Set("NewBeamDataAvailable", false); + // Do the things bool got_ctc = m_data->CStore.Get("NewCTCDataAvailable", fNewCTCData); bool goodFetch = false; if (got_ctc && fNewCTCData) { logmessage = ("Message (BeamFetcherV2): New CTC data found. Fetching. "); - Log(logmessage, v_message, verbosity); + Log(logmessage, v_message, verbosity); - goodFetch = this->FetchFromTrigger(); + goodFetch = this->FetchFromTrigger(); } else { logmessage = ("Warning (BeamFetcherV2): No new CTC data found. Nothing to fetch. "); Log(logmessage, v_message, verbosity); } + // Save it out if (goodFetch) { logmessage = ("Debug (BeamFetcherV2): Writing out BeamDataMap, which has size: " + std::to_string(BeamDataMap->size())); @@ -170,10 +181,14 @@ bool BeamFetcherV2::FetchFromTrigger() for (auto iterator = TimeToTriggerWordMap->lower_bound(fLastTimestampFetched+1); iterator != TimeToTriggerWordMap->end(); ++iterator) { - // We only care about beam triggers here - grab the undelayed beam trigger 14 + // We only care about beam triggers here if (std::find(iterator->second.begin(), iterator->second.end(), 14) == iterator->second.end()) { continue; } + // bool hasBeamTrig = false; + // for (auto word : iterator->second) + // if (word == 5) hasBeamTrig = true; + // if (!hasBeamTrig) continue; // Grab the timestamp uint64_t trigTimestamp = iterator->first; diff --git a/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp b/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp index deedadd37..8149ef343 100644 --- a/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp +++ b/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp @@ -17,6 +17,9 @@ IFBeamDBInterfaceV2::IFBeamDBInterfaceV2() if (!fCurl) throw std::runtime_error("IFBeamDBInterfaceV2 failed to" " initialize libcurl"); + + // the map include the device name we want to have in the output + requiredDevices = { {"E:TOR860", "E12"}, {"E:TOR875", "E12"}, @@ -28,7 +31,11 @@ IFBeamDBInterfaceV2::IFBeamDBInterfaceV2() {"E:VPTG1", "mm"}, {"E:HPTG2", "mm"}, {"E:VPTG2", "mm"}, - {"E:BTH2T2", "DegC"}}; + {"E:BTH2T2", "DegC"}, + {"B:BRRMPL","unknown"}, + {"B:BRRMPS","unknown"}, + {"B:BRRMPQ","unknown"}, + {"B:BRRMP","volt"}}; } IFBeamDBInterfaceV2::~IFBeamDBInterfaceV2() @@ -251,6 +258,7 @@ IFBeamDBInterfaceV2::ParseDBResponseSingleSpan(const std::string& response) cons timestamp); } + for (auto &ts : retMap) { for (auto &dev : requiredDevices) { if (ts.second.find(dev.first) == ts.second.end()) { @@ -302,14 +310,16 @@ IFBeamDBInterfaceV2::ParseDBResponseBundleSpan(const std::string& response) cons timestamp); } - // count the total number of elements in retMap times the number of elements in that element, print the total number + //count the total number of elements in retMap times the number of elements in that element, print the total number int total = 0; for (auto &ts : retMap) { total += ts.second.size(); } + std::cout << "Total number of elements in retMap: " << total << std::endl; + std::cout << "Size of retMap is " << retMap.size() << std::endl; - // check each timestamp in the retMap, to see if it have all the devices in the requiredDevices map keys, if yes, continue - // if not, create entry for that device at retMap[TS], use the data type from the value of requiredDevices + //check each timestamp in the retMap, to see if it have all the devices in the requiredDevices map keys, if yes, continue + //if not, create entry for that device at retMap[TS], use the data type from the value of requiredDevices // use value as -9999, unit as doulbe, timestamp = TS for (auto &ts : retMap) { for (auto &dev : requiredDevices) { @@ -324,6 +334,8 @@ IFBeamDBInterfaceV2::ParseDBResponseBundleSpan(const std::string& response) cons for (auto &ts : retMap) { totalAfter += ts.second.size(); } + std::cout << "After inserting, total number of elements in retMap: " << totalAfter << std::endl; + std::cout << "Size of retMap is " << retMap.size() << std::endl; return retMap; } @@ -380,7 +392,6 @@ for (auto &ts : retMap) { } } } - return retMap; } @@ -425,6 +436,7 @@ IFBeamDBInterfaceV2::ParseDBResponseBundle(const std::string& response) const timestamp); } + for (auto &ts : retMap) { for (auto &dev : requiredDevices) { if (ts.second.find(dev.first) == ts.second.end()) { diff --git a/UserTools/BeamQuality/BeamQuality.cpp b/UserTools/BeamQuality/BeamQuality.cpp index 4b8b33e99..47ba19d3a 100644 --- a/UserTools/BeamQuality/BeamQuality.cpp +++ b/UserTools/BeamQuality/BeamQuality.cpp @@ -124,9 +124,9 @@ bool BeamQuality::Execute() fLastTimestamp = timestamp; completed_timestamps.insert(timestamp); - // Check for trigger word 14 (undelayed beam trigger) + // Check for trigger word 5 (beam) // If it's not there then it isn't a beam trigger and there's nothing more to do - if (std::find(iterator->second.begin(), iterator->second.end(), 14) == iterator->second.end()) { + if (std::find(iterator->second.begin(), iterator->second.end(), 5) == iterator->second.end()) { BeamStatus tempStatus(TimeClass(timestamp), 0., BeamCondition::NonBeamMinibuffer); BeamStatusMap->emplace(timestamp, tempStatus); continue; diff --git a/UserTools/ClusterFinder/ClusterFinder.cpp b/UserTools/ClusterFinder/ClusterFinder.cpp index 3d90cf910..6d41ff085 100644 --- a/UserTools/ClusterFinder/ClusterFinder.cpp +++ b/UserTools/ClusterFinder/ClusterFinder.cpp @@ -245,7 +245,7 @@ bool ClusterFinder::Execute(){ else { bool new_pulse = false; - if (fabs(temp_times[0]-hit1)< mc_pulse_width) { + if (fabs(temp_times[0]-hit1)<10.) { new_pulse=false; temp_charges+=hits_2ns_res_charge.at(i_hit); temp_times.push_back(hit1); diff --git a/UserTools/DigitBuilder/DigitBuilder.cpp b/UserTools/DigitBuilder/DigitBuilder.cpp index b3a5a3e4e..4c658aecf 100644 --- a/UserTools/DigitBuilder/DigitBuilder.cpp +++ b/UserTools/DigitBuilder/DigitBuilder.cpp @@ -398,7 +398,7 @@ bool DigitBuilder::BuildDataPMTRecoDigit(){ if (m_all_clusters && m_all_clusters_detkey){ int clustersize = m_all_clusters->size(); - std::cout <<"Clustersize of m_all_clusters: "<1) std::cout <<"Clustersize of m_all_clusters: "<CStore.Get("PairedLAPPDTriggerTimestamp", PairedCTCTimeStamps); + m_data->CStore.Get("PairedLAPPDTimeStamps", PairedLAPPDTimeStamps); + m_data->CStore.Get("PairedLAPPD_TriggerIndex", PairedLAPPD_TriggerIndex); + m_data->CStore.Get("Buffer_LAPPDData", Buffer_LAPPDData); + m_data->CStore.Get("Buffer_LAPPDTimestamp_ns", Buffer_LAPPDTimestamp_ns); + m_data->CStore.Get("Buffer_LAPPDBeamgate_ns", Buffer_LAPPDBeamgate_ns); + m_data->CStore.Get("Buffer_LAPPDOffset", Buffer_LAPPDOffset); + m_data->CStore.Get("Buffer_LAPPDBeamgate_Raw", Buffer_LAPPDBeamgate_Raw); + m_data->CStore.Get("Buffer_LAPPDTimestamp_Raw", Buffer_LAPPDTimestamp_Raw); + m_data->CStore.Get("Buffer_LAPPDBGCorrection", Buffer_LAPPDBGCorrection); + m_data->CStore.Get("Buffer_LAPPDTSCorrection", Buffer_LAPPDTSCorrection); + m_data->CStore.Get("Buffer_LAPPDOffset_minus_ps", Buffer_LAPPDOffset_minus_ps); + m_data->CStore.Get("Buffer_LAPPDRunCode", Buffer_RunCode); + + m_data->CStore.Get("Buffer_LAPPDBG_PPSBefore", Buffer_LAPPDBG_PPSBefore); + m_data->CStore.Get("Buffer_LAPPDBG_PPSAfter", Buffer_LAPPDBG_PPSAfter); + m_data->CStore.Get("Buffer_LAPPDBG_PPSDiff", Buffer_LAPPDBG_PPSDiff); + m_data->CStore.Get("Buffer_LAPPDBG_PPSMissing", Buffer_LAPPDBG_PPSMissing); + m_data->CStore.Get("Buffer_LAPPDTS_PPSBefore", Buffer_LAPPDTS_PPSBefore); + m_data->CStore.Get("Buffer_LAPPDTS_PPSAfter", Buffer_LAPPDTS_PPSAfter); + m_data->CStore.Get("Buffer_LAPPDTS_PPSDiff", Buffer_LAPPDTS_PPSDiff); + m_data->CStore.Get("Buffer_LAPPDTS_PPSMissing", Buffer_LAPPDTS_PPSMissing); + + Log("EBLAPPD: Got pairing information from CStore, PairedLAPPDTimeStamps[14] size = " + std::to_string(PairedLAPPDTimeStamps[14].size()), v_message, verbosityEBLAPPD); + + CleanData(); + m_data->CStore.Get("RunCode", currentRunCode); + + bool IsNewLAPPDData = false; + m_data->CStore.Get("NewLAPPDDataAvailable", IsNewLAPPDData); + Log("EBLAPPD: NewLAPPDDataAvailable = " + std::to_string(IsNewLAPPDData), v_message, verbosityEBLAPPD); + bool LoadingPPS = false; + m_data->CStore.Get("LoadingPPS", LoadingPPS); + + if (IsNewLAPPDData && !LoadingPPS) + LoadLAPPDData(); + + Log("EBLAPPD: Finished Loading LAPPD data to buffer, Buffer_LAPPDData size is now " + std::to_string(Buffer_LAPPDData.size()), v_message, verbosityEBLAPPD); + + string storeFileName; + m_data->CStore.Get("SaveToFileName", storeFileName); + + bool stopLoop = false; + m_data->vars.Get("StopLoop", stopLoop); + int runNum = thisRunNum; + m_data->vars.Get("RunNumber", thisRunNum); + bool ForceLAPPDMatching = false; + m_data->CStore.Get("ForceLAPPDMatching", ForceLAPPDMatching); + + if (stopLoop || runNum != thisRunNum || exeNum % exePerMatch == 0 || ForceLAPPDMatching) + { + Log("EBLAPPD: exeNum = " + std::to_string(exeNum) + ". Doing matching", v_message, verbosityEBLAPPD); + Log("EBLAPPD: Matching reason is stopLoop = " + std::to_string(stopLoop) + ", runNum = " + std::to_string(runNum) + ", exeNum = " + std::to_string(exeNum) + ", ForceLAPPDMatching = " + std::to_string(ForceLAPPDMatching), v_message, verbosityEBLAPPD); + if (matchToAllTriggers) + { + Matching(0, 0); + } + else + { + bool BeamTriggerGroupped = false; + m_data->CStore.Get("BeamTriggerGroupped", BeamTriggerGroupped); + if (BeamTriggerGroupped) + Matching(14, 14); + else + Log("EBLAPPD: BeamTriggerGroupped is false, no beam trigger groupped in the grouper, stop matching", v_message, verbosityEBLAPPD); + + bool LaserTriggerGroupped = false; + m_data->CStore.Get("LaserTriggerGroupped", LaserTriggerGroupped); + if (LaserTriggerGroupped) + Matching(47, 47); + else + Log("EBLAPPD: LaserTriggerGroupped is false, no laser trigger groupped in the grouper, stop matching", v_message, verbosityEBLAPPD); + + bool CosmicTriggerGroupped = false; + m_data->CStore.Get("CosmicTriggerGroupped", CosmicTriggerGroupped); + if (CosmicTriggerGroupped) + Matching(45, 46); + else + Log("EBLAPPD: CosmicTriggerGroupped is false, no cosmic trigger groupped in the grouper, stop matching", v_message, verbosityEBLAPPD); + + bool LEDTriggerGroupped = false; + m_data->CStore.Get("LEDTriggerGroupped", LEDTriggerGroupped); + if (LEDTriggerGroupped) + Matching(31, 46); + else + Log("EBLAPPD: LEDTriggerGroupped is false, no LED trigger groupped in the grouper, stop matching", v_message, verbosityEBLAPPD); + + bool NuMITriggerGroupped = false; + m_data->CStore.Get("NuMITriggerGroupped", NuMITriggerGroupped); + if (NuMITriggerGroupped) + Matching(42, 46); + else + Log("EBLAPPD: NuMITriggerGroupped is false, no NuMI trigger groupped in the grouper, stop matching", v_message, verbosityEBLAPPD); + } + } + + // Set all matching info to CStore + m_data->CStore.Set("PairedLAPPDTriggerTimestamp", PairedCTCTimeStamps); + m_data->CStore.Set("PairedLAPPDTimeStamps", PairedLAPPDTimeStamps); + m_data->CStore.Set("PairedLAPPD_TriggerIndex", PairedLAPPD_TriggerIndex); + Log("EBLAPPD: Set pairing information to CStore, PairedLAPPDTimeStamps[14] size = " + std::to_string(PairedLAPPDTimeStamps[14].size()), v_message, verbosityEBLAPPD); + Log("EBLAPPD: Set pairing information to CStore, PairedLAPPDTimeStamps[47] size = " + std::to_string(PairedLAPPDTimeStamps[47].size()), v_message, verbosityEBLAPPD); + + // Set the indexing of buffer + m_data->CStore.Set("Buffer_LAPPDTimestamp_ns", Buffer_LAPPDTimestamp_ns); + + // Also set all buffers to CStore + m_data->CStore.Set("Buffer_LAPPDData", Buffer_LAPPDData); + m_data->CStore.Set("Buffer_LAPPDBeamgate_ns", Buffer_LAPPDBeamgate_ns); + m_data->CStore.Set("Buffer_LAPPDOffset", Buffer_LAPPDOffset); + m_data->CStore.Set("Buffer_LAPPDBeamgate_Raw", Buffer_LAPPDBeamgate_Raw); + m_data->CStore.Set("Buffer_LAPPDTimestamp_Raw", Buffer_LAPPDTimestamp_Raw); + m_data->CStore.Set("Buffer_LAPPDBGCorrection", Buffer_LAPPDBGCorrection); + m_data->CStore.Set("Buffer_LAPPDTSCorrection", Buffer_LAPPDTSCorrection); + m_data->CStore.Set("Buffer_LAPPDOffset_minus_ps", Buffer_LAPPDOffset_minus_ps); + m_data->CStore.Set("Buffer_LAPPDRunCode", Buffer_RunCode); + + m_data->CStore.Set("Buffer_LAPPDBG_PPSBefore", Buffer_LAPPDBG_PPSBefore); + m_data->CStore.Set("Buffer_LAPPDBG_PPSAfter", Buffer_LAPPDBG_PPSAfter); + m_data->CStore.Set("Buffer_LAPPDBG_PPSDiff", Buffer_LAPPDBG_PPSDiff); + m_data->CStore.Set("Buffer_LAPPDBG_PPSMissing", Buffer_LAPPDBG_PPSMissing); + m_data->CStore.Set("Buffer_LAPPDTS_PPSBefore", Buffer_LAPPDTS_PPSBefore); + m_data->CStore.Set("Buffer_LAPPDTS_PPSAfter", Buffer_LAPPDTS_PPSAfter); + m_data->CStore.Set("Buffer_LAPPDTS_PPSDiff", Buffer_LAPPDTS_PPSDiff); + m_data->CStore.Set("Buffer_LAPPDTS_PPSMissing", Buffer_LAPPDTS_PPSMissing); + + exeNum++; + + return true; +} + +bool EBLAPPD::Finalise() +{ + Log("\033[1;34mEBLAPPD: Finalising\033[0m", v_message, verbosityEBLAPPD); + Log("EBLAPPD: Matched LAPPD number = " + std::to_string(matchedLAPPDNumber), v_message, verbosityEBLAPPD); + Log("EBLAPPD: Unmatched LAPPD number = " + std::to_string(MatchBuffer_LAPPDTimestamp_ns.size()), v_message, verbosityEBLAPPD); + return true; +} + +bool EBLAPPD::CleanData() +{ + LAPPDBeamgate_ns = 0; + LAPPDTimestamp_ns = 0; + LAPPDOffset = 0; + LAPPDBeamgate_Raw = 0; + LAPPDTimestamp_Raw = 0; + LAPPDBGCorrection = 0; + LAPPDTSCorrection = 0; + LAPPDOffset_minus_ps = 0; + + LAPPDBG_PPSBefore = 0; + LAPPDBG_PPSAfter = 0; + LAPPDBG_PPSDiff = 0; + LAPPDBG_PPSMissing = 0; + LAPPDTS_PPSBefore = 0; + LAPPDTS_PPSAfter = 0; + LAPPDTS_PPSDiff = 0; + LAPPDTS_PPSMissing = 0; + + return true; +} + +bool EBLAPPD::LoadLAPPDData() +{ + // get the LAPPD beamgate + LAPPDBeamgate_Raw = 0; + LAPPDTimestamp_Raw = 0; + m_data->CStore.Get("LAPPDBeamgate_Raw", LAPPDBeamgate_Raw); + m_data->CStore.Get("LAPPDTimestamp_Raw", LAPPDTimestamp_Raw); + + LAPPDBeamgate_ns = LAPPDBeamgate_Raw * 3.125; + LAPPDTimestamp_ns = LAPPDTimestamp_Raw * 3.125; + + LAPPDBGCorrection = 0; + LAPPDTSCorrection = 0; + LAPPDOffset_minus_ps = 0; + m_data->CStore.Get("LAPPDBGCorrection", LAPPDBGCorrection); + m_data->CStore.Get("LAPPDTSCorrection", LAPPDTSCorrection); + m_data->CStore.Get("LAPPDOffset_minus_ps", LAPPDOffset_minus_ps); + LAPPDOffset = 0; + m_data->CStore.Get("LAPPDOffset", LAPPDOffset); + + LAPPDBeamgate_ns = LAPPDBeamgate_ns + LAPPDBGCorrection + LAPPDOffset; + LAPPDTimestamp_ns = LAPPDTimestamp_ns + LAPPDTSCorrection + LAPPDOffset; + + LAPPDBG_PPSBefore = 0; + LAPPDBG_PPSAfter = 0; + LAPPDBG_PPSDiff = 0; + LAPPDBG_PPSMissing = 0; + LAPPDTS_PPSBefore = 0; + LAPPDTS_PPSAfter = 0; + LAPPDTS_PPSDiff = 0; + LAPPDTS_PPSMissing = 0; + m_data->CStore.Get("BG_PPSBefore", LAPPDBG_PPSBefore); + m_data->CStore.Get("BG_PPSAfter", LAPPDBG_PPSAfter); + m_data->CStore.Get("BG_PPSDiff", LAPPDBG_PPSDiff); + m_data->CStore.Get("BG_PPSMissing", LAPPDBG_PPSMissing); + m_data->CStore.Get("TS_PPSBefore", LAPPDTS_PPSBefore); + m_data->CStore.Get("TS_PPSAfter", LAPPDTS_PPSAfter); + m_data->CStore.Get("TS_PPSDiff", LAPPDTS_PPSDiff); + m_data->CStore.Get("TS_PPSMissing", LAPPDTS_PPSMissing); + + if (verbosityEBLAPPD > 1) + { + cout << "Processing new LAPPD data from store" << endl; + cout << "Got info: LAPPDBeamgate_Raw: " << LAPPDBeamgate_Raw << ", LAPPDTimestamp_Raw: " << LAPPDTimestamp_Raw << ", LAPPDBGCorrection: " << LAPPDBGCorrection << ", LAPPDTSCorrection: " << LAPPDTSCorrection << ", LAPPDOffset: " << LAPPDOffset << ", LAPPDOffset_minus_ps: " << LAPPDOffset_minus_ps << ", LAPPDBG_PPSBefore: " << LAPPDBG_PPSBefore << ", LAPPDBG_PPSAfter: " << LAPPDBG_PPSAfter << ", LAPPDBG_PPSDiff: " << LAPPDBG_PPSDiff << ", LAPPDBG_PPSMissing: " << LAPPDBG_PPSMissing << ", LAPPDTS_PPSBefore: " << LAPPDTS_PPSBefore << ", LAPPDTS_PPSAfter: " << LAPPDTS_PPSAfter << ", LAPPDTS_PPSDiff: " << LAPPDTS_PPSDiff << ", LAPPDTS_PPSMissing: " << LAPPDTS_PPSMissing << endl; + cout << "LAPPDBeamgate_ns: " << LAPPDBeamgate_ns << endl; + cout << "LAPPDTimestamp_ns: " << LAPPDTimestamp_ns << endl; + } + + bool gotdata = m_data->CStore.Get("StoreLoadedLAPPDData", dat); + + if (gotdata) + { + Buffer_LAPPDTimestamp_ns.push_back(LAPPDTimestamp_ns); + + Buffer_LAPPDData.push_back(dat); + Buffer_LAPPDBeamgate_ns.push_back(LAPPDBeamgate_ns); + Buffer_LAPPDOffset.push_back(LAPPDOffset); + Buffer_LAPPDBeamgate_Raw.push_back(LAPPDBeamgate_Raw); + Buffer_LAPPDTimestamp_Raw.push_back(LAPPDTimestamp_Raw); + Buffer_LAPPDBGCorrection.push_back(LAPPDBGCorrection); + Buffer_LAPPDTSCorrection.push_back(LAPPDTSCorrection); + Buffer_LAPPDOffset_minus_ps.push_back(LAPPDOffset_minus_ps); + Buffer_RunCode.push_back(currentRunCode); + + Buffer_LAPPDBG_PPSBefore.push_back(LAPPDBG_PPSBefore); + Buffer_LAPPDBG_PPSAfter.push_back(LAPPDBG_PPSAfter); + Buffer_LAPPDBG_PPSDiff.push_back(LAPPDBG_PPSDiff); + Buffer_LAPPDBG_PPSMissing.push_back(LAPPDBG_PPSMissing); + Buffer_LAPPDTS_PPSBefore.push_back(LAPPDTS_PPSBefore); + Buffer_LAPPDTS_PPSAfter.push_back(LAPPDTS_PPSAfter); + Buffer_LAPPDTS_PPSDiff.push_back(LAPPDTS_PPSDiff); + Buffer_LAPPDTS_PPSMissing.push_back(LAPPDTS_PPSMissing); + + MatchBuffer_LAPPDTimestamp_ns.push_back(LAPPDTimestamp_ns); + + if (LAPPDTS_PPSMissing != LAPPDBG_PPSMissing) + Log("EBLAPPD: PPS missing in BG and TS are different, BG: " + std::to_string(LAPPDBG_PPSMissing) + ", TS: " + std::to_string(LAPPDTS_PPSMissing), v_warning, verbosityEBLAPPD); + + Log("EBLAPPD: Loaded LAPPD data to buffer, Buffer_LAPPDData size after this load is now " + std::to_string(Buffer_LAPPDData.size()), v_message, verbosityEBLAPPD); + } + + return true; +} + +bool EBLAPPD::Matching(int targetTrigger, int matchToTrack) +{ + cout << "\033[1;34m******* EBLAPPD : Matching *******\033[0m" << endl; + Log("EBLAPPD: Matching LAPPD data with target trigger " + std::to_string(targetTrigger) + " in track " + std::to_string(matchToTrack), v_message, verbosityEBLAPPD); + + std::map>> GroupedTriggersInTotal; // each map is a group of triggers, with the key is the target trigger word + m_data->CStore.Get("GroupedTriggersInTotal", GroupedTriggersInTotal); + // print how many trigger groups in each track + + vector matchedLAPPDTimes; + vector indexToRemove; + std::map matchedNumberInTrack; + + // loop the LAPPDDataBuffer keys, and loop all the grouped triggers + // in each group of trigger, find the target trigger word and it's time + // fine the minimum time difference, if smaller than matchTolerance_ns, then save the time to PairedCTCTimeStamps and PairedLAPPDTimeStamps + for (int i = 0; i < MatchBuffer_LAPPDTimestamp_ns.size(); i++) + { + uint64_t LAPPDtime = MatchBuffer_LAPPDTimestamp_ns.at(i); + // if found LAPPDtime at PairedLAPPDTimeStamps, skip //shouldn't happen + if (std::find(PairedLAPPDTimeStamps[matchToTrack].begin(), PairedLAPPDTimeStamps[matchToTrack].end(), LAPPDtime) != PairedLAPPDTimeStamps[matchToTrack].end()) + { + Log("EBLAPPD: Buffer " + std::to_string(i) + " with time " + std::to_string(Buffer_LAPPDTimestamp_ns.at(i)) + ": Found a match already", v_message, verbosityEBLAPPD); + continue; + } + + // set minDT to 5 min + uint64_t minDT = 5 * 60 * 1e9; + uint64_t minDTTrigger = 0; + uint64_t dt = 0; + uint32_t matchedTrigWord = 0; + int matchedTrack = 0; + int matchedIndex = 0; + + for (std::pair>> pair : GroupedTriggersInTotal) + { + int TrackTriggerWord = pair.first; + if (matchedNumberInTrack.find(TrackTriggerWord) == matchedNumberInTrack.end()) + matchedNumberInTrack.emplace(TrackTriggerWord, 0); + if (TrackTriggerWord != matchToTrack && !matchToAllTriggers) + { + // Log("EBLAPPD: Skipping TrackTriggerWord " + std::to_string(TrackTriggerWord), v_debug, verbosityEBLAPPD); + continue; + } + vector> GroupedTriggers = pair.second; + + for (int j = 0; j < GroupedTriggers.size(); j++) + { + map groupedTrigger = GroupedTriggers.at(j); + // itearte over all the grouped triggers, if the value is target trigger, then calculate the time difference + for (std::pair p : groupedTrigger) + { + if (matchToAllTriggers || p.second == targetTrigger) + { + + if (LAPPDtime > p.first) + { + dt = LAPPDtime - p.first; + } + else + { + dt = p.first - LAPPDtime; + } + if (dt < minDT) + { + minDT = dt; + minDTTrigger = p.first; + matchedTrigWord = p.second; + matchedTrack = TrackTriggerWord; + matchedIndex = j; + } + } + } + } + } + + Log("EBLAPPD: at buffer " + std::to_string(i) + " with time " + std::to_string(Buffer_LAPPDTimestamp_ns.at(i)) + ", minDT: " + std::to_string(minDT), v_debug, verbosityEBLAPPD); + if (minDT < matchTolerance_ns) + { + PairedCTCTimeStamps[matchedTrack].push_back(minDTTrigger); + PairedLAPPDTimeStamps[matchedTrack].push_back(LAPPDtime); + PairedLAPPD_TriggerIndex[matchedTrack].push_back(matchedIndex); + + matchedLAPPDTimes.push_back(LAPPDtime); + indexToRemove.push_back(i); + matchedLAPPDNumber++; + matchedNumberInTrack[matchedTrack]++; + Log("EBLAPPD: Buffer " + std::to_string(i) + " with time " + std::to_string(Buffer_LAPPDTimestamp_ns.at(i)) + ": Found a match for LAPPD data at " + std::to_string(LAPPDtime) + " with target trigger at " + std::to_string(minDTTrigger) + " with minDT " + std::to_string(minDT), v_message, verbosityEBLAPPD); + } + } + Log("EBLAPPD: Finished matching LAPPD data with target triggers, " + std::to_string(matchedLAPPDTimes.size()) + " new matched found, total matchedLAPPDNumber = " + std::to_string(matchedLAPPDNumber) + " in buffer size = " + std::to_string(MatchBuffer_LAPPDTimestamp_ns.size()), v_message, verbosityEBLAPPD); + + for (int i = indexToRemove.size() - 1; i >= 0; i--) + { + MatchBuffer_LAPPDTimestamp_ns.erase(MatchBuffer_LAPPDTimestamp_ns.begin() + indexToRemove.at(i)); + } + + Log("EBLAPPD: Finished removing paired LAPPD data from match buffer, MatchBuffer_LAPPDTimestamp_ns size is now " + std::to_string(MatchBuffer_LAPPDTimestamp_ns.size()), v_message, verbosityEBLAPPD); + // print all elements in matchedNumberInTrack with key and value + for (std::pair pair : matchedNumberInTrack) + { + Log("EBLAPPD: Match finished, matched number in Track " + std::to_string(pair.first) + " is = " + std::to_string(pair.second), v_message, verbosityEBLAPPD); + } + + return true; +} \ No newline at end of file diff --git a/UserTools/EBLAPPD/EBLAPPD.h b/UserTools/EBLAPPD/EBLAPPD.h new file mode 100644 index 000000000..a1dd6cfa3 --- /dev/null +++ b/UserTools/EBLAPPD/EBLAPPD.h @@ -0,0 +1,95 @@ +#ifndef EBLAPPD_H +#define EBLAPPD_H + +#include +#include + +#include "Tool.h" +#include "PsecData.h" +#include "BoostStore.h" + +/** + * \class EBPMT + * + * $Author: Yue Feng $ + * $Date: 2024/04 $ + * Contact: yuef@iaistate.edu + * + */ + +class EBLAPPD : public Tool +{ + +public: + EBLAPPD(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + bool LoadLAPPDData(); + bool CleanData(); + bool Matching(int targetTrigger, int matchToTrack); + +private: + int thisRunNum; + bool matchToAllTriggers; + int exePerMatch; + + PsecData dat; + uint64_t LAPPDBeamgate_ns; + uint64_t LAPPDTimestamp_ns; + uint64_t LAPPDOffset; + unsigned long LAPPDBeamgate_Raw; + unsigned long LAPPDTimestamp_Raw; + int LAPPDBGCorrection; + int LAPPDTSCorrection; + int LAPPDOffset_minus_ps; + uint64_t LAPPDBG_PPSBefore; + uint64_t LAPPDBG_PPSAfter; + uint64_t LAPPDBG_PPSDiff; + int LAPPDBG_PPSMissing; + uint64_t LAPPDTS_PPSBefore; + uint64_t LAPPDTS_PPSAfter; + uint64_t LAPPDTS_PPSDiff; + int LAPPDTS_PPSMissing; + + vector MatchBuffer_LAPPDTimestamp_ns; // used to indexing data for unmatched + + // TODO, maybe make a new "LAPPDBuildData" class? + vector Buffer_LAPPDTimestamp_ns; // used to indexing the data + vector Buffer_LAPPDData; + vector Buffer_LAPPDBeamgate_ns; + vector Buffer_LAPPDOffset; + vector Buffer_LAPPDBeamgate_Raw; + vector Buffer_LAPPDTimestamp_Raw; + vector Buffer_LAPPDBGCorrection; + vector Buffer_LAPPDTSCorrection; + vector Buffer_LAPPDOffset_minus_ps; + vector Buffer_RunCode; + vector Buffer_LAPPDBG_PPSBefore; + vector Buffer_LAPPDBG_PPSAfter; + vector Buffer_LAPPDBG_PPSDiff; + vector Buffer_LAPPDBG_PPSMissing; + vector Buffer_LAPPDTS_PPSBefore; + vector Buffer_LAPPDTS_PPSAfter; + vector Buffer_LAPPDTS_PPSDiff; + vector Buffer_LAPPDTS_PPSMissing; + + std::map> PairedCTCTimeStamps; + std::map> PairedLAPPD_TriggerIndex; + std::map> PairedLAPPDTimeStamps; + + int matchTargetTrigger; + uint64_t matchTolerance_ns; + int verbosityEBLAPPD; + + int matchedLAPPDNumber = 0; + int exeNum = 0; + int currentRunCode; + + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; +}; + +#endif diff --git a/UserTools/EBLAPPD/README.md b/UserTools/EBLAPPD/README.md new file mode 100644 index 000000000..c8b4796ae --- /dev/null +++ b/UserTools/EBLAPPD/README.md @@ -0,0 +1,35 @@ +# EBLAPPD + +EBLAPPD tool is a part of Event Building version 2 tool chain. +For reference slides, see: +https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=5633 + +EBLAPPD match the LAPPD beamgate + LAPPD offset to grouped trigger, and save the matching results to CStore for EBSaver. + +## Data + +**PairedCTCTimeStamps** +After matching, the matched trigger timestamp will be saved here. The key is the main trigger word for each run type. +Saved as PairedLAPPDTriggerTimestamp in CStore. + +**PairedLAPPDTimeStamps** +After matching, the matched LAPPD beamgate + offset will be saved here. The key is the main trigger word for each run type. +This and PairedCTCTimeStamps have the same index. A little bit dangerous, but overall works well. +Saved as PairedLAPPDTimeStamps in CStore + + +## Configuration + +**matchTargetTrigger** +This gives which trigger word that the LAPPD beamgate + offset should be matched to. + +**matchTolerance_ns** +This gives the maximum allowed time tolerance between the LAPPD beamgate + offset and the target trigger timestamp. + +**exePerMatch** +This gives how many loops need to be past for one matching between MLAPPD beamgate + offset and target trigger timestamps. +500 is generally fine with beam runs. + +**matchToAllTriggers** +1 or 0. 1 means match to all possible triggers, 0 means only match to the target trigger. + diff --git a/UserTools/EBLoadRaw/EBLoadRaw.cpp b/UserTools/EBLoadRaw/EBLoadRaw.cpp new file mode 100644 index 000000000..bb3c53fd6 --- /dev/null +++ b/UserTools/EBLoadRaw/EBLoadRaw.cpp @@ -0,0 +1,709 @@ +#include "EBLoadRaw.h" + +EBLoadRaw::EBLoadRaw() : Tool() {} + +bool EBLoadRaw::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + m_variables.Get("verbosityEBLoadRaw", verbosityEBLoadRaw); + + ReadTriggerOverlap = false; + m_variables.Get("ReadTriggerOverlap", ReadTriggerOverlap); + m_variables.Get("InputFile", InputFile); + OrganizedFileList = OrganizeRunParts(InputFile); + + LoadCTC = false; + m_variables.Get("LoadCTC", LoadCTC); + LoadPMT = false; + m_variables.Get("LoadPMT", LoadPMT); + LoadMRD = false; + m_variables.Get("LoadMRD", LoadMRD); + LoadLAPPD = false; + m_variables.Get("LoadLAPPD", LoadLAPPD); + + FileCompleted = false; + JumpBecauseLAPPD = false; + ProcessingComplete = false; + PMTPaused = false; + MRDPaused = false; + LAPPDPaused = false; + CTCPaused = false; + usingTriggerOverlap = false; + LoadingFileNumber = 0; + + RunNumber = 0; + SubRunNumber = 0; + PartFileNumber = 0; + + CTCEntryNum = 0; + PMTEntryNum = 0; + MRDEntryNum = 0; + LAPPDEntryNum = 0; + + PMTTotalEntries = 0; + MRDTotalEntries = 0; + LAPPDTotalEntries = 0; + CTCTotalEntries = 0; + PMTEntriesCompleted = false; + MRDEntriesCompleted = false; + LAPPDEntriesCompleted = false; + CTCEntriesCompleted = false; + LoadedPMTTotalEntries = 0; + LoadedMRDTotalEntries = 0; + LoadedLAPPDTotalEntries = 0; + LoadedCTCTotalEntries = 0; + + PMTMatchingForced = false; + MRDMatchingForced = false; + LAPPDMatchingForced = false; + + RawData = new BoostStore(false, 0); + PMTData = new BoostStore(false, 2); + MRDData = new BoostStore(false, 2); + LAPPDData = new BoostStore(false, 2); + CTCData = new BoostStore(false, 2); + CData = new std::vector; + TData = new TriggerData; + MData = new MRDOut; + LData = new PsecData; + + m_data->CStore.Set("FileProcessingComplete", false); + RunCodeToSave = 0; + + return true; +} + +bool EBLoadRaw::Execute() +{ + m_data->CStore.Set("NewRawDataEntryAccessed", false); + m_data->CStore.Set("NewRawDataFileAccessed", false); + m_data->CStore.Set("SaveProcessedFile", false); + + ProcessingComplete = false; + if (FileCompleted) + { + if (CurrentFile != "NONE") + { + RunCodeToSave = RunCode(CurrentFile); + m_data->CStore.Set("RunCodeToSave", RunCodeToSave); + m_data->CStore.Set("SaveProcessedFile", true); + Log("EBLoadRaw: File completed, saving file " + CurrentFile + " with RunCode: " + std::to_string(RunCodeToSave), v_message, verbosityEBLoadRaw); + } + ProcessingComplete = LoadNewFile(); + } + + if (ProcessingComplete) + { + RunCodeToSave = RunCode(CurrentFile); + m_data->CStore.Set("RunCodeToSave", RunCodeToSave); + m_data->CStore.Set("SaveProcessedFile", true); + m_data->CStore.Set("SaveEverything", true); + Log("EBLoadRaw: File completed, saving file " + CurrentFile + " with RunCode: " + std::to_string(RunCodeToSave), v_message, verbosityEBLoadRaw); + + m_data->CStore.Set("FileProcessingComplete", true); + m_data->vars.Set("StopLoop", 1); + Log("EBLoadRaw: All files have been processed, set pause flags, PMT: " + std::to_string(PMTPaused) + ", MRD: " + std::to_string(MRDPaused) + ", CTC: " + std::to_string(CTCPaused) + ", LAPPD: " + std::to_string(LAPPDPaused), v_message, verbosityEBLoadRaw); + return true; + } + + m_data->CStore.Get("PauseTankDecoding", PMTPaused); + m_data->CStore.Get("PauseMRDDecoding", MRDPaused); + m_data->CStore.Get("PauseCTCDecoding", CTCPaused); + m_data->CStore.Get("PauseLAPPDDecoding", LAPPDPaused); + + if (OrganizedFileList.size() == 0) + { + Log("EBLoadRaw: No files to process.", v_warning, verbosityEBLoadRaw); + m_data->vars.Set("StopLoop", 1); + return true; + } + if (FileCompleted || CurrentFile == "NONE") + { + Log("EBLoadRaw: Loading new file. " + OrganizedFileList.at(LoadingFileNumber), v_message, verbosityEBLoadRaw); + CurrentFile = OrganizedFileList.at(LoadingFileNumber); + RawData->Initialise(CurrentFile.c_str()); + Log("EBLoadRaw: File loaded.", v_message, verbosityEBLoadRaw); + m_data->CStore.Set("NewRawDataFileAccessed", true); + if (verbosityEBLoadRaw > 4) + RawData->Print(false); + LoadRunInfo(); + LoadPMTData(); + LoadMRDData(); + LoadCTCData(); + LoadLAPPDData(); + + PMTMatchingForced = false; + MRDMatchingForced = false; + LAPPDMatchingForced = false; + } + else + { + Log("EBLoadRaw: Loading next entry of current file " + CurrentFile, v_message, verbosityEBLoadRaw); + } + + FileCompleted = false; + if (JumpBecauseLAPPD) + { + FileCompleted = true; + JumpBecauseLAPPD = false; + Log("EBLoadRaw: Jumping to next file due to LAPPD data.", v_message, verbosityEBLoadRaw); + return true; + } + + // if more MRD events than VME PMT events, jump to next file + // this is an old option, why? + if (MRDTotalEntries > PMTTotalEntries) + { + // FileCompleted = true; + Log("EBLoadRaw: Jumping to next file due to MRD entry is more than PMT entry.", v_message, verbosityEBLoadRaw); + // return true; + } + + if (LoadPMT && PMTEntryNum == PMTTotalEntries) + { + Log("EBLoadRaw: ALL PMT entries Loaded.", v_message, verbosityEBLoadRaw); + PMTEntriesCompleted = true; + PMTPaused = true; + } + if (LoadMRD && MRDEntryNum == MRDTotalEntries) + { + Log("EBLoadRaw: ALL MRD entries Loaded.", v_message, verbosityEBLoadRaw); + MRDEntriesCompleted = true; + MRDPaused = true; + } + if (LoadCTC && CTCEntryNum == CTCTotalEntries) + { + Log("EBLoadRaw: ALL CTC entries Loaded.", v_message, verbosityEBLoadRaw); + CTCEntriesCompleted = true; + CTCPaused = true; + } + if (LoadLAPPD && LAPPDEntryNum == LAPPDTotalEntries) + { + Log("EBLoadRaw: ALL LAPPD entries Loaded.", v_message, verbosityEBLoadRaw); + LAPPDEntriesCompleted = true; + LAPPDPaused = true; + } + + if (LoadLAPPD && LAPPDTotalEntries < 0) + LAPPDEntriesCompleted = true; + + m_data->CStore.Set("PauseTankDecoding", PMTPaused); + m_data->CStore.Set("PauseMRDDecoding", MRDPaused); + m_data->CStore.Set("PauseCTCDecoding", CTCPaused); + m_data->CStore.Set("PauseLAPPDDecoding", LAPPDPaused); + + Log("EBLoadRaw: Set pause flags, PMT: " + std::to_string(PMTPaused) + ", MRD: " + std::to_string(MRDPaused) + ", CTC: " + std::to_string(CTCPaused) + ", LAPPD: " + std::to_string(LAPPDPaused), v_message, verbosityEBLoadRaw); + + if (LoadPMT && !PMTPaused && !PMTEntriesCompleted) + LoadNextPMTData(); + if (LoadMRD && !MRDPaused && !MRDEntriesCompleted) + LoadNextMRDData(); + if (LoadCTC && !CTCPaused && !CTCEntriesCompleted) + LoadNextCTCData(); + if (LoadLAPPD && !LAPPDPaused && !LAPPDEntriesCompleted) + LoadNextLAPPDData(); + + if (LoadMRD && MRDEntriesCompleted) + { + bool ForceMRDMatching = false; + m_data->CStore.Set("ForceMRDMatching", ForceMRDMatching); + } + if (LoadLAPPD && LAPPDEntriesCompleted) + { + bool ForceLAPPDMatching = false; + m_data->CStore.Set("ForceLAPPDMatching", ForceLAPPDMatching); + } + + // if all required data is loaded, set filecompleted flag to true + if ((!LoadPMT || PMTEntriesCompleted) && (!LoadMRD || MRDEntriesCompleted) && (!LoadCTC || CTCEntriesCompleted) && (!LoadLAPPD || LAPPDEntriesCompleted)) + { + FileCompleted = true; + Log("EBLoadRaw: All data loaded.", v_message, verbosityEBLoadRaw); + } + + if (verbosityEBLoadRaw > v_message) + { + std::cout << "**************************************************EBLoadRaw: Current progress after execute: " << std::endl; + std::cout << "EBLoadRaw: Current file: " << CurrentFile << std::endl; + if (LoadPMT) + std::cout << "EBLoadRaw: PMT entries: " << PMTEntryNum << " / " << PMTTotalEntries << " = " << static_cast(PMTEntryNum) / static_cast(PMTTotalEntries) * 100 << "%" << std::endl; + if (LoadMRD) + std::cout << "EBLoadRaw: MRD entries: " << MRDEntryNum << " / " << MRDTotalEntries << " = " << static_cast(MRDEntryNum) / static_cast(MRDTotalEntries) * 100 << "%" << std::endl; + if (LoadCTC) + std::cout << "EBLoadRaw: CTC entries: " << CTCEntryNum << " / " << CTCTotalEntries << " = " << static_cast(CTCEntryNum) / static_cast(CTCTotalEntries) * 100 << "%" << std::endl; + if (LoadLAPPD) + std::cout << "EBLoadRaw: LAPPD entries: " << LAPPDEntryNum << " / " << LAPPDTotalEntries << " = " << static_cast(LAPPDEntryNum) / static_cast(LAPPDTotalEntries) * 100 << "%" << std::endl; + std::cout << "**********************************************************************************************" << std::endl; + } + + m_data->CStore.Set("MRDEntriesCompleted", MRDEntriesCompleted); + m_data->CStore.Set("PMTEntriesCompleted", PMTEntriesCompleted); + m_data->CStore.Set("CTCEntriesCompleted", CTCEntriesCompleted); + m_data->CStore.Set("LAPPDEntriesCompleted", LAPPDEntriesCompleted); + Log("EBLoadRaw: Set entries completed flags, PMT: " + std::to_string(PMTEntriesCompleted) + ", MRD: " + std::to_string(MRDEntriesCompleted) + ", CTC: " + std::to_string(CTCEntriesCompleted) + ", LAPPD: " + std::to_string(LAPPDEntriesCompleted), v_message, verbosityEBLoadRaw); + + m_data->CStore.Set("NewRawDataEntryAccessed", true); + m_data->CStore.Set("FileCompleted", FileCompleted); + + Log("EBLoadRaw: Finished execution loop.", v_message, verbosityEBLoadRaw); + return true; +} + +bool EBLoadRaw::Finalise() +{ + RawData->Close(); + RawData->Delete(); + delete RawData; + if (LoadPMT) + { + PMTData->Close(); + PMTData->Delete(); + delete PMTData; + } + if (LoadMRD) + { + MRDData->Close(); + MRDData->Delete(); + delete MRDData; + } + if (LoadLAPPD) + { + LAPPDData->Close(); + LAPPDData->Delete(); + delete LAPPDData; + } + if (LoadCTC) + { + CTCData->Close(); + CTCData->Delete(); + delete CTCData; + } + + std::cout << "\033[1;34mEBLoadRaw: Finalising EBLoadRaw\033[0m" << std::endl; + std::cout << "EBLoadRaw: Loaded " << OrganizedFileList.size() << " files " + << " from " << OrganizedFileList.at(0) << " to " << OrganizedFileList.at(OrganizedFileList.size() - 1) << std::endl; + std::cout << "EBLoadRaw: Loaded " << LoadedPMTTotalEntries << " PMT entries. " << std::endl; + std::cout << "EBLoadRaw: Loaded " << LoadedMRDTotalEntries << " MRD entries. " << std::endl; + std::cout << "EBLoadRaw: Loaded " << LoadedCTCTotalEntries << " CTC entries. " << std::endl; + std::cout << "EBLoadRaw: Loaded " << LoadedLAPPDTotalEntries << " LAPPD entries. " << std::endl; + + return true; +} + +std::vector EBLoadRaw::OrganizeRunParts(std::string FileList) +{ + std::vector OrganizedFiles; + std::vector UnorganizedFileList; + std::vector RunCodes; + int ThisRunCode; + // First, parse the lines and get all files. + std::string line; + ifstream myfile(FileList.c_str()); + if (myfile.is_open()) + { + std::cout << "Lines in FileList being printed" << std::endl; // has our stuff; + while (getline(myfile, line)) + { + if (line.find("#") != std::string::npos) + continue; + std::string filename = line; + int RunCodeNumber = RunCode(filename); + + if (RunCodeNumber != -9999) + { + UnorganizedFileList.push_back(filename); + RunCodes.push_back(RunCodeNumber); + } + + } // End parsing each line in file + + // Now, organize files based on the part number array + std::vector> SortingVector; + for (int i = 0; i < (int)UnorganizedFileList.size(); i++) + { + SortingVector.push_back(std::make_pair(RunCodes.at(i), UnorganizedFileList.at(i))); + } + std::sort(SortingVector.begin(), SortingVector.end()); + for (int j = 0; j < (int)SortingVector.size(); j++) + { + OrganizedFiles.push_back(SortingVector.at(j).second); + } + } + // print the OrganizedFiles + for (int i = 0; i < (int)OrganizedFiles.size(); i++) + { + std::cout << OrganizedFiles.at(i) << std::endl; + } + + return OrganizedFiles; +} + +int EBLoadRaw::RunCode(string fileName) +{ + // extract run number and file number from filename + std::regex runNumber_regex("RAWDataR(\\d{4})"); + std::regex subrunNumber_regex("S(\\d{1,4})p"); + std::regex rawFileNumber_regex("p(\\d{1,4})$"); + std::smatch match; + int runNumber = -9999; + int subrunNumber = -9999; + int rawFileNumber = -9999; + bool allmatched = false; + if (std::regex_search(fileName, match, runNumber_regex) && match.size() > 1) + { + runNumber = std::stoi(match.str(1)); + if (verbosityEBLoadRaw > 0) + std::cout << "runNumber: " << runNumber << std::endl; + m_data->CStore.Set("runNumber", runNumber); + allmatched = true; + } + else + { + std::cout << "runNumber not found" << std::endl; + m_data->CStore.Set("rawFileNumber", -9999); + } + + if (std::regex_search(fileName, match, subrunNumber_regex) && match.size() > 1) + { + subrunNumber = std::stoi(match.str(1)); + if (verbosityEBLoadRaw > 0) + std::cout << "subrunNumber: " << subrunNumber << std::endl; + m_data->CStore.Set("subrunNumber", subrunNumber); + allmatched = true; + } + else + { + std::cout << "subrunNumber not found" << std::endl; + m_data->CStore.Set("subrunNumber", -9999); + } + + if (std::regex_search(fileName, match, rawFileNumber_regex) && match.size() > 1) + { + rawFileNumber = std::stoi(match.str(1)); + if (verbosityEBLoadRaw > 0) + std::cout << "rawFileNumber: " << rawFileNumber << std::endl; + m_data->CStore.Set("rawFileNumber", rawFileNumber); + allmatched = true; + } + else + { + std::cout << "rawFileNumber not found" << std::endl; + m_data->CStore.Set("runNumber", -9999); + } + + if (allmatched == true) + { + int runcode = runNumber * 100000 + ((subrunNumber + 1) * 10000) + rawFileNumber; + cout << "EBLoadRaw: RunCode: " << runcode << endl; + return runcode; + } + else + { + return -9999; + } +} + +bool EBLoadRaw::LoadRunInfo() +{ + int runCode = RunCode(CurrentFile); + Log("EBLoadRaw: Loading run information, RunCode: " + std::to_string(runCode), v_message, verbosityEBLoadRaw); + + RunNumber = runCode / 100000; + SubRunNumber = (runCode % 100000) / 10000 - 1; + PartFileNumber = runCode % 10000; + + Store Postgress; + + std::cout << "EBLoadRaw: loading run information, RunNumber: " << RunNumber << ", SubRunNumber: " << SubRunNumber << ", PartFileNumber: " << PartFileNumber << std::endl; + + Postgress.Set("RunNumber", RunNumber); + Postgress.Set("SubRunNumber", SubRunNumber); + Postgress.Set("PartFileNumber", PartFileNumber); + Postgress.Set("RunType", -1); + Postgress.Set("StartTime", -1); + + m_data->CStore.Set("RunInfoPostgress", Postgress); + + m_data->CStore.Set("RunNumber", RunNumber); + m_data->CStore.Set("SubRunNumber", SubRunNumber); + m_data->CStore.Set("PartFileNumber", PartFileNumber); + m_data->CStore.Set("RunCode", runCode); + + return true; +} + +// load new file and it's related boost store +bool EBLoadRaw::LoadNewFile() +{ + bool EndOfProcessing = false; + LoadingFileNumber++; + + RawData->Close(); + RawData->Delete(); + delete RawData; + RawData = new BoostStore(false, 0); + PMTData->Close(); + PMTData->Delete(); + delete PMTData; + PMTData = new BoostStore(false, 2); + MRDData->Close(); + MRDData->Delete(); + delete MRDData; + MRDData = new BoostStore(false, 2); + LAPPDData->Close(); + LAPPDData->Delete(); + delete LAPPDData; + LAPPDData = new BoostStore(false, 2); + CTCData->Close(); + CTCData->Delete(); + delete CTCData; + CTCData = new BoostStore(false, 2); + + PMTEntryNum = 0; + MRDEntryNum = 0; + LAPPDEntryNum = 0; + CTCEntryNum = 0; + + PMTEntriesCompleted = false; + MRDEntriesCompleted = false; + LAPPDEntriesCompleted = false; + CTCEntriesCompleted = false; + + m_data->CStore.Set("PauseTankDecoding", false); + m_data->CStore.Set("PauseMRDDecoding", false); + m_data->CStore.Set("PauseCTCDecoding", false); + m_data->CStore.Set("PauseLAPPDDecoding", false); + + if (LoadingFileNumber == OrganizedFileList.size()) + { + EndOfProcessing = true; + m_data->CStore.Set("PauseTankDecoding", true); + m_data->CStore.Set("PauseMRDDecoding", true); + m_data->CStore.Set("PauseCTCDecoding", true); + m_data->CStore.Set("PauseLAPPDDecoding", true); + } + + return EndOfProcessing; +} + +bool EBLoadRaw::LoadPMTData() +{ + Log("EBLoadRaw: Loading PMTData.", v_message, verbosityEBLoadRaw); + RawData->Get("PMTData", *PMTData); + PMTData->Header->Get("TotalEntries", PMTTotalEntries); + LoadedPMTTotalEntries += PMTTotalEntries; + Log("EBLoadRaw: PMTData loaded, TotalEntries: " + std::to_string(PMTTotalEntries), v_message, verbosityEBLoadRaw); + + if (verbosityEBLoadRaw > 3) + PMTData->Print(false); + if (verbosityEBLoadRaw > 3) + PMTData->Header->Print(false); + return true; +} + +bool EBLoadRaw::LoadMRDData() +{ + Log("EBLoadRaw: Loading MRDData.", v_message, verbosityEBLoadRaw); + RawData->Get("CCData", *MRDData); + MRDData->Header->Get("TotalEntries", MRDTotalEntries); + LoadedMRDTotalEntries += MRDTotalEntries; + Log("EBLoadRaw: MRDData loaded, TotalEntries: " + std::to_string(MRDTotalEntries), v_message, verbosityEBLoadRaw); + if (verbosityEBLoadRaw > 3) + MRDData->Print(false); + return true; +} + +bool EBLoadRaw::LoadCTCData() +{ + Log("EBLoadRaw: Loading CTCData.", v_message, verbosityEBLoadRaw); + RawData->Get("TrigData", *CTCData); + if (verbosityEBLoadRaw > 3) + CTCData->Print(false); + CTCData->Header->Get("TotalEntries", CTCTotalEntries); + LoadedCTCTotalEntries += CTCTotalEntries; + if (verbosityEBLoadRaw > 3) + CTCData->Header->Print(false); + if (ReadTriggerOverlap) + { + std::stringstream ss_trigoverlap; + ss_trigoverlap << "TrigOverlap_R" << RunNumber << "S" << SubRunNumber << "p" << PartFileNumber; + std::cout << "EBLoadRaw: Loading Trigger Overlap data: " << ss_trigoverlap.str() << std::endl; + BoostStore TrigOverlapStore; + bool store_exist = TrigOverlapStore.Initialise(ss_trigoverlap.str().c_str()); + std::cout << "EBLoadRaw: Trigger Overlap store exist: " << store_exist << std::endl; + if (store_exist) + { + CTCTotalEntries++; + std::cout << "EBLoadRaw: total trigger entry with overlap is: " << CTCTotalEntries << std::endl; + } + } + return true; +} + +bool EBLoadRaw::LoadLAPPDData() +{ + Log("EBLoadRaw: Loading LAPPDData.", v_message, verbosityEBLoadRaw); + try + { + RawData->Get("LAPPDData", *LAPPDData); + LAPPDData->Header->Get("TotalEntries", LAPPDTotalEntries); + Log("EBLoadRaw: LAPPDData loaded, TotalEntries: " + std::to_string(LAPPDTotalEntries), v_message, verbosityEBLoadRaw); + if (verbosityEBLoadRaw > 3) + { + LAPPDData->Print(false); + LAPPDData->Header->Print(false); + } + if (LAPPDTotalEntries < 0) + { + + cout << "EBLoadRaw: LAPPDData entry < 0, found " << LAPPDTotalEntries << ", set to 0" << endl; + LAPPDTotalEntries = 0; + LAPPDEntriesCompleted = true; + } + else if (LAPPDTotalEntries > 100000) + { + cout << "EBLoadRaw: LAPPDData entry very large, found " << LAPPDTotalEntries << ", return and set jump because LAPPD = true" << endl; + JumpBecauseLAPPD = true; + return true; + } + LoadedLAPPDTotalEntries += LAPPDTotalEntries; + } + catch (std::exception &e) + { + std::cout << "EBLoadRaw: LAPPDData not found in file." << std::endl; + LAPPDTotalEntries = 0; + LAPPDEntriesCompleted = true; + } + Log("EBLoadRaw: LAPPDData has " + std::to_string(LAPPDTotalEntries) + " entries.", v_message, verbosityEBLoadRaw); + return true; +} + +// load next entry of the current file +bool EBLoadRaw::LoadNextPMTData() +{ + Log("EBLoadRaw: Loading next PMTData entry " + std::to_string(PMTEntryNum) + " of " + std::to_string(PMTTotalEntries), v_warning, verbosityEBLoadRaw); + PMTData->GetEntry(PMTEntryNum); + Log("EBLoadRaw: Getting the PMT card data entry", v_warning, verbosityEBLoadRaw); + PMTData->Get("CardData", *CData); + Log("EBLoadRaw: Setting into CStore", v_warning, verbosityEBLoadRaw); + m_data->CStore.Set("CardData", CData); + Log("EBLoadRaw: Setting PMT entry num to CStore", v_warning, verbosityEBLoadRaw); + m_data->CStore.Set("TankEntryNum", PMTEntryNum); + PMTEntryNum++; + + if (PMTEntryNum == PMTTotalEntries && !PMTMatchingForced) + { + // force the PMT matching when all PMT entries are completed or PMTEntryNum is greater than PMTTotalEntries + Log("EBLoadRaw: PMTEntriesCompleted, force PMT matching", v_message, verbosityEBLoadRaw); + bool ForcePMTMatching = true; + m_data->CStore.Set("ForcePMTMatching", ForcePMTMatching); + PMTMatchingForced = true; + } + else + { + bool ForcePMTMatching = false; + m_data->CStore.Set("ForcePMTMatching", ForcePMTMatching); + } + + return true; +} + +bool EBLoadRaw::LoadNextMRDData() +{ + Log("EBLoadRaw: Loading next MRDData entry " + std::to_string(MRDEntryNum) + " of " + std::to_string(MRDTotalEntries), v_warning, verbosityEBLoadRaw); + MRDData->GetEntry(MRDEntryNum); + MRDData->Get("Data", *MData); + m_data->CStore.Set("MRDData", MData, true); + m_data->CStore.Set("MRDEntryNum", MRDEntryNum); + MRDEntryNum++; + + Log("EBLoadRaw: Loaded MRDData entry " + std::to_string(MRDEntryNum) + ", MRDTotalEntries " + std::to_string(MRDTotalEntries) + ", MRDMatchingForced " + std::to_string(MRDMatchingForced), v_warning, verbosityEBLoadRaw); + if (MRDEntryNum == MRDTotalEntries && !MRDMatchingForced) + { + Log("EBLoadRaw: MRDEntriesCompleted, force MRD matching", v_message, verbosityEBLoadRaw); + bool ForceMRDMatching = true; + m_data->CStore.Set("ForceMRDMatching", ForceMRDMatching); + MRDMatchingForced = true; + } + else + { + bool ForceMRDMatching = false; + m_data->CStore.Set("ForceMRDMatching", ForceMRDMatching); + } + + return true; +} + +bool EBLoadRaw::LoadNextLAPPDData() +{ + Log("EBLoadRaw: Loading next LAPPDData entry " + std::to_string(LAPPDEntryNum) + " of " + std::to_string(LAPPDTotalEntries), v_warning, verbosityEBLoadRaw); + LAPPDData->GetEntry(LAPPDEntryNum); + LAPPDData->Get("LAPPDData", *LData); + m_data->CStore.Set("LAPPDData", LData); + m_data->CStore.Set("LAPPDEntryNum", LAPPDEntryNum); + m_data->CStore.Set("LAPPDanaData", true); + LAPPDEntryNum++; + + Log("EBLoadRaw: Loaded LAPPDData entry " + std::to_string(LAPPDEntryNum) + ", LAPPDTotalEntries " + std::to_string(LAPPDTotalEntries) + ", LAPPDMatchingForced " + std::to_string(LAPPDMatchingForced), v_warning, verbosityEBLoadRaw); + if (LAPPDEntryNum == LAPPDTotalEntries && !LAPPDMatchingForced) + { + Log("EBLoadRaw: LAPPDEntriesCompleted, force LAPPD matching", v_message, verbosityEBLoadRaw); + bool ForceLAPPDMatching = true; + m_data->CStore.Set("ForceLAPPDMatching", ForceLAPPDMatching); + LAPPDMatchingForced = true; + } + else + { + bool ForceLAPPDMatching = false; + m_data->CStore.Set("ForceLAPPDMatching", ForceLAPPDMatching); + } + + return true; +} + +bool EBLoadRaw::LoadNextCTCData() +{ + Log("EBLoadRaw: Loading next CTCData entry " + std::to_string(CTCEntryNum) + " of " + std::to_string(CTCTotalEntries), v_warning, verbosityEBLoadRaw); + if (!ReadTriggerOverlap) + { + CTCData->GetEntry(CTCEntryNum); + CTCData->Get("TrigData", *TData); + Log("EBLoadRaw: Loaded CTCData entry " + std::to_string(CTCEntryNum), v_warning, verbosityEBLoadRaw); + } + else + { + if (CTCEntryNum != CTCTotalEntries - 1) + { + CTCData->GetEntry(CTCEntryNum); + CTCData->Get("TrigData", *TData); + m_data->CStore.Set("usingTriggerOverlap", false); + Log("EBLoadRaw: Loaded CTCData entry " + std::to_string(CTCEntryNum), v_warning, verbosityEBLoadRaw); + } + else + { + BoostStore TrigOverlapStore; + std::stringstream ss_trigoverlap; + ss_trigoverlap << "TrigOverlap_R" << RunNumber << "S" << SubRunNumber << "p" << PartFileNumber; + bool got_trig_o = TrigOverlapStore.Initialise(ss_trigoverlap.str().c_str()); + if (got_trig_o) + { + TrigOverlapStore.Get("TrigData", *TData); + m_data->CStore.Set("usingTriggerOverlap", true); + } + else + std::cout << "EBLoadRaw: Trigger Overlap data not found while loading" << std::endl; + } + m_data->CStore.Set("TrigData", TData); + + Log("EBLoadRaw: Loaded CTCData entry " + std::to_string(CTCEntryNum), v_warning, verbosityEBLoadRaw); + CTCEntryNum++; + } + return true; +} diff --git a/UserTools/EBLoadRaw/EBLoadRaw.h b/UserTools/EBLoadRaw/EBLoadRaw.h new file mode 100644 index 000000000..34c8257a8 --- /dev/null +++ b/UserTools/EBLoadRaw/EBLoadRaw.h @@ -0,0 +1,116 @@ +#ifndef EBLoadRaw_H +#define EBLoadRaw_H + +#include +#include + +#include "Tool.h" +#include "CardData.h" +#include "TriggerData.h" +#include "PsecData.h" +#include "BoostStore.h" +#include "Store.h" + +/** + * \class EBPMT + * + * $Author: Yue Feng $ + * $Date: 2024/04 $ + * Contact: yuef@iaistate.edu + * + */ + +class EBLoadRaw : public Tool +{ + +public: + EBLoadRaw(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + bool LoadPMTData(); + bool LoadMRDData(); + bool LoadLAPPDData(); + bool LoadCTCData(); + bool LoadRunInfo(); + + bool LoadNextPMTData(); + bool LoadNextMRDData(); + bool LoadNextLAPPDData(); + bool LoadNextCTCData(); + + bool LoadNewFile(); + int RunCode(string fileName); + std::vector OrganizeRunParts(std::string FileList); + +private: + std::string CurrentFile = "NONE"; + std::string InputFile; + std::vector OrganizedFileList; + bool ReadTriggerOverlap; + int RunCodeToSave; + + bool LoadCTC; + bool LoadPMT; + bool LoadMRD; + bool LoadLAPPD; + + int PMTTotalEntries; + int MRDTotalEntries; + int LAPPDTotalEntries; + int CTCTotalEntries; + + int LoadedPMTTotalEntries; + int LoadedMRDTotalEntries; + int LoadedLAPPDTotalEntries; + int LoadedCTCTotalEntries; + + bool ProcessingComplete; + bool FileCompleted; + bool JumpBecauseLAPPD; + bool PMTEntriesCompleted; + bool MRDEntriesCompleted; + bool LAPPDEntriesCompleted; + bool CTCEntriesCompleted; + bool usingTriggerOverlap; + + int CTCEntryNum; + int PMTEntryNum; + int MRDEntryNum; + int LAPPDEntryNum; + int LoadingFileNumber; + + int RunNumber; + int SubRunNumber; + int PartFileNumber; + + bool PMTPaused; + bool MRDPaused; + bool LAPPDPaused; + bool CTCPaused; + + bool PMTMatchingForced; + bool MRDMatchingForced; + bool LAPPDMatchingForced; + + BoostStore *RawData = nullptr; + BoostStore *PMTData = nullptr; + BoostStore *MRDData = nullptr; + BoostStore *LAPPDData = nullptr; + BoostStore *CTCData = nullptr; + + std::vector *CData = nullptr; + TriggerData *TData = nullptr; + MRDOut *MData = nullptr; + PsecData *LData = nullptr; + + int verbosityEBLoadRaw; + + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; +}; + +#endif diff --git a/UserTools/EBLoadRaw/README.md b/UserTools/EBLoadRaw/README.md new file mode 100644 index 000000000..957f68e36 --- /dev/null +++ b/UserTools/EBLoadRaw/README.md @@ -0,0 +1,20 @@ +# EBLoadRaw + +EBLoadRaw tool is a part of Event Building version 2 tool chain. +For reference slides, see: +https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=5633 +It basically follows the logic of LoadRawData, but reorganized to a different format and abort the BuileType option. If you need to load PMT and CTC data flow, just choose LoadCTC = true and LoadPMT = true, and use false for others. + +## Data + +need a list of raw part file as input, set the loaded entry to CStore. +Check Load*Data functions for each data flow. + +## Configuration + +**InputFile** is the name of txt file which has the raw part file list in it. +**ReadTriggerOverlap** will control load the overlap file or not. It's necessary for beam runs, not really necessary for source runs because lost a few events is not unacceptable for source run. + +**LoadCTC, LoadPMT, LoadMRD, LoadLAPPD** These tells the tool to load the data flow or not. Usually true for all of them. + + diff --git a/UserTools/EBMRD/EBMRD.cpp b/UserTools/EBMRD/EBMRD.cpp new file mode 100644 index 000000000..c00047144 --- /dev/null +++ b/UserTools/EBMRD/EBMRD.cpp @@ -0,0 +1,237 @@ +#include "EBMRD.h" + +EBMRD::EBMRD() : Tool() {} + +bool EBMRD::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_variables.Get("verbosityEBMRD", verbosityEBMRD); + matchTargetTrigger = 8; + m_variables.Get("matchTargetTrigger", matchTargetTrigger); + matchTolerance_ns = 2000000; // default 2ms + m_variables.Get("matchTolerance_ns", matchTolerance_ns); + exePerMatch = 500; + m_variables.Get("exePerMatch", exePerMatch); + matchToAllTriggers = 0; + m_variables.Get("matchToAllTriggers", matchToAllTriggers); + + matchedMRDNumber = 0; + + return true; +} + +bool EBMRD::Execute() +{ + m_data->CStore.Get("RunCode", currentRunCode); + + m_data->CStore.Get("MRDEvents", MRDEvents); + m_data->CStore.Get("MRDEventTriggerTypes", MRDEventTriggerTypes); + m_data->CStore.Get("MRDBeamLoopback", MRDBeamLoopback); + m_data->CStore.Get("MRDCosmicLoopback", MRDCosmicLoopback); + m_data->CStore.Get("NewMRDDataAvailable", NewMRDDataAvailable); + + m_data->CStore.Get("PairedMRDTriggerTimestamp", PairedCTCTimeStamps); + m_data->CStore.Get("PairedMRDTimeStamps", PairedMRDTimeStamps); + + Log("EBMRD: NewMRDDataAvailable = " + std::to_string(NewMRDDataAvailable) + ", Current loaded MRDEvents size is " + std::to_string(MRDEvents.size()), v_message, verbosityEBMRD); + Log("EBMRD: Current buffer size is " + std::to_string(MRDEventsBuffer.size()), v_message, verbosityEBMRD); + // loop the MRDEvents, save every event to MRDEventsBuffer if it's not already in the buffer + int newLoadedEvents = 0; + for (std::pair>> p : MRDEvents) + { + uint64_t MTCtime = p.first; + std::vector> WaveMap = p.second; + // if find the MTCtime in the PairedMRDTimeStamps, then skip + if (PairedMRDTimeStamps.size() > 0) + { + bool skip = false; + for (std::pair> pair : PairedMRDTimeStamps) + { + for (uint64_t t : pair.second) + { + if (t == MTCtime) + { + skip = true; + break; + } + } + if (skip) + break; + } + if (skip) + continue; + } + if (MRDEventsBuffer.find(MTCtime) == MRDEventsBuffer.end()) + { + MRDEventsBuffer.emplace(MTCtime, WaveMap); + newLoadedEvents++; + } + } + Log("EBMRD: Finished loading MRDEvents to buffer, Buffer_MRDEvents size is now " + std::to_string(MRDEventsBuffer.size()) + " new loaded events = " + std::to_string(newLoadedEvents), v_message, verbosityEBMRD); + + bool stopLoop = false; + m_data->vars.Get("StopLoop", stopLoop); + int runNum = thisRunNum; + m_data->vars.Get("RunNumber", thisRunNum); + bool ForceMRDMatching = false; + m_data->CStore.Get("ForceMRDMatching", ForceMRDMatching); + + if (exeNum % exePerMatch == 0 || runNum != thisRunNum || stopLoop || ForceMRDMatching) + { + Log("EBMRD: exeNum = " + std::to_string(exeNum) + ". Doing matching now", v_message, verbosityEBMRD); + if (matchToAllTriggers) + { + Matching(0, 0); + } + else + { + bool BeamTriggerGroupped = false; + m_data->CStore.Get("BeamTriggerGroupped", BeamTriggerGroupped); + bool CosmicTriggerGroupped = false; + m_data->CStore.Get("CosmicTriggerGroupped", CosmicTriggerGroupped); + bool NuMITriggerGroupped = false; + m_data->CStore.Get("NuMITriggerGroupped", NuMITriggerGroupped); + + + if (BeamTriggerGroupped) + Matching(matchTargetTrigger, 14); + if (CosmicTriggerGroupped) + { + Matching(36, 36); + Matching(45, 46); + } + if(NuMITriggerGroupped) + Matching(42, 46); + + if(!BeamTriggerGroupped && !CosmicTriggerGroupped && !NuMITriggerGroupped) + Log("EBMRD: BeamTriggerGroupped and CosmicTriggerGroupped are false, no beam trigger groupped in the grouper, stop matching", v_message, verbosityEBMRD); + } + } + + m_data->CStore.Set("PairedMRDTriggerTimestamp", PairedCTCTimeStamps); + m_data->CStore.Set("PairedMRDTimeStamps", PairedMRDTimeStamps); + m_data->CStore.Set("PairedMRD_TriggerIndex", PairedMRD_TriggerIndex); + m_data->CStore.Set("MRDHitMapRunCode", MRDHitMapRunCode); + + exeNum++; + return true; +} + +bool EBMRD::Finalise() +{ + Log("\033[1;34mEBMRD: Finalising\033[0m", v_message, verbosityEBMRD); + Log("EBMRD: Matched MRD number = " + std::to_string(matchedMRDNumber), v_message, verbosityEBMRD); + Log("EBMRD: Unmatched MRD number = " + std::to_string(MRDEventsBuffer.size()), v_message, verbosityEBMRD); + return true; +} + +bool EBMRD::Matching(int targetTrigger, int matchToTrack) +{ + cout << "\033[1;34m******* EBMRD : Matching *******\033[0m" << endl; + std::map>> GroupedTriggersInTotal; // each map is a group of triggers, with the key is the target trigger word + m_data->CStore.Get("GroupedTriggersInTotal", GroupedTriggersInTotal); + + Log("EBMRD: Got GroupedTriggersInTotal[14] size: " + std::to_string(GroupedTriggersInTotal[14].size()), v_message, verbosityEBMRD); + + vector matchedMRDTimes; + std::map matchedNumberInTrack; + + // loop the MRDEventsBuffer keys, and loop all the grouped triggers + // in each group of trigger, find the target trigger word and it's time + // fine the minimum time difference, if smaller than matchTolerance_ns, then save the time to PairedCTCTimeStamps and PairedMRDTimeStamps + int loopNum = 0; + for (std::pair>> mrdpair : MRDEventsBuffer) + { + if (verbosityEBMRD > 11) + cout << "******************EBMRD: new MRD event: " << loopNum << endl; + uint64_t MTCtime = mrdpair.first; + std::vector> WaveMap = mrdpair.second; + // set minDT to 5 min + uint64_t minDT = 5 * 60 * 1e9; + uint64_t minDTTrigger = 0; + uint64_t dt = 0; + uint32_t matchedTrigWord = 0; + int matchedTrack = 0; + int matchedIndex = 0; + for (std::pair>> pair : GroupedTriggersInTotal) + { + int TrackTriggerWord = pair.first; + if (TrackTriggerWord != matchToTrack && !matchToAllTriggers) + { + Log("EBMRD: Skipping TrackTriggerWord " + std::to_string(TrackTriggerWord), v_debug, verbosityEBMRD); + continue; + } + if (matchedNumberInTrack.find(TrackTriggerWord) == matchedNumberInTrack.end()) + matchedNumberInTrack.emplace(TrackTriggerWord, 0); + + vector> groupedTriggers = pair.second; + + for (int i = 0; i < groupedTriggers.size(); i++) + { + map groupedTrigger = groupedTriggers.at(i); + // itearte over all the grouped triggers, if the value is target trigger, then calculate the time difference + for (std::pair p : groupedTrigger) + { + if (matchToAllTriggers || p.second == targetTrigger) + { + if (MTCtime > p.first) + { + dt = MTCtime - p.first; + } + else + { + dt = p.first - MTCtime; + } + if (dt < minDT) + { + minDT = dt; + minDTTrigger = p.first; + matchedTrigWord = p.second; + matchedIndex = p.second; + matchedTrack = TrackTriggerWord; + + // if(verbosityEBMRD > 11) cout<<"EBMRD: dt: "< pair : matchedNumberInTrack) + { + Log("EBMRD: Match finished, matched number in Track " + std::to_string(pair.first) + " is " + std::to_string(pair.second), v_message, verbosityEBMRD); + } + + return true; +} \ No newline at end of file diff --git a/UserTools/EBMRD/EBMRD.h b/UserTools/EBMRD/EBMRD.h new file mode 100644 index 000000000..0722d5ae3 --- /dev/null +++ b/UserTools/EBMRD/EBMRD.h @@ -0,0 +1,63 @@ +#ifndef EBMRD_H +#define EBMRD_H + +#include +#include + +#include "Tool.h" + +/** + * \class EBPMT + * + * $Author: Yue Feng $ + * $Date: 2024/04 $ + * Contact: yuef@iaistate.edu + * + */ + +class EBMRD : public Tool +{ + +public: + EBMRD(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + bool Matching(int targetTrigger, int matchToTrack); + +private: + int verbosityEBMRD; + int matchTargetTrigger; + uint64_t matchTolerance_ns; + + int currentRunCode; + + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; + + int matchedMRDNumber = 0; + int exeNum = 0; + + std::map>> MRDEvents; // Key: {MTCTime}, value: "WaveMap" with key (CardID,ChannelID), value FinishedWaveform + std::map MRDEventTriggerTypes; // Key: {MTCTime}, value: string noting what type of trigger occured for the event + std::map MRDBeamLoopback; // Key: {MTCTime}, value: string noting what type of trigger occured for the event + std::map MRDCosmicLoopback; // KEY: {MTCTime}, value: Cosmic loopback TDC value + + std::map>> MRDEventsBuffer; + + bool NewMRDDataAvailable; + + std::map> PairedCTCTimeStamps; + std::map> PairedMRD_TriggerIndex; + std::map> PairedMRDTimeStamps; + std::map MRDHitMapRunCode; // Key: {MTCTime}, value: RunCode + + bool matchToAllTriggers; + + int thisRunNum; + int exePerMatch; +}; + +#endif diff --git a/UserTools/EBMRD/README.md b/UserTools/EBMRD/README.md new file mode 100644 index 000000000..3aed04355 --- /dev/null +++ b/UserTools/EBMRD/README.md @@ -0,0 +1,35 @@ +# EBMRD + +EBMRD tool is a part of Event Building version 2 tool chain. +For reference slides, see: +https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=5633 + +EBMRD match the MRD timestamp to grouped trigger, and save the matching results to CStore for EBSaver. + +## Data + + +**PairedCTCTimeStamps** +After matching, the matched trigger timestamp will be saved here. The key is the main trigger word for each run type. +Saved as PairedMRDTriggerTimestamp in CStore. + +**PairedMRDTimeStamps** +After matching, the matched MRD timestamp will be saved here. The key is the main trigger word for each run type. +This and PairedCTCTimeStamps have the same index. A little bit dangerous, but overall works well. +Saved as PairedMRDTimeStamps in CStore + + +## Configuration + +**matchTargetTrigger** +This gives which trigger word that the MRD timestamps should be matched to. + +**matchTolerance_ns** +This gives the maximum allowed time tolerance between the MRD timestmap and the target trigger timestamp. + +**exePerMatch** +This gives how many loops need to be past for one matching between MRD timestmaps and target trigger timestamps. +500 is generally fine with beam runs. 100 would be better for AmBe runs + +**matchToAllTriggers** +1 or 0. 1 means match MRD timestamps to all possible triggers, 0 means only match to the target trigger. diff --git a/UserTools/EBSaver/EBSaver.cpp b/UserTools/EBSaver/EBSaver.cpp new file mode 100644 index 000000000..261e50d3c --- /dev/null +++ b/UserTools/EBSaver/EBSaver.cpp @@ -0,0 +1,1535 @@ +#include "EBSaver.h" + +EBSaver::EBSaver() : Tool() {} + +bool EBSaver::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_variables.Get("verbosityEBSaver", verbosityEBSaver); + savePath = ""; + m_variables.Get("savePath", savePath); + saveName = "ProcessedData_"; + m_variables.Get("saveName", saveName); + beamInfoFileName = "BeamInfo.root"; + m_variables.Get("beamInfoFileName", beamInfoFileName); + + saveTriggerGroups = true; + savePMT = true; + + saveAllTriggers = false; + m_variables.Get("saveAllTriggers", saveAllTriggers); + saveMRD = true; + m_variables.Get("saveMRD", saveMRD); + saveLAPPD = true; + m_variables.Get("saveLAPPD", saveLAPPD); + saveOrphan = true; + m_variables.Get("saveOrphan", saveOrphan); + saveBeamInfo = true; + m_variables.Get("saveBeamInfo", saveBeamInfo); + + saveRawBRFWaveform = true; + m_variables.Get("saveRawBRFWaveform", saveRawBRFWaveform); + saveRawRWMWaveform = true; + m_variables.Get("saveRawRWMWaveform", saveRawRWMWaveform); + + ANNIEEvent = new BoostStore(false, 2); + + exeNumber = 0; + savedTriggerGroupNumber = 0; + savedPMTHitMapNumber = 0; + savedMRDNumber = 0; + savedLAPPDNumber = 0; + + savePerExe = 2000; + + if (savePMT) + saveName += "PMT"; + if (saveMRD) + saveName += "MRD"; + if (saveLAPPD) + saveName += "LAPPD"; + + m_data->CStore.Get("BeamTriggerMain", BeamTriggerMain); + m_data->CStore.Get("LaserTriggerMain", LaserTriggerMain); + m_data->CStore.Get("CosmicTriggerMain", CosmicTriggerMain); + m_data->CStore.Get("LEDTriggerMain", LEDTriggerMain); + m_data->CStore.Get("AmBeTriggerMain", AmBeTriggerMain); + m_data->CStore.Get("PPSMain", PPSMain); + + InProgressHits = new std::map> *>; + InProgressChkey = new std::map>; + InProgressRecoADCHits = new std::map>>>; + InProgressRecoADCHitsAux = new std::map>>>; + InProgressHitsAux = new std::map> *>; + FinishedRawAcqSize = new std::map>>; + + RWMRawWaveforms = new std::map>; + BRFRawWaveforms = new std::map>; + + if (saveBeamInfo) + { + Log("EBSaver: saveBeamInfo is true, loading Beam Info", v_message, verbosityEBSaver); + LoadBeamInfo(); + } + + return true; +} + +bool EBSaver::Execute() +{ + + bool saveProcessedFile = false; + bool saveEverything = false; + m_data->CStore.Get("SaveProcessedFile", saveProcessedFile); + m_data->CStore.Get("SaveEverything", saveEverything); + if (!saveProcessedFile && !saveEverything) + { + Log("EBSaver: Not saving data in this exe", v_message, verbosityEBSaver); + return true; + } + cout << "\033[1;34m******* EBSaver : Start execute *******\033[0m" << endl; + + m_data->CStore.Get("RunCodeToSave", savingRunCode); + GotAllDataFromOriginalBuffer(); + + Log("EBSaver: Start saving data for run code " + std::to_string(savingRunCode), v_message, verbosityEBSaver); + + // clean the to remove buffer + GroupedTriggerIndexToRemove.clear(); + PMTRunCodeToRemove.clear(); + MRDRunCodeToRemove.clear(); + LAPPDRunCodeToRemove.clear(); + + PMTPairInfoToRemoveTime.clear(); + MRDPairInfoToRemoveTime.clear(); + LAPPDPairInfoToRemoveTime.clear(); + + // get the grouped trigger, save the grouped triggers with the same runcode + cout << "\033[1;34m******* EBSaver : Saving *******\033[0m" << endl; + m_data->CStore.Get("GroupedTriggersInTotal", GroupedTriggersInTotal); + m_data->CStore.Get("RunCodeInTotal", RunCodeInTotal); + + int savedEventNumber = 0; + // loop each track in the RunCodeInTotal; + for (auto const &track : RunCodeInTotal) + { + int triggerTrack = track.first; + std::vector RunCodeVector = track.second; + // check if the RunCodeInTotal[tragetTrigWord] has the same size with GroupedTriggersInTotal[tragetTrigWord] + Log("EBSaver: Looping trigger track " + std::to_string(triggerTrack) + " with RunCodeInTotal size " + std::to_string(RunCodeVector.size()) + " and GroupedTriggersInTotal size " + std::to_string(GroupedTriggersInTotal[triggerTrack].size()), v_message, verbosityEBSaver); + + if (RunCodeVector.size() != GroupedTriggersInTotal[triggerTrack].size()) + { + Log("EBSaver: RunCodeInTotal and GroupedTriggersInTotal size not match, RunCodeVector size " + std::to_string(RunCodeVector.size()) + " and GroupedTriggersInTotal size " + std::to_string(GroupedTriggersInTotal[triggerTrack].size()), v_warning, verbosityEBSaver); + continue; + } + // GroupedTriggersInTotal and RunCodeInTotal have the same size + // same index is the cooresponding data + for (int i = 0; i < RunCodeVector.size(); i++) + { + int runCode = RunCodeVector[i]; + // saving + // if save Everything, in case there might be some mis aligned events not saved to that processed part file correctly and left in buffer, save them to corresponding part file + if (runCode == savingRunCode) + { + Log("\033[1;34m ****EBSaver: Saving a new event with savedEventNumber = " + std::to_string(savedEventNumber) + " ****\033[0m", v_message, verbosityEBSaver); + + std::string saveFileName = savePath + saveName + "_R" + to_string(runCode / 100000) + "S" + to_string((runCode % 100000) / 10000 - 1) + "p" + to_string(runCode % 10000); + Log("EBSaver: Saving to " + saveFileName + " with run code " + std::to_string(runCode) + " at index " + std::to_string(i), v_message, verbosityEBSaver); + + // if in last exe, the runcode for that group of trigger equals to the saving RunCode, save to ANNIEEvent Processed File + SaveToANNIEEvent(saveFileName, runCode, triggerTrack, i); + savedEventNumber++; + } + } + } + + // remove the paired trigger and data timestamp at PairInfoToRemoveIndex from the buffer like PairedLAPPDTimeStamps + for (auto const &track : GroupedTriggerIndexToRemove) + { + int triggerTrack = track.first; + int groupIndex = track.second; + GroupedTriggersInTotal[triggerTrack].erase(GroupedTriggersInTotal[triggerTrack].begin() + groupIndex); + RunCodeInTotal[triggerTrack].erase(RunCodeInTotal[triggerTrack].begin() + groupIndex); + } + int PMTToRemove = 0; + int MRDToRemove = 0; + int LAPPDToRemove = 0; + for (auto const &track : PMTPairInfoToRemoveTime) + { + int triggerTrack = track.first; + std::vector times = track.second; + PMTToRemove += times.size(); + // print the size of times, and all elements in times + Log("EBSaver: PMT PairInfoToRemoveTime at track " + std::to_string(triggerTrack) + " size " + std::to_string(times.size()), v_message, verbosityEBSaver); + for (int i = 0; i < times.size(); i++) + cout << i << ": " << times[i] << ", "; + } + cout << endl; + for (auto const &track : MRDPairInfoToRemoveTime) + { + int triggerTrack = track.first; + std::vector times = track.second; + MRDToRemove += times.size(); + Log("EBSaver: MRD PairInfoToRemoveTime at track " + std::to_string(triggerTrack) + " size " + std::to_string(times.size()), v_message, verbosityEBSaver); + for (int i = 0; i < times.size(); i++) + cout << i << ": " << times[i] << ", "; + } + cout << endl; + for (auto const &track : LAPPDPairInfoToRemoveTime) + { + int triggerTrack = track.first; + std::vector times = track.second; + LAPPDToRemove += times.size(); + Log("EBSaver: LAPPD PairInfoToRemoveTime at track " + std::to_string(triggerTrack) + " size " + std::to_string(times.size()), v_message, verbosityEBSaver); + for (int i = 0; i < times.size(); i++) + cout << i << ": " << times[i] << ", "; + } + cout << endl; + + Log("EBSaver: before remove from pair info buffer, going to remove PMT " + std::to_string(PMTToRemove) + ", MRD " + std::to_string(MRDToRemove) + ", LAPPD " + std::to_string(LAPPDToRemove), v_message, verbosityEBSaver); + + // print everything in PairedLAPPDTimeStamps for debug + for (auto const &track : PairedLAPPDTimeStamps) + { + int triggerTrack = track.first; + std::vector times = track.second; + Log("EBSaver: PairedLAPPDTimeStamps at track " + std::to_string(triggerTrack) + " size " + std::to_string(times.size()), v_message, verbosityEBSaver); + for (int i = 0; i < times.size(); i++) + cout << i << ": " << times[i] << ", "; + } + // print everything in Buffer_LAPPDTimestamp_ns for debug + Log("EBSaver: Buffer_LAPPDTimestamp_ns size " + std::to_string(Buffer_LAPPDTimestamp_ns.size()), v_message, verbosityEBSaver); + for (int i = 0; i < Buffer_LAPPDTimestamp_ns.size(); i++) + cout << i << ": " << Buffer_LAPPDTimestamp_ns[i] << ", "; + cout << endl; + + // 删除 LAPPD 相关时间戳 + int removedLAPPD = 0; + for (auto const &track : LAPPDPairInfoToRemoveTime) + { + int triggerTrack = track.first; + std::vector indexes = track.second; + for (int i = 0; i < indexes.size(); i++) + { + int foundIndex = -1; + for (int j = 0; j < PairedLAPPDTimeStamps[triggerTrack].size(); j++) + { + if (PairedLAPPDTimeStamps[triggerTrack][j] == indexes[i]) + { + foundIndex = j; + break; + } + } + if (foundIndex != -1) + { + removedLAPPD++; + Log("EBSaver: Remove LAPPD data with LAPPDTime " + std::to_string(indexes[i]) + " at index " + std::to_string(foundIndex), v_message, verbosityEBSaver); + PairedLAPPDTimeStamps[triggerTrack].erase(PairedLAPPDTimeStamps[triggerTrack].begin() + foundIndex); + PairedLAPPDTriggerTimestamp[triggerTrack].erase(PairedLAPPDTriggerTimestamp[triggerTrack].begin() + foundIndex); + } + } + } + + // 删除 PMT 相关时间戳 + + for (auto const &track : PMTPairInfoToRemoveTime) + { + int triggerTrack = track.first; + std::vector indexes = track.second; + for (int i = 0; i < indexes.size(); i++) + { + int foundIndex = -1; + for (int j = 0; j < PairedPMTTimeStamps[triggerTrack].size(); j++) + { + if (PairedPMTTimeStamps[triggerTrack][j] == indexes[i]) + { + foundIndex = j; + break; + } + } + if (foundIndex != -1) + { + PairedPMTTimeStamps[triggerTrack].erase(PairedPMTTimeStamps[triggerTrack].begin() + foundIndex); + PairedPMTTriggerTimestamp[triggerTrack].erase(PairedPMTTriggerTimestamp[triggerTrack].begin() + foundIndex); + } + } + } + + // 删除 MRD 相关时间戳 + for (auto const &track : MRDPairInfoToRemoveTime) + { + int triggerTrack = track.first; + std::vector indexes = track.second; + for (int i = 0; i < indexes.size(); i++) + { + int foundIndex = -1; + for (int j = 0; j < PairedMRDTimeStamps[triggerTrack].size(); j++) + { + if (PairedMRDTimeStamps[triggerTrack][j] == indexes[i]) + { + foundIndex = j; + break; + } + } + if (foundIndex != -1) + { + PairedMRDTimeStamps[triggerTrack].erase(PairedMRDTimeStamps[triggerTrack].begin() + foundIndex); + PairedMRDTriggerTimestamp[triggerTrack].erase(PairedMRDTriggerTimestamp[triggerTrack].begin() + foundIndex); + } + } + } + + ANNIEEvent->Close(); + ANNIEEvent->Delete(); + delete ANNIEEvent; + ANNIEEvent = new BoostStore(false, 2); + + if (saveEverything) + { + Log("EBSaver: Save everything", v_message, verbosityEBSaver); + } + + // now save other data left in the data buffer to orphan + // loop the runcode buffer of each data store, find which run code we need to save + // then loop the run code vector, for each run code, loop all data buffers, save the left data with the save run code + + m_data->CStore.Set("GroupedTriggersInTotal", GroupedTriggersInTotal); + m_data->CStore.Set("RunCodeInTotal", RunCodeInTotal); + m_data->CStore.Set("PairedLAPPDTriggerTimestamp", PairedLAPPDTriggerTimestamp); + m_data->CStore.Set("PairedLAPPDTimeStamps", PairedLAPPDTimeStamps); + m_data->CStore.Set("PairedPMTTriggerTimestamp", PairedPMTTriggerTimestamp); + m_data->CStore.Set("PairedPMTTimeStamps", PairedPMTTimeStamps); + m_data->CStore.Set("PairedMRDTriggerTimestamp", PairedMRDTriggerTimestamp); + m_data->CStore.Set("PairedMRDTimeStamps", PairedMRDTimeStamps); + + Log("EBSaver: Execute finished, saved PMT " + std::to_string(savedPMTHitMapNumber) + ", MRD " + std::to_string(savedMRDNumber) + ", LAPPD " + std::to_string(savedLAPPDNumber) + ", trigger group " + std::to_string(savedTriggerGroupNumber), v_message, verbosityEBSaver); + + Log("EBSaver: Set PMT pairing information buffer PairedPMTTimeStamps size " + std::to_string(PairedPMTTimeStamps.size()), v_message, verbosityEBSaver); + // print size of each track + for (auto const &track : PairedPMTTimeStamps) + Log("EBSaver: track " + std::to_string(track.first) + " size " + std::to_string(track.second.size()), v_message, verbosityEBSaver); + Log("EBSaver: Set MRD pairing information buffer PairedMRDTimeStamps size " + std::to_string(PairedMRDTimeStamps.size()), v_message, verbosityEBSaver); + for (auto const &track : PairedMRDTimeStamps) + Log("EBSaver: track " + std::to_string(track.first) + " size " + std::to_string(track.second.size()), v_message, verbosityEBSaver); + Log("EBSaver: Set LAPPD pairing information buffer PairedLAPPDTimeStamps size " + std::to_string(PairedLAPPDTimeStamps.size()), v_message, verbosityEBSaver); + for (auto const &track : PairedLAPPDTimeStamps) + Log("EBSaver: track " + std::to_string(track.first) + " size " + std::to_string(track.second.size()), v_message, verbosityEBSaver); + + SetDataObjects(); + cout << "\033[1;34m******* EBSaver : Finished *******\033[0m" << endl; + + return true; +} + +bool EBSaver::Finalise() +{ + Log("\033[1;34mEBSaver: Finalising\033[0m", v_message, verbosityEBSaver); + ANNIEEvent->Close(); + ANNIEEvent->Delete(); + delete ANNIEEvent; + + Log("EBSaver: Finished built " + std::to_string(TotalBuiltEventsNumber) + " events", v_message, verbosityEBSaver); + Log("EBSaver: Finished built " + std::to_string(savedTriggerGroupNumber) + " trigger groups", v_message, verbosityEBSaver); + Log("EBSaver: Finished built " + std::to_string(savedPMTHitMapNumber) + " PMT hit maps", v_message, verbosityEBSaver); + Log("EBSaver: Finished built " + std::to_string(savedMRDNumber) + " MRD events", v_message, verbosityEBSaver); + Log("EBSaver: Finished built " + std::to_string(savedLAPPDNumber) + " LAPPD events", v_message, verbosityEBSaver); + Log("EBSaver: matched but not built event number: ***********", v_message, verbosityEBSaver); + Log("\033[1;34mEBSaver: left PMT events in pairing info buffer " + std::to_string(PairedPMTTimeStamps.size()) + " \033[0m", v_message, verbosityEBSaver); + // also print the size of each track with track word + + for (auto const &track : PairedPMTTimeStamps) + { + Log("EBSaver: track " + std::to_string(track.first) + ", total left trigger number " + std::to_string(track.second.size()), v_message, verbosityEBSaver); + if (verbosityEBSaver > 9) + { + // count how many events not built for each trigger word + std::map unbuiltEvents; + for (int i = 0; i < track.second.size(); i++) + { + if (PairedPMTTimeStamps[track.first][i] != 0) + unbuiltEvents[PairedPMTTimeStamps[track.first][i]]++; + } + for (auto const &event : unbuiltEvents) + Log("EBSaver: track " + std::to_string(track.first) + ", left trigger " + std::to_string(event.first) + " number " + std::to_string(event.second), v_message, verbosityEBSaver); + } + } + Log("\033[1;34mEBSaver: left MRD events in pairing info buffer " + std::to_string(PairedMRDTimeStamps.size()) + " \033[0m", v_message, verbosityEBSaver); + for (auto const &track : PairedMRDTimeStamps) + { + Log("EBSaver: track " + std::to_string(track.first) + ", left trigger number " + std::to_string(track.second.size()), v_message, verbosityEBSaver); + if (verbosityEBSaver > 9) + { + // count how many events not built for each trigger word + std::map unbuiltEvents; + for (int i = 0; i < track.second.size(); i++) + { + if (PairedMRDTimeStamps[track.first][i] != 0) + unbuiltEvents[PairedMRDTimeStamps[track.first][i]]++; + } + for (auto const &event : unbuiltEvents) + Log("EBSaver: track " + std::to_string(track.first) + ", left trigger " + std::to_string(event.first) + " number " + std::to_string(event.second), v_message, verbosityEBSaver); + } + } + Log("\033[1;34mEBSaver: left LAPPD events in pairing info buffer " + std::to_string(PairedLAPPDTimeStamps.size()) + " \033[0m", v_message, verbosityEBSaver); + for (auto const &track : PairedLAPPDTimeStamps) + { + Log("EBSaver: track " + std::to_string(track.first) + ", left trigger number " + std::to_string(track.second.size()), v_message, verbosityEBSaver); + // count how many events not built for each trigger word + if (verbosityEBSaver > 9) + { + std::map unbuiltEvents; + for (int i = 0; i < track.second.size(); i++) + { + if (PairedLAPPDTimeStamps[track.first][i] != 0) + unbuiltEvents[PairedLAPPDTimeStamps[track.first][i]]++; + } + for (auto const &event : unbuiltEvents) + Log("EBSaver: track " + std::to_string(track.first) + ", left trigger " + std::to_string(event.first) + " number " + std::to_string(event.second), v_message, verbosityEBSaver); + } + } + Log("EBSaver: left event number: ***********", v_message, verbosityEBSaver); + Log("EBSaver: left PMT events in original data buffer " + std::to_string(InProgressHits->size()), v_message, verbosityEBSaver); + Log("EBSaver: left MRD events in original data buffer " + std::to_string(MRDEvents.size()), v_message, verbosityEBSaver); + Log("EBSaver: left LAPPD events in original data buffer " + std::to_string(Buffer_LAPPDTimestamp_ns.size()), v_message, verbosityEBSaver); + // print the size of each track of + + // add debug print for the left MRD, print TriggerTimeWithoutMRD and PairedMRDTimeStamps to two txt file + std::ofstream TriggerTimeWithoutMRDFile; + TriggerTimeWithoutMRDFile.open("EBdebug_TriggerTimeWithoutMRD.txt"); + for (auto const &track : TriggerTimeWithoutMRD) + { + TriggerTimeWithoutMRDFile << track.first << " " << track.second << endl; + } + TriggerTimeWithoutMRDFile.close(); + std::ofstream PairedMRDTimeStampsFile; + PairedMRDTimeStampsFile.open("EBdebug_PairedMRDTimeStamps.txt"); + for (auto const &track : PairedMRDTimeStamps) + { + for (int i = 0; i < track.second.size(); i++) + { + PairedMRDTimeStampsFile << track.first << " " << track.second[i] << endl; + } + } + + return true; +} + +bool EBSaver::SaveToANNIEEvent(string saveFileName, int runCode, int triggerTrack, int trackIndex) +{ + SaveRunInfo(runCode); + std::map DataStreams; + DataStreams.emplace("Tank", 0); + DataStreams.emplace("MRD", 0); + DataStreams.emplace("CTC", 1); + DataStreams.emplace("LAPPD", 0); + + SaveGroupedTriggers(triggerTrack, trackIndex); + + bool PMTSaved = false; // incase of multiple 14 found in one group + bool MRDSaved = false; + bool LAPPDSaved = false; + bool beamInfoSaved = false; + + std::map GroupedTrigger = GroupedTriggersInTotal[triggerTrack][trackIndex]; + // For each element in GroupedTrigger, find is it appear in PairedPMTTriggerTimestamp[triggerTrack], + // if yes, got the index, access the same index at PairedPMTTimeStamps[triggerTrack], that uint64_t is the PMTTime + for (auto &trigger : GroupedTrigger) + { + uint64_t triggerTime = trigger.first; + uint32_t triggerType = trigger.second; + if (triggerType == 14) + { + Log("EBSaver: Found undelayed beam trigger with time " + std::to_string(triggerTime) + " in GroupedTrigger", v_debug, verbosityEBSaver); + if (!beamInfoSaved) + { + SaveBeamInfo(triggerTime); + beamInfoSaved = true; + } + } + + if (PairedPMTTriggerTimestamp.find(triggerTrack) != PairedPMTTriggerTimestamp.end()) + { + for (int i = 0; i < PairedPMTTriggerTimestamp.at(triggerTrack).size(); i++) + { + if (PairedPMTTriggerTimestamp.at(triggerTrack).at(i) == triggerTime) + { + uint64_t PMTTime = PairedPMTTimeStamps.at(triggerTrack).at(i); + Log("EBSaver: Found trigger with time " + std::to_string(triggerTime) + " in PairedPMTTriggerTimestamp " + std::to_string(i) + " match with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + + bool saved = SavePMTData(PMTTime); + PMTSaved = saved; + DataStreams["Tank"] = 1; + if (saved) + PMTPairInfoToRemoveTime[triggerTrack].push_back(PMTTime); + Log("EBSaver: Saved " + std::to_string(savedPMTHitMapNumber) + " PMT data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + // break; + } + } + } + + // check if PairedMRDTriggerTimestamp has element with key = triggerTrack + if (!MRDSaved) + { + Log("Finding trigger track = " + std::to_string(triggerTrack) + " in PairedMRDTriggerTimestamp", v_debug, verbosityEBSaver); + // print PairedMRDTriggerTimestamp with track number and size + for (auto const &track : PairedMRDTriggerTimestamp) + { + Log("EBSaver: in PairedMRDTriggerTimestamp track " + std::to_string(track.first) + ", left trigger number " + std::to_string(track.second.size()), v_debug, verbosityEBSaver); + } + for (auto const &track : PairedMRDTimeStamps) + { + Log("EBSaver: in PairedMRDTimeStamps track " + std::to_string(track.first) + ", left trigger number " + std::to_string(track.second.size()), v_debug, verbosityEBSaver); + } + if (PairedMRDTriggerTimestamp.find(triggerTrack) != PairedMRDTriggerTimestamp.end()) + { + if (triggerTime > PairedMRDTriggerTimestamp.at(triggerTrack).at(0) && triggerTime < PairedMRDTriggerTimestamp.at(triggerTrack).at(PairedMRDTriggerTimestamp.at(triggerTrack).size() - 1)) + { + uint64_t minDiff = 100 * 60 * 1e9; + Log("Found trigger track = " + std::to_string(triggerTrack) + " in PairedMRDTriggerTimestamp with current searching trigger type = " + std::to_string(triggerType) + " and trigger time = " + std::to_string(triggerTime), v_debug, verbosityEBSaver); + // print the size of PairedMRDTriggerTimestamp.at(triggerTrack), print the first and the last timestamp + Log("EBSaver: PairedMRDTriggerTimestamp size " + std::to_string(PairedMRDTriggerTimestamp.at(triggerTrack).size()), v_debug, verbosityEBSaver); + if (PairedMRDTriggerTimestamp.at(triggerTrack).size() > 0) + Log("EBSaver: PairedMRDTriggerTimestamp first " + std::to_string(PairedMRDTriggerTimestamp.at(triggerTrack).at(0)) + ", last " + std::to_string(PairedMRDTriggerTimestamp.at(triggerTrack).at(PairedMRDTriggerTimestamp.at(triggerTrack).size() - 1)), v_debug, verbosityEBSaver); + + for (int i = 0; i < PairedMRDTriggerTimestamp.at(triggerTrack).size(); i++) + { + uint64_t diff = (PairedMRDTriggerTimestamp.at(triggerTrack).at(i) > triggerTime) ? PairedMRDTriggerTimestamp.at(triggerTrack).at(i) - triggerTime : triggerTime - PairedMRDTriggerTimestamp.at(triggerTrack).at(i); + if (diff < minDiff) + minDiff = diff; + + if (PairedMRDTriggerTimestamp.at(triggerTrack).at(i) == triggerTime || (diff < 1e6)) + { + if (diff < 1e6) + { + Log("EBSaver: diff<1e6, is " + std::to_string(diff), v_debug, verbosityEBSaver); + TriggerTimeWithoutMRD.emplace(PairedMRDTriggerTimestamp.at(triggerTrack).at(i), static_cast(diff)); + } + uint64_t MRDTime = PairedMRDTimeStamps.at(triggerTrack).at(i); + bool saved = SaveMRDData(MRDTime); + MRDSaved = saved; + DataStreams["MRD"] = 1; + if (MRDSaved) + MRDPairInfoToRemoveTime[triggerTrack].push_back(MRDTime); + Log("EBSaver: Saved " + std::to_string(savedMRDNumber) + " MRD data with MRDTime " + std::to_string(MRDTime), v_debug, verbosityEBSaver); + Log("EBSaver: Found trigger with time " + std::to_string(triggerTime) + " in PairedMRDTriggerTimestamp " + std::to_string(i) + " match with MRDTime " + std::to_string(MRDTime), v_debug, verbosityEBSaver); + // break; + Log("EBSaver: While saving MRD data, use trigger time " + std::to_string(triggerTime) + " with minDiff " + std::to_string(minDiff), v_debug, verbosityEBSaver); + } + } + } + // Log("EBSaver: MRDData saved", 8, verbosityEBSaver); + } + } + + if (PairedLAPPDTriggerTimestamp.find(triggerTrack) != PairedLAPPDTriggerTimestamp.end()) + { + for (int i = 0; i < PairedLAPPDTriggerTimestamp.at(triggerTrack).size(); i++) + { + if (PairedLAPPDTriggerTimestamp.at(triggerTrack).at(i) == triggerTime) + { + uint64_t LAPPDTime = PairedLAPPDTimeStamps.at(triggerTrack).at(i); + bool saved = SaveLAPPDData(LAPPDTime); + LAPPDSaved = saved; + DataStreams["LAPPD"] = 1; + if (LAPPDSaved) + LAPPDPairInfoToRemoveTime[triggerTrack].push_back(LAPPDTime); + Log("EBSaver: Saved " + std::to_string(savedLAPPDNumber) + " LAPPD data with LAPPDTime " + std::to_string(LAPPDTime), v_debug, verbosityEBSaver); + Log("EBSaver: Found trigger with time " + std::to_string(triggerTime) + " in PairedLAPPDTriggerTimestamp " + std::to_string(i) + " match with LAPPDTime " + std::to_string(LAPPDTime), v_debug, verbosityEBSaver); + // break; + } + } + // Log("EBSaver: LAPPDData saved", 8, verbosityEBSaver); + } + } + + ANNIEEvent->Set("DataStreams", DataStreams); + + // if Datastream is not built, save a default empty data for that into the event + if (DataStreams["Tank"] == 0) + BuildEmptyPMTData(); + if (DataStreams["MRD"] == 0) + { + BuildEmptyMRDData(); + if (triggerTrack == 14) + { + // find the time of trigger 8 in current group + uint64_t triggerTime = 0; + for (auto &trigger : GroupedTrigger) + { + if (trigger.second == 8) + { + triggerTime = trigger.first; + break; + } + } + TriggerTimeWithoutMRD.emplace(triggerTime, triggerTrack); + } + else if (triggerTrack == 36) + { + // find the time of trigger 8 in current group + uint64_t triggerTime = 0; + for (auto &trigger : GroupedTrigger) + { + if (trigger.second == 36) + { + triggerTime = trigger.first; + break; + } + } + TriggerTimeWithoutMRD.emplace(triggerTime, triggerTrack); + } + } + + if (DataStreams["LAPPD"] == 0) + BuildEmptyLAPPDData(); + + Log("EBSaver: Print ANNIEEvent, Saving to " + saveFileName, v_debug, verbosityEBSaver); + if (verbosityEBSaver > 8) + ANNIEEvent->Print(false); + ANNIEEvent->Save(saveFileName); + TotalBuiltEventsNumber++; + ANNIEEvent->Delete(); + + return true; +} + +bool EBSaver::SaveRunInfo(int runCode) +{ + int RunNumber = runCode / 100000; + int SubRunNumber = (runCode % 100000) / 10000 - 1; + int PartFileNumber = runCode % 10000; + + ANNIEEvent->Set("RunNumber", RunNumber); + ANNIEEvent->Set("SubRunNumber", SubRunNumber); + ANNIEEvent->Set("PartNumber", PartFileNumber); + Log("EBSaver: Saving run info with RunNumber " + std::to_string(RunNumber) + " SubRunNumber " + std::to_string(SubRunNumber) + " PartFileNumber " + std::to_string(PartFileNumber), v_debug, verbosityEBSaver); + return true; +} + +bool EBSaver::SaveGroupedTriggers(int triggerTrack, int groupIndex) +{ + Log("EBSaver: Saving grouped triggers for trigger track " + std::to_string(triggerTrack) + " with group index " + std::to_string(groupIndex), v_debug, verbosityEBSaver); + std::map GroupedTrigger = GroupedTriggersInTotal[triggerTrack][groupIndex]; + GroupedTriggerIndexToRemove.emplace(triggerTrack, groupIndex); + + ANNIEEvent->Set("GroupedTrigger", GroupedTrigger); + int matchTriggerType = triggerTrack; + ANNIEEvent->Set("PrimaryTriggerWord", matchTriggerType); + if (matchTriggerType != 14) + { + ANNIEEvent->Set("TriggerWord", matchTriggerType); + } + else + { + ANNIEEvent->Set("TriggerWord", 5); + } + + // find the triggertrack trigger time in GroupedTrigger + uint64_t primaryTrigTime = 0; + for (auto &trigger : GroupedTrigger) + { + if (trigger.second == triggerTrack) + { + primaryTrigTime = trigger.first; + break; + } + } + + ANNIEEvent->Set("PrimaryTriggerTime", primaryTrigTime); + ANNIEEvent->Set("CTCTimestamp", primaryTrigTime); + + bool NCExtended = false; + bool CCExtended = false; + std::string TriggerType = ""; + int CTCWordExtended = 0; + uint64_t ExtendedTriggerTime = 0; + + if (triggerTrack == BeamTriggerMain) + { + TriggerType = "Beam"; + // if found 40 in values of GroupedTrigger, set NCExtended to true + // put the data at that index to ExtendedTriggerTime + for (auto &trigger : GroupedTrigger) + { + if (trigger.second == 41) + { + NCExtended = true; + ExtendedTriggerTime = trigger.first; + CTCWordExtended = 1; + break; + } + } + for (auto &trigger : GroupedTrigger) + { + if (trigger.second == 40) + { + CCExtended = true; + ExtendedTriggerTime = trigger.first; + CTCWordExtended = 2; + break; + } + } + } + else if (triggerTrack == LaserTriggerMain) + TriggerType = "Laser"; + else if (triggerTrack == CosmicTriggerMain) + TriggerType = "Cosmic"; + else if (triggerTrack == LEDTriggerMain) + TriggerType = "LED"; + else if (triggerTrack == AmBeTriggerMain) + TriggerType = "AmBe"; + else if (triggerTrack == PPSMain) + TriggerType = "PPS"; + + ANNIEEvent->Set("NCExtended", NCExtended); + ANNIEEvent->Set("CCExtended", CCExtended); + ANNIEEvent->Set("TriggerType", TriggerType); + ANNIEEvent->Set("TriggerExtended", CTCWordExtended); // 0: normal, 1: NC extended, 2: CC extended + // Notice, in the V1 eventbuilder, there is a requirement that the matched trigger time - extended trigger time <5000, if not the extended will be 0 + // we don't have it here because the PMT was not matched to a single trigger, but a group. + // you may need to select the events based on the time difference in the grouped trigger + + TimeClass TriggerTime(primaryTrigTime); + TriggerClass TriggerData(TriggerType, matchTriggerType, CTCWordExtended, true, TriggerTime); + ANNIEEvent->Set("TriggerData", TriggerData); + + savedTriggerGroupNumber++; + Log("EBSaver: Saved trigger group with trigger type " + TriggerType + " and trigger time " + std::to_string(primaryTrigTime), v_debug, verbosityEBSaver); + return true; +} + +bool EBSaver::SavePMTData(uint64_t PMTTime) +{ + Log("EBSaver: Saving PMT data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + // find PMTTime in InProgressHits, if not found, return false + if (InProgressHits->find(PMTTime) == InProgressHits->end()) + { + Log("EBSaver: PMT data with PMTTime " + std::to_string(PMTTime) + " not found in InProgressHits", v_debug, verbosityEBSaver); + return false; + } + ANNIEEvent->Set("EventTimeTank", PMTTime); + + std::map> *PMTHits = InProgressHits->at(PMTTime); + std::map>> PMTRecoADCHits = InProgressRecoADCHits->at(PMTTime); + std::map> *PMTHitsAux = InProgressHitsAux->at(PMTTime); + std::map>> PMTRecoADCHitsAux = InProgressRecoADCHitsAux->at(PMTTime); + std::map> PMTRawAcqSize = FinishedRawAcqSize->at(PMTTime); + + Log("EBSaver: Got PMT data, saving", v_debug, verbosityEBSaver); + + // check does the ANNIEEvent already have the key "Hits", if yes, print the size of the vector of each key + // also print the size of the vector of each key in new PMTHits + // Then Merger the two maps + std::map> *OldPMTHits = new std::map>; + bool gotHits = ANNIEEvent->Get("Hits", OldPMTHits); + if (gotHits) + { + Log("EBSaver: ANNIEEvent already has key Hits, size " + std::to_string(OldPMTHits->size()), v_debug, verbosityEBSaver); + for (auto const &time : *OldPMTHits) + Log("EBSaver: OldPMTHits old time " + std::to_string(time.first) + " size " + std::to_string(time.second.size()), v_debug, verbosityEBSaver); + for (auto const &time : *PMTHits) + Log("EBSaver: PMTHits new time " + std::to_string(time.first) + " size " + std::to_string(time.second.size()), v_debug, verbosityEBSaver); + for (auto const &time : *OldPMTHits) + { + if (PMTHits->count(time.first) == 0) + { + PMTHits->emplace(time.first, time.second); + } + else + { + for (auto const &hit : time.second) + { + PMTHits->at(time.first).push_back(hit); + } + } + } + Log("EBSaver: Merged PMT data, PMTHits size " + std::to_string(PMTHits->size()), v_debug, verbosityEBSaver); + } + + ANNIEEvent->Set("Hits", PMTHits, true); + ANNIEEvent->Set("RecoADCData", PMTRecoADCHits); + ANNIEEvent->Set("AuxHits", PMTHitsAux, true); + ANNIEEvent->Set("RecoAuxADCData", PMTRecoADCHitsAux); + ANNIEEvent->Set("RawAcqSize", PMTRawAcqSize); + + if (saveRawRWMWaveform) + { + // find PMTTime as key in RWMRawWaveforms, if found, save it, if not, save an empty vector + if (RWMRawWaveforms->find(PMTTime) != RWMRawWaveforms->end() && RWMRawWaveforms->at(PMTTime).size() > 0) + { + std::vector RWMRawWaveform = RWMRawWaveforms->at(PMTTime); + ANNIEEvent->Set("RWMRawWaveform", RWMRawWaveform); + Log("EBSaver: Saved RWM data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + RWMRawWaveforms->erase(PMTTime); + } + else + { + std::vector RWMRawWaveform; + ANNIEEvent->Set("RWMRawWaveform", RWMRawWaveform); + Log("EBSaver: Saved empty RWM data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + } + } + if (saveRawBRFWaveform) + { + // find PMTTime as key in BRFRawWaveforms, if found, save it, if not, save an empty vector + if (BRFRawWaveforms->find(PMTTime) != BRFRawWaveforms->end() && BRFRawWaveforms->at(PMTTime).size() > 0) + { + std::vector BRFRawWaveform = BRFRawWaveforms->at(PMTTime); + ANNIEEvent->Set("BRFRawWaveform", BRFRawWaveform); + Log("EBSaver: Saved BRF data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + BRFRawWaveforms->erase(PMTTime); + } + else + { + std::vector BRFRawWaveform; + ANNIEEvent->Set("BRFRawWaveform", BRFRawWaveform); + Log("EBSaver: Saved empty BRF data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + } + } + + savedPMTHitMapNumber++; + + // erase the built data from original data buffer + InProgressHits->erase(PMTTime); + InProgressRecoADCHits->erase(PMTTime); + InProgressHitsAux->erase(PMTTime); + InProgressRecoADCHitsAux->erase(PMTTime); + FinishedRawAcqSize->erase(PMTTime); + + Log("EBSaver: Saved PMT data with PMTTime " + std::to_string(PMTTime), v_debug, verbosityEBSaver); + return true; +} + +bool EBSaver::SaveMRDData(uint64_t MRDTime) +{ + Log("EBSaver: Saving MRD data with MRDTime " + std::to_string(MRDTime), v_debug, verbosityEBSaver); + // find MRDTime in MRDEvents, if not found, return false + if (MRDEvents.find(MRDTime) == MRDEvents.end()) + { + Log("EBSaver: not found MRD data with MRDTime " + std::to_string(MRDTime) + " in MRDEvents", v_debug, verbosityEBSaver); + return false; + } + + // find the index of the MRDTime in PairedMRDTimeStamps + std::vector> MRDHits = MRDEvents.at(MRDTime); + std::string MRDTriggerType = MRDEventTriggerTypes.at(MRDTime); + int beam_tdc = MRDBeamLoopback.at(MRDTime); + int cosmic_tdc = MRDCosmicLoopback.at(MRDTime); + + std::map> *TDCData = new std::map>; + + for (unsigned int i_value = 0; i_value < MRDHits.size(); i_value++) + { + unsigned long channelkey = MRDHits.at(i_value).first; + int hitTimeADC = MRDHits.at(i_value).second; + double hitTime = 4000. - 4. * static_cast(hitTimeADC); + + if (TDCData->count(channelkey) == 0) + { + std::vector newhitvector; + newhitvector.push_back(Hit(0, hitTime, 1.)); + TDCData->emplace(channelkey, newhitvector); + } + else + { + TDCData->at(channelkey).push_back(Hit(0, hitTime, 1.)); + } + } + + std::map mrd_loopback_tdc; + mrd_loopback_tdc.emplace("BeamLoopbackTDC", beam_tdc); + mrd_loopback_tdc.emplace("CosmicLoopbackTDC", cosmic_tdc); + + Log("EBSaver: TDCdata size: " + std::to_string(TDCData->size()), v_warning, verbosityEBSaver); + + ANNIEEvent->Set("TDCData", TDCData, true); + TimeClass t(MRDTime); + ANNIEEvent->Set("EventTimeMRD", t); + ANNIEEvent->Set("MRDTriggerType", MRDTriggerType); + ANNIEEvent->Set("MRDLoopbackTDC", mrd_loopback_tdc); + + savedMRDNumber++; + + // erase the built data from original data buffer + MRDEvents.erase(MRDTime); + MRDEventTriggerTypes.erase(MRDTime); + MRDBeamLoopback.erase(MRDTime); + MRDCosmicLoopback.erase(MRDTime); + + Log("EBSaver: Saved MRD data with MRDTime " + std::to_string(MRDTime), v_debug, verbosityEBSaver); + return true; +} + +bool EBSaver::SaveLAPPDData(uint64_t LAPPDTime) +{ + Log("EBSaver: Saving LAPPD data with LAPPDTime " + std::to_string(LAPPDTime), v_debug, verbosityEBSaver); + // find LAPPDTime in Buffer_LAPPDTimestamp_ns, if not found, return false + if (std::find(Buffer_LAPPDTimestamp_ns.begin(), Buffer_LAPPDTimestamp_ns.end(), LAPPDTime) == Buffer_LAPPDTimestamp_ns.end()) + { + Log("EBSaver: LAPPD data with LAPPDTime " + std::to_string(LAPPDTime) + " not found in Buffer_LAPPDTimestamp_ns", v_debug, verbosityEBSaver); + return false; + } + + // find the index of the LAPPDTime in PairedLAPPDTimeStamps + int index = -1; + for (int i = 0; i < Buffer_LAPPDTimestamp_ns.size(); i++) + { + if (Buffer_LAPPDTimestamp_ns.at(i) == LAPPDTime) + { + index = i; + break; + } + } + + // save the data at index i to ANNIE event, then remove that index from buffer + if (index != -1) + { + std::map LAPPDDataMap; + std::map LAPPDBeamgate_ns; + std::map LAPPDTimeStamps_ns; // data and key are the same + std::map LAPPDTimeStampsRaw; + std::map LAPPDBeamgatesRaw; + std::map LAPPDOffsets; + std::map LAPPDTSCorrection; + std::map LAPPDBGCorrection; + std::map LAPPDOSInMinusPS; + std::map LAPPDBG_PPSBefore; + std::map LAPPDBG_PPSAfter; + std::map LAPPDBG_PPSDiff; + std::map LAPPDBG_PPSMissing; + std::map LAPPDTS_PPSBefore; + std::map LAPPDTS_PPSAfter; + std::map LAPPDTS_PPSDiff; + std::map LAPPDTS_PPSMissing; + + bool gotMap = ANNIEEvent->Get("LAPPDDataMap", LAPPDDataMap); + bool gotBeamgates_ns = ANNIEEvent->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + bool gotTimeStamps_ns = ANNIEEvent->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + bool gotTimeStampsRaw = ANNIEEvent->Get("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + bool gotBeamgatesRaw = ANNIEEvent->Get("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + bool gotOffsets = ANNIEEvent->Get("LAPPDOffsets", LAPPDOffsets); + bool gotTSCorrection = ANNIEEvent->Get("LAPPDTSCorrection", LAPPDTSCorrection); + bool gotDBGCorrection = ANNIEEvent->Get("LAPPDBGCorrection", LAPPDBGCorrection); + bool gotOSInMinusPS = ANNIEEvent->Get("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + bool gotBG_PPSBefore = ANNIEEvent->Get("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + bool gotBG_PPSAfter = ANNIEEvent->Get("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + bool gotBG_PPSDiff = ANNIEEvent->Get("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + bool gotBG_PPSMissing = ANNIEEvent->Get("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + bool gotTS_PPSBefore = ANNIEEvent->Get("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + bool gotTS_PPSAfter = ANNIEEvent->Get("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + bool gotTS_PPSDiff = ANNIEEvent->Get("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + bool gotTS_PPSMissing = ANNIEEvent->Get("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + + LAPPDDataMap.emplace(LAPPDTime, Buffer_LAPPDData.at(index)); + LAPPDBeamgate_ns.emplace(LAPPDTime, Buffer_LAPPDBeamgate_ns.at(index)); + LAPPDTimeStamps_ns.emplace(LAPPDTime, Buffer_LAPPDTimestamp_ns.at(index)); + LAPPDTimeStampsRaw.emplace(LAPPDTime, Buffer_LAPPDTimestamp_Raw.at(index)); + LAPPDBeamgatesRaw.emplace(LAPPDTime, Buffer_LAPPDBeamgate_Raw.at(index)); + LAPPDOffsets.emplace(LAPPDTime, Buffer_LAPPDOffset.at(index)); + LAPPDTSCorrection.emplace(LAPPDTime, Buffer_LAPPDTSCorrection.at(index)); + LAPPDBGCorrection.emplace(LAPPDTime, Buffer_LAPPDBGCorrection.at(index)); + LAPPDOSInMinusPS.emplace(LAPPDTime, Buffer_LAPPDOffset_minus_ps.at(index)); + LAPPDBG_PPSBefore.emplace(LAPPDTime, Buffer_LAPPDBG_PPSBefore.at(index)); + LAPPDBG_PPSAfter.emplace(LAPPDTime, Buffer_LAPPDBG_PPSAfter.at(index)); + LAPPDBG_PPSDiff.emplace(LAPPDTime, Buffer_LAPPDBG_PPSDiff.at(index)); + LAPPDBG_PPSMissing.emplace(LAPPDTime, Buffer_LAPPDBG_PPSMissing.at(index)); + LAPPDTS_PPSBefore.emplace(LAPPDTime, Buffer_LAPPDTS_PPSBefore.at(index)); + LAPPDTS_PPSAfter.emplace(LAPPDTime, Buffer_LAPPDTS_PPSAfter.at(index)); + LAPPDTS_PPSDiff.emplace(LAPPDTime, Buffer_LAPPDTS_PPSDiff.at(index)); + LAPPDTS_PPSMissing.emplace(LAPPDTime, Buffer_LAPPDTS_PPSMissing.at(index)); + + if (Buffer_LAPPDTS_PPSMissing.at(index) != Buffer_LAPPDBG_PPSMissing.at(index)) + { + Log("EBSaver: LAPPDTS_PPSMissing is different from LAPPDBG_PPSMissing, LAPPDTS_PPSMissing " + std::to_string(Buffer_LAPPDTS_PPSMissing.at(index)) + " LAPPDBG_PPSMissing " + std::to_string(Buffer_LAPPDBG_PPSMissing.at(index)), v_message, verbosityEBSaver); + } + + ANNIEEvent->Set("LAPPDDataMap", LAPPDDataMap); + ANNIEEvent->Set("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + ANNIEEvent->Set("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + ANNIEEvent->Set("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + ANNIEEvent->Set("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + ANNIEEvent->Set("LAPPDOffsets", LAPPDOffsets); + ANNIEEvent->Set("LAPPDTSCorrection", LAPPDTSCorrection); + ANNIEEvent->Set("LAPPDBGCorrection", LAPPDBGCorrection); + ANNIEEvent->Set("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + ANNIEEvent->Set("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + ANNIEEvent->Set("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + ANNIEEvent->Set("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + ANNIEEvent->Set("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + ANNIEEvent->Set("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + ANNIEEvent->Set("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + ANNIEEvent->Set("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + ANNIEEvent->Set("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + + savedLAPPDNumber++; + + // erase the built data from original data buffer + Buffer_LAPPDData.erase(Buffer_LAPPDData.begin() + index); + Buffer_LAPPDBeamgate_ns.erase(Buffer_LAPPDBeamgate_ns.begin() + index); + Buffer_LAPPDTimestamp_ns.erase(Buffer_LAPPDTimestamp_ns.begin() + index); + Buffer_LAPPDTimestamp_Raw.erase(Buffer_LAPPDTimestamp_Raw.begin() + index); + Buffer_LAPPDBeamgate_Raw.erase(Buffer_LAPPDBeamgate_Raw.begin() + index); + Buffer_LAPPDOffset.erase(Buffer_LAPPDOffset.begin() + index); + Buffer_LAPPDTSCorrection.erase(Buffer_LAPPDTSCorrection.begin() + index); + Buffer_LAPPDBGCorrection.erase(Buffer_LAPPDBGCorrection.begin() + index); + Buffer_LAPPDOffset_minus_ps.erase(Buffer_LAPPDOffset_minus_ps.begin() + index); + Buffer_LAPPDBG_PPSBefore.erase(Buffer_LAPPDBG_PPSBefore.begin() + index); + Buffer_LAPPDBG_PPSAfter.erase(Buffer_LAPPDBG_PPSAfter.begin() + index); + Buffer_LAPPDBG_PPSDiff.erase(Buffer_LAPPDBG_PPSDiff.begin() + index); + Buffer_LAPPDBG_PPSMissing.erase(Buffer_LAPPDBG_PPSMissing.begin() + index); + Buffer_LAPPDTS_PPSBefore.erase(Buffer_LAPPDTS_PPSBefore.begin() + index); + Buffer_LAPPDTS_PPSAfter.erase(Buffer_LAPPDTS_PPSAfter.begin() + index); + Buffer_LAPPDTS_PPSDiff.erase(Buffer_LAPPDTS_PPSDiff.begin() + index); + Buffer_LAPPDTS_PPSMissing.erase(Buffer_LAPPDTS_PPSMissing.begin() + index); + + Log("EBSaver: Saved LAPPD data with LAPPDTime " + std::to_string(LAPPDTime), v_debug, verbosityEBSaver); + return true; + } + else + { + Log("EBSaver: Failed to find LAPPD data with LAPPDTime " + std::to_string(LAPPDTime), v_debug, verbosityEBSaver); + + return false; + } +} + +bool EBSaver::SaveOrphan(int runCode) +{ + // loop everything in the data buffer, save + SaveOrphanPMT(runCode); + SaveOrphanMRD(runCode); + SaveOrphanLAPPD(runCode); + SaveOrphanCTC(runCode); + return true; +} + +bool EBSaver::SaveOrphanPMT(int runCode) +{ + + return true; +} + +bool EBSaver::SaveOrphanMRD(int runCode) +{ + + return true; +} + +bool EBSaver::SaveOrphanCTC(int runCode) +{ + + return true; +} + +bool EBSaver::SaveOrphanLAPPD(int runCode) +{ + + return true; +} + +bool EBSaver::GotAllDataFromOriginalBuffer() +{ + // got PMT data + bool gotPMTHits = m_data->CStore.Get("InProgressHits", InProgressHits); + bool gotPMTChkey = m_data->CStore.Get("InProgressChkey", InProgressChkey); + bool gotIPRecoADCHits = m_data->CStore.Get("InProgressRecoADCHits", InProgressRecoADCHits); + bool gotIPHitsAux = m_data->CStore.Get("InProgressHitsAux", InProgressHitsAux); + bool gotIPRADCH = m_data->CStore.Get("InProgressRecoADCHitsAux", InProgressRecoADCHitsAux); + bool gotFRAS = m_data->CStore.Get("FinishedRawAcqSize", FinishedRawAcqSize); // Filled in PhaseIIADCCalibrator + bool gotRWM = m_data->CStore.Get("RWMRawWaveforms", RWMRawWaveforms); + bool gotBRF = m_data->CStore.Get("BRFRawWaveforms", BRFRawWaveforms); + + if (!gotPMTHits || !gotPMTChkey || !gotIPRecoADCHits || !gotIPHitsAux || !gotIPRADCH || !gotFRAS) + { + Log("EBSaver: Failed to get some PMT data from buffer", v_message, verbosityEBSaver); + // print which one was failed + if (!gotPMTHits) + Log("EBSaver: Failed to get PMT hits from buffer", v_message, verbosityEBSaver); + if (!gotPMTChkey) + Log("EBSaver: Failed to get PMT chkey from buffer", v_message, verbosityEBSaver); + if (!gotIPRecoADCHits) + Log("EBSaver: Failed to get PMT recoADCHits from buffer", v_message, verbosityEBSaver); + if (!gotIPHitsAux) + Log("EBSaver: Failed to get PMT hits aux from buffer", v_message, verbosityEBSaver); + if (!gotIPRADCH) + Log("EBSaver: Failed to get PMT recoADCHits aux from buffer", v_message, verbosityEBSaver); + if (!gotFRAS) + Log("EBSaver: Failed to get PMT raw acq size from buffer", v_message, verbosityEBSaver); + } + // got PMT match info + bool gotPairedPMTTriggerTimestamp = m_data->CStore.Get("PairedPMTTriggerTimestamp", PairedPMTTriggerTimestamp); + bool gotPairedPMTTimeStamps = m_data->CStore.Get("PairedPMTTimeStamps", PairedPMTTimeStamps); + bool gotPairedPMT_TriggerIndex = m_data->CStore.Get("PairedPMT_TriggerIndex", PairedPMT_TriggerIndex); + bool gotPMTHitmapRunCode = m_data->CStore.Get("PMTHitmapRunCode", PMTHitmapRunCode); + if (!gotPairedPMTTriggerTimestamp || !gotPairedPMTTimeStamps || !gotPairedPMT_TriggerIndex || !gotPMTHitmapRunCode) + { + Log("EBSaver: Failed to get PMT match info from buffer", v_message, verbosityEBSaver); + // print which one was failed + if (!gotPairedPMTTriggerTimestamp) + Log("EBSaver: Failed to get PairedPMTTriggerTimestamp", v_message, verbosityEBSaver); + if (!gotPairedPMTTimeStamps) + Log("EBSaver: Failed to get PairedPMTTimeStamps", v_message, verbosityEBSaver); + if (!gotPairedPMT_TriggerIndex) + Log("EBSaver: Failed to get PairedPMT_TriggerIndex", v_message, verbosityEBSaver); + if (!gotPMTHitmapRunCode) + Log("EBSaver: Failed to get PMTHitmapRunCode", v_message, verbosityEBSaver); + } + // + // got MRD data + bool gotMRDEvents = m_data->CStore.Get("MRDEvents", MRDEvents); + bool gotMRDEventTriggerTypes = m_data->CStore.Get("MRDEventTriggerTypes", MRDEventTriggerTypes); + bool gotMRDBeamLoopback = m_data->CStore.Get("MRDBeamLoopback", MRDBeamLoopback); + bool gotMRDCosmicLoopback = m_data->CStore.Get("MRDCosmicLoopback", MRDCosmicLoopback); + if (!gotMRDEvents || !gotMRDEventTriggerTypes || !gotMRDBeamLoopback || !gotMRDCosmicLoopback) + Log("EBSaver: Failed to get some MRD data from buffer", v_message, verbosityEBSaver); + // got MRD match info + bool gotPairedMRDTriggerTimestamp = m_data->CStore.Get("PairedMRDTriggerTimestamp", PairedMRDTriggerTimestamp); + bool gotPairedMRDTimeStamps = m_data->CStore.Get("PairedMRDTimeStamps", PairedMRDTimeStamps); + bool gotPairedMRD_TriggerIndex = m_data->CStore.Get("PairedMRD_TriggerIndex", PairedMRD_TriggerIndex); + bool gotMRDHitMapRunCode = m_data->CStore.Get("MRDHitMapRunCode", MRDHitMapRunCode); + if (!gotPairedMRDTriggerTimestamp || !gotPairedMRDTimeStamps || !gotPairedMRD_TriggerIndex || !gotMRDHitMapRunCode) + Log("EBSaver: Failed to get MRD match info from buffer", v_message, verbosityEBSaver); + // + // got LAPPD data + bool gotBuffer_LAPPDTimestamp_ns = m_data->CStore.Get("Buffer_LAPPDTimestamp_ns", Buffer_LAPPDTimestamp_ns); + bool gotBuffer_LAPPDData = m_data->CStore.Get("Buffer_LAPPDData", Buffer_LAPPDData); + bool gotBuffer_LAPPDBeamgate_ns = m_data->CStore.Get("Buffer_LAPPDBeamgate_ns", Buffer_LAPPDBeamgate_ns); + bool gotBuffer_LAPPDOffset = m_data->CStore.Get("Buffer_LAPPDOffset", Buffer_LAPPDOffset); + bool gotBuffer_LAPPDBeamgate_Raw = m_data->CStore.Get("Buffer_LAPPDBeamgate_Raw", Buffer_LAPPDBeamgate_Raw); + bool gotBuffer_LAPPDTimestamp_Raw = m_data->CStore.Get("Buffer_LAPPDTimestamp_Raw", Buffer_LAPPDTimestamp_Raw); + bool gotBuffer_LAPPDBGCorrection = m_data->CStore.Get("Buffer_LAPPDBGCorrection", Buffer_LAPPDBGCorrection); + bool gotBuffer_LAPPDTSCorrection = m_data->CStore.Get("Buffer_LAPPDTSCorrection", Buffer_LAPPDTSCorrection); + bool gotBuffer_LAPPDOffset_minus_ps = m_data->CStore.Get("Buffer_LAPPDOffset_minus_ps", Buffer_LAPPDOffset_minus_ps); + if (!gotBuffer_LAPPDTimestamp_ns || !gotBuffer_LAPPDData || !gotBuffer_LAPPDBeamgate_ns || !gotBuffer_LAPPDOffset || !gotBuffer_LAPPDBeamgate_Raw || !gotBuffer_LAPPDTimestamp_Raw || !gotBuffer_LAPPDBGCorrection || !gotBuffer_LAPPDTSCorrection || !gotBuffer_LAPPDOffset_minus_ps) + Log("EBSaver: Failed to get some LAPPD data from buffer", v_message, verbosityEBSaver); + bool gotBuffer_LAPPDBG_PPSBefore = m_data->CStore.Get("Buffer_LAPPDBG_PPSBefore", Buffer_LAPPDBG_PPSBefore); + bool gotBuffer_LAPPDBG_PPSAfter = m_data->CStore.Get("Buffer_LAPPDBG_PPSAfter", Buffer_LAPPDBG_PPSAfter); + bool gotBuffer_LAPPDBG_PPSDiff = m_data->CStore.Get("Buffer_LAPPDBG_PPSDiff", Buffer_LAPPDBG_PPSDiff); + bool gotBuffer_LAPPDBG_PPSMissing = m_data->CStore.Get("Buffer_LAPPDBG_PPSMissing", Buffer_LAPPDBG_PPSMissing); + bool gotBuffer_LAPPDTS_PPSBefore = m_data->CStore.Get("Buffer_LAPPDTS_PPSBefore", Buffer_LAPPDTS_PPSBefore); + bool gotBuffer_LAPPDTS_PPSAfter = m_data->CStore.Get("Buffer_LAPPDTS_PPSAfter", Buffer_LAPPDTS_PPSAfter); + bool gotBuffer_LAPPDTS_PPSDiff = m_data->CStore.Get("Buffer_LAPPDTS_PPSDiff", Buffer_LAPPDTS_PPSDiff); + bool gotBuffer_LAPPDTS_PPSMissing = m_data->CStore.Get("Buffer_LAPPDTS_PPSMissing", Buffer_LAPPDTS_PPSMissing); + if (!gotBuffer_LAPPDBG_PPSBefore || !gotBuffer_LAPPDBG_PPSAfter || !gotBuffer_LAPPDBG_PPSDiff || !gotBuffer_LAPPDBG_PPSMissing || !gotBuffer_LAPPDTS_PPSBefore || !gotBuffer_LAPPDTS_PPSAfter || !gotBuffer_LAPPDTS_PPSDiff || !gotBuffer_LAPPDTS_PPSMissing) + Log("EBSaver: Failed to get LAPPD PPS data from buffer", v_message, verbosityEBSaver); + + // got LAPPD match info + bool gotPairedLAPPDTriggerTimestamp = m_data->CStore.Get("PairedLAPPDTriggerTimestamp", PairedLAPPDTriggerTimestamp); + bool gotPairedLAPPDTimeStamps = m_data->CStore.Get("PairedLAPPDTimeStamps", PairedLAPPDTimeStamps); + bool gotPairedLAPPD_TriggerIndex = m_data->CStore.Get("PairedLAPPD_TriggerIndex", PairedLAPPD_TriggerIndex); + bool gotLAPPDRunCode = m_data->CStore.Get("Buffer_LAPPDRunCode", Buffer_LAPPDRunCode); + if (!gotPairedLAPPDTriggerTimestamp || !gotPairedLAPPDTimeStamps || !gotPairedLAPPD_TriggerIndex || !gotLAPPDRunCode) + { + Log("EBSaver: Failed to get LAPPD match info from buffer", v_message, verbosityEBSaver); + // print which one was failed + if (!gotPairedLAPPDTriggerTimestamp) + Log("EBSaver: Failed to get PairedLAPPDTriggerTimestamp", v_message, verbosityEBSaver); + if (!gotPairedLAPPDTimeStamps) + Log("EBSaver: Failed to get PairedLAPPDTimeStamps", v_message, verbosityEBSaver); + if (!gotPairedLAPPD_TriggerIndex) + Log("EBSaver: Failed to get PairedLAPPD_TriggerIndex", v_message, verbosityEBSaver); + if (!gotLAPPDRunCode) + Log("EBSaver: Failed to get LAPPDRunCode", v_message, verbosityEBSaver); + } + + Log("EBSaver: got PMT pairing information buffer PairedPMTTimeStamps size " + std::to_string(PairedPMTTimeStamps.size()), v_message, verbosityEBSaver); + Log("EBSaver: got MRD pairing information buffer PairedMRDTimeStamps size " + std::to_string(PairedMRDTimeStamps.size()), v_message, verbosityEBSaver); + for (auto const &track : PairedMRDTimeStamps) + { + int triggerTrack = track.first; + std::vector times = track.second; + Log("EBSaver: PairedMRDTimeStamps at track " + std::to_string(triggerTrack) + " size " + std::to_string(times.size()), v_message, verbosityEBSaver); + for (int i = 0; i < times.size(); i++) + cout << i << ": " << times[i] << ", "; + } + cout << endl; + + Log("EBSaver: got LAPPD pairing information buffer PairedLAPPDTimeStamps size " + std::to_string(PairedLAPPDTimeStamps.size()), v_message, verbosityEBSaver); + for (auto const &track : PairedLAPPDTimeStamps) + { + int triggerTrack = track.first; + std::vector times = track.second; + Log("EBSaver: PairedLAPPDTimeStamps at track " + std::to_string(triggerTrack) + " size " + std::to_string(times.size()), v_message, verbosityEBSaver); + for (int i = 0; i < times.size(); i++) + cout << i << ": " << times[i] << ", "; + } + cout << endl; + + // print PairedLAPPD_TriggerIndex + Log("EBSaver: got LAPPD pairing information buffer PairedLAPPD_TriggerIndex size " + std::to_string(PairedLAPPD_TriggerIndex.size()), v_message, verbosityEBSaver); + for (auto const &track : PairedLAPPD_TriggerIndex) + { + int triggerTrack = track.first; + std::vector indexes = track.second; + Log("EBSaver: PairedLAPPD_TriggerIndex at track " + std::to_string(triggerTrack) + " size " + std::to_string(indexes.size()), v_message, verbosityEBSaver); + for (int i = 0; i < indexes.size(); i++) + cout << i << ": " << indexes[i] << ", "; + } + cout << endl; + + // print Buffer_LAPPDBeamgate_ns + Log("EBSaver: got LAPPD pairing information buffer Buffer_LAPPDBeamgate_ns size " + std::to_string(Buffer_LAPPDBeamgate_ns.size()), v_message, verbosityEBSaver); + for (int i = 0; i < Buffer_LAPPDBeamgate_ns.size(); i++) + cout << i << ": " << Buffer_LAPPDBeamgate_ns[i] << ", "; + cout << endl; + + return true; +} + +void EBSaver::SetDataObjects() +{ + // after erase those data, set them back to CStore + // set PMT data + m_data->CStore.Set("InProgressHits", InProgressHits); + m_data->CStore.Set("InProgressChkey", InProgressChkey); + m_data->CStore.Set("InProgressRecoADCHits", InProgressRecoADCHits); + m_data->CStore.Set("InProgressHitsAux", InProgressHitsAux); + m_data->CStore.Set("InProgressRecoADCHitsAux", InProgressRecoADCHitsAux); + m_data->CStore.Set("FinishedRawAcqSize", FinishedRawAcqSize); + m_data->CStore.Set("RWMRawWaveforms", RWMRawWaveforms); + m_data->CStore.Set("BRFRawWaveforms", BRFRawWaveforms); + // set PMT match info + m_data->CStore.Set("PairedPMTTriggerTimestamp", PairedPMTTriggerTimestamp); + m_data->CStore.Set("PairedPMTTimeStamps", PairedPMTTimeStamps); + m_data->CStore.Set("PairedPMT_TriggerIndex", PairedPMT_TriggerIndex); + m_data->CStore.Set("PMTHitmapRunCode", PMTHitmapRunCode); + // set MRD data + m_data->CStore.Set("MRDEvents", MRDEvents); + m_data->CStore.Set("MRDEventTriggerTypes", MRDEventTriggerTypes); + m_data->CStore.Set("MRDBeamLoopback", MRDBeamLoopback); + m_data->CStore.Set("MRDCosmicLoopback", MRDCosmicLoopback); + // set MRD match info + m_data->CStore.Set("PairedMRDTriggerTimestamp", PairedMRDTriggerTimestamp); + m_data->CStore.Set("PairedMRDTimeStamps", PairedMRDTimeStamps); + m_data->CStore.Set("PairedMRD_TriggerIndex", PairedMRD_TriggerIndex); + m_data->CStore.Set("MRDHitMapRunCode", MRDHitMapRunCode); + // set LAPPD data + m_data->CStore.Set("Buffer_LAPPDTimestamp_ns", Buffer_LAPPDTimestamp_ns); + m_data->CStore.Set("Buffer_LAPPDData", Buffer_LAPPDData); + m_data->CStore.Set("Buffer_LAPPDBeamgate_ns", Buffer_LAPPDBeamgate_ns); + m_data->CStore.Set("Buffer_LAPPDOffset", Buffer_LAPPDOffset); + m_data->CStore.Set("Buffer_LAPPDBeamgate_Raw", Buffer_LAPPDBeamgate_Raw); + m_data->CStore.Set("Buffer_LAPPDTimestamp_Raw", Buffer_LAPPDTimestamp_Raw); + m_data->CStore.Set("Buffer_LAPPDBGCorrection", Buffer_LAPPDBGCorrection); + m_data->CStore.Set("Buffer_LAPPDTSCorrection", Buffer_LAPPDTSCorrection); + m_data->CStore.Set("Buffer_LAPPDOffset_minus_ps", Buffer_LAPPDOffset_minus_ps); + m_data->CStore.Set("Buffer_LAPPDBG_PPSBefore", Buffer_LAPPDBG_PPSBefore); + m_data->CStore.Set("Buffer_LAPPDBG_PPSAfter", Buffer_LAPPDBG_PPSAfter); + m_data->CStore.Set("Buffer_LAPPDBG_PPSDiff", Buffer_LAPPDBG_PPSDiff); + m_data->CStore.Set("Buffer_LAPPDBG_PPSMissing", Buffer_LAPPDBG_PPSMissing); + m_data->CStore.Set("Buffer_LAPPDTS_PPSBefore", Buffer_LAPPDTS_PPSBefore); + m_data->CStore.Set("Buffer_LAPPDTS_PPSAfter", Buffer_LAPPDTS_PPSAfter); + m_data->CStore.Set("Buffer_LAPPDTS_PPSDiff", Buffer_LAPPDTS_PPSDiff); + m_data->CStore.Set("Buffer_LAPPDTS_PPSMissing", Buffer_LAPPDTS_PPSMissing); + // set LAPPD match info + m_data->CStore.Set("PairedLAPPDTriggerTimestamp", PairedLAPPDTriggerTimestamp); + m_data->CStore.Set("PairedLAPPDTimeStamps", PairedLAPPDTimeStamps); + m_data->CStore.Set("PairedLAPPD_TriggerIndex", PairedLAPPD_TriggerIndex); + m_data->CStore.Set("Buffer_LAPPDRunCode", Buffer_LAPPDRunCode); +} + +void EBSaver::BuildEmptyPMTData() +{ + std::map> *PMTHits = new std::map>; + std::map>> PMTRecoADCHits; + std::map> *PMTHitsAux = new std::map>; + std::map>> PMTRecoADCHitsAux; + std::map> PMTRawAcqSize; + + ANNIEEvent->Set("Hits", PMTHits, true); + ANNIEEvent->Set("RecoADCData", PMTRecoADCHits); + ANNIEEvent->Set("AuxHits", PMTHitsAux, true); + ANNIEEvent->Set("RecoAuxADCData", PMTRecoADCHitsAux); + ANNIEEvent->Set("RawAcqSize", PMTRawAcqSize); +} + +void EBSaver::BuildEmptyMRDData() +{ + std::map> *TDCData = new std::map>; + std::string MRDTriggerType = ""; + std::map mrd_loopback_tdc; + + ANNIEEvent->Set("TDCData", TDCData, true); + TimeClass t(0); + ANNIEEvent->Set("EventTimeMRD", t); + ANNIEEvent->Set("MRDTriggerType", MRDTriggerType); + ANNIEEvent->Set("MRDLoopbackTDC", mrd_loopback_tdc); +} + +void EBSaver::BuildEmptyLAPPDData() +{ + std::map LAPPDDataMap; + std::map LAPPDBeamgate_ns; + std::map LAPPDTimeStamps_ns; // data and key are the same + std::map LAPPDTimeStampsRaw; + std::map LAPPDBeamgatesRaw; + std::map LAPPDOffsets; + std::map LAPPDTSCorrection; + std::map LAPPDBGCorrection; + std::map LAPPDOSInMinusPS; + std::map LAPPDBG_PPSBefore; + std::map LAPPDBG_PPSAfter; + std::map LAPPDBG_PPSDiff; + std::map LAPPDBG_PPSMissing; + std::map LAPPDTS_PPSBefore; + std::map LAPPDTS_PPSAfter; + std::map LAPPDTS_PPSDiff; + std::map LAPPDTS_PPSMissing; + + ANNIEEvent->Set("LAPPDDataMap", LAPPDDataMap); + ANNIEEvent->Set("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + ANNIEEvent->Set("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + ANNIEEvent->Set("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + ANNIEEvent->Set("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + ANNIEEvent->Set("LAPPDOffsets", LAPPDOffsets); + ANNIEEvent->Set("LAPPDTSCorrection", LAPPDTSCorrection); + ANNIEEvent->Set("LAPPDBGCorrection", LAPPDBGCorrection); + ANNIEEvent->Set("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + ANNIEEvent->Set("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + ANNIEEvent->Set("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + ANNIEEvent->Set("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + ANNIEEvent->Set("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + ANNIEEvent->Set("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + ANNIEEvent->Set("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + ANNIEEvent->Set("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + ANNIEEvent->Set("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); +} + +void EBSaver::LoadBeamInfo() +{ + TFile *file = new TFile(beamInfoFileName.c_str(), "READ"); + TTree *tree; + file->GetObject("BeamTree", tree); + + if (!tree) + { + cout << "EBSaver: Failed to load beam info from file with name: " << beamInfoFileName << endl; + return; + } + + // copy from IFBeamDBInterfaceV2.cpp + // Here's some documentation for some of the parameters stored in the beam + // database. It's taken from the MicroBooNE operations wiki: + // http://tinyurl.com/z3c4mxs + // + // The status page shows the present reading of beamline instrumentation. All + // of this data is being stored to IF beam Database. The "IF Beam DB + // dashboard":http://dbweb4.fnal.gov:8080/ifbeam/app/BNBDash/index provides + // another view of beam data. Some of it is redundant to the status page, but + // it verifies that the data is being stored in the database. At present the + // page shows following devices: + // * TOR860, TOR875 - two toroids in BNB measuring beam intensity. TOR860 is + // at the beginning of the beamline, and TOR875 is at the end. + // * THCURR - horn current + // * HWTOUT - horn water temperature coming out of the horn. + // * BTJT2 - target temperature + // * HP875, VP875 - beam horizontal and vertical positions at the 875 + // location, about 4.5 m upstream of the target center. + // * HPTG1, VPTG1 - beam horizontal and vertical positions immediately + // (about 2.5 m) upstream of the target center. + // * HPTG2, VPTG2 - beam horizontal and vertical positions more immediately + // (about 1.5 m) upstream of the target center. + // * Because there are no optics between H/VP875 and H/VPTG2, the movements + // on these monitors should scale with the difference in distances. + // * BTJT2 - target air cooling temperature. Four RTD measure the return + // temperature of the cooling air. This is the one closest to the target. + // * BTH2T2 - target air cooling temperature. This is the temperature of the + // air going into the horn. + + // For bunch rotation, the information can be found here: + // https://beamdocs.fnal.gov/AD/DocDB/0069/006904/008/20181214BunchRotation.pdf + // The B_BRRMP has unit of volt, others are not clear. + + // additionally, the unit of E_TOR860 and E_TOR875 is E12 + + uint64_t timestamp; + double E_TOR860, E_TOR875, THCURR, BTJT2, HP875, VP875, HPTG1, VPTG1, HPTG2, VPTG2, BTH2T2; + double B_BRRMPL, B_BRRMPQ, B_BRRMPS, B_BRRMP; + + tree->SetBranchAddress("Timestamp", ×tamp); + tree->SetBranchAddress("E_TOR860", &E_TOR860); + tree->SetBranchAddress("E_TOR875", &E_TOR875); + tree->SetBranchAddress("E_THCURR", &THCURR); + tree->SetBranchAddress("E_BTJT2", &BTJT2); + tree->SetBranchAddress("E_HP875", &HP875); + tree->SetBranchAddress("E_VP875", &VP875); + tree->SetBranchAddress("E_HPTG1", &HPTG1); + tree->SetBranchAddress("E_VPTG1", &VPTG1); + tree->SetBranchAddress("E_HPTG2", &HPTG2); + tree->SetBranchAddress("E_VPTG2", &VPTG2); + tree->SetBranchAddress("E_BTH2T2", &BTH2T2); + tree->SetBranchAddress("B_BRRMPL", &B_BRRMPL); + tree->SetBranchAddress("B_BRRMPQ", &B_BRRMPQ); + tree->SetBranchAddress("B_BRRMPS", &B_BRRMPS); + tree->SetBranchAddress("B_BRRMP", &B_BRRMP); + + Long64_t nentries = tree->GetEntries(); + Log("EBSaver: Loading beam infor, total entries in beam info file: " + std::to_string(nentries), v_message, verbosityEBSaver); + for (Long64_t i = 0; i < nentries; ++i) + { + tree->GetEntry(i); + if (i % (static_cast(nentries / 10)) == 0) + Log("EBSaver: Loading beam info, processed " + std::to_string(i) + " entries", v_message, verbosityEBSaver); + BeamInfoTimestamps.push_back(timestamp); + E_TOR860_map.emplace(timestamp, E_TOR860); + E_TOR875_map.emplace(timestamp, E_TOR875); + THCURR_map.emplace(timestamp, THCURR); + BTJT2_map.emplace(timestamp, BTJT2); + HP875_map.emplace(timestamp, HP875); + VP875_map.emplace(timestamp, VP875); + HPTG1_map.emplace(timestamp, HPTG1); + VPTG1_map.emplace(timestamp, VPTG1); + HPTG2_map.emplace(timestamp, HPTG2); + VPTG2_map.emplace(timestamp, VPTG2); + BTH2T2_map.emplace(timestamp, BTH2T2); + B_BRRMPL_map.emplace(timestamp, B_BRRMPL); + B_BRRMPQ_map.emplace(timestamp, B_BRRMPQ); + B_BRRMPS_map.emplace(timestamp, B_BRRMPS); + B_BRRMP_map.emplace(timestamp, B_BRRMP); + } + + Log("EBSaver: Loaded number of E_TOR860 entries: " + std::to_string(E_TOR860_map.size()), v_message, verbosityEBSaver); + + Log("EBSaver: Finished loading beam info from " + beamInfoFileName, v_message, verbosityEBSaver); + + return; +} + +bool EBSaver::SaveBeamInfo(uint64_t TriggerTime) +{ + double E_TOR860, E_TOR875, THCURR, BTJT2, HP875, VP875, HPTG1, VPTG1, HPTG2, VPTG2, BTH2T2; + double B_BRRMPL, B_BRRMPQ, B_BRRMPS, B_BRRMP; + // find the closest timestamp in vector BeamInfoTimestamps + + uint64_t closestTimestamp = 0; + double minDiff = 60 * 60 * 1e9; // 60 minutes + int minIndex = -1; + + for (int i = 0; i < BeamInfoTimestamps.size(); i++) + { + uint64_t timestamp = BeamInfoTimestamps.at(i) * 1e6; + double diff = (timestamp > TriggerTime) ? timestamp - TriggerTime : TriggerTime - timestamp; + if (i == 0) + Log("EBSaver: First beam info timestamp is " + std::to_string(timestamp) + " with diff = " + std::to_string(diff), v_warning, verbosityEBSaver); + else if (i == BeamInfoTimestamps.size() - 1) + Log("EBSaver: Last beam info timestamp is " + std::to_string(timestamp) + " with diff = " + std::to_string(diff), v_warning, verbosityEBSaver); + + if (diff < minDiff) + { + minDiff = diff; + minIndex = i; + } + } + + if (minIndex == -1) + { + Log("EBSaver: Failed to find the closest beam info timestamp to trigger time", v_message, verbosityEBSaver); + + uint64_t beamInfoTime_long = 0; + int64_t timeDiff = -9999; + double defaultVal = -9999.; + int beam_good = 0; + int bunch_rotation_on = 0; + ANNIEEvent->Set("BeamInfoTime", beamInfoTime_long); + ANNIEEvent->Set("BeamInfoTimeToTriggerDiff", timeDiff); + ANNIEEvent->Set("beam_E_TOR860", defaultVal); + ANNIEEvent->Set("beam_E_TOR875", defaultVal); + ANNIEEvent->Set("beam_THCURR", defaultVal); + ANNIEEvent->Set("beam_BTJT2", defaultVal); + ANNIEEvent->Set("beam_HP875", defaultVal); + ANNIEEvent->Set("beam_VP875", defaultVal); + ANNIEEvent->Set("beam_HPTG1", defaultVal); + ANNIEEvent->Set("beam_VPTG1", defaultVal); + ANNIEEvent->Set("beam_HPTG2", defaultVal); + ANNIEEvent->Set("beam_VPTG2", defaultVal); + ANNIEEvent->Set("beam_BTH2T2", defaultVal); + ANNIEEvent->Set("beam_B_BRRMPL", defaultVal); + ANNIEEvent->Set("beam_B_BRRMPQ", defaultVal); + ANNIEEvent->Set("beam_B_BRRMPS", defaultVal); + ANNIEEvent->Set("beam_B_BRRMP", defaultVal); + ANNIEEvent->Set("beam_good", beam_good); + ANNIEEvent->Set("bunch_rotation_on", bunch_rotation_on); + + Log("EBSaver: Saved beam info with time " + std::to_string(0) + ", pot E_TOR860 = " + std::to_string(-9999) + ", beam_good = " + std::to_string(-9999), v_message, verbosityEBSaver); + } + else + { + Log("Found the closest beam info timestamp to trigger time at index " + std::to_string(minIndex) + " with time " + std::to_string(BeamInfoTimestamps.at(minIndex)) + " and dt = " + std::to_string(minDiff), v_message, verbosityEBSaver); + + // get the precise difference + uint64_t beamInfoTime = BeamInfoTimestamps.at(minIndex); + ULong64_t beamInfoTime_long = beamInfoTime * 1e6; + int64_t timeDiff = beamInfoTime_long - TriggerTime; + + // check if the map has the key + E_TOR860 = E_TOR860_map.at(beamInfoTime); + E_TOR875 = E_TOR875_map.at(beamInfoTime); + THCURR = THCURR_map.at(beamInfoTime); + BTJT2 = BTJT2_map.at(beamInfoTime); + HP875 = HP875_map.at(beamInfoTime); + VP875 = VP875_map.at(beamInfoTime); + HPTG1 = HPTG1_map.at(beamInfoTime); + VPTG1 = VPTG1_map.at(beamInfoTime); + HPTG2 = HPTG2_map.at(beamInfoTime); + VPTG2 = VPTG2_map.at(beamInfoTime); + BTH2T2 = BTH2T2_map.at(beamInfoTime); + B_BRRMPL = B_BRRMPL_map.at(beamInfoTime); + B_BRRMPQ = B_BRRMPQ_map.at(beamInfoTime); + B_BRRMPS = B_BRRMPS_map.at(beamInfoTime); + B_BRRMP = B_BRRMP_map.at(beamInfoTime); + + ANNIEEvent->Set("BeamInfoTime", beamInfoTime); + ANNIEEvent->Set("BeamInfoTimeToTriggerDiff", timeDiff); + + ANNIEEvent->Set("beam_E_TOR860", E_TOR860); + ANNIEEvent->Set("beam_E_TOR875", E_TOR875); + ANNIEEvent->Set("beam_THCURR", THCURR); + ANNIEEvent->Set("beam_BTJT2", BTJT2); + ANNIEEvent->Set("beam_HP875", HP875); + ANNIEEvent->Set("beam_VP875", VP875); + ANNIEEvent->Set("beam_HPTG1", HPTG1); + ANNIEEvent->Set("beam_VPTG1", VPTG1); + ANNIEEvent->Set("beam_HPTG2", HPTG2); + ANNIEEvent->Set("beam_VPTG2", VPTG2); + ANNIEEvent->Set("beam_BTH2T2", BTH2T2); + ANNIEEvent->Set("beam_B_BRRMPL", B_BRRMPL); + ANNIEEvent->Set("beam_B_BRRMPQ", B_BRRMPQ); + ANNIEEvent->Set("beam_B_BRRMPS", B_BRRMPS); + ANNIEEvent->Set("beam_B_BRRMP", B_BRRMP); + + int beam_good = 0; + + // the upper limit is increased from 176 to 178 to include earlier runs before 2022 summer shutdown + // current plot can be fround at docdb 6475, thanks to Steven Doran + // https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=6475 + // so, the beam_ok for beam cluster trees before v1.2 requires current >172 and <176. + // the files processed after are using this new upper limit + if (THCURR > 172 && THCURR < 178) + { + if (E_TOR860 > 0.5 && E_TOR860 < 8 && E_TOR875 > 0.5 && E_TOR875 < 8 && (E_TOR875 - E_TOR860) / E_TOR860 < 0.05) + beam_good = 1; + } + + ANNIEEvent->Set("beam_good", beam_good); + + int bunch_rotation_on = 0; + if (B_BRRMP > 0) + { + bunch_rotation_on = 1; + } + ANNIEEvent->Set("bunch_rotation_on", bunch_rotation_on); + + Log("EBSaver: Saved beam info with time " + std::to_string(beamInfoTime) + ", pot E_TOR860 = " + std::to_string(E_TOR860) + ", beam_good = " + std::to_string(beam_good), v_message, verbosityEBSaver); + } + + return true; +} diff --git a/UserTools/EBSaver/EBSaver.h b/UserTools/EBSaver/EBSaver.h new file mode 100644 index 000000000..9a78b2ac1 --- /dev/null +++ b/UserTools/EBSaver/EBSaver.h @@ -0,0 +1,207 @@ +#ifndef EBSaver_H +#define EBSaver_H + +#include +#include + +#include "Tool.h" +#include "BoostStore.h" +#include "PsecData.h" +#include "TimeClass.h" +#include "TriggerClass.h" +#include "Waveform.h" +#include "ANNIEalgorithms.h" +#include "ADCPulse.h" +#include "CalibratedADCWaveform.h" +#include "BeamStatus.h" +#include "TFile.h" +#include "TTree.h" + +/** + * \class EBPMT + * + * $Author: Yue Feng $ + * $Date: 2024/04 $ + * Contact: yuef@iaistate.edu + * + */ + +class EBSaver : public Tool +{ + +public: + EBSaver(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + bool GotAllDataFromOriginalBuffer(); + void SetDataObjects(); + + bool SaveToANNIEEvent(string saveFileName, int runCode, int triggerTrack, int trackIndex); // save the data to the ANNIEEvent, include all other saving functions. + bool SaveRunInfo(int runCode); // get run numbers from the RunCode in trigger grouper + bool SaveGroupedTriggers(int triggerTrack, int groupIndex); + // use the targetTrigWord to get the trigger track, use the groupIndex to get the group of triggers in that track + // save triggers from std::map>> GroupedTriggersInTotal; //each map is a group of triggers, with the key is the target trigger word + + bool SavePMTData(uint64_t PMTTime); + bool SaveMRDData(uint64_t MRDTime); + bool SaveLAPPDData(uint64_t LAPPDTime); + bool SaveBeamInfo(uint64_t TriggerTime); + + bool SaveOrphan(int runCode); + bool SaveOrphanPMT(int runCode); + bool SaveOrphanMRD(int runCode); + bool SaveOrphanCTC(int runCode); + bool SaveOrphanLAPPD(int runCode); + + void BuildEmptyPMTData(); + void BuildEmptyMRDData(); + void BuildEmptyLAPPDData(); + + void LoadBeamInfo(); + +private: + int saveRunNumber; + int saveSubrunNumber; + int savePartFileNumber; + int savingRunCode; + + bool saveTriggerGroups = true; + bool saveAllTriggers; + bool savePMT = true; + bool saveMRD; + bool saveLAPPD; + bool saveOrphan; + bool saveBeamInfo; + + bool saveRawRWMWaveform; + bool saveRawBRFWaveform; + + string savePath; + string saveName; + + string beamInfoFileName; + + int verbosityEBSaver; + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; + + BoostStore *ANNIEEvent; + + int exeNumber; + int savedTriggerGroupNumber; + int savedPMTHitMapNumber; + int savedMRDNumber; + int savedLAPPDNumber; + + std::map TriggerTimeWithoutMRD; // trigger time, 8 or 36 + + int thisRunNum; + int thisSubrunNum; + int thisPartFileNum; + + int savePerExe; + + int TotalBuiltEventsNumber = 0; + int TotalBuiltPMTNumber; + int TotalBuiltMRDNumber; + int TotalBuiltLAPPDNumber; + int TotalBuiltTriggerGroupNumber; + + std::map PMTRunCodeToRemove; + std::map MRDRunCodeToRemove; + std::map LAPPDRunCodeToRemove; + std::map GroupedTriggerIndexToRemove; + + std::map> PMTPairInfoToRemoveTime; + std::map> MRDPairInfoToRemoveTime; + std::map> LAPPDPairInfoToRemoveTime; + + std::map>> GroupedTriggersInTotal; // each map is a group of triggers, with the key is the target trigger word + std::map> RunCodeInTotal; + + int BeamTriggerMain; + int LaserTriggerMain; + int CosmicTriggerMain; + int LEDTriggerMain; + int AmBeTriggerMain; + int PPSMain; + + // PMT related data object + std::map> *> *InProgressHits; // Key: {MTCTime}, value: map of Hit distributions + std::map> *InProgressChkey; // Key: {MTCTime}, value: vector of in progress chankeys + std::map>>> *InProgressRecoADCHits; // Key: {MTCTime}, value: map of found pulses + std::map>>> *InProgressRecoADCHitsAux; // Key: {MTCTime}, value: map of found pulses + std::map> *> *InProgressHitsAux; // Key: {MTCTime}, value: map of Hit distributions + std::map>> *FinishedRawAcqSize; // Key: {MTCTime}, value: map of acquisition time window sizes + + std::map> *RWMRawWaveforms; // Key: MTCTime, Value: RWM waveform + std::map> *BRFRawWaveforms; // Key: MTCTime, Value: BRF waveform + + std::map> PairedPMTTriggerTimestamp; + std::map> PairedPMT_TriggerIndex; + std::map> PairedPMTTimeStamps; + std::map PMTHitmapRunCode; // Key: {MTCTime}, value: RunCode + + // MRD related data object + std::map>> MRDEvents; // Key: {MTCTime}, value: "WaveMap" with key (CardID,ChannelID), value FinishedWaveform + std::map MRDEventTriggerTypes; // Key: {MTCTime}, value: string noting what type of trigger occured for the event + std::map MRDBeamLoopback; // Key: {MTCTime}, value: string noting what type of trigger occured for the event + std::map MRDCosmicLoopback; // KEY: {MTCTime}, value: Cosmic loopback TDC value + + std::map> PairedMRDTriggerTimestamp; + std::map> PairedMRD_TriggerIndex; + std::map> PairedMRDTimeStamps; + std::map MRDHitMapRunCode; // Key: {MTCTime}, value: RunCode + + // LAPPD related data object + vector Buffer_IndexOfData; // index of unpaired data + vector Buffer_LAPPDTimestamp_ns; // used to match + + vector Buffer_LAPPDData; + vector Buffer_LAPPDBeamgate_ns; + vector Buffer_LAPPDOffset; + vector Buffer_LAPPDBeamgate_Raw; + vector Buffer_LAPPDTimestamp_Raw; + vector Buffer_LAPPDBGCorrection; + vector Buffer_LAPPDTSCorrection; + vector Buffer_LAPPDOffset_minus_ps; + vector Buffer_LAPPDBG_PPSBefore; + vector Buffer_LAPPDBG_PPSAfter; + vector Buffer_LAPPDBG_PPSDiff; + vector Buffer_LAPPDBG_PPSMissing; + vector Buffer_LAPPDTS_PPSBefore; + vector Buffer_LAPPDTS_PPSAfter; + vector Buffer_LAPPDTS_PPSDiff; + vector Buffer_LAPPDTS_PPSMissing; + + vector Buffer_LAPPDRunCode; + + std::map> PairedLAPPDTriggerTimestamp; + std::map> PairedLAPPD_TriggerIndex; + std::map> PairedLAPPDTimeStamps; + + // beam info related objects + vector BeamInfoTimestamps; + std::map E_TOR860_map; + std::map E_TOR875_map; + std::map THCURR_map; + std::map BTJT2_map; + std::map HP875_map; + std::map VP875_map; + std::map HPTG1_map; + std::map VPTG1_map; + std::map HPTG2_map; + std::map VPTG2_map; + std::map BTH2T2_map; + std::map B_BRRMPL_map; + std::map B_BRRMPS_map; + std::map B_BRRMPQ_map; + std::map B_BRRMP_map; + +}; + +#endif diff --git a/UserTools/EBSaver/README.md b/UserTools/EBSaver/README.md new file mode 100644 index 000000000..a05a2dc7c --- /dev/null +++ b/UserTools/EBSaver/README.md @@ -0,0 +1,29 @@ +# EBSaver + +EBSaver is a part of Event Building version 2 tool chain. +For reference slides, see: +https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=5633 + +For a group of trigger with it's main trigger in part file x, that event will be saved as processed file x. +There shouldn't be any error if the file is correctly processed, the stat info will be printed out at Finalise. +Processing one part file usually just take a few minutes. The time of processing multiple files will be increased quick because of the trigger grouping. There is a limit but more than 7 beam files are not recommended. + + +## Data + +EBSaver take four cataogeies of inputs +1. Beam Info. (From beam fetcher) +2. Grouped triggers. (from EBTriggerGrouper) + GroupedTriggersInTotal +3. Data from subsystems. (PMT, MRD, LAPPD, from data decoders) + In GotAllDataFromOriginalBuffer function +4. Matched pairs of data timestamps and grouped triggers. (from EBPMT, EBMRD, EBLAPPD) + Also in GotAllDataFromOriginalBuffer function + + +## Configuration + +beamInfoFileName: name of the beam info file generated by beam fetcher V2 + +Other configs are set by defalut +Save Orphan is not implemented right now. \ No newline at end of file diff --git a/UserTools/EventSelector/EventSelector.cpp b/UserTools/EventSelector/EventSelector.cpp index e06fb99c5..89447d4d2 100644 --- a/UserTools/EventSelector/EventSelector.cpp +++ b/UserTools/EventSelector/EventSelector.cpp @@ -14,7 +14,6 @@ bool EventSelector::Initialise(std::string configfile, DataModel &data){ fPMTMRDOffset = false; fIsMC = true; - fMCWaveform = false; fPMTMRDOffset = 755; fRecoPDG = -1; diff --git a/UserTools/Factory/Factory.cpp b/UserTools/Factory/Factory.cpp index cbff25aa7..d7d621874 100644 --- a/UserTools/Factory/Factory.cpp +++ b/UserTools/Factory/Factory.cpp @@ -168,12 +168,25 @@ if (tool=="NeutronMultiplicity") ret=new NeutronMultiplicity; if (tool=="PlotsTrackLengthAndEnergy") ret=new PlotsTrackLengthAndEnergy; if (tool=="SaveConfigInfo") ret=new SaveConfigInfo; if (tool=="ReadConfigInfo") ret=new ReadConfigInfo; -if (tool=="MuonFitter") ret=new MuonFitter; +if (tool=="LAPPDLoadStore") ret=new LAPPDLoadStore; +if (tool=="LAPPDTreeMaker") ret=new LAPPDTreeMaker; +if (tool=="LAPPDPlots") ret=new LAPPDPlots; +if (tool=="LAPPDThresReco") ret=new LAPPDThresReco; +if (tool=="LAPPDTimeAlignment") ret=new LAPPDTimeAlignment; +if (tool=="LAPPDBaseline") ret=new LAPPDBaseline; +if (tool=="LAPPDStoreReorder") ret=new LAPPDStoreReorder; +if (tool=="EBLoadRaw") ret=new EBLoadRaw; +if (tool=="EBTriggerGrouper") ret=new EBTriggerGrouper; +if (tool=="EBLAPPD") ret=new EBLAPPD; +if (tool=="EBPMT") ret=new EBPMT; +if (tool=="EBMRD") ret=new EBMRD; +if (tool=="EBSaver") ret=new EBSaver; +if (tool=="ANNIEEventTreeMaker") ret=new ANNIEEventTreeMaker; +if (tool=="ProcessedLAPPDFilter") ret=new ProcessedLAPPDFilter; if (tool=="BeamQuality") ret=new BeamQuality; -if (tool=="BackTracker") ret=new BackTracker; -if (tool=="PrintDQ") ret=new PrintDQ; -if (tool=="AssignBunchTimingMC") ret=new AssignBunchTimingMC; if (tool=="FitRWMWaveform") ret=new FitRWMWaveform; +if (tool=="LAPPDLoadTXT") ret=new LAPPDLoadTXT; +if (tool=="LAPPDBSCharging") ret=new LAPPDBSCharging; if (tool=="EBTriggerGrouper") ret=new EBTriggerGrouper; if (tool=="EBPMT") ret=new EBPMT; if (tool=="LAPPDLoadStore") ret=new LAPPDLoadStore; diff --git a/UserTools/FindMrdTracks/FindMrdTracks.cpp b/UserTools/FindMrdTracks/FindMrdTracks.cpp index bf344cafe..cad0d47ff 100755 --- a/UserTools/FindMrdTracks/FindMrdTracks.cpp +++ b/UserTools/FindMrdTracks/FindMrdTracks.cpp @@ -104,7 +104,8 @@ bool FindMrdTracks::Execute(){ get_ok = m_data->Stores.at("ANNIEEvent")->Get("MRDTriggerType",MRDTriggertype); if (not get_ok){ Log("FindMrdTracks: Did not find MRDTriggerType in ANNIEEvent. Please check the settings in MRDDataDecoder+BuildANNIEEvent/LoadWCSim?",v_error,verbosity); - m_data->vars.Set("StopLoop",1); + //m_data->vars.Set("StopLoop",1); + Log("FindMrdTracks tool was supposed to stop the loop, but will continue anyway",0,verbosity); } } Log("FindMrdTracks tool: MRDTriggertype is "+MRDTriggertype+" (from ANNIEEvent store)",v_debug,verbosity); diff --git a/UserTools/FitRWMWaveform/FitRWMWaveform.cpp b/UserTools/FitRWMWaveform/FitRWMWaveform.cpp index 45035356e..22220ac21 100644 --- a/UserTools/FitRWMWaveform/FitRWMWaveform.cpp +++ b/UserTools/FitRWMWaveform/FitRWMWaveform.cpp @@ -5,10 +5,13 @@ FitRWMWaveform::FitRWMWaveform() : Tool() {} bool FitRWMWaveform::Initialise(std::string configfile, DataModel &data) { + /////////////////// Useful header /////////////////////// if (configfile != "") - m_variables.Initialise(configfile); + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); - m_data = &data; + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// m_variables.Get("verbosityFitRWMWaveform", verbosityFitRWMWaveform); m_variables.Get("printToRootFile", printToRootFile); @@ -86,7 +89,6 @@ bool FitRWMWaveform::Finalise() hRWM->SetBinContent(i + 1, val[i]); // Note the 1-based index } hRWM->Write(); - delete hRWM; RWMCount++; } @@ -101,12 +103,10 @@ bool FitRWMWaveform::Finalise() hBRF->SetBinContent(i + 1, val[i]); // Note the 1-based index } hBRF->Write(); - delete hBRF; BRFCount++; } fOutput_tfile->Close(); - delete fOutput_tfile; } return true; @@ -358,6 +358,17 @@ void FitRWMWaveform::FitBRF() y_vals.push_back(BRFRawWaveform[i]); } + //TGraph graph(x_vals.size(), &x_vals[0], &y_vals[0]); + //TF1 gaus("gaus", "gaus", fit_start_bin * bin_size, fit_end_bin * bin_size); + + //graph.Fit(&gaus, "Q"); + + //BRFFirstPeakFit = gaus.GetParameter(1); // Mean value of the Gaussian fit + //Log("FitRWMWaveform: FitBRF(): First peak fit at " + std::to_string(BRFFirstPeakFit), v_debug, verbosityFitRWMWaveform); + + + + // Find the bin with the minimum value between the 5th and 15th bins auto min_it = std::min_element(BRFRawWaveform.begin() + 4, BRFRawWaveform.begin() + 15); int bin_minimum = std::distance(BRFRawWaveform.begin(), min_it); diff --git a/UserTools/FitRWMWaveform/README.md b/UserTools/FitRWMWaveform/README.md index 798057458..0c3f851ef 100644 --- a/UserTools/FitRWMWaveform/README.md +++ b/UserTools/FitRWMWaveform/README.md @@ -1,35 +1,20 @@ -# FitRWMWaveform - -FitRWMWaveform tool takes the auxilliary channel waveforms saved in the Processed Data and peforms rising edge fitting to determine the rising edge time. - -Currently the two auxillary waveforms are the Booster RF and the Booster RWM signals (https://github.com/ANNIEsoft/ToolAnalysis/blob/ff86893aa905652621594f8ac093be45f3bd13b5/configfiles/LoadGeometry/AuxChannels.csv#L5). - -Motivation for this tool and details of the waveform shape and fitting can be found here: https://annie-docdb.fnal.gov/cgi-bin/sso/ProcessDocumentAdd - -## Data - -The tool will populate the following objects (all `double` datatype): - -### RWM fits -* **RWMRisingStart**: Time where the RWM trace crosses predefined threshold -* **RWMRisingEnd**: Time where RWM trace crosses below predefined threshold (at the end) -* **RWMHalfRising**: Time where the RWM rising edge crosses 50% of its maximum above baseline. -* **RWMFHWM**: FWHM of the RWM waveform (sorry for the typo). -* **RWMFirstPeak**: After the rising edge of the RWM trace, there is often a sharp peak. This the time of this first peak. - -### BRF fit -* **BRFFirstPeak**: For the BRF waveform, fit of the first BRF pulse. -* **BRFAveragePeak** The average (or baseline) y-value (in ADC) of the signal across the entire window. -* **BRFFirstPeakFit** Fit for the half-rising time of the first BRF pulse. - - -## Configuration - -Configuration variables for FitRWMWaveform. - -``` -verbosityFitRWMWaveform 0 # verbosity level -printToRootFile 1 # 1 to print the RWM and BRF waveforms to an output root file, 0 for no printing -maxPrintNumber 100 # maximum number of waveforms to save to the output root file -output_filename RWMBRFWaveforms.root # name of the output root file -``` +# FitRWMWaveform + +FitRWMWaveform + +## Data + +Describe any data formats FitRWMWaveform creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for FitRWMWaveform. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDBSCharging/LAPPDBSCharging.cpp b/UserTools/LAPPDBSCharging/LAPPDBSCharging.cpp new file mode 100644 index 000000000..878aa77a8 --- /dev/null +++ b/UserTools/LAPPDBSCharging/LAPPDBSCharging.cpp @@ -0,0 +1,28 @@ +#include "LAPPDBSCharging.h" + +LAPPDBSCharging::LAPPDBSCharging():Tool(){} + + +bool LAPPDBSCharging::Initialise(std::string configfile, DataModel &data){ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + //m_variables.Print(); + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + return true; +} + + +bool LAPPDBSCharging::Execute(){ + + return true; +} + + +bool LAPPDBSCharging::Finalise(){ + + return true; +} diff --git a/UserTools/LAPPDBSCharging/LAPPDBSCharging.h b/UserTools/LAPPDBSCharging/LAPPDBSCharging.h new file mode 100644 index 000000000..f8c90801c --- /dev/null +++ b/UserTools/LAPPDBSCharging/LAPPDBSCharging.h @@ -0,0 +1,39 @@ +#ifndef LAPPDBSCharging_H +#define LAPPDBSCharging_H + +#include +#include + +#include "Tool.h" + + +/** + * \class LAPPDBSCharging + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. +* +* $Author: B.Richards $ +* $Date: 2019/05/28 10:44:00 $ +* Contact: b.richards@qmul.ac.uk +*/ +class LAPPDBSCharging: public Tool { + + + public: + + LAPPDBSCharging(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + + private: + + + + + +}; + + +#endif diff --git a/UserTools/LAPPDBSCharging/README.md b/UserTools/LAPPDBSCharging/README.md new file mode 100644 index 000000000..af939269b --- /dev/null +++ b/UserTools/LAPPDBSCharging/README.md @@ -0,0 +1,20 @@ +# LAPPDBSCharging + +LAPPDBSCharging + +## Data + +Describe any data formats LAPPDBSCharging creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDBSCharging. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDBaseline/LAPPDBaseline.cpp b/UserTools/LAPPDBaseline/LAPPDBaseline.cpp new file mode 100644 index 000000000..7b9353470 --- /dev/null +++ b/UserTools/LAPPDBaseline/LAPPDBaseline.cpp @@ -0,0 +1,195 @@ +#include "LAPPDBaseline.h" + +LAPPDBaseline::LAPPDBaseline() : Tool() {} + +bool LAPPDBaseline::Initialise(std::string configfile, DataModel &data) +{ + /////////////////// Usefull header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + // bool isBLsub = true; + // m_data->Stores["ANNIEEvent"]->Header->Set("isBLsubtracted",isBLsub); + + m_variables.Get("Nsamples", DimSize); + m_variables.Get("SampleSize", Deltat); + m_variables.Get("TrigChannel", TrigChannel); + m_variables.Get("LowBLfitrange", LowBLfitrange); + m_variables.Get("HiBLfitrange", HiBLfitrange); + m_variables.Get("TrigLowBLfitrange", TrigLowBLfitrange); + m_variables.Get("TrigHiBLfitrange", TrigHiBLfitrange); + m_variables.Get("BLSInputWavLabel", BLSInputWavLabel); + m_variables.Get("BLSOutputWavLabel", BLSOutputWavLabel); + m_variables.Get("BaselineSubstractVerbosityLevel", BLSVerbosityLevel); + m_variables.Get("LAPPDchannelOffset", LAPPDchannelOffset); + execludeAmpDifference = 100; + m_variables.Get("execludeAmpDifference", execludeAmpDifference); + + return true; +} + +bool LAPPDBaseline::Execute() +{ + + bool LAPPDana = false; + + m_data->CStore.Get("LAPPDana", LAPPDana); + if (!LAPPDana) + { + return true; + } + else + { + if (BLSVerbosityLevel > 1) + cout << "YES LAPPD Data found in baselinesub" << endl; + } + + bool isBLsub = true; + m_data->Stores["ANNIEEvent"]->Set("isBLsubtracted", isBLsub); + if (BLSVerbosityLevel > 2) + cout << "Made it to here " << BLSInputWavLabel << " is read in." << endl; + Waveform bwav; + + std::map>> lappddata; + m_data->Stores["ANNIEEvent"]->Get(BLSInputWavLabel, lappddata); + if (BLSVerbosityLevel > 2) + cout << "And data is loaded" << endl; + // the filtered Waveform + std::map>> blsublappddata; + + map>>::iterator itr; + for (itr = lappddata.begin(); itr != lappddata.end(); ++itr) + { + int channelno = itr->first; + channelno = channelno%1000 + 1000; + vector> Vwavs = itr->second; + vector> Vfwavs; + int bi = (int)(channelno - LAPPDchannelOffset) / 30; + + // loop over all Waveforms + for (int i = 0; i < Vwavs.size(); i++) + { + + Waveform bwav = Vwavs.at(i); + + // This is from back when we had a sinusoidal pedestal + // Waveform blswav = SubtractSine(bwav); + + // Loop over first N samples and get average value + if (LowBLfitrange > DimSize || HiBLfitrange > DimSize) + { + cout << "BASELINE FITRANGE IS WRONG!!! " << LowBLfitrange << " " << HiBLfitrange << endl; + LowBLfitrange = 0; + HiBLfitrange = 1; + } + + if (TrigLowBLfitrange > DimSize || TrigHiBLfitrange > DimSize) + { + cout << "BASELINE FITRANGE IS WRONG!!! " << TrigLowBLfitrange << " " << TrigHiBLfitrange << endl; + TrigLowBLfitrange = 0; + TrigHiBLfitrange = 1; + } + + double BLval = 0; + int execuldedBins = 0; + + if (channelno == (LAPPDchannelOffset + (30 * bi) + TrigChannel)) + { + for (int j = TrigLowBLfitrange; j < TrigHiBLfitrange; j++) + { + if (j > 0) + { + if (abs(bwav.GetSamples()->at(j) - bwav.GetSamples()->at(j - 1)) < execludeAmpDifference) + BLval += bwav.GetSamples()->at(j); + else + execuldedBins++; + } + else + { + BLval += bwav.GetSamples()->at(j); + } + } + } + else + { + for (int j = LowBLfitrange; j < HiBLfitrange; j++) + { + if (j > 0) + { + if (abs(bwav.GetSamples()->at(j) - bwav.GetSamples()->at(j - 1)) < execludeAmpDifference) + BLval += bwav.GetSamples()->at(j); + else + execuldedBins++; + } + else + { + BLval += bwav.GetSamples()->at(j); + } + } + } + + double AvgBL = BLval / ((double)(HiBLfitrange - LowBLfitrange - execuldedBins)); + + Waveform blswav; + for (int k = 0; k < bwav.GetSamples()->size(); k++) + { + blswav.PushSample((bwav.GetSamples()->at(k)) - AvgBL); + } + + Vfwavs.push_back(blswav); + } + + blsublappddata.insert(pair>>(channelno, Vfwavs)); + } + + if (BLSVerbosityLevel > 2) + cout << "Baseline substraction is done in " << BLSOutputWavLabel << endl; + m_data->Stores["ANNIEEvent"]->Set(BLSOutputWavLabel, blsublappddata); + + return true; +} + +Waveform LAPPDBaseline::SubtractSine(Waveform iwav) +{ + Waveform subWav; + + int nbins = iwav.GetSamples()->size(); + double starttime = 0.; + double endtime = starttime + ((double)nbins) * 100.; + TH1D *hwav_raw = new TH1D("hwav_raw", "hwav_raw", nbins, starttime, endtime); + + for (int i = 0; i < nbins; i++) + { + hwav_raw->SetBinContent(i + 1, iwav.GetSample(i)); + hwav_raw->SetBinError(i + 1, 0.1); + } + + TF1 *sinit = new TF1("sinit", "([0]*sin([2]*x+[1]))", 0, DimSize * Deltat); + sinit->SetParameter(0, 0.4); + sinit->SetParameter(1, 0.0); + sinit->SetParameter(2, 0.0); + sinit->SetParameter(2, 0.00055); + sinit->SetParLimits(2, 0.0003, 0.0008); + sinit->SetParLimits(0, 0., 1.0); + + hwav_raw->Fit("sinit", "QNO", "", LowBLfitrange, HiBLfitrange); + // cout<<"Parameters: "<< sinit->GetParameter(3)<<" "<GetBinContent(j + 1)) - (sinit->Eval(hwav_raw->GetBinCenter(j + 1)))); + } + + delete hwav_raw; + delete sinit; + return subWav; +} + +bool LAPPDBaseline::Finalise() +{ + return true; +} diff --git a/UserTools/LAPPDBaseline/LAPPDBaseline.h b/UserTools/LAPPDBaseline/LAPPDBaseline.h new file mode 100644 index 000000000..34ac201d7 --- /dev/null +++ b/UserTools/LAPPDBaseline/LAPPDBaseline.h @@ -0,0 +1,44 @@ +#ifndef LAPPDBaseline_H +#define LAPPDBaseline_H + + +#include +#include + +#include "TH1.h" +#include "TF1.h" +#include "Tool.h" + +class LAPPDBaseline: public Tool { + + + public: + + LAPPDBaseline(); + bool Initialise(std::string configfile,DataModel &data); + bool Execute(); + bool Finalise(); + + + private: + + Waveform SubtractSine(Waveform iwav); + int LAPPDchannelOffset; + int BLSVerbosityLevel; + bool isSim; + int DimSize; + int TrigChannel; + double Deltat; + double LowBLfitrange; + double HiBLfitrange; + double TrigLowBLfitrange; + double TrigHiBLfitrange; + string BLSInputWavLabel; + string BLSOutputWavLabel; + + double execludeAmpDifference; + +}; + + +#endif diff --git a/UserTools/LAPPDBaseline/README.md b/UserTools/LAPPDBaseline/README.md new file mode 100644 index 000000000..2b28737d8 --- /dev/null +++ b/UserTools/LAPPDBaseline/README.md @@ -0,0 +1,20 @@ +# LAPPDBaseline + +LAPPDBaseline + +## Data + +Describe any data formats LAPPDBaseline creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDBaseline. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDLoadTXT/LAPPDLoadTXT.cpp b/UserTools/LAPPDLoadTXT/LAPPDLoadTXT.cpp new file mode 100644 index 000000000..95a96d05a --- /dev/null +++ b/UserTools/LAPPDLoadTXT/LAPPDLoadTXT.cpp @@ -0,0 +1,269 @@ +#include "LAPPDLoadTXT.h" + +LAPPDLoadTXT::LAPPDLoadTXT() : Tool() {} + +bool LAPPDLoadTXT::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + LAPPDLoadTXTVerbosity = 0; + m_variables.Get("LAPPDLoadTXTVerbosity", LAPPDLoadTXTVerbosity); + + PedFileNameTXT = "../Pedestals/TXTPdedestals/P"; + m_variables.Get("PedFileNameTXT", PedFileNameTXT); + + NBoards = 2; + m_variables.Get("NBoards", NBoards); + + OutputWavLabel = "RawLAPPDData"; + m_variables.Get("OutputWavLabel", OutputWavLabel); + + DoPedSubtract = true; + m_variables.Get("DoPedSubtract", DoPedSubtract); + + if (DoPedSubtract) + { + PedestalValues = new std::map>; + for (int i = 0; i < NBoards; i++) + { + Log("LAPPDLoadTXT: Loading " + std::to_string(NBoards) + "Pedestal file from " + PedFileNameTXT, 0, LAPPDLoadTXTVerbosity); + ReadPedestal(i); + } + Log("LAPPDLoadTXT: Pedestal file loaded", 0, LAPPDLoadTXTVerbosity); + } + + Nsamples = 256; + m_variables.Get("Nsamples", Nsamples); + NChannels = 30; + m_variables.Get("NChannels", NChannels); + TrigChannel = 5; + m_variables.Get("TrigChannel", TrigChannel); + LAPPDchannelOffset = 1000; + m_variables.Get("LAPPDchannelOffset", LAPPDchannelOffset); + SampleSize = 80; + m_variables.Get("SampleSize", SampleSize); + + m_data->Stores["ANNIEEvent"]->Set("Nsamples", Nsamples); + m_data->Stores["ANNIEEvent"]->Set("NChannels", NChannels); + m_data->Stores["ANNIEEvent"]->Set("TrigChannel", TrigChannel); + m_data->Stores["ANNIEEvent"]->Set("LAPPDchannelOffset", LAPPDchannelOffset); + m_data->Stores["ANNIEEvent"]->Set("SampleSize", SampleSize); + + m_variables.Get("DataFileName", DataFileName); + DataFile.open(DataFileName); + if (!DataFile.is_open()) + { + cout << "LAPPDLoadTXT: Failed to open " << DataFileName << "!" << endl; + return false; + } + + eventNo = 0; + + oldLaser = 0; + m_variables.Get("oldLaser", oldLaser); + + return true; +} + +bool LAPPDLoadTXT::Execute() +{ + Log("LAPPDLoadTXT: Reading data file", v_debug, LAPPDLoadTXTVerbosity); + bool isFiltered = false; + m_data->Stores["ANNIEEvent"]->Set("isFiltered", isFiltered); + bool isBLsub = false; + m_data->Stores["ANNIEEvent"]->Set("isBLsubtracted", isBLsub); + bool isCFD = false; + m_data->Stores["ANNIEEvent"]->Set("isCFD", isCFD); + + LAPPDWaveforms = new std::map>>; + + if (eventNo % 50 == 0) + Log("LAPPDLoadTXT: Event " + std::to_string(eventNo), v_message, LAPPDLoadTXTVerbosity); + + // alwasys set LAPPDana to true because we are loading ASCII data, every loop mush has data + bool LAPPDana = true; + m_data->CStore.Set("LAPPDana", LAPPDana); + + ReadData(); + + vector NReadBoards = {0, 1}; + m_data->Stores["ANNIEEvent"]->Set("ACDCboards", NReadBoards); + m_data->Stores["ANNIEEvent"]->Set("SortedBoards", NReadBoards); + + vector ACDCReadedLAPPDID = {0, 0}; + m_data->Stores["ANNIEEvent"]->Set("ACDCReadedLAPPDID", ACDCReadedLAPPDID); + + int LAPPD_ID = 0; + m_data->Stores["ANNIEEvent"]->Set("oldLaser", oldLaser); + m_data->Stores["ANNIEEvent"]->Set("LAPPD_ID", LAPPD_ID); + m_data->Stores["ANNIEEvent"]->Set("TrigChannel", TrigChannel); + m_data->Stores["ANNIEEvent"]->Set("LAPPDchannelOffset", LAPPDchannelOffset); + m_data->Stores["ANNIEEvent"]->Set("SampleSize", SampleSize); + + m_data->Stores["ANNIEEvent"]->Set(OutputWavLabel, LAPPDWaveforms); + m_data->Stores["ANNIEEvent"]->Set("ACDCmetadata", metaData); + LAPPDWaveforms->clear(); + metaData.clear(); + eventNo++; + + return true; +} + +bool LAPPDLoadTXT::Finalise() +{ + DataFile.close(); + Log("LAPPDLoadTXT: Data file closed", v_message, LAPPDLoadTXTVerbosity); + + return true; +} + +bool LAPPDLoadTXT::ReadPedestal(int boardNo) +{ + // copied fomr LAPPDLoadStore + + if (LAPPDLoadTXTVerbosity > 0) + cout << "Getting Pedestals " << boardNo << endl; + + std::string LoadName = PedFileNameTXT; + string nextLine; // temp line to parse + double finalsampleNo; + std::string ext = std::to_string(boardNo); + ext += ".txt"; + LoadName += ext; + ifstream PedFile; + PedFile.open(LoadName); // final name: PedFileNameTXT + boardNo + .txt + if (!PedFile.is_open()) + { + cout << "Failed to open " << LoadName << "!" << endl; + return false; + } + if (LAPPDLoadTXTVerbosity > 0) + cout << "Opened pedestal file: " << LoadName << endl; + + int sampleNo = 0; // sample number + while (getline(PedFile, nextLine)) + { + istringstream iss(nextLine); // copies the current line in the file + int location = -1; // counts the current perameter in the line + string stempValue; // current string in the line + int tempValue; // current int in the line + unsigned long channelNo = boardNo * 30; // channel number + // cout<<"NEW BOARD "<> stempValue) + { + location++; + tempValue = stoi(stempValue, 0, 10); + if (sampleNo == 0) + { + vector tempPed; + tempPed.push_back(tempValue); + PedestalValues->insert(pair>(channelNo, tempPed)); + if (LAPPDLoadTXTVerbosity > 0) + cout << "Inserting pedestal at channelNo " << channelNo << endl; + } + else + { + (((PedestalValues->find(channelNo))->second)).push_back(tempValue); + } + + channelNo++; + } + sampleNo++; + } + if (LAPPDLoadTXTVerbosity > 0) + cout << "FINAL SAMPLE NUMBER: " << PedestalValues->size() << " " << (((PedestalValues->find(0))->second)).size() << endl; + PedFile.close(); + return true; +} + +void LAPPDLoadTXT::ReadData() +{ + string nextLine; // temp line to parse + + map>>::iterator itr; + + int lineNumber = 0; + while (getline(DataFile, nextLine)) + { + int sampleNo = 0; // sample number + unsigned long channelNo = 0; // channel number + istringstream iss(nextLine); // copies the current line in the file + int location = -1; // counts the current perameter in the line + string stempValue; // current string in the line + int tempValue; // current int in the line + + while (iss >> stempValue) + { + location++; + if (location == 0) + { + sampleNo = stoi(stempValue, 0, 10); + Log("LAPPDLoadTXT: at sampleNo " + std::to_string(sampleNo) + " at line " + std::to_string(lineNumber), 5, LAPPDLoadTXTVerbosity); + continue; + } + Log("LAPPDLoadTXT: Parsing 30 channels for sample " + std::to_string(sampleNo) + " at location " + std::to_string(location), 10, LAPPDLoadTXTVerbosity); + + if (location % 31 == 0) + { + metaDataString.push_back(stempValue); + // convert string stempValue to unsigned short + unsigned short tempMeta = (unsigned short)stoi(stempValue, 0, 16); + metaData.push_back(tempMeta); + continue; + } + + int tempValue = stoi(stempValue, 0, 10); + + int theped; + map>::iterator pitr; + if ((PedestalValues->count(channelNo)) > 0) + { + pitr = PedestalValues->find(channelNo); + theped = (pitr->second).at(sampleNo); + } + else + { + theped = 0; + } + + int pedsubValue = tempValue - theped; + if (LAPPDLoadTXTVerbosity > 11) + cout << "LAPPDLoadTXT: data value: " << tempValue << " pedestal value: " << theped << " pedsub value: " << pedsubValue << ", inserted " << 0.3 * ((double)pedsubValue) << endl; + + if (sampleNo == 0) + { + Waveform tempwav; + tempwav.PushSample(0.3 * ((double)pedsubValue)); // what is 0.3? + vector> Vtempwav; + Vtempwav.push_back(tempwav); + LAPPDWaveforms->insert(pair>>(channelNo, Vtempwav)); + Log("LAPPDLoadTXT: Inserting waveform at channel " + std::to_string(channelNo), 5, LAPPDLoadTXTVerbosity); + } + else + { + (((LAPPDWaveforms->find(channelNo))->second).at(0)).PushSample(0.3 * ((double)pedsubValue)); + } + + channelNo++; + } + lineNumber++; + if (sampleNo == 255) + { + Log("LAPPDLoadTXT: Event " + std::to_string(eventNo) + " loaded", v_debug, LAPPDLoadTXTVerbosity); + if (DataFile.peek() == EOF) // 检查下一个字符是否为EOF + { + m_data->vars.Set("StopLoop", 1); + Log("LAPPDLoadTXT: End of data file reached, setting StopLoop to 1", 0, LAPPDLoadTXTVerbosity); + } + break; + } + } +} diff --git a/UserTools/LAPPDLoadTXT/LAPPDLoadTXT.h b/UserTools/LAPPDLoadTXT/LAPPDLoadTXT.h new file mode 100644 index 000000000..fdf838617 --- /dev/null +++ b/UserTools/LAPPDLoadTXT/LAPPDLoadTXT.h @@ -0,0 +1,67 @@ +#ifndef LAPPDLoadTXT_H +#define LAPPDLoadTXT_H + +#include +#include + +#include "Tool.h" + +#include +#include +#include +#include "Tool.h" + +/** + * \class LAPPDLoadTXT + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. + * + * $Author: B.Richards $ + * $Date: 2019/05/28 10:44:00 $ + * Contact: b.richards@qmul.ac.uk + */ +class LAPPDLoadTXT : public Tool +{ + +public: + LAPPDLoadTXT(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + bool ReadPedestal(int boardNo); ///< Read in the Pedestal Files + void ReadData(); + +private: + int LAPPDLoadTXTVerbosity; + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; + + string PedFileNameTXT; + int NBoards; + string DataFileName; + + ifstream DataFile; + + std::map> *PedestalValues; + std::map>> *LAPPDWaveforms; + vector metaData; + vector metaDataString; + + int DoPedSubtract; + + string OutputWavLabel; + + int eventNo; + + int NChannels; + int Nsamples; + int TrigChannel; + double SampleSize; + int LAPPDchannelOffset; + + int oldLaser; +}; + +#endif diff --git a/UserTools/LAPPDLoadTXT/README.md b/UserTools/LAPPDLoadTXT/README.md new file mode 100644 index 000000000..42ba05ec1 --- /dev/null +++ b/UserTools/LAPPDLoadTXT/README.md @@ -0,0 +1,20 @@ +# LAPPDLoadTXT + +LAPPDLoadTXT + +## Data + +Describe any data formats LAPPDLoadTXT creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDLoadTXT. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDPlots/LAPPDPlots.cpp b/UserTools/LAPPDPlots/LAPPDPlots.cpp new file mode 100644 index 000000000..63341fcee --- /dev/null +++ b/UserTools/LAPPDPlots/LAPPDPlots.cpp @@ -0,0 +1,565 @@ +#include "LAPPDPlots.h" + +LAPPDPlots::LAPPDPlots() : Tool() {} + +bool LAPPDPlots::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_data->Stores["ANNIEEvent"]->Header->Get("AnnieGeometry", _geom); + + m_variables.Get("LAPPDPlotInputWaveLabel", LAPPDPlotInputWaveLabel); + LAPPDPlotsVerbosity = 0; + m_variables.Get("LAPPDPlotsVerbosity", LAPPDPlotsVerbosity); + CanvasXSubPlotNumber = 2; + m_variables.Get("CanvasXSubPlotNumber", CanvasXSubPlotNumber); + CanvasYSubPlotNumber = 3; + m_variables.Get("CanvasYSubPlotNumber", CanvasYSubPlotNumber); + CanvasTotalSubPlotNumber = CanvasXSubPlotNumber * CanvasYSubPlotNumber; + Side0EventWaveformDrawPosition = 1; + m_variables.Get("Side0EventWaveformDrawPosition", Side0EventWaveformDrawPosition); + Side1EventWaveformDrawPosition = 2; + m_variables.Get("Side1EventWaveformDrawPosition", Side1EventWaveformDrawPosition); + drawTriggerChannel = true; + m_variables.Get("drawTriggerChannel", drawTriggerChannel); + drawHighThreshold = 50; + m_variables.Get("drawHighThreshold", drawHighThreshold); + drawLowThreshold = -20; + m_variables.Get("drawLowThreshold", drawLowThreshold); + titleSize = 0.05; + m_variables.Get("titleSize", titleSize); + canvasTitleOffset = 1.05; + m_variables.Get("canvasTitleOffset", canvasTitleOffset); + canvasMargin = 0.15; + m_variables.Get("canvasMargin", canvasMargin); + CanvasWidth = 800; + m_variables.Get("CanvasWidth", CanvasWidth); + CanvasHeight = 1200; + m_variables.Get("CanvasHeight", CanvasHeight); + maxDrawEventNumber = 20; + m_variables.Get("maxDrawEventNumber", maxDrawEventNumber); + colorPalette = 112; + m_variables.Get("colorPalette", colorPalette); + DrawEventWaveform = true; + m_variables.Get("DrawEventWaveform", DrawEventWaveform); + OnlyDrawInBeamWindow = false; + m_variables.Get("OnlyDrawInBeamWindow", OnlyDrawInBeamWindow); + BeamWindowStart = 8000; + m_variables.Get("BeamWindowStart", BeamWindowStart); + BeamWindowEnd = 10000; + m_variables.Get("BeamWindowEnd", BeamWindowEnd); + Side0BinDrawPosition = 3; + m_variables.Get("Side0BinDrawPosition", Side0BinDrawPosition); + Side1BinDrawPosition = 4; + m_variables.Get("Side1BinDrawPosition", Side1BinDrawPosition); + DrawBinHist = true; + m_variables.Get("DrawBinHist", DrawBinHist); + BinHistMin = -20; + m_variables.Get("BinHistMin", BinHistMin); + BinHistMax = 50; + m_variables.Get("BinHistMax", BinHistMax); + BinHistNumber = 100; + m_variables.Get("BinHistNumber", BinHistNumber); + + printEventWaveform = 0; + m_variables.Get("printEventWaveform", printEventWaveform); + printLAPPDNumber = 2; + m_variables.Get("printLAPPDNumber", printLAPPDNumber); + printEventNumber = 10; + m_variables.Get("printEventNumber", printEventNumber); + + LoadLAPPDMap = false; + m_variables.Get("LoadLAPPDMap", LoadLAPPDMap); + + eventNumber = 0; + + f = new TFile("LAPPDPlots.root", "RECREATE"); + c = new TCanvas("c", "c", CanvasWidth, CanvasHeight); + + return true; +} + +bool LAPPDPlots::Execute() +{ + m_data->CStore.Get("LAPPDana", LAPPDana); + if (!LAPPDana) + return true; + if (eventNumber > maxDrawEventNumber) + return true; + + inBeamWindow = CheckInBeamgateWindow(); + if (OnlyDrawInBeamWindow && (inBeamWindow == 0 || inBeamWindow == -1)) + return true; + + m_data->Stores["ANNIEEvent"]->Get("ACDCReadedLAPPDID", ACDCReadedLAPPDID); + m_data->Stores["ANNIEEvent"]->Get("LAPPD_IDs", LAPPD_IDs); + + if (LoadLAPPDMap) + CanvasXSubPlotNumber = *max_element(ACDCReadedLAPPDID.begin(), ACDCReadedLAPPDID.end()) - *min_element(ACDCReadedLAPPDID.begin(), ACDCReadedLAPPDID.end()) + 1; + CanvasXSubPlotNumber = CanvasXSubPlotNumber * 2; + CanvasTotalSubPlotNumber = CanvasXSubPlotNumber * CanvasYSubPlotNumber; + + c->Clear(); + c->Divide(CanvasXSubPlotNumber, CanvasYSubPlotNumber); + + if (LAPPDPlotsVerbosity > 0) + cout << "Divide canvas into " << CanvasXSubPlotNumber << "x" << CanvasYSubPlotNumber << " subplots" << endl; + c->SetTitle("Event " + TString::Itoa(eventNumber, 10)); + c->SetName("Event" + TString::Itoa(eventNumber, 10)); + // c->cd(1); + gStyle->SetPalette(colorPalette); + + bool gotdata = m_data->Stores["ANNIEEvent"]->Get(LAPPDPlotInputWaveLabel, lappddata); + m_data->Stores["ANNIEEvent"]->Get("ACDCboards", ReadBoards); + m_data->CStore.Get("LAPPD_ID", LAPPD_ID); + if (LAPPDPlotsVerbosity > 0) + { + cout << "LAPPDPlots, got ACDCboards size = " << ReadBoards.size() << " with id = "; + for (auto i : ReadBoards) + cout << i << " "; + cout << endl; + if (LoadLAPPDMap) + { + cout << "ACDCReadedLAPPDID size = " << ACDCReadedLAPPDID.size() << ": "; + for (auto i : ACDCReadedLAPPDID) + cout << i << " "; + cout << endl; + } + } + + vector drawPositions = ReadBoards; + if (LoadLAPPDMap) + { + vector drawPositions = ACDCReadedLAPPDID; + int minID = *min_element(ACDCReadedLAPPDID.begin(), ACDCReadedLAPPDID.end()); + for (int i = 0; i < drawPositions.size(); i++) + { + drawPositions.at(i) = (drawPositions.at(i) - minID) * 2 + 1; + if (i % 2 == 1) + drawPositions.at(i) = drawPositions.at(i) + 1; + } + } + if (LAPPDPlotsVerbosity > 0) + { + cout << "drawPositions size = " << drawPositions.size() << ": "; + for (auto i : drawPositions) + cout << i << " "; + cout << endl; + } + + vector drawBoardID = ReadBoards; + + if (LoadLAPPDMap) + { + drawBoardID = ACDCReadedLAPPDID; + for (int i = 0; i < drawBoardID.size(); i++) + { + drawBoardID.at(i) = drawBoardID.at(i) * 2; + if (i % 2 == 1) + drawBoardID.at(i) = (drawBoardID.at(i) + 1); + } + } + if (LAPPDPlotsVerbosity > 0) + { + cout << "drawBoardID size = " << drawBoardID.size() << ": "; + for (auto i : drawBoardID) + cout << i << " "; + cout << endl; + cout << "LAPPDPlots execute with data " << LAPPDPlotInputWaveLabel << ", got data " << gotdata << ", data size " << lappddata.size() << ", Board IDs size " << ReadBoards.size() << ", (single) ID " << LAPPD_ID << endl; + } + + if (DrawEventWaveform) + { + vector DrawPosition = {Side0EventWaveformDrawPosition, Side1EventWaveformDrawPosition}; + if (LoadLAPPDMap) + { + if (ACDCReadedLAPPDID.size() > DrawPosition.size()) + { + DrawPosition = drawPositions; + } + } + for (int i = 0; i < drawBoardID.size(); i++) + { + const int drawPosition = DrawPosition[i]; + TPad *p = (TPad *)c->cd(drawPosition); + // c->cd(drawPosition); + p->cd(); + p->SetRightMargin(canvasMargin); + p->SetLeftMargin(canvasMargin); + p->SetTopMargin(canvasMargin); + p->SetBottomMargin(canvasMargin); + if (LAPPDPlotsVerbosity > 0) + cout << "Drawing board " << drawBoardID[i] << " at canvas position " << drawPosition << " start" << endl; + std::map>> boarddata = GetDataForBoard(drawBoardID[i]); + TString HistoName = "Event" + TString::Itoa(eventNumber, 10) + "_B" + drawBoardID[i] + "_ID"; + if (LoadLAPPDMap) + HistoName += ACDCReadedLAPPDID[i]; + // convert BGTiming to string and add to HistoName + // if (OnlyDrawInBeamWindow) + HistoName += "_BG" + TString::Itoa(BGTiming, 10); + + // DrawEventWaveform(c, DrawPosition[i], HistoName, boarddata); + // TH2D h = DrawEventWaveform(HistoName, boarddata); + + int nstrips = 30; + if (!drawTriggerChannel) + nstrips = 28; + TH2D *h = new TH2D(HistoName, HistoName, 256, 0, 256, nstrips, 0 - 0.5, nstrips - 0.5); + if (LAPPDPlotsVerbosity > 3) + cout << "Start Drawing event waveform with data size = " << boarddata.size() << endl; + std::map>>::iterator it; + for (it = boarddata.begin(); it != boarddata.end(); it++) + { + unsigned long originalChannelNo = it->first; + unsigned long channelNo = ((it->first % 1000)) % 60 + 1000; + Waveform w = it->second[0]; + Channel *ch = _geom->GetChannel(channelNo); + int stripNo = ch->GetStripNum(); + if (LAPPDPlotsVerbosity > 3) + cout << "Drawing channel " << originalChannelNo << " as channelNo " << channelNo << " strip " << stripNo << ", with sample size " << w.GetSamples()->size() << ", data at bin 0 = " << -w.GetSamples()->at(0) << endl; + if (!drawTriggerChannel) + if ((channelNo % 1000) % 30 == 5) + continue; + + for (int i = 0; i < w.GetSamples()->size(); i++) + { + h->SetBinContent(i, stripNo + 1, -w.GetSamples()->at(i)); + if (LAPPDPlotsVerbosity > 0) + { + if (i < 5) + cout << -w.GetSamples()->at(i) << ", "; + } + } + } + if (LAPPDPlotsVerbosity > 3) + cout << " Finish Drawing event waveform" << endl; + + h->SetMaximum(drawHighThreshold); + h->SetMinimum(drawLowThreshold); + h->SetStats(0); + h->GetXaxis()->SetTitle("Time (0.1ns)"); + h->GetXaxis()->SetTitleSize(titleSize); + h->GetXaxis()->SetTitleOffset(canvasTitleOffset); + h->GetYaxis()->SetTitle("Strip Number"); + h->GetYaxis()->SetTitleSize(titleSize); + h->GetYaxis()->SetTitleOffset(canvasTitleOffset); + h->GetZaxis()->SetTitle("Amplitude (mV)"); + + h->Draw("colz"); + f->cd(); + h->Write(); + if (LAPPDPlotsVerbosity > 0) + cout << "Drawing board " << drawBoardID[i] << " finished for Draw Event waveform" << endl; + } + } + + if (DrawBinHist) + { + + vector DrawPositionBinHist = {Side0BinDrawPosition, Side1BinDrawPosition}; + if (drawBoardID.size() > DrawPositionBinHist.size()) + { + DrawPositionBinHist.clear(); + for (int i = 0; i < drawBoardID.size(); i++) + { + DrawPositionBinHist.push_back(drawBoardID.at(i) + CanvasXSubPlotNumber + 1); + } + } + for (int i = 0; i < drawBoardID.size(); i++) + { + const int drawPosition = DrawPositionBinHist[i]; + TPad *p = (TPad *)c->cd(drawPosition); + // c->cd(drawPosition); + p->cd(); + p->SetRightMargin(canvasMargin); + p->SetLeftMargin(canvasMargin); + p->SetTopMargin(canvasMargin); + p->SetBottomMargin(canvasMargin); + if (LAPPDPlotsVerbosity > 0) + cout << "Drawing board " << drawBoardID[i] << " at position " << DrawPositionBinHist[i] << " start" << endl; + std::map>> boarddata = GetDataForBoard(drawBoardID[i]); + TString HistoName = "Event" + TString::Itoa(eventNumber, 10) + "_Bin_B" + drawBoardID[i] + "_ID"; + if (LoadLAPPDMap) + HistoName += ACDCReadedLAPPDID[i]; + // convert BGTiming to string and add to HistoName + // if (OnlyDrawInBeamWindow) + HistoName += "_BG" + TString::Itoa(BGTiming, 10); + + int nstrips = 30; + if (!drawTriggerChannel) + nstrips = 28; + const double BinHistMinConst = BinHistMin; + //cout<<"min is "< 3) + cout << "Start Drawing event waveform with data size = " << boarddata.size() << endl; + std::map>>::iterator it; + for (it = boarddata.begin(); it != boarddata.end(); it++) + { + + unsigned long originalChannelNo = it->first; + unsigned long channelNo = ((it->first % 1000)) % 60 + 1000; + Waveform w = it->second[0]; + Channel *ch = _geom->GetChannel(channelNo); + int stripNo = ch->GetStripNum(); + if (LAPPDPlotsVerbosity > 3) + cout << "Drawing channel " << originalChannelNo << " as channelNo" << channelNo << " strip " << stripNo << ", with sample size " << w.GetSamples()->size() << endl; + + if (!drawTriggerChannel) + if ((channelNo % 1000) % 30 == 5) + continue; + + for (int i = 0; i < w.GetSamples()->size(); i++) + { + h->Fill(-w.GetSamples()->at(i), stripNo + 1); + } + } + if (LAPPDPlotsVerbosity > 3) + cout << "Finish Drawing event waveform" << endl; + + h->SetStats(0); + h->GetXaxis()->SetTitle("Amplitude (mV)"); + h->GetXaxis()->SetTitleSize(titleSize); + h->GetXaxis()->SetTitleOffset(canvasTitleOffset); + h->GetYaxis()->SetTitle("Strip Number"); + h->GetYaxis()->SetTitleSize(titleSize); + h->GetYaxis()->SetTitleOffset(canvasTitleOffset); + h->GetZaxis()->SetTitle("Entries"); + h->Draw("colz"); + + f->cd(); + h->Write(); + if (LAPPDPlotsVerbosity > 0) + cout << "Drawing board " << drawBoardID[i] << ", i=" << i << " in " << drawBoardID.size() << " finished for Draw Bin Hist" << endl; + } + } + + c->Modified(); + c->Update(); + + if (eventNumber == 0) + c->Print("LAPPDPlots.pdf("); + else if (eventNumber == maxDrawEventNumber) + c->Print("LAPPDPlots.pdf)"); + else if (eventNumber < maxDrawEventNumber) + c->Print("LAPPDPlots.pdf"); + + // if printEventNumber was set to be zero, print all events + if (printEventWaveform && (eventNumber < printEventNumber || printEventNumber == 0)) + { + vector>> LAPPDOnSide0; + vector>> LAPPDOnSide1; + LAPPDOnSide0.resize(printLAPPDNumber); + LAPPDOnSide1.resize(printLAPPDNumber); + + vector savedBoard; + for (int i = 0; i < printLAPPDNumber * 2; i++) + { + savedBoard.push_back(0); + } + + for (int i = 0; i < drawBoardID.size(); i++) + { + // data on board i, in key as channel number + std::map>> boarddata = GetDataForBoard(drawBoardID[i]); + std::map>>::iterator it; + for (it = boarddata.begin(); it != boarddata.end(); it++) + { + unsigned long channelNo = it->first; + Waveform w = it->second[0]; + Channel *ch = _geom->GetChannel(channelNo); + int stripSide = ch->GetStripSide(); + int stripNo = ch->GetStripNum(); + int lappd_id = static_cast((channelNo - 1000) / 60); + if (lappd_id < printLAPPDNumber) + { + vector printW; + + for (int i = 0; i < w.GetSamples()->size(); i++) + { + printW.push_back(-w.GetSamples()->at(i)); + } + if (LAPPDPlotsVerbosity > 0) + cout << "LAPPD ID " << lappd_id << ", strip number " << stripNo << ", waveform size " << printW.size() << endl; + if (stripSide == 0) + LAPPDOnSide0[lappd_id][stripNo] = printW; + else if (stripSide == 1) + LAPPDOnSide1[lappd_id][stripNo] = printW; + if (LAPPDPlotsVerbosity > 0) + cout << "Saved waveform " << endl; + + savedBoard[drawBoardID[i]] = 1; + } + } + } + + // loop savedBoard, if the board was not saved, add empty vector with 256 0 in it. + for (int i = 0; i < savedBoard.size(); i++) + { + if (savedBoard[i] == 0) + { + int id = static_cast(i / 2); + + vector printW; + for (int k = 0; k < 256; k++) + { + printW.push_back(0); + } + if (i % 2 == 0) + LAPPDOnSide0[id][i] = printW; + else + LAPPDOnSide1[id][i] = printW; + } + } + + WaveformToPringSide0.push_back(LAPPDOnSide0); + WaveformToPringSide1.push_back(LAPPDOnSide1); + } + + if (printEventWaveform && printEventNumber != 0 && eventNumber == printEventNumber) + PrintWaveformToTxt(); + + eventNumber++; + return true; +} + +bool LAPPDPlots::Finalise() +{ + if (eventNumber < maxDrawEventNumber) + c->Print("LAPPDPlots.pdf)"); + c->Clear(); + c->Close(); + delete c; + + f->cd(); + f->Close(); + delete f; + + if (printEventWaveform && printEventNumber == 0) + PrintWaveformToTxt(); + + return true; +} + +std::map>> LAPPDPlots::GetDataForBoard(int boardID) +{ + + std::map>> boarddata; + for (auto &it : lappddata) + { + unsigned long channelNo = it.first; + unsigned long forStripChannelNo = ((it.first % 1000)) % 60 + 1000; + + Channel *ch = _geom->GetChannel(forStripChannelNo); + int stripSide = ch->GetStripSide(); + + int thisLAPPDID = static_cast((channelNo % 1000) / 60); + + int targetLAPPDID = static_cast(boardID / 2); + if (LoadLAPPDMap) + { + targetLAPPDID = thisLAPPDID; + } + + if (LAPPDPlotsVerbosity > 4) + cout << "GetData, channelNo: " << channelNo << ", side number" << stripSide << ", with input boardID " << boardID << ", targetLAPPDID " << targetLAPPDID << endl; + + if (static_cast((channelNo % 1000) / 60) == targetLAPPDID && stripSide == boardID % 2) + { + boarddata[channelNo] = it.second; + if (LAPPDPlotsVerbosity > 4) + cout << "insearting data for channel " << channelNo << endl; + } + } + + return boarddata; +} + +void LAPPDPlots::CleanObjects() +{ + lappddata.clear(); + ReadBoards.clear(); + LAPPD_ID = -1; + inBeamWindow = -1; + BGTiming = -1; +} + +int LAPPDPlots::CheckInBeamgateWindow() +{ + unsigned long LAPPDDataBeamgateUL; + unsigned long LAPPDDataTimeStampUL; + bool got = m_data->CStore.Get("LAPPDBeamgate_Raw", LAPPDDataBeamgateUL); + got = m_data->CStore.Get("LAPPDTimestamp_Raw", LAPPDDataTimeStampUL); + + if (got) + { + unsigned long Timing = (LAPPDDataTimeStampUL - LAPPDDataBeamgateUL) * 3.125; + BGTiming = Timing; + if (Timing > BeamWindowStart && Timing < BeamWindowEnd) + return 1; + else + return 0; + } + else + return -1; +} + +void LAPPDPlots::PrintWaveformToTxt() +{ + // print all information in WaveformToPringSide0 and WaveformToPringSide1 to two txt files + // print a header of printLAPPDNumber, printEventNumber + ofstream LAPPDPlot_side0_eventWaveform; + LAPPDPlot_side0_eventWaveform.open("LAPPDPlot_side0_eventWaveform.txt"); + LAPPDPlot_side0_eventWaveform << "printLAPPDNumber: " << printLAPPDNumber << " printEventNumber: " << printEventNumber << ", there should be " << printLAPPDNumber << " * " << printEventNumber << " * 256 lines" << endl; + for (int i = 0; i < WaveformToPringSide0.size(); i++) + { + // print i_th event + for (int j = 0; j < WaveformToPringSide0[i].size(); j++) + { + // print j_th LAPPD + // loop the map, in each line, print i, j, key, and all values in vector + for (auto it = WaveformToPringSide0[i][j].begin(); it != WaveformToPringSide0[i][j].end(); it++) + { + LAPPDPlot_side0_eventWaveform << i << " " << j << " " << it->first << " "; + for (int k = 0; k < it->second.size(); k++) + { + LAPPDPlot_side0_eventWaveform << it->second[k] << " "; + } + LAPPDPlot_side0_eventWaveform << endl; + } + } + } + LAPPDPlot_side0_eventWaveform.close(); + + ofstream LAPPDPlot_side1_eventWaveform; + LAPPDPlot_side1_eventWaveform.open("LAPPDPlot_side1_eventWaveform.txt"); + LAPPDPlot_side1_eventWaveform << "printLAPPDNumber: " << printLAPPDNumber << " printEventNumber: " << printEventNumber << ", there should be " << printLAPPDNumber << " * " << printEventNumber << " * 256 lines" << endl; + for (int i = 0; i < WaveformToPringSide1.size(); i++) + { + // print i_th event + for (int j = 0; j < WaveformToPringSide1[i].size(); j++) + { + // print j_th LAPPD + // loop the map, in each line, print i, j, key, and all values in vector + for (auto it = WaveformToPringSide1[i][j].begin(); it != WaveformToPringSide1[i][j].end(); it++) + { + LAPPDPlot_side1_eventWaveform << i << " " << j << " " << it->first << " "; + for (int k = 0; k < it->second.size(); k++) + { + LAPPDPlot_side1_eventWaveform << it->second[k] << " "; + } + LAPPDPlot_side1_eventWaveform << endl; + } + } + } +} \ No newline at end of file diff --git a/UserTools/LAPPDPlots/LAPPDPlots.h b/UserTools/LAPPDPlots/LAPPDPlots.h new file mode 100644 index 000000000..7feaf09d7 --- /dev/null +++ b/UserTools/LAPPDPlots/LAPPDPlots.h @@ -0,0 +1,117 @@ +#ifndef LAPPDPlots_H +#define LAPPDPlots_H + +#include +#include + +#include "Tool.h" + +#include "TFile.h" +#include "TH1D.h" +#include "TH2D.h" +#include "TString.h" +#include "TTree.h" +#include "LAPPDHit.h" +#include "LAPPDPulse.h" +#include "TCanvas.h" +#include "TStyle.h" +#include "TColor.h" +#include "TLegend.h" +#include "TMath.h" +#include "Detector.h" +#include "Geometry.h" + +/** + * \class LAPPDPlots + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. + * + * $Author: B.Richards $ + * $Date: 2019/05/28 10:44:00 $ + * Contact: b.richards@qmul.ac.uk + */ +class LAPPDPlots : public Tool +{ + +public: + LAPPDPlots(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + std::map>> GetDataForBoard(int boardID); + int CheckInBeamgateWindow(); + void CleanObjects(); + void PrintWaveformToTxt(); + +private: + //**************************** This tool, control variables *************************************************** + // (only used in this tool, every thing that is not an data object) + // Variables that you get from the config file + int CanvasXSubPlotNumber; + int CanvasYSubPlotNumber; // c->Divide(x, y); + int CanvasWidth; + int CanvasHeight; + int maxDrawEventNumber; + string LAPPDPlotInputWaveLabel; + int LAPPDPlotsVerbosity; + // draw event waveform + int Side0EventWaveformDrawPosition; + int Side1EventWaveformDrawPosition; + bool drawTriggerChannel; + double drawHighThreshold; + double drawLowThreshold; + double titleSize; + double canvasTitleOffset; + double canvasMargin; + int colorPalette; + bool DrawEventWaveform; + bool OnlyDrawInBeamWindow; + int BeamWindowStart; + int BeamWindowEnd; + bool DrawBinHist; + int Side0BinDrawPosition; + int Side1BinDrawPosition; + double BinHistMin; + double BinHistMax; + int BinHistNumber; + bool LoadLAPPDMap; + + + // Variables that you need in the tool + int CanvasTotalSubPlotNumber; + int inBeamWindow; + double BGTiming; + //**************************** LAPPD tool chain, control variables *************************************************** + //(Will be shared in multiple LAPPD tools to show the state of the tool chain in each loop) + // Variables that you get from the config file + + // Variables that you need in the tool + bool LAPPDana; + + //**************************** LAPPD tool chain, data variables *************************************************** + // (Will be used in multiple LAPPD tools) + // everything you get or set to Store, which means it may be used in other tools or it's from other tools + Geometry *_geom; + std::map>> lappddata; + std::vector ReadBoards; + int LAPPD_ID; + vector ACDCReadedLAPPDID; + vector LAPPD_IDs; + + //**************************** This tool, data variables *************************************************** + // (only used in this tool, every thing that is an data object) + // data variables don't need to be cleared in each loop + TCanvas *c; + TFile *f; + int eventNumber; + + bool printEventWaveform; + int printLAPPDNumber; + int printEventNumber; + + //event number, lappd_id order, map of strip number and waveform + vector>>> WaveformToPringSide0; + vector>>> WaveformToPringSide1; +}; + +#endif diff --git a/UserTools/LAPPDPlots/README.md b/UserTools/LAPPDPlots/README.md new file mode 100644 index 000000000..e00a11b82 --- /dev/null +++ b/UserTools/LAPPDPlots/README.md @@ -0,0 +1,20 @@ +# LAPPDPlots + +LAPPDPlots + +## Data + +Describe any data formats LAPPDPlots creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDPlots. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDStoreReorder/LAPPDStoreReorder.cpp b/UserTools/LAPPDStoreReorder/LAPPDStoreReorder.cpp new file mode 100644 index 000000000..9fd31430e --- /dev/null +++ b/UserTools/LAPPDStoreReorder/LAPPDStoreReorder.cpp @@ -0,0 +1,356 @@ +#include "LAPPDStoreReorder.h" + +LAPPDStoreReorder::LAPPDStoreReorder() : Tool() {} + +bool LAPPDStoreReorder::Initialise(std::string configfile, DataModel &data) +{ + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_variables.Get("ReorderInputWavLabel", InputWavLabel); + m_variables.Get("ReorderOutputWavLabel", OutputWavLabel); + m_variables.Get("DelayOffset", delayoffset); + m_variables.Get("GlobalShift", GlobalShift); + m_variables.Get("LAPPDReorderVerbosityLevel", LAPPDReorderVerbosityLevel); + m_variables.Get("NUM_VECTOR_METADATA", NUM_VECTOR_METADATA); + m_variables.Get("LAPPDchannelOffset", LAPPDchannelOffset); + bool gotGeomerty = m_data->Stores["ANNIEEvent"]->Header->Get("AnnieGeometry", _geom); + if (!gotGeomerty) + { + Log("Error: LAPPDStoreReorder: Failed to get ANNIEGeometry from the ANNIEEvent store", 0, LAPPDReorderVerbosityLevel); + return false; + } + LoadLAPPDMap = false; + m_variables.Get("LoadLAPPDMap", LoadLAPPDMap); + + return true; +} + +bool LAPPDStoreReorder::Execute() +{ + CleanDataObjects(); + if (LAPPDReorderVerbosityLevel > 3) + cout << "LAPPDStoreReorder::Execute()" << endl; + m_data->CStore.Get("LAPPDana", LAPPDana); + if (!LAPPDana) + { + if (LAPPDReorderVerbosityLevel > 3) + cout << "LAPPDStoreReorder::Execute() LAPPDana is false, returning" << endl; + return true; + } + + m_data->Stores["ANNIEEvent"]->Get("ACDCmetadata", acdcmetadata); + m_data->Stores["ANNIEEvent"]->Get(InputWavLabel, lappddata); + m_data->Stores["ANNIEEvent"]->Get("ACDCboards", NReadBoards); + m_data->Stores["ANNIEEvent"]->Get("ACDCReadedLAPPDID;", ACDCReadedLAPPDID); + + // Loop over waveforms, reorder data + DoReorder(); + // this reorder will change the channel number by adding an channel offset. + + m_data->Stores["ANNIEEvent"]->Set("TimingCounters", tcounters); + m_data->Stores["ANNIEEvent"]->Set(OutputWavLabel, reordereddata); + + if (LAPPDReorderVerbosityLevel > 1) + { + cout << "LAPPDStoreReorder, reordered data size is " << reordereddata.size() << endl; + } + + if (LAPPDReorderVerbosityLevel > 3) + cout << "LAPPDStoreReorder::Execute() done" << endl; + + return true; +} + +bool LAPPDStoreReorder::Finalise() +{ + return true; +} + +void LAPPDStoreReorder::CleanDataObjects() +{ + reordereddata.clear(); + lappddata.clear(); + acdcmetadata.clear(); + NReadBoards.clear(); + ACDCReadedLAPPDID.clear(); + tcounters.clear(); +} + +bool LAPPDStoreReorder::DoReorder() +{ + Log("LAPPDStoreReorder::DoReorder()", 1, LAPPDReorderVerbosityLevel); + // For 30 channels change to 10 + vector Smeta26; + for (int meta26 = 0; meta26 < NReadBoards.size(); meta26++) + { + Smeta26.push_back(acdcmetadata.at((meta26 * NUM_VECTOR_METADATA) + 10)); + if (LAPPDReorderVerbosityLevel > 1) + { + cout << "Metaword entry " << meta26 << " is " << Smeta26[meta26] << endl; + cout << "pushed meta26 = " << meta26 << ", with value at " << (meta26 * NUM_VECTOR_METADATA) + 10 << " is " << acdcmetadata.at((meta26 * NUM_VECTOR_METADATA) + 10) << endl; + } + } + + vector Smeta_BG; + for (int meta_bg = 0; meta_bg < NReadBoards.size(); meta_bg++) + { + unsigned short metaBG = acdcmetadata.at((meta_bg * NUM_VECTOR_METADATA) + 67); + Smeta_BG.push_back((metaBG & 0x7)); + if (LAPPDReorderVerbosityLevel > 1) + { + cout << "Metaword entry " << meta_bg << " is " << Smeta_BG[meta_bg] << endl; + cout << "pushed meta_bg = " << meta_bg << ", with value at " << (meta_bg * NUM_VECTOR_METADATA) + 67 << " is " << acdcmetadata.at((meta_bg * NUM_VECTOR_METADATA) + 67) << endl; + } + } + + std::map> Smeta_BG_map; // key is id, value is the switch bit for beamgate + + if (LAPPDReorderVerbosityLevel > 2) + cout << "REORDER TIME!!!! " << acdcmetadata.size() << " " << acdcmetadata.at(10) << " " << acdcmetadata.at(102) << " lappd data size is " << lappddata.size() << ", reordereddata size is " << reordereddata.size() << endl; + map>>::iterator itr; + for (itr = lappddata.begin(); itr != lappddata.end(); ++itr) + { + if (LAPPDReorderVerbosityLevel > 4) + cout << "reordering channelno= " << itr->first << endl; + unsigned long channelno = itr->first; + int channelHere = channelno; + channelHere = channelHere % 1000 + 1000; // hmmm the offset in geometry is 1000 + Channel *chan = _geom->GetChannel(channelHere); + int stripno = chan->GetStripNum(); + vector> Vwavs = itr->second; + if (LAPPDReorderVerbosityLevel > 5) + { + cout << "this channel has " << Vwavs.size() << " waveforms" << endl; + if (Vwavs.size() > 0) + cout << "The first waveform has " << Vwavs.at(0).GetSamples()->size() << " samples" << endl; + } + int switchbit = 0; + // Get the current board and the respective meta word + int bi = (int)channelno / 30; + int LAPPDID = static_cast((channelno % 1000) / 60); + // if (LoadLAPPDMap) + // { + int beginningBoardIDofThisLAPPDID = NReadBoards.at(std::distance(ACDCReadedLAPPDID.begin(), std::find(ACDCReadedLAPPDID.begin(), ACDCReadedLAPPDID.end(), LAPPDID))); + bi = beginningBoardIDofThisLAPPDID + bi % 2; + // }else{ + // bi = bi%2; + // } + if (LAPPDReorderVerbosityLevel > 6) + { + // print the elements in NReadBoards, print LAPPDID; + cout << "NReadBoards size is " << NReadBoards.size() << endl; + for (int i = 0; i < NReadBoards.size(); i++) + { + cout << "NReadBoards[" << i << "] = " << NReadBoards[i] << endl; + } + cout << "LAPPDID = " << LAPPDID << endl; + } + unsigned short switchword = Smeta26[std::distance(NReadBoards.begin(), std::find(NReadBoards.begin(), NReadBoards.end(), bi))]; + int switchBitBG = Smeta_BG[std::distance(NReadBoards.begin(), std::find(NReadBoards.begin(), NReadBoards.end(), bi))]; + + //check if key LAPPDID is already exist in Smeta_BG_map, if not, resize that vector to size 2 + if (Smeta_BG_map.find(LAPPDID) == Smeta_BG_map.end()) + { + Smeta_BG_map[LAPPDID] = vector(2); + } + Smeta_BG_map[LAPPDID][bi%2] = switchBitBG; + + // Smeta26, 0 or 1, so switchword is the first timestmap or the second + // Set the switchbit + switchbit = (switchword & 0x7) * 32; + // insert the stripno and switchbit into the map + + // take the last 3 bits of PSEC0 timestamp (10 in meta words), then times 2^5, shift left by 5 + switchbit += delayoffset; + + vector> Vrwav; + // loop over all Waveforms + for (int i = 0; i < Vwavs.size(); i++) + { + + Waveform bwav = Vwavs.at(i); + Waveform rwav; + Waveform rwavCorr; + + for (int j = 0; j < bwav.GetSamples()->size(); j++) + { + + if (switchbit > 255 || switchbit < 0) + switchbit = 0; + double nsamp = bwav.GetSamples()->at(switchbit); + rwav.PushSample(nsamp); + switchbit++; + } + for (int j = 0; j < rwav.GetSamples()->size(); j++) + { + int ibin = j + GlobalShift; + if (ibin > 255) + ibin = ibin - 255; + double nsamp = rwav.GetSamples()->at(ibin); + // cout << "ibin before shift is " << j << " value is " << rwav.GetSamples()->at(j) << ", after shift is " << ibin << " value is " << nsamp << endl; + rwavCorr.PushSample(nsamp); + } + + Vrwav.push_back(rwavCorr); + } + + reordereddata.insert(pair>>(LAPPDchannelOffset + channelno, Vrwav)); + if (LAPPDReorderVerbosityLevel > 4) + cout << "inserted channelno: " << LAPPDchannelOffset + channelno << ", current reorded data size is " << reordereddata.size() << ", switchword = " << switchword << ", switchbit = " << switchbit << endl; + } + if (LAPPDReorderVerbosityLevel > 4) + { + cout << "LAPPDStoreReorder, reordered data size is " << reordereddata.size() << endl; + } + + m_data->Stores["ANNIEEvent"]->Set("SwitchBitBG", Smeta_BG_map); + if(LAPPDReorderVerbosityLevel>3) + { + cout << "LAPPDStoreReorder:: insert SwitchBitBG map size is " << Smeta_BG_map.size() << endl; + } + + return true; +} + +bool LAPPDStoreReorder::ConstructTimestampsFromMeta() +{ + // get the appropriate metadata words from the meta structure + unsigned short beamgate_63_48 = acdcmetadata.at(7); + unsigned short beamgate_47_32 = acdcmetadata.at(27); + unsigned short beamgate_31_16 = acdcmetadata.at(47); + unsigned short beamgate_15_0 = acdcmetadata.at(67); + + std::bitset<16> bits_beamgate_63_48(beamgate_63_48); + std::bitset<16> bits_beamgate_47_32(beamgate_47_32); + std::bitset<16> bits_beamgate_31_16(beamgate_31_16); + std::bitset<16> bits_beamgate_15_0(beamgate_15_0); + + // cout statements + + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_beamgate_63_48: " << bits_beamgate_63_48 << std::endl; + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_beamgate_47_32: " << bits_beamgate_47_32 << std::endl; + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_beamgate_31_16: " << bits_beamgate_31_16 << std::endl; + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_beamgate_15_0: " << bits_beamgate_15_0 << std::endl; + // construct the full 64-bit counter number + unsigned long beamgate_63_0 = (static_cast(beamgate_63_48) << 48) + (static_cast(beamgate_47_32) << 32) + (static_cast(beamgate_31_16) << 16) + (static_cast(beamgate_15_0)); + // cout statement + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "beamgate combined: " << beamgate_63_0 << std::endl; + // binary digit + std::bitset<64> bits_beamgate_63_0(beamgate_63_0); + // cout the binary + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_beamgate_63_0: " << bits_beamgate_63_0 << std::endl; + + // hex manipulations + std::stringstream str_beamgate_15_0; + str_beamgate_15_0 << std::hex << (beamgate_15_0); + std::stringstream str_beamgate_31_16; + str_beamgate_31_16 << std::hex << (beamgate_31_16); + std::stringstream str_beamgate_47_32; + str_beamgate_47_32 << std::hex << (beamgate_47_32); + std::stringstream str_beamgate_63_48; + str_beamgate_63_48 << std::hex << (beamgate_63_48); + const char *hexstring = str_beamgate_63_48.str().c_str(); + unsigned int meta7_1 = (unsigned int)strtol(hexstring, NULL, 16); + hexstring = str_beamgate_47_32.str().c_str(); + unsigned int meta27_1 = (unsigned int)strtol(hexstring, NULL, 16); + hexstring = str_beamgate_31_16.str().c_str(); + unsigned int meta47_1 = (unsigned int)strtol(hexstring, NULL, 16); + hexstring = str_beamgate_15_0.str().c_str(); + unsigned int meta67_1 = (unsigned int)strtol(hexstring, NULL, 16); + meta7_1 = meta7_1 << 16; + meta47_1 = meta47_1 << 16; + + // my two beam counter values + unsigned int beamcounter = meta47_1 + meta67_1; + unsigned int beamcounterL = meta7_1 + meta27_1; + // as doubles + double largetime = (double)beamcounterL * 13.1; + double smalltime = ((double)beamcounter / 1E9) * 3.125; + + // bunch of couts + if (LAPPDReorderVerbosityLevel > 2) + { + std::cout << "meta7_1: " << meta7_1 << std::endl; + std::cout << "meta27_1: " << meta27_1 << std::endl; + std::cout << "meta47_1: " << meta47_1 << std::endl; + std::cout << "meta67_1: " << meta67_1 << std::endl; + std::cout << "beamcounter: " << beamcounter << std::endl; + std::cout << "beamcounterL: " << beamcounterL << std::endl; + std::cout << "largetime: " << largetime << std::endl; + std::cout << "smalltime: " << smalltime << std::endl; + std::cout << "eventtime: " << (largetime + smalltime) << std::endl; + std::cout << "beamgate old: " << ((beamgate_63_0 / 1E9) * 3.125) << std::endl; + } + + // Build data timestamp + unsigned short timestamp_63_48 = acdcmetadata.at(70); + unsigned short timestamp_47_32 = acdcmetadata.at(50); + unsigned short timestamp_31_16 = acdcmetadata.at(30); + unsigned short timestamp_15_0 = acdcmetadata.at(10); + std::bitset<16> bits_timestamp_63_48(timestamp_63_48); + std::bitset<16> bits_timestamp_47_32(timestamp_47_32); + std::bitset<16> bits_timestamp_31_16(timestamp_31_16); + std::bitset<16> bits_timestamp_15_0(timestamp_15_0); + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_timestamp_63_48: " << bits_timestamp_63_48 << std::endl; + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_timestamp_47_32: " << bits_timestamp_47_32 << std::endl; + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_timestamp_31_16: " << bits_timestamp_31_16 << std::endl; + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_timestamp_15_0: " << bits_timestamp_15_0 << std::endl; + // construct the full 64-bit counter number + unsigned long timestamp_63_0 = (static_cast(timestamp_63_48) << 48) + (static_cast(timestamp_47_32) << 32) + (static_cast(timestamp_31_16) << 16) + (static_cast(timestamp_15_0)); + // cout statement + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "timestamp combined: " << timestamp_63_0 << std::endl; + std::bitset<64> bits_timestamp_63_0(timestamp_63_0); + // cout the binary + if (LAPPDReorderVerbosityLevel > 2) + std::cout << "bits_timestamp_63_0: " << bits_timestamp_63_0 << std::endl; + + // hex manipulations + std::stringstream str_timestamp_63_48; + str_timestamp_63_48 << std::hex << (timestamp_63_48); + std::stringstream str_timestamp_47_32; + str_timestamp_47_32 << std::hex << (timestamp_47_32); + std::stringstream str_timestamp_31_16; + str_timestamp_31_16 << std::hex << (timestamp_31_16); + std::stringstream str_timestamp_15_0; + str_timestamp_15_0 << std::hex << (timestamp_15_0); + + hexstring = str_timestamp_63_48.str().c_str(); + unsigned int meta70_1 = (unsigned int)strtol(hexstring, NULL, 16); + hexstring = str_timestamp_47_32.str().c_str(); + unsigned int meta50_1 = (unsigned int)strtol(hexstring, NULL, 16); + hexstring = str_timestamp_31_16.str().c_str(); + unsigned int meta30_1 = (unsigned int)strtol(hexstring, NULL, 16); + hexstring = str_timestamp_15_0.str().c_str(); + unsigned int meta10_1 = (unsigned int)strtol(hexstring, NULL, 16); + meta70_1 = meta70_1 << 16; + meta30_1 = meta30_1 << 16; + + // my two beam counter values + unsigned int trigcounter = meta30_1 + meta10_1; + unsigned int trigcounterL = meta50_1 + meta70_1; + // as doubles + + tcounters.push_back(beamcounter); + tcounters.push_back(beamcounterL); + tcounters.push_back(trigcounter); + tcounters.push_back(trigcounterL); + + return true; +} diff --git a/UserTools/LAPPDStoreReorder/LAPPDStoreReorder.h b/UserTools/LAPPDStoreReorder/LAPPDStoreReorder.h new file mode 100644 index 000000000..746ab5657 --- /dev/null +++ b/UserTools/LAPPDStoreReorder/LAPPDStoreReorder.h @@ -0,0 +1,75 @@ +#ifndef LAPPDStoreReorder_H +#define LAPPDStoreReorder_H + +#include +#include + +#include "Tool.h" +#include +#include "Geometry.h" + + +using namespace std; +/** +* \class LAPPDStoreReorder +* +* Do LAPPD data read in from BoostStore +* +* $Author: $ +* $Date: $ +* Contact: +*/ +class LAPPDStoreReorder: public Tool { + + + public: + + LAPPDStoreReorder(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + +void CleanDataObjects(); +bool DoReorder(); +bool ConstructTimestampsFromMeta(); + private: + + //**************************** This tool, control variables *************************************************** + // (only used in this tool, every thing that is not an data object) + // Variables that you get from the config file + int LAPPDReorderVerbosityLevel; + int NUM_VECTOR_METADATA; + int delayoffset; + int GlobalShift; + bool LoadLAPPDMap; + // Variables that you need in the tool + + //**************************** LAPPD tool chain, control variables *************************************************** + //(Will be shared in multiple LAPPD tools to show the state of the tool chain in each loop) + // Variables that you get from the config file + int LAPPDchannelOffset; + string InputWavLabel; + string OutputWavLabel; + + // Variables that you need in the tool + bool LAPPDana; + + //**************************** LAPPD tool chain, data variables *************************************************** + // (Will be used in multiple LAPPD tools) + // everything you get or set to Store, which means it may be used in other tools or it's from other tools + std::map>> reordereddata; + std::map>> lappddata; + vector acdcmetadata; + vector NReadBoards; + vector ACDCReadedLAPPDID; + vector tcounters; + + //**************************** This tool, data variables *************************************************** + // (only used in this tool, every thing that is an data object) + // data variables don't need to be cleared in each loop + Geometry* _geom; + +}; + + +#endif diff --git a/UserTools/LAPPDStoreReorder/README.md b/UserTools/LAPPDStoreReorder/README.md new file mode 100644 index 000000000..2e088501d --- /dev/null +++ b/UserTools/LAPPDStoreReorder/README.md @@ -0,0 +1,20 @@ +# LAPPDStoreReorder + +LAPPDStoreReorder + +## Data + +Describe any data formats LAPPDStoreReorder creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDStoreReorder. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDThresReco/LAPPDThresReco.cpp b/UserTools/LAPPDThresReco/LAPPDThresReco.cpp new file mode 100644 index 000000000..7feceb1c1 --- /dev/null +++ b/UserTools/LAPPDThresReco/LAPPDThresReco.cpp @@ -0,0 +1,999 @@ +#include "LAPPDThresReco.h" + +LAPPDThresReco::LAPPDThresReco() : Tool() {} + +bool LAPPDThresReco::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + // Control variables + // Control variables used in this tool + // Control variables that you get from the config file, for this tool + LAPPDThresRecoVerbosity = 0; + m_variables.Get("LAPPDThresRecoVerbosity", LAPPDThresRecoVerbosity); + threshold = 15; + m_variables.Get("threshold", threshold); + minPulseWidth = 3; // number of bins require for a pulse + m_variables.Get("minPulseWidth", minPulseWidth); + printHitsTXT = 1; // 1 print hit information to a txt file + m_variables.Get("printHitsTXT", printHitsTXT); + useMaxTime = true; // use the max amplitude time of the pulse as the time of the hit + m_variables.Get("useMaxTime", useMaxTime); + signalSpeedOnStrip = 0.567; // speed of the signal on the strip in fraction of speed of light, 0.567 was previous measured data + m_variables.Get("signalSpeedOnStrip", signalSpeedOnStrip); + triggerBoardDelay = 0; // arbitrary added to include the electronic delay between two ACDC boards + m_variables.Get("triggerBoardDelay", triggerBoardDelay); + savePositionOnStrip = true; // save the position of the hit on the strip, for event display purpose + m_variables.Get("savePositionOnStrip", savePositionOnStrip); + useRange = -1; // use the pulse time for hit time, rather than the reconstructed hit time. -1 averaged peak time, 0 low range, 1 high range + m_variables.Get("useRange", useRange); + loadPrintMRDinfo = true; // print MRD track information + m_variables.Get("loadPrintMRDinfo", loadPrintMRDinfo); + pulseFollowTimeStandard = 20; // 20 bins (2 ns) integral after each pulse + m_variables.Get("pulseFollowTimeStandard", pulseFollowTimeStandard); + baselineStart = 50; // start time for independent baseline calculation, 5ns + m_variables.Get("baselineStart", baselineStart); + baselineEnd = 100; + m_variables.Get("baselineEnd", baselineEnd); + // Control variables in this tool, initialized in this tool + eventNumber = 0; + LoadLAPPDMapInfo = false; + m_variables.Get("LoadLAPPDMapInfo", LoadLAPPDMapInfo); + + // Global Control variables that you get from the config file + ThresRecoInputWaveLabel = "LAPPDWave"; + m_variables.Get("ThresRecoInputWaveLabel", ThresRecoInputWaveLabel); + ThresRecoOutputPulseLabel = "LAPPDPulse"; + m_variables.Get("ThresRecoOutputPulseLabel", ThresRecoOutputPulseLabel); + ThresRecoOutputHitLabel = "LAPPDHit"; + m_variables.Get("ThresRecoOutputHitLabel", ThresRecoOutputHitLabel); + // Global control variables/objects that you get from other tools + m_data->Stores["ANNIEEvent"]->Header->Get("AnnieGeometry", _geom); + if (LAPPDThresRecoVerbosity > 0) + cout << "LAPPDThresReco: Geometry loaded as AnnieGeometry from Store [ANNIEEvent]" << endl; + + // Data variables + // Data variables you get from other tools (it not initialized in execute) + + // Data variables you use in this tool + if (printHitsTXT) + { + // recreate myfile + myfile.open("LAPPDThresRecoHits.txt"); + myfile << "eventNumber" + << "\t" + << "thisEventHitNumber" + << "\t" + << "stripno" + << "\t" + << "ParallelToStripPos" + << "\t" + << "TransverseToStripPos" + << "\t" + << "HitArivTime" + << "\t" + << "HitAmp" + << "\t" + << "Pulse1LastTime" + << "\t" + << "Pulse2LastTime" + << "\t" + << "Pulse1StartTime" + << "\t" + << "Pulse2StartTime" << endl; + } + if (loadPrintMRDinfo) + { + mrdfile.open("LAPPDThresRecoMRDinfo.txt"); + mrdfile << "eventNumber" + << "\t" + << "trackNumber" + << "\t" + << "trackAngle" + << "\t" + << "trackAngleError" + << "\t" + << "penetrationDepth" + << "\t" + << "trackLength" + << "\t" + << "entryPointRadius" + << "\t" + << "energyLoss" + << "\t" + << "energyLossError" + << "\t" + << "trackStartX" + << "\t" + << "trackStartY" + << "\t" + << "trackStartZ" + << "\t" + << "trackStopX" + << "\t" + << "trackStopY" + << "\t" + << "trackStopZ" + << "\t" + << "trackSide" + << "\t" + << "trackStop" + << "\t" + << "trackThrough" + << "\t" + << "fHtrackFitChi2" + << "\t" + << "fHtrackFitCov" + << "\t" + << "fVtrackFitChi2" + << "\t" + << "fVtrackFitCov" + << "\t" + << "fHtrackOrigin" + << "\t" + << "fHtrackOriginError" + << "\t" + << "fHtrackGradient" + << "\t" + << "fHtrackGradientError" + << "\t" + << "fVtrackOrigin" + << "\t" + << "fVtrackOriginError" + << "\t" + << "fVtrackGradient" + << "\t" + << "fVtrackGradientError" + << "\t" + << "particlePID" << endl; + } + + return true; +} + +bool LAPPDThresReco::Execute() +{ + CleanDataObjects(); + + m_data->CStore.Get("LAPPDana", LAPPDana); + if (!LAPPDana) + return true; + + if (LoadLAPPDMapInfo) + { + m_data->Stores["ANNIEEvent"]->Get("LAPPD_IDs", LAPPD_IDs); + // print + /*cout << "ThresReco got LAPPD_IDs: "; + for (int i = 0; i < LAPPD_IDs.size(); i++) + { + cout << LAPPD_IDs.at(i) << " "; + } + cout << endl;*/ + } + else + { + // get current LAPPD_ID + m_data->CStore.Get("LAPPD_ID", LAPPD_ID); + } + + // get the input LAPPD Data waveform; + m_data->Stores["ANNIEEvent"]->Get(ThresRecoInputWaveLabel, lappdData); + + if (LAPPDThresRecoVerbosity > 1) + cout << "Start WaveformMaximaFinding" << endl; + WaveformMaximaFinding(); // find the maxima of the waveforms + if (LAPPDThresRecoVerbosity > 1) + cout << "Start FillLAPPDPulse" << endl; + FillLAPPDPulse(); // find pulses + if (LAPPDThresRecoVerbosity > 1) + cout << "Start FillLAPPDHit" << endl; + FillLAPPDHit(); // find hits + if (LAPPDThresRecoVerbosity > 1) + cout << "Reco Finished, start filling" << endl; + + m_data->Stores["ANNIEEvent"]->Set(ThresRecoOutputPulseLabel, lappdPulses); + m_data->Stores["ANNIEEvent"]->Set(ThresRecoOutputHitLabel, lappdHits); + m_data->Stores["ANNIEEvent"]->Set("waveformMax", waveformMax); + m_data->Stores["ANNIEEvent"]->Set("waveformRMS", waveformRMS); + m_data->Stores["ANNIEEvent"]->Set("waveformMaxLast", waveformMaxLast); + m_data->Stores["ANNIEEvent"]->Set("waveformMaxNearing", waveformMaxNearing); + m_data->Stores["ANNIEEvent"]->Set("waveformMaxTimeBin", waveformMaxTimeBin); + eventNumber++; // operation in this loop finished, increase the event number + + if (LAPPDThresRecoVerbosity > 1) + cout << "Filling finished, printing to txt" << endl; + if (printHitsTXT) + PrintHitsToTXT(); // print hits to a txt file + if (loadPrintMRDinfo) + { + bool gotMRDdata = m_data->CStore.Get("MrdTimeClusters", MrdTimeClusters); + if (gotMRDdata) + PrintMRDinfoToTXT(); + } + + return true; +} + +void LAPPDThresReco::CleanDataObjects() +{ + + lappdData.clear(); + lappdPulses.clear(); + lappdHits.clear(); + MrdTimeClusters.clear(); + waveformRMS.clear(); + waveformMax.clear(); + waveformMaxLast.clear(); + waveformMaxNearing.clear(); + + LAPPD_ID = -9999; + LAPPDana = false; + pulseFollowTime = pulseFollowTimeStandard; +} + +void LAPPDThresReco::FillLAPPDPulse() +{ + + // loop over the data and fine pulses + std::map>>::iterator it; + for (it = lappdData.begin(); it != lappdData.end(); it++) + { + + // get the waveforms from channel number + unsigned long channel = it->first; + channel = channel % 1000 + 1000; + if ((channel % 1000) % 30 == 5) + continue; + Waveform waveforms = it->second.at(0); + vector wav = *waveforms.GetSamples(); + vector wave = wav; + if (wave.size() != 256) + { + cout << "FillLAPPDPulse: Found a bug waveform at channel " << channel << ", size is " << wave.size() << endl; + continue; + } + if (LAPPDThresRecoVerbosity > 2) + cout << "FillLAPPDPulse: Found waveform at channel " << channel << ", size is " << wave.size() << endl; + // flip the waveform, so that the signal is positive + for (int i = 0; i < wave.size(); i++) + { + wave.at(i) = -wave.at(i); + } + + if (LoadLAPPDMapInfo) + LAPPD_ID = static_cast((channel - 1000) / 60); + + // cout << "FillLAPPDPulse LAPPD_ID: " << LAPPD_ID << " channel: " << channel << endl; + + // for this channel, find the pulses + vector pulses = FindPulses(wave, LAPPD_ID, channel); + + Channel *chan = _geom->GetChannel(channel); + int stripno = chan->GetStripNum(); + int stripSide = chan->GetStripSide(); + + // check, in lappdPulses, is there an element with the strip no, if not, create one vector with lenth 2, set the pulses to element with index stripSide + if (lappdPulses.find(stripno) == lappdPulses.end()) + { + vector> stripPulses; + stripPulses.resize(2); + stripPulses.at(stripSide) = pulses; + lappdPulses[stripno] = stripPulses; + } + else + { + lappdPulses[stripno].at(stripSide) = pulses; + } + } +} + +void LAPPDThresReco::FillLAPPDHit() +{ + int numberOfHits = 0; + std::map>>::iterator it2; + for (it2 = lappdPulses.begin(); it2 != lappdPulses.end(); it2++) + { + unsigned long stripno = it2->first; + vector> pulses = it2->second; + vector lHits = FindHit(pulses); + lappdHits[stripno] = lHits; + numberOfHits += lHits.size(); + } + if (LAPPDThresRecoVerbosity > 1) + cout << "LAPPDThresReco found hits: " << numberOfHits << endl; +} + +void LAPPDThresReco::PrintHitsToTXT() +{ + int thisEventHitNumber = 0; + + // print all hits in this event to a txt file, column was separated by tab + // print: event number, hit number, hit strip number, hit loacl parallel position x, hit local transverse position y, hit time, hit amplitude + std::map>::iterator it3; + for (it3 = lappdHits.begin(); it3 != lappdHits.end(); it3++) + { + unsigned long stripno = it3->first; + vector lHits = it3->second; + for (int i = 0; i < lHits.size(); i++) + { + LAPPDHit hit = lHits.at(i); + vector positionOnLAPPD = hit.GetLocalPosition(); + double pulse1StartTime = hit.GetPulse1StartTime(); + double pulse2StartTime = hit.GetPulse2StartTime(); + double pulse1LastTime = hit.GetPulse1LastTime(); + double pulse2LastTime = hit.GetPulse2LastTime(); + // print the data in this order:myfile<LoadMRDTrackReco(i); + if (LAPPDThresRecoVerbosity > 1) + cout << "LAPPDThresReco found MRD tracks: " << fNumClusterTracks << endl; + for (int i = 0; i < fMRDTrackAngle.size(); i++) + { + mrdfile << eventNumber << "\t" << i << "\t" << fMRDTrackAngle.at(i) << "\t" << fMRDTrackAngleError.at(i) << "\t" << fMRDPenetrationDepth.at(i) << "\t" << fMRDTrackLength.at(i) << "\t" << fMRDEntryPointRadius.at(i) << "\t" << fMRDEnergyLoss.at(i) << "\t" << fMRDEnergyLossError.at(i) << "\t" << fMRDTrackStartX.at(i) << "\t" << fMRDTrackStartY.at(i) << "\t" << fMRDTrackStartZ.at(i) << "\t" << fMRDTrackStopX.at(i) << "\t" << fMRDTrackStopY.at(i) << "\t" << fMRDTrackStopZ.at(i) << "\t" << fMRDSide.at(i) << "\t" << fMRDStop.at(i) << "\t" << fMRDThrough.at(i) << "\t" << fHtrackFitChi2.at(i) << "\t" << fHtrackFitCov.at(i) << "\t" << fVtrackFitChi2.at(i) << "\t" << fVtrackFitCov.at(i) << "\t" << fHtrackOrigin.at(i) << "\t" << fHtrackOriginError.at(i) << "\t" << fHtrackGradient.at(i) << "\t" << fHtrackGradientError.at(i) << "\t" << fVtrackOrigin.at(i) << "\t" << fVtrackOriginError.at(i) << "\t" << fVtrackGradient.at(i) << "\t" << fVtrackGradientError.at(i) << "\t" << fparticlePID.at(i) << endl; + } +} + +bool LAPPDThresReco::Finalise() +{ + + // close txt file + myfile.close(); + mrdfile.close(); + + return true; +} + +vector LAPPDThresReco::FindPulses(vector wave, int LAPPD_ID, int channel) +{ + // the wave pass to here must be all positive, not the default negative signals + std::vector pulses; + + // loop the waveform, find the pulses with amplitude larger than threshold and last for bin number > minPulseWidth + bool inPulse = false; + double currentSig = threshold; + + int pulseStart = 0; + int pulseSize = 0; // number of bins of the pulse + double peakBin = 0; // which bin is the peak + double peakAmp = 0; // the peak amplitude + double Q = 0; + + vector binNumbers; + vector amplitudes; + + double baselineGet = 0; + for (int i = baselineStart; i < baselineEnd; i++) + { + baselineGet += wave.at(i); + } + baselineGet = baselineGet / (baselineEnd - baselineStart); + + for (int i = 1; i < wave.size(); i++) + { + currentSig = wave.at(i); + if (wave.at(i) > threshold) + { // if the signal is larger than threshold + if (!inPulse) + { + inPulse = true; + pulseStart = i - 1; + pulseSize = 1; + peakBin = i; + peakAmp = currentSig; + Q = currentSig / 50000. * (1e-10); // same as LAPPDFindPeak + } + else + { + if (inPulse) + { + pulseSize++; + if (currentSig > peakAmp) + { + peakAmp = currentSig; + peakBin = i; + } + Q += currentSig / 50000. * (1e-10); + } + } + binNumbers.push_back(static_cast(i)); + amplitudes.push_back(currentSig); + } + else + { // if the signal is smaller than threshold + if (inPulse) + { + inPulse = false; // exit the pulse + if (pulseSize > minPulseWidth) + { // if the pulse is long enough + double peakBinGaus = GaussianFit(binNumbers, amplitudes); + // use a linear interpolation to find the half peak time, from wave.at(pulseStart) to wave.at(peakBin), divide each bin 0.1 ns to 100 parts, 1ps per bin,find the bin number that the amplitude is half of the peakAmp + double startBin = pulseStart; + if (pulseStart > 10) + startBin = pulseStart - 10; + else + startBin = 1; + double targetAmp = peakAmp / 2; + int stopBin = wave.size() - 1; + if (peakBin < wave.size() - 1) + stopBin = peakBin; + + double halfPeakBin = startBin; + for (int j = startBin; j < stopBin; j++) + { + halfPeakBin = j - 1; + if (wave.at(j) > targetAmp) + { + break; + } + } + int halfPeak_ps = 0; + double halfHeightAmp = 0; + for (int j = 1; j < 100; j++) + { + double interpAmp = wave.at(halfPeakBin) + (wave.at(halfPeakBin + 1) - wave.at(halfPeakBin)) * (j / 100.0); + if (interpAmp > targetAmp) + { + double prevInterAmp = wave.at(halfPeakBin) + (wave.at(halfPeakBin + 1) - wave.at(halfPeakBin)) * ((j - 1) / 100.0); + if (abs(interpAmp - targetAmp) < abs(prevInterAmp - targetAmp)) + { + halfPeak_ps = j; + halfHeightAmp = interpAmp; + break; + } + else + { + halfPeak_ps = j - 1; + halfHeightAmp = prevInterAmp; + break; + } + } + } + if (LAPPDThresRecoVerbosity > 0) + cout << "LAPPDThresReco: thres: " << threshold << " thres Start: " << pulseStart << " pulseStart Amp: " << wave.at(pulseStart) << " halfPeakBin: " << halfPeakBin << " halfPeakBin Amp: " << wave.at(halfPeakBin) << " peakBin: " << peakBin << " peakBin Amp: " << wave.at(peakBin) << " half height time: " << (halfPeakBin * (25. / 256.) + halfPeak_ps * 0.001 * 25 / 25.6) << " halfHeightAmp: " << halfHeightAmp << endl; + + // from the peak bin, find half end time + double halfEndBin = peakBin; + for (int j = peakBin; j < wave.size() - 1; j++) + { + halfEndBin = j - 1; + if (wave.at(j) < targetAmp) + { + break; + } + } + int halfEnd_ps = 0; + for (int j = 1; j < 100; j++) + { + double interpAmp = wave.at(halfEndBin) + (wave.at(halfEndBin + 1) - wave.at(halfEndBin)) * (j / 100.0); + if (interpAmp < targetAmp) + { + double prevInterAmp = wave.at(halfEndBin) + (wave.at(halfEndBin + 1) - wave.at(halfEndBin)) * ((j - 1) / 100.0); + if (abs(interpAmp - targetAmp) < abs(prevInterAmp - targetAmp)) + { + halfEnd_ps = j; + break; + } + else + { + halfEnd_ps = j - 1; + break; + } + } + } + + int startFollowTime = i; + int stopFollowTime = i + static_cast(pulseFollowTime); + if (stopFollowTime > 256) + { + stopFollowTime = 256; + pulseFollowTime = 256 - i; + } + + double integralFollowCharge = 0; + for (int j = startFollowTime; j < stopFollowTime; j++) + { + integralFollowCharge += wave.at(j); + } + + if (LAPPDThresRecoVerbosity > 1) + cout << "inserting pulse on LAPPD ID =" << LAPPD_ID << " at time: " << peakBin * (25. / 256.) << "(" << peakBinGaus << ") with peakAmp: " << peakAmp << " from " << pulseStart << " to " << pulseStart + pulseSize << endl; + if (useMaxTime) + { + LAPPDPulse thisPulse(LAPPD_ID, channel, peakBin * (25. / 256.), Q, peakAmp, pulseStart, pulseStart + pulseSize); + thisPulse.SetHalfHeightTime(halfPeakBin * (25. / 256.) + halfPeak_ps * 0.001 * 25 / 25.6); + thisPulse.SetHalfEndTime(halfEndBin * (25. / 256.) + halfEnd_ps * 0.001 * 25 / 25.6); + thisPulse.SetBaseline(baselineGet); + thisPulse.SetPulseFollowTime(pulseFollowTime); + thisPulse.SetPulseFollowCharge(integralFollowCharge); + pulses.push_back(thisPulse); + } + else + { + LAPPDPulse thisPulse(LAPPD_ID, channel, peakBinGaus * (25. / 256.), Q, peakAmp, pulseStart, pulseStart + pulseSize); + thisPulse.SetHalfHeightTime(halfPeakBin * (25. / 256.) + halfPeak_ps * 0.001 * 25 / 25.6); + thisPulse.SetHalfEndTime(halfEndBin * (25. / 256.) + halfEnd_ps * 0.001 * 25 / 25.6); + thisPulse.SetBaseline(baselineGet); + thisPulse.SetPulseFollowTime(pulseFollowTime); + thisPulse.SetPulseFollowCharge(integralFollowCharge); + pulses.push_back(thisPulse); + } + // tube ID: LAPPD_ID + // channel: this channel + // peakBin: the bin number of the peak in the 256 bins (use 256 bins for 25 ns, might be wrong) + // Q: charge of the pulse + // peakAmp: the peak amplitude + // pulseStart: the bin number of the start of the pulse + // pulseStart+pulseSize: the bin number of the end of the pulse + + // clean the bin numbers and amplitudes vectors + binNumbers.clear(); + amplitudes.clear(); + } + else + { + pulseStart = 0; + pulseSize = 0; + peakAmp = currentSig; + Q = 0; + } + } + } + } + return pulses; +} + +vector LAPPDThresReco::FindHit(vector> pulses) +{ + vector lHits; + + // loop the pulses, find the pairs of pulses with the same strip number and different side, then do the reco + vector side0 = pulses.at(0); + vector side1 = pulses.at(1); + if (side0.size() == 0 || side1.size() == 0) + return lHits; + + // use the vector with less number of pulse to do reco, incase some noise pulses are inserted + if (side0.size() < side1.size()) + { // if side 0 has fewer pulses + for (int i = 0; i < side0.size(); i++) + { + if (side1.size() == 0) + break; + LAPPDPulse pulse0; + LAPPDPulse pulse1; + pulse0 = side0.at(i); + int bestMatchIndex = -1; + double prob = 0; + for (int j = 0; j < side1.size(); j++) + { + pulse1 = side1.at(j); + // if the higher pulse peak amplitude is larger than 50% of the lower one, don't match + if ((pulse0.GetPeak() < pulse1.GetPeak() * 0.5) || (pulse0.GetPeak() * 0.5 > pulse1.GetPeak())) + continue; + + // if the peak time of the pulse is 2ns away from the peak time of the other pulse, don't match + if (abs(pulse1.GetTime() - pulse0.GetTime()) > 20) + continue; + + // just use a simple inverse product as the prob, the pulse finding is very rough anyway + double thisProb = 1 / (abs(pulse1.GetTime() - pulse0.GetTime()) * abs(pulse1.GetPeak() - pulse0.GetPeak())); + if (thisProb > prob) + { + prob = thisProb; + bestMatchIndex = j; + } + } + // if found the bestMatch, pair to make a hit, if not, skip + if (bestMatchIndex != -1) + { + pulse1 = side1.at(bestMatchIndex); + pulse0 = side0.at(i); + LAPPDHit hit = MakeHit(pulse0, pulse1); + lHits.push_back(hit); + side1.erase(side1.begin() + bestMatchIndex); + } + } + } + else + { // if side 1 has fewer pulses + for (int i = 0; i < side1.size(); i++) + { + if (side0.size() == 0) + break; + LAPPDPulse pulse0; + LAPPDPulse pulse1; + pulse1 = side1.at(i); + int bestMatchIndex = -1; + double prob = 0; + for (int j = 0; j < side0.size(); j++) + { + pulse0 = side0.at(j); + // if the higher pulse peak amplitude is larger than 50% of the lower one, don't match + if ((pulse0.GetPeak() < pulse1.GetPeak() * 0.5) || (pulse0.GetPeak() * 0.5 > pulse1.GetPeak())) + continue; + + // if the peak time of the pulse is 2ns away from the peak time of the other pulse, don't match + if (abs(pulse1.GetTime() - pulse0.GetTime()) > 20) + continue; + + // just use a simple inverse product as the prob, the pulse finding is very rough anyway + double thisProb = 1 / (abs(pulse1.GetTime() - pulse0.GetTime()) * abs(pulse1.GetPeak() - pulse0.GetPeak())); + if (thisProb > prob) + { + prob = thisProb; + bestMatchIndex = j; + } + } + // if found the bestMatch, pair to make a hit, if not, skip + if (bestMatchIndex != -1) + { + pulse0 = side0.at(bestMatchIndex); + pulse1 = side1.at(i); + LAPPDHit hit = MakeHit(pulse0, pulse1); + lHits.push_back(hit); + side0.erase(side0.begin() + bestMatchIndex); + } + } + } + + return lHits; +} + +LAPPDHit LAPPDThresReco::MakeHit(LAPPDPulse pulse0, LAPPDPulse pulse1) +{ + // Always use pulse1 - pulse0 + double deltaT = pulse1.GetTime() - pulse0.GetTime(); + double averageAmp = (pulse1.GetPeak() + pulse0.GetPeak()) / 2; + double averageQ = (pulse1.GetCharge() + pulse0.GetCharge()) / 2; + + if (LAPPDThresRecoVerbosity > 1) + { + cout << "Making Hit: " << endl; + cout << "Pulse0: " << endl; + cout << "Channel = " << pulse0.GetChannelID() << endl; + pulse0.Print(); + cout << "Pulse1: " << endl; + cout << "Channel = " << pulse1.GetChannelID() << endl; + pulse1.Print(); + cout << "DeltaT: " << deltaT << endl; + cout << "AverageAmp: " << averageAmp << endl; + cout << "AverageQ: " << averageQ << endl; + } + Channel *chan0 = _geom->GetChannel(pulse0.GetChannelID()); + int stripno0 = chan0->GetStripNum(); + Channel *chan1 = _geom->GetChannel(pulse1.GetChannelID()); + int stripno1 = chan1->GetStripNum(); + if (stripno0 != stripno1) + { + if (LAPPDThresRecoVerbosity > 1) + cout << "Error: the two pulses are not on the same strip!" << endl; + LAPPDHit hit; + return hit; + } + else + { + // double stripWidth = 4.62+2.29; //mm + // double LAPPDEdgeWidth = 14.40s; //mm + // double transversePos = LAPPDEdgeWidth + stripWidth*(stripno0-0.5); + + double stripWidth = 4.62 + 2.29; // mm + double LAPPDEdgeWidth = 14.40 + 4.62 / 2; // mm + double transversePos = LAPPDEdgeWidth + stripWidth * (stripno0); + + // use the center position of the strip in mm + if (LAPPDThresRecoVerbosity > 1) + { + cout << "making hit from pulse0 on channel " << pulse0.GetChannelID() << ", strip " << stripno0 << endl; + cout << "making hit from pulse1 on channel " << pulse1.GetChannelID() << ", strip " << stripno1 << endl; + cout << "transversePos: " << transversePos << endl; + } + double t0 = pulse0.GetTime() + triggerBoardDelay / 169.982; + double t1 = pulse1.GetTime(); + + // double parallelPos = (t0 - t1 + 1.14555)*0.5 *signalSpeedOnStrip * 100; + double parallelPos = (t0 - t1 + 1.37724) * 0.5 * signalSpeedOnStrip * 100; + // position from the edge of the start of pulse0 (side 0) in mm + + double averageTime = (t0 + t1) * 0.5; + double averageTimeLow = (pulse0.GetLowRange() + pulse1.GetLowRange()) * 0.5; + double averageTimeHi = (pulse0.GetHiRange() + pulse1.GetHiRange()) * 0.5; + + double arrivalTime = t0 - (t0 - t1 + 1) * 0.5; + + if (LAPPDThresRecoVerbosity > 1) + cout << "Position on LAPPD: " << parallelPos << " " << transversePos << endl; + + vector positionOnLAPPD = {parallelPos, transversePos}; + vector positionInTank = {0 + transversePos / 1000 - 0.1, -0.2255, 2.951}; // need to get this from the geometry + if (savePositionOnStrip) + { + if (parallelPos < 100 && parallelPos > -100) + positionInTank[1] = -0.2255 + parallelPos / 1000; + } + + int tubeID = pulse0.GetTubeId(); + double pulse1LastTime = pulse0.GetHiRange() - pulse0.GetLowRange(); + double pulse2LastTime = pulse1.GetHiRange() - pulse1.GetLowRange(); + double pulse1StartTime = pulse0.GetLowRange(); + double pulse2StartTime = pulse1.GetLowRange(); + // print tubeID + if (LAPPDThresRecoVerbosity > 1) + { + cout << "TubeID: " << tubeID << endl; + cout << "average charge is " << averageQ << ", q/amplitude is " << averageQ / averageAmp << endl; + cout << "average amplitude is " << averageAmp << ", amplitude/7 is " << averageAmp / 7 << endl; + } + if (useRange == -1) + { + LAPPDHit hit(tubeID, averageTime, averageAmp, positionInTank, positionOnLAPPD, pulse1LastTime, pulse2LastTime, pulse1StartTime, pulse2StartTime, pulse0, pulse1); + return hit; + } + else if (useRange == 0) + { + LAPPDHit hit(tubeID, averageTimeLow, averageAmp, positionInTank, positionOnLAPPD, pulse1LastTime, pulse2LastTime, pulse1StartTime, pulse2StartTime, pulse0, pulse1); + return hit; + } + else if (useRange == 1) + { + LAPPDHit hit(tubeID, averageTimeHi, averageAmp, positionInTank, positionOnLAPPD, pulse1LastTime, pulse2LastTime, pulse1StartTime, pulse2StartTime, pulse0, pulse1); + return hit; + } + else + { + cout << "Error: useRange should be -1, 0 or 1" << endl; + return LAPPDHit(); + } + + //********************* + // NOTE: we are actually using the average AMPLITUDE here, rather than the charge + //********************* + + // return hit; + } +} + +double LAPPDThresReco::GaussianFit(const vector &xData, const vector &yData) +{ + TGraph graph(xData.size(), &xData[0], &yData[0]); + TF1 f("gaus", "gaus", xData.front(), xData.back()); + graph.Fit(&f, "Q"); // "Q" for quiet mode, no output + return f.GetParameter(1); // 返回高斯拟合的峰值位置 +} + +void LAPPDThresReco::CleanMRDRecoInfo() +{ + fMRDTrackAngle.clear(); + fMRDTrackAngleError.clear(); + fMRDPenetrationDepth.clear(); + fMRDTrackLength.clear(); + fMRDEntryPointRadius.clear(); + fMRDEnergyLoss.clear(); + fMRDEnergyLossError.clear(); + fMRDTrackStartX.clear(); + fMRDTrackStartY.clear(); + fMRDTrackStartZ.clear(); + fMRDTrackStopX.clear(); + fMRDTrackStopY.clear(); + fMRDTrackStopZ.clear(); + fMRDSide.clear(); + fMRDStop.clear(); + fMRDThrough.clear(); + fHtrackFitChi2.clear(); + fHtrackFitCov.clear(); + fVtrackFitChi2.clear(); + fVtrackFitCov.clear(); + fHtrackOrigin.clear(); + fHtrackOriginError.clear(); + fHtrackGradient.clear(); + fHtrackGradientError.clear(); + fVtrackOrigin.clear(); + fVtrackOriginError.clear(); + fVtrackGradient.clear(); + fVtrackGradientError.clear(); + fparticlePID.clear(); +} + +int LAPPDThresReco::LoadMRDTrackReco(int SubEventID) +{ + + // Check for valid track criteria + m_data->Stores["MRDTracks"]->Get("MRDTracks", theMrdTracks); + m_data->Stores["MRDTracks"]->Get("NumMrdTracks", numtracksinev); + // Loop over reconstructed tracks + + Position StartVertex; + Position StopVertex; + double TrackLength = -9999; + double TrackAngle = -9999; + double TrackAngleError = -9999; + double PenetrationDepth = -9999; + Position MrdEntryPoint; + double EnergyLoss = -9999; // in MeV + double EnergyLossError = -9999; + double EntryPointRadius = -9999; + bool IsMrdPenetrating; + bool IsMrdStopped; + bool IsMrdSideExit; + double HtrackFitChi2 = -9999; + double HtrackFitCov = -9999; + double VtrackFitChi2 = -9999; + double VtrackFitCov = -9999; + double HtrackOrigin = -9999; + double HtrackOriginError = -9999; + double HtrackGradient = -9999; + double HtrackGradientError = -9999; + double VtrackOrigin = -9999; + double VtrackOriginError = -9999; + double VtrackGradient = -9999; + double VtrackGradientError = -9999; + int particlePID = -9999; + + int NumClusterTracks = 0; + for (int tracki = 0; tracki < numtracksinev; tracki++) + { + BoostStore *thisTrackAsBoostStore = &(theMrdTracks->at(tracki)); + int TrackEventID = -1; + // get track properties that are needed for the through-going muon selection + thisTrackAsBoostStore->Get("MrdSubEventID", TrackEventID); + if (TrackEventID != SubEventID) + continue; + + // If we're here, this track is associated with this cluster + thisTrackAsBoostStore->Get("StartVertex", StartVertex); + thisTrackAsBoostStore->Get("StopVertex", StopVertex); + thisTrackAsBoostStore->Get("TrackAngle", TrackAngle); + thisTrackAsBoostStore->Get("TrackAngleError", TrackAngleError); + thisTrackAsBoostStore->Get("PenetrationDepth", PenetrationDepth); + thisTrackAsBoostStore->Get("MrdEntryPoint", MrdEntryPoint); + thisTrackAsBoostStore->Get("EnergyLoss", EnergyLoss); + thisTrackAsBoostStore->Get("EnergyLossError", EnergyLossError); + thisTrackAsBoostStore->Get("IsMrdPenetrating", IsMrdPenetrating); // bool + thisTrackAsBoostStore->Get("IsMrdStopped", IsMrdStopped); // bool + thisTrackAsBoostStore->Get("IsMrdSideExit", IsMrdSideExit); + thisTrackAsBoostStore->Get("HtrackFitChi2", HtrackFitChi2); + thisTrackAsBoostStore->Get("HtrackFitCov", HtrackFitCov); + thisTrackAsBoostStore->Get("VtrackFitChi2", VtrackFitChi2); + thisTrackAsBoostStore->Get("VtrackFitCov", VtrackFitCov); + TrackLength = sqrt(pow((StopVertex.X() - StartVertex.X()), 2) + pow(StopVertex.Y() - StartVertex.Y(), 2) + pow(StopVertex.Z() - StartVertex.Z(), 2)) * 100.0; + EntryPointRadius = sqrt(pow(MrdEntryPoint.X(), 2) + pow(MrdEntryPoint.Y(), 2)) * 100.0; // convert to cm + PenetrationDepth = PenetrationDepth * 100.0; + thisTrackAsBoostStore->Get("HtrackOrigin", HtrackOrigin); + thisTrackAsBoostStore->Get("HtrackOriginError", HtrackOriginError); + thisTrackAsBoostStore->Get("HtrackGradient", HtrackGradient); + thisTrackAsBoostStore->Get("HtrackGradientError", HtrackGradientError); + thisTrackAsBoostStore->Get("VtrackOrigin", VtrackOrigin); + thisTrackAsBoostStore->Get("VtrackOriginError", VtrackOriginError); + thisTrackAsBoostStore->Get("VtrackGradient", VtrackGradient); + thisTrackAsBoostStore->Get("VtrackGradientError", VtrackGradientError); + thisTrackAsBoostStore->Get("particlePID", particlePID); + + // Push back some properties + fMRDTrackAngle.push_back(TrackAngle); + fMRDTrackAngleError.push_back(TrackAngleError); + fMRDTrackLength.push_back(TrackLength); + fMRDPenetrationDepth.push_back(PenetrationDepth); + fMRDEntryPointRadius.push_back(EntryPointRadius); + fMRDEnergyLoss.push_back(EnergyLoss); + fMRDEnergyLossError.push_back(EnergyLossError); + fMRDTrackStartX.push_back(StartVertex.X()); + fMRDTrackStartY.push_back(StartVertex.Y()); + fMRDTrackStartZ.push_back(StartVertex.Z()); + fMRDTrackStopX.push_back(StopVertex.X()); + fMRDTrackStopY.push_back(StopVertex.Y()); + fMRDTrackStopZ.push_back(StopVertex.Z()); + fMRDStop.push_back(IsMrdStopped); + fMRDSide.push_back(IsMrdSideExit); + fMRDThrough.push_back(IsMrdPenetrating); + fHtrackFitChi2.push_back(HtrackFitChi2); + fHtrackFitCov.push_back(HtrackFitCov); + fVtrackFitChi2.push_back(VtrackFitChi2); + fVtrackFitCov.push_back(VtrackFitCov); + fHtrackOrigin.push_back(HtrackOrigin); + fHtrackOriginError.push_back(HtrackOriginError); + fHtrackGradient.push_back(HtrackGradient); + fHtrackGradientError.push_back(HtrackGradientError); + fVtrackOrigin.push_back(VtrackOrigin); + fVtrackOriginError.push_back(VtrackOriginError); + fVtrackGradient.push_back(VtrackGradient); + fVtrackGradientError.push_back(VtrackGradientError); + fparticlePID.push_back(particlePID); + NumClusterTracks += 1; + } + return NumClusterTracks; +} + +void LAPPDThresReco::WaveformMaximaFinding() +{ + // loop the lappdData map, for each value, find the maxima and RMS, and put them into waveformMax and waveformRMS + // use the strip number + 30* strip side as the key + if (LAPPDThresRecoVerbosity > 0) + cout << "WaveformMaximaFinding: Start finding maxima and RMS of the waveforms" << endl; + + std::map>>::iterator it; + for (it = lappdData.begin(); it != lappdData.end(); it++) + { + unsigned long channel = it->first; + channel = channel % 1000 + 1000; + if (channel == 1005 || channel == 1035) + continue; + Channel *chan = _geom->GetChannel(channel); + int stripno = chan->GetStripNum(); + int stripSide = chan->GetStripSide(); + Waveform waveforms = it->second.at(0); + vector wav = *waveforms.GetSamples(); + + vector wave = wav; + if (wave.size() != 256) + { + cout << "WaveformMaximaFinding: Found a bug waveform at channel " << channel << ", size is " << wav.size() << endl; + continue; + } + if (LAPPDThresRecoVerbosity > 2) + cout << "WaveformMaximaFinding: Found a waveform at channel " << channel << ", size is " << wave.size() << ",side is " << stripSide << ", stripno is " << stripno << endl; + for (int i = 0; i < wave.size(); i++) + { + wave.at(i) = -wave.at(i); + } + double max = wave.at(0); + double rms = wave.at(0) * wave.at(0); + bool maxIsLast = 0; + double nearingMin = 0; + int binOfMax = -1; + for (int i = 1; i < wave.size() - 1; i++) + { + if (wave.at(i) > max) + { + if (wave.at(i + 1) > 0.8 * wave.at(i) && wave.at(i - 1) > 0.8 * wave.at(i)) + { + max = wave.at(i); + maxIsLast = 1; + binOfMax = i; + } + if (wave.at(i + 1) > wave.at(i - 1)) + { + nearingMin = wave.at(i - 1); + } + else + { + nearingMin = wave.at(i + 1); + } + } + + rms += (wave.at(i)) * (wave.at(i)); + } + + rms = sqrt(rms / wave.size()); + int LAPPD_ID = static_cast((channel - 1000) / 60); + int key = stripno + 30 * stripSide + LAPPD_ID * 60; + if (waveformMax[key].size() == 0) + { + waveformMax[key].resize(2); + waveformRMS[key].resize(2); + waveformMaxLast[key].resize(2); + waveformMaxNearing[key].resize(2); + waveformMaxTimeBin[key].resize(2); + } + waveformMax[key].at(stripSide) = max; + waveformRMS[key].at(stripSide) = rms; + waveformMaxLast[key].at(stripSide) = maxIsLast; + waveformMaxNearing[key].at(stripSide) = nearingMin; + waveformMaxTimeBin[key].at(stripSide) = binOfMax; + } +} diff --git a/UserTools/LAPPDThresReco/LAPPDThresReco.h b/UserTools/LAPPDThresReco/LAPPDThresReco.h new file mode 100644 index 000000000..3959302df --- /dev/null +++ b/UserTools/LAPPDThresReco/LAPPDThresReco.h @@ -0,0 +1,133 @@ +#ifndef LAPPDThresReco_H +#define LAPPDThresReco_H + +#include +#include + +#include "Tool.h" +#include "LAPPDPulse.h" +#include "LAPPDHit.h" +#include "Geometry.h" +#include "TGraph.h" +#include "TF1.h" +#include "Position.h" + +/** + * \class LAPPDThresReco + * + * Use an input std::map>> lappdData and a threshold to find pulses and construct hits. + * Output a std::map> lappdHits. + * Also generate txt files for hits and muon tracks. (need the muon track tools in the tool chain) + * + * $Author: Yue Feng $ + * $Date: 2024/01/29 $ + * Contact: yuef@iastate.edu + */ + +class LAPPDThresReco : public Tool +{ + +public: + LAPPDThresReco(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + vector FindPulses(vector wave, int LAPPD_ID, int channel); + vector FindHit(vector> pulses); + LAPPDHit MakeHit(LAPPDPulse pulse0, LAPPDPulse pulse1); + double GaussianFit(const vector &xData, const vector &yData); + int LoadMRDTrackReco(int SubEventID); + void CleanMRDRecoInfo(); + void CleanDataObjects(); + void FillLAPPDPulse(); + void FillLAPPDHit(); + void PrintHitsToTXT(); + void PrintMRDinfoToTXT(); + void WaveformMaximaFinding(); + +private: + // This tool, control variables (only used in this tool, every thing that is not an data object) + // Variables that you get from the config file + int LAPPDThresRecoVerbosity; + double threshold; + int minPulseWidth; + int printHitsTXT; + bool useMaxTime; + double signalSpeedOnStrip; + double triggerBoardDelay; + bool savePositionOnStrip; + int useRange; //-1 averaged peak time, 0 low, 1 high + bool loadPrintMRDinfo; + double pulseFollowTimeStandard; + int baselineStart; + int baselineEnd; + // Variables that you need in the tool + int eventNumber; + double pulseFollowTime; + + // LAPPD tool chain, control variables (Will be shared in multiple LAPPD tools to show the state of the tool chain in each loop) + // Variables that you get from the config file + string ThresRecoInputWaveLabel; + string ThresRecoOutputPulseLabel; + string ThresRecoOutputHitLabel; + // Variables that you need in the tool + Geometry *_geom; + bool LAPPDana; + bool LoadLAPPDMapInfo; + + // LAPPD tool chain, data variables. (Will be used in multiple LAPPD tools) + // everything you get or set to Store, which means it may be used in other tools or it's from other tools + std::vector *theMrdTracks; // the reconstructed tracks + int numtracksinev; + std::map channelnoToSwitchbit; + std::map> waveformMax; + std::map> waveformRMS; + std::map> waveformMaxLast; + std::map> waveformMaxNearing; + std::map> waveformMaxTimeBin; + vector LAPPD_IDs; + + // This tool, data variables (only used in this tool, every thing that is an data object) + std::map>> lappdData; // waveform data + std::map>> lappdPulses; // save threshold based method found lappd pulses + std::map> lappdHits; + std::vector> MrdTimeClusters; + int LAPPD_ID; + std::vector fMRDTrackAngle; + std::vector fMRDTrackAngleError; + std::vector fMRDPenetrationDepth; + std::vector fMRDTrackLength; + std::vector fMRDEntryPointRadius; + std::vector fMRDEnergyLoss; + std::vector fMRDEnergyLossError; + std::vector fMRDTrackStartX; + std::vector fMRDTrackStartY; + std::vector fMRDTrackStartZ; + std::vector fMRDTrackStopX; + std::vector fMRDTrackStopY; + std::vector fMRDTrackStopZ; + std::vector fHtrackFitChi2; + std::vector fHtrackFitCov; + std::vector fVtrackFitChi2; + std::vector fVtrackFitCov; + std::vector fMRDSide; + std::vector fMRDStop; + std::vector fMRDThrough; + std::vector fHtrackOrigin; + std::vector fHtrackOriginError; + std::vector fHtrackGradient; + std::vector fHtrackGradientError; + std::vector fVtrackOrigin; + std::vector fVtrackOriginError; + std::vector fVtrackGradient; + std::vector fVtrackGradientError; + std::vector fparticlePID; + + // data variables don't need to be cleared in each loop + ofstream myfile; + ofstream mrdfile; + +}; + +#endif diff --git a/UserTools/LAPPDThresReco/README.md b/UserTools/LAPPDThresReco/README.md new file mode 100644 index 000000000..ed43861cc --- /dev/null +++ b/UserTools/LAPPDThresReco/README.md @@ -0,0 +1,20 @@ +# LAPPDThresReco + +LAPPDThresReco + +## Data + +Describe any data formats LAPPDThresReco creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDThresReco. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.cpp b/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.cpp new file mode 100644 index 000000000..8185d3bbe --- /dev/null +++ b/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.cpp @@ -0,0 +1,375 @@ +#include "LAPPDTimeAlignment.h" +#include "TGraph.h" + +LAPPDTimeAlignment::LAPPDTimeAlignment() : Tool() {} + +bool LAPPDTimeAlignment::Initialise(std::string configfile, DataModel &data) +{ + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_variables.Get("FindT0InputWavLabel", InputWavLabel); + m_variables.Get("FindT0OutputWavLabel", OutputWavLabel); + + m_variables.Get("FindT0Verbosity", FindT0VerbosityLevel); + + m_variables.Get("TrigEarlyCut", trigearlycut); + m_variables.Get("TrigLateCut", triglatecut); + + m_variables.Get("T0signalmax", T0signalmax); + m_variables.Get("T0signalthreshold", T0signalthreshold); + + m_variables.Get("T0signalmaxOld", T0signalmaxOld); + m_variables.Get("T0signalthresholdOld", T0signalthresholdOld); + + m_variables.Get("T0offset", T0offset); + m_variables.Get("GlobalShiftT0", globalshiftT0); + + m_data->Stores["ANNIEEvent"]->Get("TrigChannel", TrigChannel); + m_data->Stores["ANNIEEvent"]->Get("LAPPDchannelOffset", LAPPDchannelOffset); + + LoadLAPPDMap = false; + m_variables.Get("LoadLAPPDMap", LoadLAPPDMap); + + return true; +} + +bool LAPPDTimeAlignment::Execute() +{ + bool LAPPDana = false; + m_data->CStore.Get("LAPPDana", LAPPDana); + if (!LAPPDana) + return true; + + oldLaser = 0; + m_data->Stores["ANNIEEvent"]->Get("oldLaser", oldLaser); + if (oldLaser == 1) + { + T0signalmax = T0signalmaxOld; + T0signalthreshold = T0signalthresholdOld; + } + + if (FindT0VerbosityLevel > 0) + cout << "OLD LASER? " << oldLaser << " " << T0signalmax << " " << T0signalthreshold << endl; + + double AnalogBoardShift[60] = { + 54, 54, 54, 54, 0, 0, // 0-5 + 88, 88, 88, 88, 88, 88, // 6-11 + 232, 232, 232, 232, 232, 232, // 12-17 + 220, 220, 220, 220, 220, 220, // 18-23 + 185, 185, 185, 185, 185, 185, // 24-29 + 54, 54, 54, 54, 0, 0, // 30-35 + 88, 88, 88, 88, 88, 88, // 36-41 + 232, 232, 232, 232, 232, 232, // 42-47 + 220, 220, 220, 220, 220, 220, // 48-53 + 185, 185, 185, 185, 185, 185, // 54-59 + }; + for (auto &k : AnalogBoardShift) + { + // k=(k-54)*10/197.86272; + k = (k - 54) * 10 / 169.982; + } + + std::map>> lappddata; + m_data->Stores["ANNIEEvent"]->Get(InputWavLabel, lappddata); + vector NReadBoards; + m_data->Stores["ANNIEEvent"]->Get("ACDCboards", NReadBoards); + std::map>> reordereddata; + bool T0signalInWindow = false; + double deltaT; + + vector ACDCReadedLAPPDID; + m_data->Stores["ANNIEEvent"]->Get("ACDCReadedLAPPDID", ACDCReadedLAPPDID); + + // print NReadBoards + if (FindT0VerbosityLevel > 0) + { + cout << "NReadBoards: "; + for (int i = 0; i < NReadBoards.size(); i++) + { + cout << NReadBoards.at(i) << " "; + } + cout << endl; + } + // print ACDCReadedLAPPDID + if (FindT0VerbosityLevel > 0 && LoadLAPPDMap) + { + cout << "ACDCReadedLAPPDID: "; + for (int i = 0; i < ACDCReadedLAPPDID.size(); i++) + { + cout << ACDCReadedLAPPDID.at(i) << " "; + } + cout << endl; + } + vector fittedBoardIDInMap; + + map>>::iterator itr_bi; + for (int i = 0; i < NReadBoards.size(); i++) + { + int bi = NReadBoards.at(i); + + int thisLAPPDID = 0; + + // TrigChannel is 5; + T0channelNo = LAPPDchannelOffset + (30 * bi) + TrigChannel; + if (LoadLAPPDMap) + { + thisLAPPDID = ACDCReadedLAPPDID.at(i); + T0channelNo = 1000 + (30 * (bi % 2)) + 60 * thisLAPPDID + TrigChannel; + } + + if (FindT0VerbosityLevel > 0) + cout << "For board " << bi << ", InputWavlabel: " << InputWavLabel << endl; + + if (FindT0VerbosityLevel > 0) + cout << "In LAPPDTimeAlignment, T0 channel:" << T0channelNo << " , InputWavlabel: " << InputWavLabel << " , LAPPDdata.size()=" << lappddata.size() << endl; + bool channelthere = lappddata.count((unsigned long)T0channelNo); + if (FindT0VerbosityLevel > 1) + cout << "is the channel there? " << channelthere << endl; + if (!channelthere) + { + int LAPPD_ID = 0; + m_data->CStore.Get("LAPPD_ID", LAPPD_ID); + T0channelNo = 1000 + (30 * (bi % 2)) + 60 * LAPPD_ID + TrigChannel; + if (FindT0VerbosityLevel > 0) + cout << " channel number " << T0channelNo << " not found, use LAPPD ID " << LAPPD_ID << " to find channel No " << T0channelNo << endl; + } + + itr_bi = lappddata.find((unsigned long)T0channelNo); + Waveform bwav = (itr_bi->second).at(0); + + double thetime = Tfit(bwav.GetSamples()); + int switchbit = (int)(thetime / 100.); + deltaT = thetime - (100. * (double)switchbit); + int Qvar = 0; + if ((switchbit >= trigearlycut) && (switchbit <= triglatecut)) + T0signalInWindow = true; + + // vector transcribe + vec_deltaT.push_back(deltaT); + vec_T0signalInWindow.push_back(T0signalInWindow); + vec_T0Bin.push_back(switchbit); + fittedBoardIDInMap.push_back(static_cast((T0channelNo - 1000) / 30)); + + if (FindT0VerbosityLevel > 0) + cout << "Done finding the time, switchbit:" << switchbit << " , deltaT: " << deltaT << " , inwindow: " << T0signalInWindow << endl; + if (FindT0VerbosityLevel > 1) + cout << "ready to loop" << endl; + } + + for (bool k : vec_T0signalInWindow) + { + if (!k) + { + T0signalInWindow = false; + } + } + + map>>::iterator itr; + for (itr = lappddata.begin(); itr != lappddata.end(); ++itr) + { + unsigned long channelno = itr->first; + if (FindT0VerbosityLevel > 5) + cout << "Found channelno: " << channelno << endl; + } + + int printcount = 0; + for (itr = lappddata.begin(); itr != lappddata.end(); ++itr) + { + unsigned long channelno = itr->first; + vector> Vwavs = itr->second; + vector> Vrwav; + int bi = (int)(channelno - LAPPDchannelOffset) / 30 % 2; // TODO: fix this, why loading data with board 2 and 3 have channel from 0 to 120? + int thisBoardID = static_cast((channelno - 1000) / 30); + if (LoadLAPPDMap) + { + int index = std::distance(fittedBoardIDInMap.begin(), std::find(fittedBoardIDInMap.begin(), fittedBoardIDInMap.end(), thisBoardID)); + bi = index; + if (FindT0VerbosityLevel > 5 && printcount < 5) + { + cout << "thisBoardID: " << thisBoardID << " , index: " << index << " , bi: " << bi << endl; + printcount++; + } + } + + int countnumber = (channelno % 1000) % 60; + if (FindT0VerbosityLevel > 2) + cout << "Looping with channelno: " << channelno << " , bi: " << bi << " , countnumber: " << countnumber << endl; + + // loop over all Waveforms + for (int i = 0; i < Vwavs.size(); i++) + { + if (FindT0VerbosityLevel > 2 && i == 0) + cout << "Looping waveform at" << i << endl; + Waveform bwav = Vwavs.at(i); + Waveform rwav; + Waveform rwavShift; + + int sb = vec_T0Bin[bi] + T0offset + AnalogBoardShift[countnumber]; + if (LoadLAPPDMap) + { + } + + countnumber++; + + if (sb < 0) + sb += 255; + + for (int j = 0; j < bwav.GetSamples()->size(); j++) + { + if (sb > 255) + sb = 0; + double nsamp = bwav.GetSamples()->at(sb); + rwav.PushSample(nsamp); + sb++; + } + + for (int j = 0; j < rwav.GetSamples()->size(); j++) + { + int ibin = j + globalshiftT0; + if (ibin > 255) + ibin = ibin - 255; + double nsamp = rwav.GetSamples()->at(ibin); + rwavShift.PushSample(nsamp); + } + Vrwav.push_back(rwavShift); + } + reordereddata.insert(pair>>(channelno, Vrwav)); + } + + if (FindT0VerbosityLevel > 0) + cout << "End of LAPPDTimeAlignment..." << endl; + + m_data->Stores["ANNIEEvent"]->Set(OutputWavLabel, reordereddata); + m_data->Stores["ANNIEEvent"]->Set("deltaT", vec_deltaT); + m_data->Stores["ANNIEEvent"]->Set("T0signalInWindow", T0signalInWindow); + m_data->Stores["ANNIEEvent"]->Set("T0Bin", vec_T0Bin); + vec_deltaT.clear(); + vec_T0signalInWindow.clear(); + vec_T0Bin.clear(); + + return true; +} + +bool LAPPDTimeAlignment::Finalise() +{ + return true; +} + +double LAPPDTimeAlignment::Tfit(std::vector *wf) +{ + int nbin = wf->size(); + + double ppre = 0.0; + double pvol = 0.0; + + bool firstcross = true; + double ttime = 0; + + for (int i = 0; i < nbin; i++) + { + pvol = (wf->at(i)); + if (i > 1) + ppre = (wf->at(i - 1)); + + if (FindT0VerbosityLevel > 2) + cout << i << " " << ppre << " " << pvol << " " << T0signalmax << endl; + + if (oldLaser == 1) + { + if (firstcross && pvol > T0signalmax && ppre < T0signalmax && i > 1 && i < 255) + { // trigger up to +200 2020 data + if (FindT0VerbosityLevel > 1) + cout << "Old t0 bin: " << i << endl; + TGraph *edge = new TGraph(); + for (int j = -7; j < 1; j++) + { + edge->SetPoint(j + 7, (i + j) * 100., (wf->at(i + j))); // select 7 points + } + bool firstthreshcross = true; + for (int k = (i - 7) * 100; k < (i + 1) * 100; k += 10) + { + if (FindT0VerbosityLevel == 3) + cout << k << " " << (edge->Eval((double)k, 0, "S")) << endl; + if (((edge->Eval((double)k, 0, "S")) < T0signalthreshold) && firstthreshcross) + { + if (FindT0VerbosityLevel > 2) + cout << "time: " << k << endl; + ttime = (double)k; + firstthreshcross = false; + } + } + firstcross = false; + } + } + else + { + + if (firstcross && pvol < T0signalmax && ppre > T0signalmax && i > 1 && i < 255) + { + + if (FindT0VerbosityLevel > 1) + cout << "New t0 bin: " << i << endl; + + TGraph *edge = new TGraph(); + int start = -7; + if(i<7) start = -i; + for (int j = start; j < 1; j++) + { + edge->SetPoint(j -start, (i + j) * 100., (wf->at(i + j))); + } + + bool firstthreshcross = true; + for (int k = (i +start) * 100; k < (i + 1) * 100; k += 10) + { + + if (FindT0VerbosityLevel == 3) + cout << k << " " << (edge->Eval((double)k, 0, "S")) << endl; + + if (((edge->Eval((double)k, 0, "S")) < T0signalthreshold) && firstthreshcross) + { + if (FindT0VerbosityLevel > 2) + cout << "time: " << k << endl; + ttime = (double)k; + firstthreshcross = false; + } + } + + /* + for (int j = -7; j < 1; j++) + { + edge->SetPoint(j + 7, (i + j) * 100., (wf->at(i + j))); + } + + bool firstthreshcross = true; + for (int k = (i - 7) * 100; k < (i + 1) * 100; k += 10) + { + + if (FindT0VerbosityLevel == 3) + cout << k << " " << (edge->Eval((double)k, 0, "S")) << endl; + + if (((edge->Eval((double)k, 0, "S")) < T0signalthreshold) && firstthreshcross) + { + if (FindT0VerbosityLevel > 2) + cout << "time: " << k << endl; + ttime = (double)k; + firstthreshcross = false; + } + } + */ + + firstcross = false; + } + } + } + + if (FindT0VerbosityLevel > 0) + cout << "Done Finding T0" << endl; + + return ttime; +} diff --git a/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.h b/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.h new file mode 100644 index 000000000..7a3b02ab0 --- /dev/null +++ b/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.h @@ -0,0 +1,54 @@ +#ifndef LAPPDTimeAlignment_H +#define LAPPDTimeAlignment_H + +#include +#include + +#include "Tool.h" + + +/** + * \class LAPPDTimeAlignment + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. +* +* $Author: B.Richards $ +* $Date: 2019/05/28 10:44:00 $ +* Contact: b.richards@qmul.ac.uk +*/ +class LAPPDTimeAlignment: public Tool { + + + public: + + LAPPDTimeAlignment(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + double Tfit(std::vector* wf); + + private: + + //vector for save + vector vec_T0signalInWindow; + vector vec_deltaT; + vector vec_T0Bin; + + int LAPPDchannelOffset; + int TrigChannel; + int T0offset; + double T0signalmax,T0signalthreshold; + double T0signalmaxOld,T0signalthresholdOld; + int T0channelNo; + int FindT0VerbosityLevel; + int globalshiftT0; + string InputWavLabel; + string OutputWavLabel; + int trigearlycut,triglatecut; + int oldLaser; + + bool LoadLAPPDMap; +}; + + +#endif diff --git a/UserTools/LAPPDTimeAlignment/README.md b/UserTools/LAPPDTimeAlignment/README.md new file mode 100644 index 000000000..7690759f1 --- /dev/null +++ b/UserTools/LAPPDTimeAlignment/README.md @@ -0,0 +1,20 @@ +# LAPPDTimeAlignment + +LAPPDTimeAlignment + +## Data + +Describe any data formats LAPPDTimeAlignment creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDTimeAlignment. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.cpp b/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.cpp new file mode 100644 index 000000000..3091f508f --- /dev/null +++ b/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.cpp @@ -0,0 +1,1093 @@ +#include "LAPPDTreeMaker.h" + +LAPPDTreeMaker::LAPPDTreeMaker() : Tool() {} + +bool LAPPDTreeMaker::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if (configfile != "") + m_variables.Initialise(configfile); // loading config file + // m_variables.Print(); + + m_data = &data; // assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + m_variables.Get("treeMakerVerbosity", treeMakerVerbosity); + m_variables.Get("treeMakerInputPulseLabel", treeMakerInputPulseLabel); + m_variables.Get("treeMakerInputHitLabel", treeMakerInputHitLabel); + treeMakerOutputFileName = "LAPPDTree.root"; + m_variables.Get("treeMakerOutputFileName", treeMakerOutputFileName); + + LoadPulse = false; + m_variables.Get("LoadPulse", LoadPulse); + LoadHit = false; + m_variables.Get("LoadHit", LoadHit); + LoadWaveform = false; + m_variables.Get("LoadWaveform", LoadWaveform); + LoadLAPPDDataTimeStamp = false; + m_variables.Get("LoadLAPPDDataTimeStamp", LoadLAPPDDataTimeStamp); + LoadPPSTimestamp = false; + m_variables.Get("LoadPPSTimestamp", LoadPPSTimestamp); + LoadRunInfoRaw = false; + m_variables.Get("LoadRunInfoRaw", LoadRunInfoRaw); + LoadRunInfoANNIEEvent = false; + m_variables.Get("LoadRunInfoANNIEEvent", LoadRunInfoANNIEEvent); + LoadTriggerInfo = false; + m_variables.Get("LoadTriggerInfo", LoadTriggerInfo); + LoadGroupedTriggerInfo = false; + m_variables.Get("LoadGroupedTriggerInfo", LoadGroupedTriggerInfo); + if (!LoadTriggerInfo) + LoadGroupedTriggerInfo = false; // if not loading trigger, don't fill grouped trigger + LoadGroupOption = "beam"; + m_variables.Get("LoadGroupOption", LoadGroupOption); + MultiLAPPDMapTreeMaker = false; + m_variables.Get("MultiLAPPDMapTreeMaker", MultiLAPPDMapTreeMaker); + + TString filename = treeMakerOutputFileName; + file = new TFile(filename, "RECREATE"); + fPulse = new TTree("Pulse", "Pulse"); + fHit = new TTree("Hit", "Hit"); + fWaveform = new TTree("Waveform", "Waveform"); + fTimeStamp = new TTree("TimeStamp", "TimeStamp"); + fTrigger = new TTree("Trig", "Trig"); + fGroupedTrigger = new TTree("GTrig", "GTrig"); + + fPulse->Branch("RunNumber", &RunNumber, "RunNumber/I"); + fPulse->Branch("SubRunNumber", &SubRunNumber, "SubRunNumber/I"); + fPulse->Branch("PartFileNumber", &PartFileNumber, "PartFileNumber/I"); + fPulse->Branch("EventNumber", &EventNumber, "EventNumber/I"); + fPulse->Branch("LAPPD_ID", &LAPPD_ID, "LAPPD_ID/I"); + fPulse->Branch("LAPPDDataTimeStampUL", &LAPPDDataTimeStampUL, "LAPPDDataTimeStampUL/l"); + fPulse->Branch("LAPPDDataBeamgateUL", &LAPPDDataBeamgateUL, "LAPPDDataBeamgateUL/l"); + fPulse->Branch("ChannelID", &ChannelID, "ChannelID/I"); + fPulse->Branch("StripNumber", &StripNumber, "StripNumber/I"); + fPulse->Branch("PeakTime", &PeakTime, "PeakTime/D"); + fPulse->Branch("Charge", &Charge, "Charge/D"); + fPulse->Branch("PeakAmp", &PeakAmp, "PeakAmp/D"); + fPulse->Branch("PulseStart", &PulseStart, "PulseStart/D"); + fPulse->Branch("PulseEnd", &PulseEnd, "PulseEnd/D"); + fPulse->Branch("PulseSize", &PulseSize, "PulseSize/D"); + fPulse->Branch("PulseSide", &PulseSide, "PulseSide/I"); + fPulse->Branch("PulseThreshold", &PulseThreshold, "PulseThreshold/D"); + fPulse->Branch("PulseBaseline", &PulseBaseline, "PulseBaseline/D"); + if (MultiLAPPDMapTreeMaker) + { + fPulse->Branch("LTSRaw", <SRaw, "LTSRaw/l"); + fPulse->Branch("LBGRaw", &LBGRaw, "LBGRaw/l"); + fPulse->Branch("LOffset_ns", &LOffset_ns, "LOffset_ns/l"); + fPulse->Branch("LTSCorrection", <SCorrection, "LTSCorrection/I"); + fPulse->Branch("LBGCorrection", &LBGCorrection, "LBGCorrection/I"); + fPulse->Branch("LOSInMinusPS", &LOSInMinusPS, "LOSInMinusPS/I"); + fPulse->Branch("CTCPrimeTriggerTime", &CTCPrimeTriggerTime, "CTCPrimeTriggerTime/l"); + } + + fHit->Branch("RunNumber", &RunNumber, "RunNumber/I"); + fHit->Branch("SubRunNumber", &SubRunNumber, "SubRunNumber/I"); + fHit->Branch("PartFileNumber", &PartFileNumber, "PartFileNumber/I"); + fHit->Branch("EventNumber", &EventNumber, "EventNumber/I"); + fHit->Branch("LAPPD_ID", &LAPPD_ID, "LAPPD_ID/I"); + fHit->Branch("LAPPDDataTimeStampUL", &LAPPDDataTimeStampUL, "LAPPDDataTimeStampUL/l"); + fHit->Branch("LAPPDDataBeamgateUL", &LAPPDDataBeamgateUL, "LAPPDDataBeamgateUL/l"); + fHit->Branch("StripNumber", &StripNumber, "StripNumber/I"); + fHit->Branch("HitTime", &HitTime, "HitTime/D"); + fHit->Branch("HitAmp", &HitAmp, "HitAmp/D"); + fHit->Branch("XPosTank", &XPosTank, "XPosTank/D"); + fHit->Branch("YPosTank", &YPosTank, "YPosTank/D"); + fHit->Branch("ZPosTank", &ZPosTank, "ZPosTank/D"); + fHit->Branch("ParallelPos", &ParallelPos, "ParallelPos/D"); + fHit->Branch("TransversePos", &TransversePos, "TransversePos/D"); + fHit->Branch("Pulse1StartTime", &Pulse1StartTime, "Pulse1StartTime/D"); + fHit->Branch("Pulse2StartTime", &Pulse2StartTime, "Pulse2StartTime/D"); + fHit->Branch("Pulse1LastTime", &Pulse1LastTime, "Pulse1LastTime/D"); + fHit->Branch("Pulse2LastTime", &Pulse2LastTime, "Pulse2LastTime/D"); + if (MultiLAPPDMapTreeMaker) + { + fHit->Branch("LTSRaw", <SRaw, "LTSRaw/l"); + fHit->Branch("LBGRaw", &LBGRaw, "LBGRaw/l"); + fHit->Branch("LOffset_ns", &LOffset_ns, "LOffset_ns/l"); + fHit->Branch("LTSCorrection", <SCorrection, "LTSCorrection/I"); + fHit->Branch("LBGCorrection", &LBGCorrection, "LBGCorrection/I"); + fHit->Branch("LOSInMinusPS", &LOSInMinusPS, "LOSInMinusPS/I"); + fHit->Branch("CTCPrimeTriggerTime", &CTCPrimeTriggerTime, "CTCPrimeTriggerTime/l"); + } + + fWaveform->Branch("RunNumber", &RunNumber, "RunNumber/I"); + fWaveform->Branch("SubRunNumber", &SubRunNumber, "SubRunNumber/I"); + fWaveform->Branch("PartFileNumber", &PartFileNumber, "PartFileNumber/I"); + fWaveform->Branch("EventNumber", &EventNumber, "EventNumber/I"); + fWaveform->Branch("LAPPD_ID", &LAPPD_ID, "LAPPD_ID/I"); + fWaveform->Branch("LAPPDDataTimeStampUL", &LAPPDDataTimeStampUL, "LAPPDDataTimeStampUL/l"); + fWaveform->Branch("LAPPDDataBeamgateUL", &LAPPDDataBeamgateUL, "LAPPDDataBeamgateUL/l"); + fWaveform->Branch("StripNumber", &StripNumber, "StripNumber/I"); + fWaveform->Branch("PulseSide", &PulseSide, "PulseSide/I"); + fWaveform->Branch("WaveformMax", &waveformMaxValue, "WaveformMax/D"); + fWaveform->Branch("WaveformRMS", &waveformRMSValue, "WaveformRMS/D"); + fWaveform->Branch("WaveformMaxTimeBin", &waveformMaxTimeBinValue, "WaveformMaxTimeBin/I"); + fWaveform->Branch("waveformMaxFoundNear", &waveformMaxFoundNear, "waveformMaxFoundNear/O"); // O is boolean + fWaveform->Branch("WaveformMaxNearing", &waveformMaxNearingValue, "WaveformMaxNearing/D"); + if (MultiLAPPDMapTreeMaker) + { + fWaveform->Branch("LTSRaw", <SRaw, "LTSRaw/l"); + fWaveform->Branch("LBGRaw", &LBGRaw, "LBGRaw/l"); + fWaveform->Branch("LOffset_ns", &LOffset_ns, "LOffset_ns/l"); + fWaveform->Branch("LTSCorrection", <SCorrection, "LTSCorrection/I"); + fWaveform->Branch("LBGCorrection", &LBGCorrection, "LBGCorrection/I"); + fWaveform->Branch("LOSInMinusPS", &LOSInMinusPS, "LOSInMinusPS/I"); + fWaveform->Branch("CTCPrimeTriggerTime", &CTCPrimeTriggerTime, "CTCPrimeTriggerTime/l"); + } + + fTimeStamp->Branch("RunNumber", &RunNumber, "RunNumber/I"); + fTimeStamp->Branch("SubRunNumber", &SubRunNumber, "SubRunNumber/I"); + fTimeStamp->Branch("PartFileNumber", &PartFileNumber, "PartFileNumber/I"); + fTimeStamp->Branch("EventNumber", &EventNumber, "EventNumber/I"); + fTimeStamp->Branch("LAPPD_ID", &LAPPD_ID, "LAPPD_ID/I"); + fTimeStamp->Branch("LAPPDDataTimeStampUL", &LAPPDDataTimeStampUL, "LAPPDDataTimeStampUL/l"); + fTimeStamp->Branch("LAPPDDataBeamgateUL", &LAPPDDataBeamgateUL, "LAPPDDataBeamgateUL/l"); + fTimeStamp->Branch("LAPPDDataTimestamp", &LAPPDDataTimestampPart1, "LAPPDDataTimestamp/l"); + fTimeStamp->Branch("LAPPDDataBeamgate", &LAPPDDataBeamgatePart1, "LAPPDDataBeamgate/l"); + fTimeStamp->Branch("LAPPDDataTimestampFloat", &LAPPDDataTimestampPart2, "LAPPDDataTimestampFloat/D"); + fTimeStamp->Branch("LAPPDDataBeamgateFloat", &LAPPDDataBeamgatePart2, "LAPPDDataBeamgateFloat/D"); + fTimeStamp->Branch("ppsDiff", &ppsDiff, "ppsDiff/L"); + fTimeStamp->Branch("ppsCount0", &ppsCount0, "ppsCount0/l"); + fTimeStamp->Branch("ppsCount1", &ppsCount1, "ppsCount1/l"); + fTimeStamp->Branch("ppsTime0", &ppsTime0, "ppsTime0/l"); + fTimeStamp->Branch("ppsTime1", &ppsTime1, "ppsTime1/l"); + + // trigger trees have no related to LAPPD data or PPS, so don't need event number + fTrigger->Branch("RunNumber", &RunNumber, "RunNumber/I"); + fTrigger->Branch("SubRunNumber", &SubRunNumber, "SubRunNumber/I"); + fTrigger->Branch("PartFileNumber", &PartFileNumber, "PartFileNumber/I"); + fTrigger->Branch("CTCTimeStamp", &CTCTimeStamp, "CTCTimeStamp/l"); + fTrigger->Branch("CTCTriggerWord", &CTCTriggerWord); + fTrigger->Branch("trigNumInMap", &trigNumInThisMap, "trigNumInMap/I"); + fTrigger->Branch("trigIndexInMap", &trigIndexInThisMap, "trigNumInMap/I"); + + fGroupedTrigger->Branch("RunNumber", &RunNumber, "RunNumber/I"); + fGroupedTrigger->Branch("SubRunNumber", &SubRunNumber, "SubRunNumber/I"); + fGroupedTrigger->Branch("PartFileNumber", &PartFileNumber, "PartFileNumber/I"); + fGroupedTrigger->Branch("gTrigWord", &groupedTriggerWords); + fGroupedTrigger->Branch("gTrigTime", &groupedTriggerTimestamps); + fGroupedTrigger->Branch("gTrigType", &groupedTriggerType, "gTrigType/I"); + fGroupedTrigger->Branch("gTrigNum", &TriggerGroupNumInThisEvent, "gTrigNum/I"); + + TriggerWordMap = new std::map>; + m_data->Stores["ANNIEEvent"]->Header->Get("AnnieGeometry", _geom); + EventNumber = 0; + + return true; +} + +bool LAPPDTreeMaker::Execute() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::Execute()" << endl; + CleanVariables(); + + m_data->CStore.Get("LoadingPPS", LoadingPPS); + if (treeMakerVerbosity > 0) + cout << "LoadingPPS: " << LoadingPPS << endl; + + m_data->CStore.Get("LAPPDana", LAPPDana); + if (treeMakerVerbosity > 0) + cout << "LAPPDana: " << LAPPDana << endl; + + if (LoadRunInfoRaw) + LoadRunInfoFromRaw(); + + if (LoadRunInfoANNIEEvent) + LoadRunInfoFromANNIEEvent(); + + bool loadTriggerPaused = false; + m_data->CStore.Get("PauseCTCDecoding", loadTriggerPaused); + if (treeMakerVerbosity > 0) + cout << "loadTriggerPaused: " << loadTriggerPaused << endl; + if (!loadTriggerPaused) + { + if (LoadTriggerInfo) + { + bool getTrig = m_data->CStore.Get("TimeToTriggerWordMap", TriggerWordMap); + if (!getTrig) + cout << "Error in getting trigger word map" << endl; + if (getTrig) + { + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker:: TimeToTriggerWordMap size: " << TriggerWordMap->size() << endl; + FillTriggerTree(); + } + } + } + + if (LoadGroupedTriggerInfo) + FillGroupedTriggerTree(); + + if (MultiLAPPDMapTreeMaker && LAPPDana) + { + m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerTime", CTCPrimeTriggerTime); + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::Execute() MultiLAPPDMapTreeMaker" << endl; + LoadLAPPDMapInfo(); + bool getMap = m_data->Stores["ANNIEEvent"]->Get("LAPPDDataMap", LAPPDDataMap); + bool gotBeamgates_ns = m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + bool gotTimeStamps_ns = m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + bool gotTimeStampsRaw = m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + bool gotBeamgatesRaw = m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + bool gotOffsets = m_data->Stores["ANNIEEvent"]->Get("LAPPDOffsets", LAPPDOffsets); + bool gotTSCorrection = m_data->Stores["ANNIEEvent"]->Get("LAPPDTSCorrection", LAPPDTSCorrection); + bool gotDBGCorrection = m_data->Stores["ANNIEEvent"]->Get("LAPPDBGCorrection", LAPPDBGCorrection); + bool gotOSInMinusPS = m_data->Stores["ANNIEEvent"]->Get("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::Execute() MultiLAPPDMapTreeMaker get map = " << getMap << endl; + if (getMap) + { + if (treeMakerVerbosity > 0) + cout << "map size: " << LAPPDDataMap.size() << endl; + for (auto &item : LAPPDDataMap) + { + PsecData thisData = item.second; + int thisLAPPD_ID = thisData.LAPPD_ID; + + uint64_t thisDataTime = item.first; + uint64_t thisTSRaw = LAPPDTimeStampsRaw.at(thisDataTime); + uint64_t thisBGRaw = LAPPDBeamgatesRaw.at(thisDataTime); + uint64_t thisOffset = LAPPDOffsets.at(thisDataTime); + int thisTSCorr = LAPPDTSCorrection.at(thisDataTime); + int thisDBGCorr = LAPPDBGCorrection.at(thisDataTime); + int thisOSInMinusPS = LAPPDOSInMinusPS.at(thisDataTime); + + if (treeMakerVerbosity > 0) + cout << "outside tree maker, Got LAPPD ID: " << thisLAPPD_ID << ", time stamp: " << thisDataTime << ", TSraw " << thisTSRaw << ", BGraw " << thisBGRaw << ", offset " << thisOffset << ", TSCorr " << thisTSCorr << ", DBGCorr " << thisDBGCorr << ", OSInMinusPS " << thisOSInMinusPS << endl; + + LAPPD_IDs.push_back(thisLAPPD_ID); + LAPPDMapTimeStampRaw.push_back(thisTSRaw); + LAPPDMapBeamgateRaw.push_back(thisBGRaw); + LAPPDMapOffsets.push_back(thisOffset); + LAPPDMapTSCorrections.push_back(thisTSCorr); + LAPPDMapBGCorrections.push_back(thisDBGCorr); + LAPPDMapOSInMinusPS.push_back(thisOSInMinusPS); + + if (treeMakerVerbosity > 0) + cout << "outside size of LAPPD_IDs: " << LAPPD_IDs.size() << endl; + } + } + else + { + cout << "outside LAPPDTreeMaker::LoadLAPPDMapInfo, no LAPPDDataMap found" << endl; + } + + if (treeMakerVerbosity > 0) + { + cout << "LAPPDMapTimeStampRaw: "; + for (auto &item : LAPPDMapTimeStampRaw) + cout << item << " "; + cout << "LAPPDTreeMaker::Execute() MultiLAPPDMapTreeMaker finished " << endl; + } + } + + if (LoadPPSTimestamp && LoadingPPS) + { + bool gotPPSTimestamp = m_data->CStore.Get("LAPPDPPSVector", pps_vector); + bool gotPPSCounter = m_data->CStore.Get("LAPPDPPScount", pps_count_vector); + if (!gotPPSTimestamp) + cout << "Error in getting PPS timestamp" << endl; + if (!gotPPSCounter) + cout << "Error in getting PPS counter" << endl; + if (gotPPSTimestamp && gotPPSCounter) + FillPPSTimestamp(); + } + + if (LoadLAPPDDataTimeStamp && !LoadingPPS) + { + bool newDataEvent; + m_data->CStore.Get("LAPPD_new_event", newDataEvent); + if (newDataEvent) + FillLAPPDDataTimeStamp(); + m_data->CStore.Set("LAPPD_new_event", true); + } + + if (LoadPulse && LAPPDana) + { + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::Execute() LoadPulse" << endl; + bool gotPulse = m_data->Stores["ANNIEEvent"]->Get(treeMakerInputPulseLabel, lappdPulses); + if (!gotPulse) + cout << "Error in getting LAPPD pulses" << endl; + if (gotPulse) + FillPulseTree(); + } + + if (LoadHit && LAPPDana) + { + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::Execute() LoadHit" << endl; + bool gotHit = m_data->Stores["ANNIEEvent"]->Get(treeMakerInputHitLabel, lappdHits); + if (!gotHit) + cout << "Error in getting LAPPD hits" << endl; + if (gotHit) + FillHitTree(); + } + + if (LoadWaveform && LAPPDana) + { + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::Execute() LoadWaveform" << endl; + bool gotWaveformMax = m_data->Stores["ANNIEEvent"]->Get("waveformMax", waveformMax); + if (!gotWaveformMax) + cout << "Error in getting waveform max" << endl; + bool gotWaveformRMS = m_data->Stores["ANNIEEvent"]->Get("waveformRMS", waveformRMS); + if (!gotWaveformRMS) + cout << "Error in getting waveform RMS" << endl; + bool gotWaveformMaxLast = m_data->Stores["ANNIEEvent"]->Get("waveformMaxLast", waveformMaxLast); + if (!gotWaveformMaxLast) + cout << "Error in getting waveform max last" << endl; + bool gotWaveformMaxNearing = m_data->Stores["ANNIEEvent"]->Get("waveformMaxNearing", waveformMaxNearing); + if (!gotWaveformMaxNearing) + cout << "Error in getting waveform max nearing" << endl; + bool gotWaveformMaxTimeBin = m_data->Stores["ANNIEEvent"]->Get("waveformMaxTimeBin", waveformMaxTimeBin); + if (!gotWaveformMaxTimeBin) + cout << "Error in getting waveform max time bin" << endl; + + if (gotWaveformMax && gotWaveformRMS && gotWaveformMaxLast && gotWaveformMaxNearing && gotWaveformMaxTimeBin) + FillWaveformTree(); + } + + if (LAPPDana) + EventNumber++; + + if (TriggerWordMap != nullptr) + TriggerWordMap->clear(); + + return true; +} + +bool LAPPDTreeMaker::Finalise() +{ + file->cd(); + fPulse->Write(); + fHit->Write(); + fWaveform->Write(); + fTimeStamp->Write(); + fTrigger->Write(); + fGroupedTrigger->Write(); + file->Close(); + return true; +} + +void LAPPDTreeMaker::CleanVariables() +{ + LAPPDana = false; + + RunNumber = -9999; + SubRunNumber = -9999; + PartFileNumber = -9999; + + lappdPulses.clear(); + lappdHits.clear(); + lappdData.clear(); + waveformMax.clear(); + waveformRMS.clear(); + waveformMaxLast.clear(); + waveformMaxNearing.clear(); + waveformMaxTimeBin.clear(); + pps_vector.clear(); + pps_count_vector.clear(); + + LAPPD_ID = -9999; + ChannelID = -9999; + PeakTime = -9999; + Charge = -9999; + PeakAmp = -9999; + PulseStart = -9999; + PulseEnd = -9999; + PulseSize = -9999; + PulseSide = -9999; + PulseThreshold = -9999; + PulseBaseline = -9999; + + HitTime = -9999; + HitAmp = -9999; + XPosTank = -9999; + YPosTank = -9999; + ZPosTank = -9999; + ParallelPos = -9999; + TransversePos = -9999; + Pulse1StartTime = -9999; + Pulse2StartTime = -9999; + Pulse1LastTime = -9999; + Pulse2LastTime = -9999; + + LAPPDDataTimeStampUL = 0; + LAPPDDataBeamgateUL = 0; + LAPPDDataTimestampPart1 = 0; + LAPPDDataBeamgatePart1 = 0; + LAPPDDataTimestampPart2 = -9999; + LAPPDDataBeamgatePart2 = -9999; + + ppsDiff = -9999; + ppsCount0 = 0; + ppsCount1 = 0; + ppsTime0 = 0; + ppsTime1 = 0; + + CTCTimeStamp = 0; + CTCTriggerWord.clear(); + trigNumInThisMap = -9999; + trigIndexInThisMap = 0; + + groupedTriggerWordsVector.clear(); + groupedTriggerTimestampsVector.clear(); + groupedTriggerWords.clear(); + groupedTriggerTimestamps.clear(); + groupedTriggerByType.clear(); + groupedTriggerType = -9999; + TriggerGroupNumInThisEvent = 0; // start from 0 + groupedTriggerType = -9999; + + LAPPD_IDs.clear(); + LAPPDMapTimeStampRaw.clear(); + LAPPDMapBeamgateRaw.clear(); + LAPPDMapOffsets.clear(); + LAPPDMapTSCorrections.clear(); + LAPPDMapBGCorrections.clear(); + LAPPDMapOSInMinusPS.clear(); + + LAPPDDataMap.clear(); + LAPPDBeamgate_ns.clear(); + LAPPDTimeStamps_ns.clear(); + LAPPDTimeStampsRaw.clear(); + LAPPDBeamgatesRaw.clear(); + LAPPDOffsets.clear(); + LAPPDTSCorrection.clear(); + LAPPDBGCorrection.clear(); + LAPPDOSInMinusPS.clear(); +} + +bool LAPPDTreeMaker::LoadRunInfoFromRaw() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::LoadRunInfoFromRaw" << endl; + m_data->CStore.Get("runNumber", RunNumber); + m_data->CStore.Get("rawFileNumber", PartFileNumber); + m_data->CStore.Get("subrunNumber", SubRunNumber); + return true; +} + +bool LAPPDTreeMaker::LoadRunInfoFromANNIEEvent() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::LoadRunInfoFromANNIEEvent" << endl; + m_data->Stores["ANNIEEvent"]->Get("RunNumber", RunNumber); + m_data->Stores["ANNIEEvent"]->Get("SubRunNumber", SubRunNumber); + m_data->Stores["ANNIEEvent"]->Get("PartNumber", PartFileNumber); + if (treeMakerVerbosity > 0) + cout << "RunNumber: " << RunNumber << ", SubRunNumber: " << SubRunNumber << ", PartFileNumber: " << PartFileNumber << endl; + return true; +} + +bool LAPPDTreeMaker::FillPulseTree() +{ + // LAPPDPulse thisPulse(LAPPD_ID, channel, peakBin*(25./256.), Q, peakAmp, pulseStart, pulseStart+pulseSize); + std::map>>::iterator it; + int foundPulseNum = 0; + if (lappdPulses.size() == 0) + { + if (treeMakerVerbosity > 0) + cout << "No pulses found" << endl; + return true; + } + for (it = lappdPulses.begin(); it != lappdPulses.end(); it++) + { + int stripno = it->first; + vector> stripPulses = it->second; + vector pulse0 = stripPulses.at(0); + vector pulse1 = stripPulses.at(1); + for (int i = 0; i < pulse0.size(); i++) + { + PulseSide = 0; + LAPPDPulse thisPulse = pulse0.at(i); + LAPPD_ID = thisPulse.GetTubeId(); + ChannelID = thisPulse.GetChannelID(); + StripNumber = stripno; + PeakTime = thisPulse.GetTime(); + Charge = thisPulse.GetCharge(); + PeakAmp = thisPulse.GetPeak(); + PulseStart = thisPulse.GetLowRange(); + PulseEnd = thisPulse.GetHiRange(); + PulseSize = PulseEnd - PulseStart; + // cout << " tree maker, this pulse0 LAPPD ID is " << LAPPD_ID << endl; + // TODO save threshold and baseline + if (MultiLAPPDMapTreeMaker) + { + // find the LAPPD_ID in LAPPD_IDs, get the index + // use that index to get the timestamp and beamgate + // if not found, set them to zero + int index = std::distance(LAPPD_IDs.begin(), std::find(LAPPD_IDs.begin(), LAPPD_IDs.end(), LAPPD_ID)); + if (index < LAPPDMapTimeStampRaw.size()) + { + LTSRaw = LAPPDMapTimeStampRaw.at(index); + LBGRaw = LAPPDMapBeamgateRaw.at(index); + LOffset_ns = LAPPDMapOffsets.at(index); + LTSCorrection = LAPPDMapTSCorrections.at(index); + LBGCorrection = LAPPDMapBGCorrections.at(index); + LOSInMinusPS = LAPPDMapOSInMinusPS.at(index); + } + else + { + LTSRaw = 0; + LBGRaw = 0; + LOffset_ns = 0; + LTSCorrection = 0; + LBGCorrection = 0; + LOSInMinusPS = 0; + } + } + + fPulse->Fill(); + foundPulseNum++; + } + for (int i = 0; i < pulse1.size(); i++) + { + PulseSide = 1; + LAPPDPulse thisPulse = pulse1.at(i); + LAPPD_ID = thisPulse.GetTubeId(); + ChannelID = thisPulse.GetChannelID(); + StripNumber = stripno; + PeakTime = thisPulse.GetTime(); + Charge = thisPulse.GetCharge(); + PeakAmp = thisPulse.GetPeak(); + PulseStart = thisPulse.GetLowRange(); + PulseEnd = thisPulse.GetHiRange(); + PulseSize = PulseEnd - PulseStart; + /*cout << " this pulse1 LAPPD ID is " << LAPPD_ID << endl; + cout << "ThresReco pulse1 got LAPPD_IDs: "; + for (int i = 0; i < LAPPD_IDs.size(); i++) + { + cout << LAPPD_IDs.at(i) << " "; + }*/ + // TODO save threshold and baseline + if (MultiLAPPDMapTreeMaker) + { + // find the index of LAPPD_ID in LAPPD_IDs, use that index to assign the timestamlUL and beam gate UL, if not found set them to zero + int index = std::distance(LAPPD_IDs.begin(), std::find(LAPPD_IDs.begin(), LAPPD_IDs.end(), LAPPD_ID)); + if (index < LAPPDMapTimeStampRaw.size()) + { + LTSRaw = LAPPDMapTimeStampRaw.at(index); + LBGRaw = LAPPDMapBeamgateRaw.at(index); + LOffset_ns = LAPPDMapOffsets.at(index); + LTSCorrection = LAPPDMapTSCorrections.at(index); + LBGCorrection = LAPPDMapBGCorrections.at(index); + LOSInMinusPS = LAPPDMapOSInMinusPS.at(index); + } + else + { + LTSRaw = 0; + LBGRaw = 0; + LOffset_ns = 0; + LTSCorrection = 0; + LBGCorrection = 0; + LOSInMinusPS = 0; + } + } + fPulse->Fill(); + foundPulseNum++; + } + } + if (treeMakerVerbosity > 0) + cout << "Found and saved " << foundPulseNum << " pulses" << endl; + return true; +} + +bool LAPPDTreeMaker::FillHitTree() +{ + // LAPPDHit hit(tubeID, averageTimeLow, averageAmp, positionInTank, positionOnLAPPD, pulse1LastTime, pulse2LastTime, pulse1StartTime, pulse2StartTime); + int foundHitNum = 0; + if (lappdHits.size() == 0) + { + if (treeMakerVerbosity > 0) + cout << "No hits found" << endl; + return true; + } + std::map>::iterator it; + for (it = lappdHits.begin(); it != lappdHits.end(); it++) + { + int stripno = it->first; + vector stripHits = it->second; + for (int i = 0; i < stripHits.size(); i++) + { + LAPPDHit thisHit = stripHits.at(i); + LAPPD_ID = thisHit.GetTubeId(); + StripNumber = stripno; + HitTime = thisHit.GetTime(); + HitAmp = thisHit.GetCharge(); + vector position = thisHit.GetPosition(); + XPosTank = position.at(0); + YPosTank = position.at(1); + ZPosTank = position.at(2); + vector localPosition = thisHit.GetLocalPosition(); + ParallelPos = localPosition.at(0); + TransversePos = localPosition.at(1); + Pulse1StartTime = thisHit.GetPulse1StartTime(); + Pulse2StartTime = thisHit.GetPulse2StartTime(); + Pulse1LastTime = thisHit.GetPulse1LastTime(); + Pulse2LastTime = thisHit.GetPulse2LastTime(); + if (treeMakerVerbosity > 0) + { + cout << " this hit LAPPD ID is " << LAPPD_ID << endl; + cout << "ThresReco hit got LAPPD_IDs: "; + for (int i = 0; i < LAPPD_IDs.size(); i++) + { + cout << LAPPD_IDs.at(i) << " "; + } + } + if (MultiLAPPDMapTreeMaker) + { + // find the LAPPD_ID in LAPPD_IDs, get the index + // use that index to get the timestamp and beamgate + // if not found, set them to zero + int index = std::distance(LAPPD_IDs.begin(), std::find(LAPPD_IDs.begin(), LAPPD_IDs.end(), LAPPD_ID)); + if (index < LAPPDMapTimeStampRaw.size()) + { + LTSRaw = LAPPDMapTimeStampRaw.at(index); + LBGRaw = LAPPDMapBeamgateRaw.at(index); + LOffset_ns = LAPPDMapOffsets.at(index); + LTSCorrection = LAPPDMapTSCorrections.at(index); + LBGCorrection = LAPPDMapBGCorrections.at(index); + LOSInMinusPS = LAPPDMapOSInMinusPS.at(index); + } + else + { + LTSRaw = 0; + LBGRaw = 0; + LOffset_ns = 0; + LTSCorrection = 0; + LBGCorrection = 0; + LOSInMinusPS = 0; + } + } + fHit->Fill(); + foundHitNum++; + } + } + if (treeMakerVerbosity > 0) + cout << "Found and saved " << foundHitNum << " hits" << endl; + return true; +} + +bool LAPPDTreeMaker::FillWaveformTree() +{ + if (waveformMax.size() == 0) + { + if (treeMakerVerbosity > 0) + cout << "No waveforms found" << endl; + return true; + } + std::map>::iterator it; + for (it = waveformMax.begin(); it != waveformMax.end(); it++) + { + int key = it->first; + LAPPD_ID = static_cast(key / 60); + int stripSide = static_cast((key - LAPPD_ID * 60) / 30); + StripNumber = key - LAPPD_ID * 60 - stripSide * 30; + // cout << " this waveform LAPPD ID is " << LAPPD_ID << endl; + + for (int side = 0; side < 2; side++) + { + PulseSide = side; + waveformMaxValue = waveformMax.at(key).at(side); + waveformRMSValue = waveformRMS.at(key).at(side); + waveformMaxFoundNear = waveformMaxLast.at(key).at(side); + waveformMaxNearingValue = waveformMaxNearing.at(key).at(side); + waveformMaxTimeBinValue = waveformMaxTimeBin.at(key).at(side); + /*cout << " LAPPDTreeMaker fill waveform tree, LAPPD ID is " << LAPPD_ID << endl; + cout << "ThresReco got LAPPD_IDs: "; + for (int i = 0; i < LAPPD_IDs.size(); i++) + { + cout << LAPPD_IDs.at(i) << " "; + }*/ + if (MultiLAPPDMapTreeMaker) + { + // find the LAPPD_ID in LAPPD_IDs, get the index + // use that index to get the timestamp and beamgate + // if not found, set them to zero + int index = std::distance(LAPPD_IDs.begin(), std::find(LAPPD_IDs.begin(), LAPPD_IDs.end(), LAPPD_ID)); + if (index < LAPPDMapTimeStampRaw.size()) + { + LTSRaw = LAPPDMapTimeStampRaw.at(index); + LBGRaw = LAPPDMapBeamgateRaw.at(index); + LOffset_ns = LAPPDMapOffsets.at(index); + LTSCorrection = LAPPDMapTSCorrections.at(index); + LBGCorrection = LAPPDMapBGCorrections.at(index); + LOSInMinusPS = LAPPDMapOSInMinusPS.at(index); + } + else + { + LTSRaw = 0; + LBGRaw = 0; + LOffset_ns = 0; + LTSCorrection = 0; + LBGCorrection = 0; + LOSInMinusPS = 0; + } + } + fWaveform->Fill(); + } + } + if (treeMakerVerbosity > 0) + cout << "Found and saved " << waveformMax.size() << " waveforms" << endl; + return true; +} + +bool LAPPDTreeMaker::FillPPSTimestamp() +{ + ppsTime0 = pps_vector.at(0); + ppsTime1 = pps_vector.at(1); + ppsCount0 = pps_count_vector.at(0); + ppsCount1 = pps_count_vector.at(1); + ppsDiff = ppsTime1 - ppsTime0; + m_data->CStore.Get("LAPPD_ID", LAPPD_ID); + if (treeMakerVerbosity > 0) + cout << "LAPPD_ID: " << LAPPD_ID << ", ppsDiff: " << ppsDiff << ", ppsTime0: " << ppsTime0 << ", ppsTime1: " << ppsTime1 << ", ppsCount0: " << ppsCount0 << ", ppsCount1: " << ppsCount1 << endl; + fTimeStamp->Fill(); + return true; +} + +bool LAPPDTreeMaker::FillLAPPDDataTimeStamp() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::FillLAPPDDataTimeStamp. Before fill: LAPPDDataTimeStampUL: " << LAPPDDataTimeStampUL << ", LAPPDDataBeamgateUL: " << LAPPDDataBeamgateUL << ", LAPPDDataTimestampPart1: " << LAPPDDataTimestampPart1 << ", LAPPDDataBeamgatePart1: " << LAPPDDataBeamgatePart1 << ", LAPPDDataTimestampPart2: " << LAPPDDataTimestampPart2 << ", LAPPDDataBeamgatePart2: " << LAPPDDataBeamgatePart2 << endl; + if (!MultiLAPPDMapTreeMaker) + { + m_data->CStore.Get("LAPPDBeamgate_Raw", LAPPDDataBeamgateUL); + m_data->CStore.Get("LAPPDTimestamp_Raw", LAPPDDataTimeStampUL); + m_data->CStore.Get("LAPPDBGIntCombined", LAPPDDataBeamgatePart1); + m_data->CStore.Get("LAPPDBGFloat", LAPPDDataBeamgatePart2); + m_data->CStore.Get("LAPPDTSIntCombined", LAPPDDataTimestampPart1); + m_data->CStore.Get("LAPPDTSFloat", LAPPDDataTimestampPart2); + m_data->CStore.Get("LAPPD_ID", LAPPD_ID); + fTimeStamp->Fill(); + } + else + { + for (int i = 0; i < LAPPD_IDs.size(); i++) + { + LAPPD_ID = LAPPD_IDs.at(i); + LAPPDDataBeamgateUL = LAPPDMapBeamgateRaw.at(i); + LAPPDDataTimeStampUL = LAPPDMapTimeStampRaw.at(i); + fTimeStamp->Fill(); + } + } + if (treeMakerVerbosity > 0) + cout << "LAPPDDataTimeStampUL: " << LAPPDDataTimeStampUL << ", LAPPDDataBeamgateUL: " << LAPPDDataBeamgateUL << ", LAPPDDataTimestampPart1: " << LAPPDDataTimestampPart1 << ", LAPPDDataBeamgatePart1: " << LAPPDDataBeamgatePart1 << ", LAPPDDataTimestampPart2: " << LAPPDDataTimestampPart2 << ", LAPPDDataBeamgatePart2: " << LAPPDDataBeamgatePart2 << endl; + return true; +} + +bool LAPPDTreeMaker::FillTriggerTree() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::FillTriggerTree" << endl; + + trigNumInThisMap = TriggerWordMap->size(); + for (const auto &item : *TriggerWordMap) + { + CTCTimeStamp = item.first; + CTCTriggerWord = item.second; + fTrigger->Fill(); + trigIndexInThisMap++; + } + if (treeMakerVerbosity > 0) + cout << "FillTriggerTree: " << trigNumInThisMap << " triggers filled" << endl; + + return true; +} + +bool LAPPDTreeMaker::FillGroupedTriggerTree() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::FillGroupedTriggerTree" << endl; + + // fill new triggers from the map to ungrouped trigger buffer + for (const auto &item : *TriggerWordMap) + { + CTCTimeStamp = item.first; + CTCTriggerWord = item.second; + + for (const auto &trigw : CTCTriggerWord) + { + unGroupedTriggerTimestamps.push_back(CTCTimeStamp); + unGroupedTriggerWords.push_back(trigw); + } + } + + if (LoadGroupOption == "beam") + GroupTriggerByBeam(); + else if (LoadGroupOption == "laser") + GroupTriggerByLaser(); + + GroupPPSTrigger(); + + for (int i = 0; i < groupedTriggerWordsVector.size(); i++) + { + groupedTriggerWords = groupedTriggerWordsVector.at(i); + groupedTriggerTimestamps = groupedTriggerTimestampsVector.at(i); + groupedTriggerType = groupedTriggerByType.at(i); + fGroupedTrigger->Fill(); + TriggerGroupNumInThisEvent += 1; + } + + CleanTriggers(); + + return true; +} + +bool LAPPDTreeMaker::GroupTriggerByBeam() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::GroupTriggerByBeam" << endl; + + vector removeIndex; + bool beamNow = false; + bool trigger2ed = false; + bool trigger14ed = false; + bool trigger1ed = false; + int beamConfirm = 0; + vector thisTGroup; + vector thisTTimestamp; + bool ppsNow = false; + + for (int i = 0; i < unGroupedTriggerWords.size(); i++) + { + uint32_t tWord = unGroupedTriggerWords.at(i); + unsigned long tTime = unGroupedTriggerTimestamps.at(i); + bool pushedToBuffer = false; + if (!beamNow) + { + // not in a beam group + if (tWord == 3) + { + beamNow = true; + beamConfirm = 0; + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + pushedToBuffer = true; + trigger2ed = false; + trigger14ed = false; + trigger1ed = false; + } + } + else + { // while in a group + if (beamConfirm <= 2 && tWord == 3) + { + // in grouping mode, meet a new start, but haven't got enough trigger 14 and 2 + // clear buffer, restart the grouping from this t 3 + thisTGroup.clear(); + thisTTimestamp.clear(); + beamNow = true; + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + pushedToBuffer = true; + trigger2ed = false; + trigger14ed = false; + trigger1ed = false; + } + + if (beamConfirm > 2 && tWord == 10) + { + // if beam confirmed and meet a trigger 10, save the grouped triggers + // 10 always come with 8, which is delayed trigger to MRD + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + pushedToBuffer = true; + // if found trigger 14 and 2, save the grouped triggers + if ((std::find(thisTGroup.begin(), thisTGroup.end(), 14) != thisTGroup.end()) && (std::find(thisTGroup.begin(), thisTGroup.end(), 2) != thisTGroup.end())) + { + groupedTriggerWordsVector.push_back(thisTGroup); + groupedTriggerTimestampsVector.push_back(thisTTimestamp); + groupedTriggerByType.push_back(14); + } + thisTGroup.clear(); + thisTTimestamp.clear(); + beamNow = false; + trigger14ed = false; + trigger2ed = false; + trigger1ed = false; + beamConfirm = 0; + } + + if (!pushedToBuffer && tWord != 32 && tWord != 34 && tWord != 36) + { + if (tWord == 2) + { + trigger2ed = true; + beamConfirm++; + } + + if (tWord != 14) + { + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + } + else if (!trigger14ed) + { + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + trigger14ed = true; + beamConfirm++; + } + pushedToBuffer = true; + } + } + + if (pushedToBuffer) + { + removeIndex.push_back(i); + } + } + + vector unRemovedTriggerWords; + vector unRemovedTriggerTimestamps; + for (int i = 0; i < unGroupedTriggerWords.size(); i++) + { + if (std::find(removeIndex.begin(), removeIndex.end(), i) == removeIndex.end()) + { + unRemovedTriggerWords.push_back(unGroupedTriggerWords.at(i)); + unRemovedTriggerTimestamps.push_back(unGroupedTriggerTimestamps.at(i)); + } + } + unGroupedTriggerTimestamps = unRemovedTriggerTimestamps; + unGroupedTriggerWords = unRemovedTriggerWords; + + return true; +} + +bool LAPPDTreeMaker::GroupPPSTrigger() +{ + if (treeMakerVerbosity > 0) + cout << "LAPPDTreeMaker::GroupPPSTrigger" << endl; + + vector removeIndex; + vector thisTGroup; + vector thisTTimestamp; + bool ppsNow = false; + for (int i = 0; i < unGroupedTriggerWords.size(); i++) + { + uint32_t tWord = unGroupedTriggerWords.at(i); + unsigned long tTime = unGroupedTriggerTimestamps.at(i); + bool pushedToBuffer = false; + if (!ppsNow) + { + if (tWord == 32) + { + ppsNow = true; + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + pushedToBuffer = true; + } + } + else + { + if (tWord == 34) + { + thisTGroup.push_back(tWord); + thisTTimestamp.push_back(tTime); + pushedToBuffer = true; + groupedTriggerWordsVector.push_back(thisTGroup); + groupedTriggerTimestampsVector.push_back(thisTTimestamp); + groupedTriggerByType.push_back(32); + thisTGroup.clear(); + thisTTimestamp.clear(); + ppsNow = false; + } + } + + if (pushedToBuffer) + { + removeIndex.push_back(i); + } + } + + vector unRemovedTriggerWords; + vector unRemovedTriggerTimestamps; + for (int i = 0; i < unGroupedTriggerWords.size(); i++) + { + if (std::find(removeIndex.begin(), removeIndex.end(), i) == removeIndex.end()) + { + unRemovedTriggerWords.push_back(unGroupedTriggerWords.at(i)); + unRemovedTriggerTimestamps.push_back(unGroupedTriggerTimestamps.at(i)); + } + } + unGroupedTriggerTimestamps = unRemovedTriggerTimestamps; + unGroupedTriggerWords = unRemovedTriggerWords; + return true; +} + +bool LAPPDTreeMaker::GroupTriggerByLaser() +{ + // waiting for implementation + return true; +} + +void LAPPDTreeMaker::CleanTriggers() +{ + // only keep the last 1000 triggers + // create new vector to store the last 1000 triggers + if (unGroupedTriggerWords.size() > 1000) + { + std::vector lastTrigWords(unGroupedTriggerWords.end() - 1000, unGroupedTriggerWords.end()); + unGroupedTriggerWords = lastTrigWords; + std::vector lastTrigTimestamps(unGroupedTriggerTimestamps.end() - 1000, unGroupedTriggerTimestamps.end()); + unGroupedTriggerTimestamps = lastTrigTimestamps; + } +} + +void LAPPDTreeMaker::LoadLAPPDMapInfo() +{ + // cout << "LAPPDTreeMaker::LoadLAPPDMapInfo" << endl; + bool getMap = m_data->Stores["ANNIEEvent"]->Get("LAPPDDataMap", LAPPDDataMap); + bool gotBeamgates_ns = m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + bool gotTimeStamps_ns = m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + bool gotTimeStampsRaw = m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + bool gotBeamgatesRaw = m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + bool gotOffsets = m_data->Stores["ANNIEEvent"]->Get("LAPPDOffsets", LAPPDOffsets); + bool gotTSCorrection = m_data->Stores["ANNIEEvent"]->Get("LAPPDTSCorrection", LAPPDTSCorrection); + bool gotDBGCorrection = m_data->Stores["ANNIEEvent"]->Get("LAPPDBGCorrection", LAPPDBGCorrection); + bool gotOSInMinusPS = m_data->Stores["ANNIEEvent"]->Get("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + // cout << "LAPPDTreeMaker::LoadLAPPDMapInfo() get map = " << getMap << endl; + + if (getMap) + { + if (treeMakerVerbosity > 0) + cout << "map size: " << LAPPDDataMap.size() << endl; + for (auto &item : LAPPDDataMap) + { + PsecData thisData = item.second; + int thisLAPPD_ID = thisData.LAPPD_ID; + + uint64_t thisDataTime = item.first; + uint64_t thisTSRaw = LAPPDTimeStampsRaw.at(thisDataTime); + uint64_t thisBGRaw = LAPPDBeamgatesRaw.at(thisDataTime); + uint64_t thisOffset = LAPPDOffsets.at(thisDataTime); + int thisTSCorr = LAPPDTSCorrection.at(thisDataTime); + int thisDBGCorr = LAPPDBGCorrection.at(thisDataTime); + int thisOSInMinusPS = LAPPDOSInMinusPS.at(thisDataTime); + + if (treeMakerVerbosity > 0) + cout << "tree maker, Got LAPPD ID: " << thisLAPPD_ID << ", time stamp: " << thisDataTime << ", TSraw " << thisTSRaw << ", BGraw " << thisBGRaw << ", offset " << thisOffset << ", TSCorr " << thisTSCorr << ", DBGCorr " << thisDBGCorr << ", OSInMinusPS " << thisOSInMinusPS << endl; + + LAPPD_IDs.push_back(thisLAPPD_ID); + LAPPDMapTimeStampRaw.push_back(thisTSRaw); + LAPPDMapBeamgateRaw.push_back(thisBGRaw); + LAPPDMapOffsets.push_back(thisOffset); + LAPPDMapTSCorrections.push_back(thisTSCorr); + LAPPDMapBGCorrections.push_back(thisDBGCorr); + LAPPDMapOSInMinusPS.push_back(thisOSInMinusPS); + + if (treeMakerVerbosity > 0) + cout << "size of LAPPD_IDs: " << LAPPD_IDs.size() << endl; + } + } + else + { + cout << "LAPPDTreeMaker::LoadLAPPDMapInfo, no LAPPDDataMap found" << endl; + } +} \ No newline at end of file diff --git a/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.h b/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.h new file mode 100644 index 000000000..9fc491e2b --- /dev/null +++ b/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.h @@ -0,0 +1,185 @@ +#ifndef LAPPDTreeMaker_H +#define LAPPDTreeMaker_H + +#include +#include + +#include "Tool.h" +#include "TTree.h" +#include "TFile.h" +#include "TString.h" +#include "LAPPDPulse.h" +#include "LAPPDHit.h" +#include "Geometry.h" +#include "Position.h" +#include "PsecData.h" + +/** + * \class LAPPDTreeMaker + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. + * + * $Author: Yue Feng $ + * $Date: 2024/02/03 16:10:00 $ + * Contact: yuef@iastate.edu + */ +class LAPPDTreeMaker : public Tool +{ + +public: + LAPPDTreeMaker(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + void CleanVariables(); + bool FillPulseTree(); + bool FillHitTree(); + bool FillWaveformTree(); + bool FillPPSTimestamp(); + bool FillLAPPDDataTimeStamp(); + bool LoadRunInfoFromRaw(); + bool LoadRunInfoFromANNIEEvent(); + bool GroupTriggerByBeam(); + bool GroupTriggerByLaser(); + bool GroupPPSTrigger(); + bool FillTriggerTree(); + bool FillGroupedTriggerTree(); + void CleanTriggers(); + void LoadLAPPDMapInfo(); + +private: + TFile *file; + TTree *fPulse; + TTree *fHit; + TTree *fWaveform; + TTree *fTimeStamp; + TTree *fTrigger; + TTree *fGroupedTrigger; + + int treeMakerVerbosity; + bool LAPPDana; + bool LoadingPPS; + + bool LoadPulse; + bool LoadHit; + bool LoadWaveform; + bool LoadLAPPDDataTimeStamp; + bool LoadPPSTimestamp; + bool LoadRunInfoRaw; + bool LoadRunInfoANNIEEvent; + bool LoadTriggerInfo; + bool LoadGroupedTriggerInfo; + string LoadGroupOption; // using beam, or laser, or other. + + std::map>> lappdData; + std::map> waveformMax; // strip number+30*side, value + std::map> waveformRMS; + std::map> waveformMaxLast; + std::map> waveformMaxNearing; + std::map> waveformMaxTimeBin; + + map> *TriggerWordMap; + unsigned long CTCTimeStamp; + std::vector CTCTriggerWord; + int trigNumInThisMap; + int trigIndexInThisMap; + int TriggerGroupNumInThisEvent; + int groupedTriggerType; + + vector unGroupedTriggerWords; + vector unGroupedTriggerTimestamps; + vector> groupedTriggerWordsVector; + vector> groupedTriggerTimestampsVector; + vector groupedTriggerByType; + vector groupedTriggerWords; + vector groupedTriggerTimestamps; + + double waveformMaxValue; + double waveformRMSValue; + bool waveformMaxFoundNear; + double waveformMaxNearingValue; + int waveformMaxTimeBinValue; + + std::map>> lappdPulses; + std::map> lappdHits; + Geometry *_geom; + string treeMakerInputPulseLabel; + string treeMakerInputHitLabel; + string treeMakerOutputFileName; + + int EventNumber; // this is for LAPPD relate event number, data or PPS, not trigger!! + int StripNumber; + + int LAPPD_ID; + int ChannelID; + double PeakTime; + double Charge; + double PeakAmp; + double PulseStart; + double PulseEnd; + double PulseSize; + int PulseSide; + double PulseThreshold; + double PulseBaseline; + + double HitTime; + double HitAmp; + double XPosTank; + double YPosTank; + double ZPosTank; + double ParallelPos; + double TransversePos; + double Pulse1StartTime; + double Pulse2StartTime; + double Pulse1LastTime; + double Pulse2LastTime; + + unsigned long LAPPDDataTimeStampUL; + unsigned long LAPPDDataBeamgateUL; + unsigned long LAPPDDataTimestampPart1; + unsigned long LAPPDDataBeamgatePart1; + double LAPPDDataTimestampPart2; + double LAPPDDataBeamgatePart2; + + vector pps_vector; + vector pps_count_vector; + Long64_t ppsDiff; + unsigned long ppsCount0; + unsigned long ppsCount1; + unsigned long ppsTime0; // in clock tick, without 3.125ns + unsigned long ppsTime1; // in clock tick, without 3.125ns + + int RunNumber; + int SubRunNumber; + int PartFileNumber; + + bool MultiLAPPDMapTreeMaker; + vector LAPPD_IDs; + vector LAPPDMapTimeStampRaw; + vector LAPPDMapBeamgateRaw; + vector LAPPDMapOffsets; + vector LAPPDMapTSCorrections; + vector LAPPDMapBGCorrections; + vector LAPPDMapOSInMinusPS; + + std::map LAPPDDataMap; + std::map LAPPDBeamgate_ns; + std::map LAPPDTimeStamps_ns; // data and key are the same + std::map LAPPDTimeStampsRaw; + std::map LAPPDBeamgatesRaw; + std::map LAPPDOffsets; + std::map LAPPDTSCorrection; + std::map LAPPDBGCorrection; + std::map LAPPDOSInMinusPS; + + + uint64_t LTSRaw; + uint64_t LBGRaw; + uint64_t LOffset_ns; + int LTSCorrection; + int LBGCorrection; + int LOSInMinusPS; + uint64_t CTCPrimeTriggerTime; +}; + +#endif diff --git a/UserTools/LAPPDTreeMaker/README.md b/UserTools/LAPPDTreeMaker/README.md new file mode 100644 index 000000000..23363ae82 --- /dev/null +++ b/UserTools/LAPPDTreeMaker/README.md @@ -0,0 +1,20 @@ +# LAPPDTreeMaker + +LAPPDTreeMaker + +## Data + +Describe any data formats LAPPDTreeMaker creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for LAPPDTreeMaker. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/LoadANNIEEvent/LoadANNIEEvent.cpp b/UserTools/LoadANNIEEvent/LoadANNIEEvent.cpp index eca215941..a2b4537b3 100644 --- a/UserTools/LoadANNIEEvent/LoadANNIEEvent.cpp +++ b/UserTools/LoadANNIEEvent/LoadANNIEEvent.cpp @@ -176,6 +176,7 @@ bool LoadANNIEEvent::Execute() { std::string input_filename = input_filenames_.at(current_file_); bool filename_valid = false; filename_valid = theANNIEEvent->Initialise(input_filename); + Log("LoadANNIEEvent: Loading new file "+input_filename, 1, verbosity_); if (!filename_valid){ Log("LoadANNIEEvent: Filename "+input_filename+" not found! Proceed to next file",v_error,verbosity_); current_file_++; @@ -183,6 +184,8 @@ bool LoadANNIEEvent::Execute() { } m_data->Stores["ANNIEEvent"] = theANNIEEvent; m_data->Stores.at("ANNIEEvent")->Header->Get("TotalEntries",total_entries_in_file_); + Log("LoadANNIEEvent: total number of entry in this file is "+std::to_string(total_entries_in_file_), 1, verbosity_ ); + if (current_file_==0) { global_events.push_back(total_entries_in_file_); global_events_start.push_back(0); @@ -278,7 +281,7 @@ bool LoadANNIEEvent::Execute() { Log("ANNIEEvent store has "+std::to_string(total_entries_in_file_)+" entries",v_debug,verbosity_); Log("Loading entry " + std::to_string(current_entry_) + " from the" " ANNIEEvent input file \"" + input_filenames_.at(current_file_) - + '\"', 1, verbosity_); + + '\"', 2, verbosity_); if ((int)current_entry_ != offset_evnum) m_data->Stores["ANNIEEvent"]->Delete(); //ensures that we can access pointers without problems @@ -290,7 +293,9 @@ bool LoadANNIEEvent::Execute() { - if (global_evnr && !has_local){ m_data->Stores["ANNIEEvent"]->Set("EventNumber",global_ev); } + if (global_evnr && !has_local){ m_data->Stores["ANNIEEvent"]->Set("EventNumber",global_ev); + m_data->CStore.Set("EventNumberTree",global_ev); + } global_ev++; if ( current_entry_ >= total_entries_in_file_ ) { diff --git a/UserTools/LoadGeometry/LoadGeometry.cpp b/UserTools/LoadGeometry/LoadGeometry.cpp index d30bbc97e..e077e1f9a 100644 --- a/UserTools/LoadGeometry/LoadGeometry.cpp +++ b/UserTools/LoadGeometry/LoadGeometry.cpp @@ -77,7 +77,6 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ TankPMTCrateSpaceToChannelNumMap = new std::map,int>; ChannelNumToTankPMTSPEChargeMap = new std::map; ChannelNumToTankPMTTimingOffsetMap = new std::map; - ChannelNumToTankPMTTimingSigmaMap = new std::map; ChannelNumToTankPMTCrateSpaceMap = new std::map>; AuxCrateSpaceToChannelNumMap = new std::map,int>; AuxChannelNumToTypeMap = new std::map; @@ -113,7 +112,6 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ m_data->CStore.Set("ChannelNumToTankPMTCrateSpaceMap",ChannelNumToTankPMTCrateSpaceMap); m_data->CStore.Set("ChannelNumToTankPMTSPEChargeMap",ChannelNumToTankPMTSPEChargeMap); m_data->CStore.Set("ChannelNumToTankPMTTimingOffsetMap",ChannelNumToTankPMTTimingOffsetMap); - m_data->CStore.Set("ChannelNumToTankPMTTimingSigmaMap",ChannelNumToTankPMTTimingSigmaMap); m_data->CStore.Set("AuxCrateSpaceToChannelNumMap",AuxCrateSpaceToChannelNumMap); m_data->CStore.Set("AuxChannelNumToCrateSpaceMap",AuxChannelNumToCrateSpaceMap); m_data->CStore.Set("AuxChannelNumToTypeMap",AuxChannelNumToTypeMap); @@ -632,6 +630,22 @@ bool LoadGeometry::ParseTankPMTDataEntry(std::vector SpecLine, detstatus, 0.); + if (verbosity > 5) std::cout << "Filling a channel with PMT_type == " << PMT_type << ", PMT_type == LUX:" << (PMT_type == "LUX") << ", PMT_type == Hamamatsu:" << (PMT_type == "Hamamatsu") << std::endl; + int channelType = 0; + if (PMT_type == "LUX"){ + channelType = 1; + } else if (PMT_type == "ETEL"){ + channelType = 2; + } else if (PMT_type == "Hamamatsu"){ + channelType = 3; + } else if (PMT_type == "Watchboy"){ + channelType = 4; + } else if (PMT_type == "Watchman"){ + channelType = 5; + } else { + Log("LoadGeometry Tool: Loading UNDEFINED PMT type for channel "+std::to_string(channel_num),0,verbosity); + } + Channel pmtchannel( channel_num, Position(0,0,0.), -1, // stripside @@ -645,7 +659,8 @@ bool LoadGeometry::ParseTankPMTDataEntry(std::vector SpecLine, hv_crate, hv_slot, hv_channel, - chanstatus); //channel status same as detector status here + chanstatus, + channelType); //channel status same as detector status here // Also add this channel to the Tank PMT electronics map std::vector crate_map{signal_crate,signal_slot,signal_channel}; @@ -921,25 +936,21 @@ void LoadGeometry::LoadTankPMTGains(){ return; } -// load in both the timing offsets and uncertainties from the 2023 laser campaign void LoadGeometry::LoadTankPMTTimingOffsets(){ ifstream myfile(fTankPMTTimingOffsetFile.c_str()); std::string line; if (myfile.is_open()){ - // Timing offset file has columns: [0] chankey [1] PMT_location [2] offset value (ns) [3] sigma (ns) [4] notes + //Loop over lines, collect all detector data (should only be one line here) while(getline(myfile,line)){ if(verbosity>3) std::cout << line << std::endl; //has our stuff; if(line.find("#")!=std::string::npos) continue; std::vector DataEntries; boost::split(DataEntries,line, boost::is_any_of(","), boost::token_compress_on); int channelkey = -9999; - double TimingOffset = -9999; - double TimingSigma = -9999; + double TimingOffset = -9999.; channelkey = std::stoul(DataEntries.at(0)); TimingOffset= std::stod(DataEntries.at(2)); - TimingSigma = std::stod(DataEntries.at(3)); ChannelNumToTankPMTTimingOffsetMap->emplace(channelkey,TimingOffset); - ChannelNumToTankPMTTimingSigmaMap->emplace(channelkey,TimingSigma); } } return; diff --git a/UserTools/LoadGeometry/LoadGeometry.h b/UserTools/LoadGeometry/LoadGeometry.h index 8841ad510..9f4e2210a 100644 --- a/UserTools/LoadGeometry/LoadGeometry.h +++ b/UserTools/LoadGeometry/LoadGeometry.h @@ -69,7 +69,6 @@ class LoadGeometry: public Tool { std::map>* AuxChannelNumToCrateSpaceMap; std::map* ChannelNumToTankPMTSPEChargeMap; std::map* ChannelNumToTankPMTTimingOffsetMap; - std::map* ChannelNumToTankPMTTimingSigmaMap; std::map* AuxChannelNumToTypeMap; std::map,int>* LAPPDCrateSpaceToChannelNumMap; diff --git a/UserTools/LoadRawData/LoadRawData.cpp b/UserTools/LoadRawData/LoadRawData.cpp index d99d04225..d317657bf 100644 --- a/UserTools/LoadRawData/LoadRawData.cpp +++ b/UserTools/LoadRawData/LoadRawData.cpp @@ -179,7 +179,7 @@ bool LoadRawData::Execute(){ } FileCompleted = false; if (JumpBecauseLAPPD){ - //sometimes the LAPPD data in raw data file may have a very large entry number due to overflow + //something the LAPPD data in raw data file may have a very large entry number seems like because of overflow //then the whole loader will be stuck in the loop, so we need to jump to the next file //only set while loading with LAPPD, won't affect others FileCompleted = true; @@ -315,13 +315,13 @@ bool LoadRawData::Execute(){ LAPPDEntriesCompleted = true; LAPPDPaused = true; //if(TrigEntryNum < trigtotalentries) CTCPaused = false; - //when using ANNIEEventBuilder, the CTC data are usually pulsed at ~10 entries + //when use ANNIEEventBuilder, the CTC data are usually pulsed at ~10 entries //but if we also load the LAPPD data, the pulse will be canceled here //and there is no need to recheck everything is not paused again if(TankEntryNum < tanktotalentries) TankPaused = false; if(MRDEntryNum < mrdtotalentries) MRDPaused = false; } - if (lappdtotalentries < 0){ //some times the lappd broken data can give negative value + if (lappdtotalentries < 0){ //some time the lappd broken data can give negative value LAPPDEntriesCompleted = true; } diff --git a/UserTools/PMTDataDecoder/PMTDataDecoder.cpp b/UserTools/PMTDataDecoder/PMTDataDecoder.cpp index 00c6db28b..d6c1082da 100644 --- a/UserTools/PMTDataDecoder/PMTDataDecoder.cpp +++ b/UserTools/PMTDataDecoder/PMTDataDecoder.cpp @@ -52,6 +52,7 @@ bool PMTDataDecoder::Initialise(std::string configfile, DataModel &data){ m_variables.Get("saveBRFRaw",saveBRFRaw); RWMRawWaveforms = new std::map>; BRFRawWaveforms = new std::map>; + std::cout << "PMTDataDecoder Tool: Initialized successfully" << std::endl; return true; @@ -329,26 +330,55 @@ bool PMTDataDecoder::Execute(){ unsigned int uSlotNum = (unsigned int)SlotNum; unsigned int uChannelID = (unsigned int)ChannelID; - - //in MonitorTankTime tool, it load a file about active slot and crate, if not active, don't find the waveform in it. not sure do we need it or not - if(saveBRFRaw){ - if(uCrateNum == 1 && uSlotNum == 15 && ChannelID == 1) - { - std::vector BRFWaveform = apair.second; - (*BRFRawWaveforms)[timestamp] = BRFWaveform; - } - } - if(saveRWMRaw){ - if(uCrateNum == 1 && uSlotNum == 15 && ChannelID == 2) + //in MonitorTankTime tool, it load a file about active slot and crate, if not active, don't find the waveform in it. not sure do we need it or not + + if(RunNumber >= 5870) { - std::vector RWMWaveform = apair.second; - (*RWMRawWaveforms)[timestamp] = RWMWaveform; - } + // BRF is at crate 1, slot 2 , channel 1 after run 5870 (first run for beamyear 2025-2026) + // the timeline is: + // around 5870 we started taking beam runs to check DAQ was ok. no BNB + // run 5887 LAPPD IDs were changed. no BNB + // run 5896 BNB returns + // BRF is moved back to crate 1, slot 15, channel 1 and tested working since run 5914, by swapping the Level Translator + // The BRF (create 1, slot 15, channel 1), RWM (crate 1, slot 15, channel 3) and BES (crate 1, slot 3, channel 1) + if(saveBRFRaw){ + if(uCrateNum == 1 && uSlotNum == 15 && ChannelID == 1) + { + std::vector BRFWaveform = apair.second; + (*BRFRawWaveforms)[timestamp] = BRFWaveform; + } + } + + if(saveRWMRaw){ + if(uCrateNum == 1 && uSlotNum == 15 && ChannelID == 3) + { + std::vector RWMWaveform = apair.second; + (*RWMRawWaveforms)[timestamp] = RWMWaveform; + } + } + }else{ + // BRF is at crate 1, slot 15 , channel 1 after run 5870 (first run for beamyear 2025-2026) + if(saveBRFRaw){ + if(uCrateNum == 1 && uSlotNum == 15 && ChannelID == 1) + { + std::vector BRFWaveform = apair.second; + (*BRFRawWaveforms)[timestamp] = BRFWaveform; + } + } + + if(saveRWMRaw){ + if(uCrateNum == 1 && uSlotNum == 15 && ChannelID == 2) + { + std::vector RWMWaveform = apair.second; + (*RWMRawWaveforms)[timestamp] = RWMWaveform; + } + } } + + } } } - m_data->CStore.Set("RWMRawWaveforms",RWMRawWaveforms); m_data->CStore.Set("BRFRawWaveforms",BRFRawWaveforms); diff --git a/UserTools/PMTDataDecoder/PMTDataDecoder.h b/UserTools/PMTDataDecoder/PMTDataDecoder.h index 8972b3950..6963f7af2 100644 --- a/UserTools/PMTDataDecoder/PMTDataDecoder.h +++ b/UserTools/PMTDataDecoder/PMTDataDecoder.h @@ -132,9 +132,11 @@ class PMTDataDecoder: public Tool { int vv_debug=4; std::string logmessage; + //option about whether to save raw RWM and BRF waveforms bool saveRWMRaw; bool saveBRFRaw; + std::map>* RWMRawWaveforms; //Key: MTCTime, Value: RWM waveform std::map>* BRFRawWaveforms; //Key: MTCTime, Value: BRF waveform diff --git a/UserTools/PhaseIIADCCalibrator/PhaseIIADCCalibrator.cpp b/UserTools/PhaseIIADCCalibrator/PhaseIIADCCalibrator.cpp index a85341ac1..bcca11115 100644 --- a/UserTools/PhaseIIADCCalibrator/PhaseIIADCCalibrator.cpp +++ b/UserTools/PhaseIIADCCalibrator/PhaseIIADCCalibrator.cpp @@ -723,20 +723,27 @@ PhaseIIADCCalibrator::make_calibrated_waveforms_ze3ra_multi( // come from the same readout for the same channel) std::vector< CalibratedADCWaveform > calibrated_waveforms; for (const auto& raw_waveform : raw_waveforms) { - std::vector baselines; + std::vector baselines; + std::vector sigma_baselines; std::vector RepresentationRegion; - double first_baseline=0; - double first_sigma_baseline; + bool isFirst = true; + double first_baseline, first_sigma_baseline; double baseline, sigma_baseline; const size_t nsamples = raw_waveform.Samples().size(); for(size_t starting_sample = 0; starting_sample < nsamples; starting_sample += baseline_rep_samples){ double baseline, sigma_baseline; ze3ra_baseline(raw_waveform, baseline, sigma_baseline, num_baseline_samples,starting_sample); - if(sigma_baseline4) std::cout << "BASELINE UNCERTAINTY BEYOND SET THRESHOLD. IGNORING SAMPLE" << std::endl; } } @@ -746,6 +753,7 @@ PhaseIIADCCalibrator::make_calibrated_waveforms_ze3ra_multi( if(verbosity>4) std::cout << "NO BASLINE FOUND WITHIN TOLERANCE. USING FIRST AS BEST ESTIMATE" << std::endl; RepresentationRegion.push_back(baseline_rep_samples); baselines.push_back(first_baseline); + sigma_baselines.push_back(first_sigma_baseline); } std::vector cal_data; const std::vector& raw_data = raw_waveform.Samples(); @@ -762,10 +770,23 @@ PhaseIIADCCalibrator::make_calibrated_waveforms_ze3ra_multi( } } } - double bl_estimates_mean, bl_estimates_var; - ComputeMeanAndVariance(baselines, bl_estimates_mean, bl_estimates_var); + double bl_estimates_mean = 0; + double bl_estimates_sigma = 0; + + // When averaging multiple means you need to average the variances as well + // We don't want to use the variance of the mean of all the baselines. + // If there is only one baseline then the variance is 0 if you do that... + for (size_t idx = 0; idx < baselines.size(); ++idx) { + bl_estimates_mean += baselines[idx]; + bl_estimates_sigma += pow(sigma_baselines[idx],2); + } + bl_estimates_sigma = sqrt(bl_estimates_sigma / double(baselines.size())); + bl_estimates_mean = bl_estimates_mean / double(baselines.size()); + + // ComputeMeanAndVariance(baselines, bl_estimates_mean, bl_estimates_var, std::numeric_limits::max(), 0, 7); + calibrated_waveforms.emplace_back(raw_waveform.GetStartTime(), - cal_data, bl_estimates_mean, bl_estimates_var); + cal_data, bl_estimates_mean, bl_estimates_sigma); } return calibrated_waveforms; } diff --git a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp index f1a48b62d..83a1519fd 100755 --- a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp +++ b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp @@ -79,8 +79,7 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat m_data->CStore.Get("AuxChannelNumToTypeMap",AuxChannelNumToTypeMap); // Get the timing offsets - if (!mc_waveforms) // (don't need them for MC) - m_data->CStore.Get("ChannelNumToTankPMTTimingOffsetMap",ChannelKeyToTimingOffsetMap); + m_data->CStore.Get("ChannelNumToTankPMTTimingOffsetMap",ChannelKeyToTimingOffsetMap); //Recreate maps that were deleted with ANNIEEvent->Delete() ANNIEEventBuilder tool hit_map = new std::map>; @@ -763,12 +762,13 @@ std::vector PhaseIIADCHitFinder::find_pulses_bywindow( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>2 && !mc_waveforms){ + if(verbosity>2){ std::cout << "Didn't find Timing offset for channel " << channel_key << std::endl; } } - // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + std::vector trace_x; std::vector trace_y; @@ -892,12 +892,13 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>v_error && !mc_waveforms){ + if(verbosity>v_error){ std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel... setting this channel's offset to 0ns" << channel_key << std::endl; } } - // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + std::vector trace_x; std::vector trace_y; @@ -911,6 +912,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( trace_y.push_back(val_adc - pulse_baseline); } + // Store the freshly made pulse in the vector of found pulses pulses.emplace_back(channel_key, ( pulse_start_sample * NS_PER_ADC_SAMPLE )-timing_offset, @@ -918,7 +920,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( calibrated_minibuffer_data.GetBaseline(), calibrated_minibuffer_data.GetSigmaBaseline(), raw_area, max_ADC, calibrated_amplitude, charge, - trace_x, trace_y); + trace_x, trace_y); } @@ -935,17 +937,17 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( size_t pulse_start_sample = BOGUS_INT; size_t pulse_end_sample = BOGUS_INT; - // loop through samples until we find a pulse, then extract pulse parameters + // loop through samples until we find a pulse, then extraction pulse parameters for (size_t s = 0; s < num_samples; ++s) { // if any values are above threshold, we have found a pulse if ( !in_pulse && raw_minibuffer_data.GetSample(s) > adc_threshold ) { in_pulse = true; - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: FOUND PULSE" << std::endl; + if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: FOUND PULSE" << std::endl; // for cases that are very early in the buffer, we can just assign the pulse start as 0 to avoid errors if (static_cast(s) - 5 < 0) { - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Pulse found is VERY EARLY in the minibuffer (< 5 samples)... assigning pulse start as 0" << std::endl; + if(verbosity>v_debug) std::cout << "Pulse found is VERY EARLY in the minibuffer (< 5 samples)... assigning pulse start as 0" << std::endl; pulse_start_sample = 0; } @@ -962,7 +964,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( } else { - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Baseline crossing is VERY EARLY in the minibuffer (< 5 samples)... assigning pulse start as 0" << std::endl; + if(verbosity>v_debug) std::cout << "Baseline crossing is VERY EARLY in the minibuffer (< 5 samples)... assigning pulse start as 0" << std::endl; pulse_start_sample = 0; } @@ -974,7 +976,9 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( // if pulsewinleft reaches 0 without finding a baseline crossing (maybe ringing?), hault it at 0 and assign pulse start // TODO: figure out what is wrong with these pulses if (pulsewinleft == 0) { - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Baseline crossing was not found... assigning pulse start as 0" << std::endl; + if (verbosity > v_debug) { + std::cout << "Baseline crossing was not found... assigning pulse start as 0" << std::endl; + } pulse_start_sample = 0; } } @@ -985,18 +989,19 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( in_pulse = false; if (s == num_samples - 1) { - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Pulse found is VERY LATE in the minibuffer (we're at the final sample)... forcing pulse to end" << std::endl; + if(verbosity>v_debug) std::cout << "Pulse found is VERY LATE in the minibuffer (we're at the final sample)... forcing pulse to end" << std::endl; pulse_end_sample = s; } else { pulse_end_sample = (s + 5 < (num_samples - 1)) ? (s + 5) : (num_samples - 1); // ensure we don't exceed the buffer } // double check that pulse start and stop were found successfully - if (verbosity > v_debug) { - std::cout << "PhaseIIADCHitFinder: Pulse start and end determined! (" << pulse_start_sample + if (verbosity > v_debug) { + std::cout << "Pulse start and end determined! (" << pulse_start_sample << ", " << pulse_end_sample << ")" << std::endl; } + // Integrate the pulse to get its area. Use a Riemann sum. Also get // the raw amplitude (maximum ADC value within the pulse) and the // sample at which the peak occurs. @@ -1035,8 +1040,8 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>v_error && !mc_waveforms){ - std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel " << channel_key << "... setting this channel's offset to 0ns" << std::endl; + if(verbosity>v_error){ + std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel... setting this channel's offset to 0ns" << channel_key << std::endl; } } @@ -1059,7 +1064,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( // Perform simple linear interpolation to find exact crossing point if (hit_time_found) { - if(verbosity>v_debug) std::cout << "Interpolating hit time..." << std::endl; + if(verbosity>v_debug) std::cout << "Interpolating hit time..." << std::endl; if (hit_time > pulse_start_sample && hit_time < pulse_end_sample) { double x1 = hit_time; double x2 = hit_time + 1.0; @@ -1069,9 +1074,11 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( } } - // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + std::vector trace_x; std::vector trace_y; + double pulse_start_time = pulse_start_sample * NS_PER_ADC_SAMPLE; double pulse_baseline = calibrated_minibuffer_data.GetBaseline(); @@ -1082,22 +1089,26 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( trace_y.push_back(val_adc - pulse_baseline); } - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; - - if (hit_time < 0.0) { - if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Hit time is negative! Defaulting to peak time" << std::endl; - hit_time = peak_sample; - } - - if(verbosity>v_debug) { - std::cout << "PhaseIIADCHitFinder: Pulse properties: " << std::endl; - std::cout << " chanID: " << channel_key << std::endl; - std::cout << " charge: " << ( charge ) << std::endl; - std::cout << " start time: " << ( pulse_start_sample ) << std::endl; - std::cout << " hit time: " << ( hit_time ) << std::endl; - std::cout << " stop time: " << ( pulse_end_sample ) << std::endl; - } - + if(verbosity>v_debug) { + + std::cout << "Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; + + if (hit_time < 0.0) { + // If for some reason the interpolation finds a negative time value (if the pulse is extremely early in the buffer), + // default to the peak time (maximum ADC value of the pulse) + std::cout << "Hit time is negative! Defaulting to peak time" << std::endl; + hit_time = peak_sample; + } + + std::cout << "Pulse properties: " << std::endl; + std::cout << " chanID: " << channel_key << std::endl; + std::cout << " charge: " << ( charge ) << std::endl; + std::cout << " start time: " << ( pulse_start_sample ) << std::endl; + std::cout << " hit time: " << ( hit_time ) << std::endl; + std::cout << " stop time: " << ( pulse_end_sample ) << std::endl; + + } + // Store the freshly made pulse in the vector of found pulses pulses.emplace_back(channel_key, ( pulse_start_sample * NS_PER_ADC_SAMPLE )-timing_offset, @@ -1105,12 +1116,13 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( calibrated_minibuffer_data.GetBaseline(), calibrated_minibuffer_data.GetSigmaBaseline(), raw_area, max_ADC, calibrated_amplitude, charge, - trace_x, trace_y); + trace_x, trace_y); } } // ****************************************************************** + // Previously used in the event building // Peak windows are defined only by crossing and un-crossing of ADC threshold } else if(pulse_window_type == "dynamic"){ size_t pulse_start_sample = BOGUS_INT; @@ -1171,7 +1183,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>v_error && !mc_waveforms){ + if(verbosity>v_error){ std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel... setting this channel's offset to 0ns" << channel_key << std::endl; } } @@ -1205,9 +1217,23 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( } } - // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + if(verbosity>v_debug) { + + std::cout << "Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; + + if (hit_time < 0.0) { + // If for some reason the interpolation finds a negative time value (if the pulse is extremely early in the buffer), + // default to the peak time (maximum ADC value of the pulse) + std::cout << "Hit time is negative! Defaulting to peak time" << std::endl; + hit_time = peak_sample; + } + } + + // extract the x and y points of the pulse (subtract off baseline and "zero" the pulse to the pulse start) + std::vector trace_x; std::vector trace_y; + double pulse_start_time = pulse_start_sample * NS_PER_ADC_SAMPLE; double pulse_baseline = calibrated_minibuffer_data.GetBaseline(); @@ -1218,27 +1244,6 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( trace_y.push_back(val_adc - pulse_baseline); } - if (hit_time < 0.0) { - // If for some reason the interpolation finds a negative time value (if the pulse is extremely early in the buffer), - // default to the peak time (maximum ADC value of the pulse) - std::cout << "Hit time is negative! Defaulting to peak time" << std::endl; - hit_time = peak_sample; - } - - if(verbosity>v_debug) { - - std::cout << "Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; - - std::cout << "Pulse properties: " << std::endl; - std::cout << " chanID: " << channel_key << std::endl; - std::cout << " charge: " << ( charge ) << std::endl; - std::cout << " start time: " << ( pulse_start_sample ) << std::endl; - std::cout << " hit time: " << ( hit_time ) << std::endl; - std::cout << " stop time: " << ( pulse_end_sample ) << std::endl; - std::cout << " pulse width: " << ( pulse_end_sample - pulse_start_sample ) << std::endl; - - } - // Store the freshly made pulse in the vector of found pulses pulses.emplace_back(channel_key, diff --git a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp index d952cd04f..a1853bbfe 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp @@ -34,6 +34,8 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ m_variables.Get("SimpleReco_fill", SimpleReco_fill); m_variables.Get("RingCounting_fill", RingCounting_fill); m_variables.Get("muonTruthRecoDiff_fill", muonTruthRecoDiff_fill); + m_variables.Get("LAPPDData_fill", LAPPDData_fill); + m_variables.Get("LAPPDReco_fill", LAPPDReco_fill); m_variables.Get("SiPMPulseInfo_fill",SiPMPulseInfo_fill); m_variables.Get("TankClusterProcessing",TankClusterProcessing); @@ -114,19 +116,47 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITankClusterTree->Branch("SiPM1NPulses",&fSiPM1NPulses,"SiPM1NPulses/I"); fPhaseIITankClusterTree->Branch("SiPM2NPulses",&fSiPM2NPulses,"SiPM2NPulses/I"); } - //MuonFitter reco track length, vtx, energy; juju - if (MuonFitter_fill) + if(LAPPDData_fill) { - fPhaseIITankClusterTree->Branch("recoMuonVtxX", &fRecoMuonVtxX, "recoMuonVtxX/D"); - fPhaseIITankClusterTree->Branch("recoMuonVtxY", &fRecoMuonVtxY, "recoMuonVtxY/D"); - fPhaseIITankClusterTree->Branch("recoMuonVtxZ", &fRecoMuonVtxZ, "recoMuonVtxZ/D"); - fPhaseIITankClusterTree->Branch("recoTankTrack", &fRecoTankTrack, "recoTankTrack/D"); - fPhaseIITankClusterTree->Branch("recoMuonKE", &fRecoMuonKE, "recoMuonKE/D"); - } - // MC BNB spill structure timing - AssignBunchTimingMC tool - if(hasBNBtimingMC){ - fPhaseIITankClusterTree->Branch("bunchTimes",&fbunchTimes,"bunchTimes/D"); - } + fPhaseIITankClusterTree->Branch("LAPPD_ID",&fLAPPD_ID); + fPhaseIITankClusterTree->Branch("LAPPD_Beamgate_ns",&fLAPPD_Beamgate_ns); + fPhaseIITankClusterTree->Branch("LAPPD_Timestamp_ns",&fLAPPD_Timestamp_ns); + fPhaseIITankClusterTree->Branch("LAPPD_Beamgate_Raw",&fLAPPD_Beamgate_Raw); + fPhaseIITankClusterTree->Branch("LAPPD_Timestamp_Raw",&fLAPPD_Timestamp_Raw); + fPhaseIITankClusterTree->Branch("LAPPD_Offset",&fLAPPD_Offset); + fPhaseIITankClusterTree->Branch("LAPPD_TSCorrection",&fLAPPD_TSCorrection); + fPhaseIITankClusterTree->Branch("LAPPD_BGCorrection",&fLAPPD_BGCorrection); + fPhaseIITankClusterTree->Branch("LAPPD_OSInMinusPS",&fLAPPD_OSInMinusPS); + + fPhaseIITankClusterTree->Branch("GroupedTriggerTime",&fGroupedTriggerTime); + fPhaseIITankClusterTree->Branch("GroupedTriggerWord",&fGroupedTriggerWord); + + if(LAPPDReco_fill) + { + fPhaseIITankClusterTree->Branch("LAPPD_PulseIDs",&fLAPPD_IDs); + fPhaseIITankClusterTree->Branch("LAPPD_ChannelID",&fChannelID); + fPhaseIITankClusterTree->Branch("LAPPD_PeakTime",&fPulsePeakTime); + fPhaseIITankClusterTree->Branch("LAPPD_PeakAmp",&fPulsePeakAmp); + fPhaseIITankClusterTree->Branch("LAPPD_Charge",&fPulseCharge); + fPhaseIITankClusterTree->Branch("LAPPD_PulseStart",&fPulseStart); + fPhaseIITankClusterTree->Branch("LAPPD_PulseEnd",&fPulseEnd); + fPhaseIITankClusterTree->Branch("LAPPD_PulseWidth",&fPulseWidth); + fPhaseIITankClusterTree->Branch("LAPPD_PulseSide",&fPulseSide); + fPhaseIITankClusterTree->Branch("LAPPD_PulseStripNum",&fPulseStripNum); + + fPhaseIITankClusterTree->Branch("LAPPDID_Hit",&fLAPPDHit_IDs); + fPhaseIITankClusterTree->Branch("LAPPDHitChannel",&fLAPPDHitChannel); + fPhaseIITankClusterTree->Branch("LAPPDHitStrip",&fLAPPDHitStrip); + fPhaseIITankClusterTree->Branch("LAPPDHitTime",&fLAPPDHitTime); + fPhaseIITankClusterTree->Branch("LAPPDHitAmp",&fLAPPDHitAmp); + fPhaseIITankClusterTree->Branch("LAPPDHitParallelPos",&fLAPPDHitParallelPos); + fPhaseIITankClusterTree->Branch("LAPPDHitTransversePos",&fLAPPDHitTransversePos); + fPhaseIITankClusterTree->Branch("LAPPDHitP1StartTime",&fLAPPDHitP1StartTime); + fPhaseIITankClusterTree->Branch("LAPPDHitP2StartTime",&fLAPPDHitP2StartTime); + fPhaseIITankClusterTree->Branch("LAPPDHitP1EndTime",&fLAPPDHitP1EndTime); + fPhaseIITankClusterTree->Branch("LAPPDHitP2EndTime",&fLAPPDHitP2EndTime); + } + } } if(MRDClusterProcessing){ @@ -183,6 +213,49 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIIMRDClusterTree->Branch("MRDThrough",&fMRDThrough); } + if(LAPPDData_fill) + { + fPhaseIIMRDClusterTree->Branch("LAPPD_ID",&fLAPPD_ID); + fPhaseIIMRDClusterTree->Branch("LAPPD_Beamgate_ns",&fLAPPD_Beamgate_ns); + fPhaseIIMRDClusterTree->Branch("LAPPD_Timestamp_ns",&fLAPPD_Timestamp_ns); + fPhaseIIMRDClusterTree->Branch("LAPPD_Beamgate_Raw",&fLAPPD_Beamgate_Raw); + fPhaseIIMRDClusterTree->Branch("LAPPD_Timestamp_Raw",&fLAPPD_Timestamp_Raw); + fPhaseIIMRDClusterTree->Branch("LAPPD_Offset",&fLAPPD_Offset); + fPhaseIIMRDClusterTree->Branch("LAPPD_TSCorrection",&fLAPPD_TSCorrection); + fPhaseIIMRDClusterTree->Branch("LAPPD_BGCorrection",&fLAPPD_BGCorrection); + fPhaseIIMRDClusterTree->Branch("LAPPD_OSInMinusPS",&fLAPPD_OSInMinusPS); + + fPhaseIIMRDClusterTree->Branch("GroupedTriggerTime",&fGroupedTriggerTime); + fPhaseIIMRDClusterTree->Branch("GroupedTriggerWord",&fGroupedTriggerWord); + + if(LAPPDReco_fill) + { + fPhaseIIMRDClusterTree->Branch("LAPPD_PulseIDs",&fLAPPD_IDs); + fPhaseIIMRDClusterTree->Branch("LAPPD_ChannelID",&fChannelID); + fPhaseIIMRDClusterTree->Branch("LAPPD_PeakTime",&fPulsePeakTime); + fPhaseIIMRDClusterTree->Branch("LAPPD_PeakAmp",&fPulsePeakAmp); + fPhaseIIMRDClusterTree->Branch("LAPPD_Charge",&fPulseCharge); + fPhaseIIMRDClusterTree->Branch("LAPPD_PulseStart",&fPulseStart); + fPhaseIIMRDClusterTree->Branch("LAPPD_PulseEnd",&fPulseEnd); + fPhaseIIMRDClusterTree->Branch("LAPPD_PulseWidth",&fPulseWidth); + fPhaseIIMRDClusterTree->Branch("LAPPD_PulseSide",&fPulseSide); + fPhaseIIMRDClusterTree->Branch("LAPPD_PulseStripNum",&fPulseStripNum); + + fPhaseIIMRDClusterTree->Branch("LAPPDID_Hit",&fLAPPDHit_IDs); + fPhaseIIMRDClusterTree->Branch("LAPPDHitChannel",&fLAPPDHitChannel); + fPhaseIIMRDClusterTree->Branch("LAPPDHitStrip",&fLAPPDHitStrip); + fPhaseIIMRDClusterTree->Branch("LAPPDHitTime",&fLAPPDHitTime); + fPhaseIIMRDClusterTree->Branch("LAPPDHitAmp",&fLAPPDHitAmp); + fPhaseIIMRDClusterTree->Branch("LAPPDHitParallelPos",&fLAPPDHitParallelPos); + fPhaseIIMRDClusterTree->Branch("LAPPDHitTransversePos",&fLAPPDHitTransversePos); + fPhaseIIMRDClusterTree->Branch("LAPPDHitP1StartTime",&fLAPPDHitP1StartTime); + fPhaseIIMRDClusterTree->Branch("LAPPDHitP2StartTime",&fLAPPDHitP2StartTime); + fPhaseIIMRDClusterTree->Branch("LAPPDHitP1EndTime",&fLAPPDHitP1EndTime); + fPhaseIIMRDClusterTree->Branch("LAPPDHitP2EndTime",&fLAPPDHitP2EndTime); + } + + } + } if(TriggerProcessing){ @@ -514,6 +587,48 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITrigTree->Branch("deltaZenith",&fDeltaZenith,"deltaZenith/D"); fPhaseIITrigTree->Branch("deltaAngle",&fDeltaAngle,"deltaAngle/D"); } + + if(LAPPDData_fill) + { + fPhaseIITrigTree->Branch("LAPPD_ID",&fLAPPD_ID); + fPhaseIITrigTree->Branch("LAPPD_Beamgate_ns",&fLAPPD_Beamgate_ns); + fPhaseIITrigTree->Branch("LAPPD_Timestamp_ns",&fLAPPD_Timestamp_ns); + fPhaseIITrigTree->Branch("LAPPD_Beamgate_Raw",&fLAPPD_Beamgate_Raw); + fPhaseIITrigTree->Branch("LAPPD_Timestamp_Raw",&fLAPPD_Timestamp_Raw); + fPhaseIITrigTree->Branch("LAPPD_Offset",&fLAPPD_Offset); + fPhaseIITrigTree->Branch("LAPPD_TSCorrection",&fLAPPD_TSCorrection); + fPhaseIITrigTree->Branch("LAPPD_BGCorrection",&fLAPPD_BGCorrection); + fPhaseIITrigTree->Branch("LAPPD_OSInMinusPS",&fLAPPD_OSInMinusPS); + + fPhaseIITrigTree->Branch("GroupedTriggerTime",&fGroupedTriggerTime); + fPhaseIITrigTree->Branch("GroupedTriggerWord",&fGroupedTriggerWord); + + if(LAPPDReco_fill) + { + fPhaseIITrigTree->Branch("LAPPD_PulseIDs",&fLAPPD_IDs); + fPhaseIITrigTree->Branch("LAPPD_ChannelID",&fChannelID); + fPhaseIITrigTree->Branch("LAPPD_PeakTime",&fPulsePeakTime); + fPhaseIITrigTree->Branch("LAPPD_PeakAmp",&fPulsePeakAmp); + fPhaseIITrigTree->Branch("LAPPD_Charge",&fPulseCharge); + fPhaseIITrigTree->Branch("LAPPD_PulseStart",&fPulseStart); + fPhaseIITrigTree->Branch("LAPPD_PulseEnd",&fPulseEnd); + fPhaseIITrigTree->Branch("LAPPD_PulseWidth",&fPulseWidth); + fPhaseIITrigTree->Branch("LAPPD_PulseSide",&fPulseSide); + fPhaseIITrigTree->Branch("LAPPD_PulseStripNum",&fPulseStripNum); + + fPhaseIITrigTree->Branch("LAPPDID_Hit",&fLAPPDHit_IDs); + fPhaseIITrigTree->Branch("LAPPDHitChannel",&fLAPPDHitChannel); + fPhaseIITrigTree->Branch("LAPPDHitStrip",&fLAPPDHitStrip); + fPhaseIITrigTree->Branch("LAPPDHitTime",&fLAPPDHitTime); + fPhaseIITrigTree->Branch("LAPPDHitAmp",&fLAPPDHitAmp); + fPhaseIITrigTree->Branch("LAPPDHitParallelPos",&fLAPPDHitParallelPos); + fPhaseIITrigTree->Branch("LAPPDHitTransversePos",&fLAPPDHitTransversePos); + fPhaseIITrigTree->Branch("LAPPDHitP1StartTime",&fLAPPDHitP1StartTime); + fPhaseIITrigTree->Branch("LAPPDHitP2StartTime",&fLAPPDHitP2StartTime); + fPhaseIITrigTree->Branch("LAPPDHitP1EndTime",&fLAPPDHitP1EndTime); + fPhaseIITrigTree->Branch("LAPPDHitP2EndTime",&fLAPPDHitP2EndTime); + } + } } return true; } @@ -522,10 +637,32 @@ bool PhaseIITreeMaker::Execute(){ Log("===========================================================================================",v_debug,verbosity); Log("PhaseIITreeMaker Tool: Executing",v_debug,verbosity); +/* + std::map checkDataStreams; + m_data->Stores.at("ANNIEEvent")->Get("DataStreams",checkDataStreams); + //print out the data streams + if(checkDataStreams["LAPPD"]==1){ + m_data->Stores.at("ANNIEEvent")->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + m_data->Stores.at("ANNIEEvent")->Get("LAPPDOffsets", LAPPDOffsets); + //check they have the same size, if not print in log + if(LAPPDTimeStamps_ns.size() != LAPPDOffsets.size()){ + Log("PhaseIITreeMaker Tool: LAPPD Time Stamps and Offsets are not the same size!",v_message,verbosity); + }else{ + cout<<"LAPPDTimeStamps_ns size is: "<ResetVariables(); + if (LAPPDData_fill) this->LoadLAPPDData(); + fClusterNumber = cluster_num; //Standard run level information - Log("PhaseIITreeMaker Tool: Getting run level information from ANNIEEvent",v_debug,verbosity); + Log("PhaseIITreeMaker Tool: tank cluster, Getting run level information from ANNIEEvent",v_debug,verbosity); + // m_data->Stores.at("ANNIEEvent")->Print(false); + m_data->Stores.at("ANNIEEvent")->Get("RunNumber",fRunNumber); m_data->Stores.at("ANNIEEvent")->Get("SubrunNumber",fSubrunNumber); m_data->Stores.at("ANNIEEvent")->Get("RunType",fRunType); m_data->Stores.at("ANNIEEvent")->Get("RunStartTime",fStartTime); - fStartTime_Tree = (ULong64_t) fStartTime; + uint64_t primaryTrigTime = 0; + m_data->Stores.at("ANNIEEvent")->Get("PrimaryTriggerTime", primaryTrigTime); + + fStartTime_Tree = (ULong64_t) primaryTrigTime; // ANNIE Event number m_data->Stores.at("ANNIEEvent")->Get("EventTimeTank",fEventTimeTank); fEventTimeTank_Tree = (ULong64_t) fEventTimeTank; @@ -625,10 +769,19 @@ bool PhaseIITreeMaker::Execute(){ fTriggerword = int(trigword_tmp); m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); BeamStatus beamstat; - m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + bool get_beamstat = m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + + if(get_beamstat) + { if (beamstat.ok()) fBeamok = 1; else fBeamok = 0; fPot = beamstat.pot(); + }else{ + bool gotfBeamok = m_data->Stores["ANNIEEvent"]->Get("beam_good",fBeamok); + bool gotpot = m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR875",fPot); + if(!gotfBeamok) fBeamok = 0; + if(!gotpot) fPot = -99999; + } bool pmtmrdcoinc, noveto; m_data->Stores.at("RecoEvent")->Get("PMTMRDCoinc",pmtmrdcoinc); @@ -798,10 +951,20 @@ bool PhaseIITreeMaker::Execute(){ fTriggerword = int(trigword_temp); m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); BeamStatus beamstat; - m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + bool get_beamstat = m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + + if(get_beamstat) + { if (beamstat.ok()) fBeamok = 1; else fBeamok = 0; fPot = beamstat.pot(); + }else{ + bool gotfBeamok = m_data->Stores["ANNIEEvent"]->Get("beam_good",fBeamok); + bool gotpot = m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR875",fPot); + if(!gotfBeamok) fBeamok = 0; + if(!gotpot) fPot = -99999; + } + bool pmtmrdcoinc, noveto; m_data->Stores.at("RecoEvent")->Get("PMTMRDCoinc",pmtmrdcoinc); m_data->Stores.at("RecoEvent")->Get("NoVeto",noveto); @@ -874,12 +1037,17 @@ bool PhaseIITreeMaker::Execute(){ //FIXME: calculate fMRDClusterTime //Standard run level information - Log("PhaseIITreeMaker Tool: Getting run level information from ANNIEEvent",v_debug,verbosity); + Log("PhaseIITreeMaker Tool: MRD cluster, Getting run level information from ANNIEEvent",v_debug,verbosity); + + // // m_data->Stores.at("ANNIEEvent")->Print(false); + m_data->Stores.at("ANNIEEvent")->Get("RunNumber",fRunNumber); m_data->Stores.at("ANNIEEvent")->Get("SubrunNumber",fSubrunNumber); m_data->Stores.at("ANNIEEvent")->Get("RunType",fRunType); m_data->Stores.at("ANNIEEvent")->Get("RunStartTime",fStartTime); - fStartTime_Tree = (ULong64_t) fStartTime; + uint64_t primaryTrigTime = 0; + m_data->Stores.at("ANNIEEvent")->Get("PrimaryTriggerTime", primaryTrigTime); + fStartTime_Tree = (ULong64_t) primaryTrigTime; m_data->Stores.at("ANNIEEvent")->Get("EventNumber",fEventNumber); m_data->Stores.at("ANNIEEvent")->Get("EventTimeTank",fEventTimeTank); fEventTimeTank_Tree = (ULong64_t) fEventTimeTank; @@ -894,6 +1062,7 @@ bool PhaseIITreeMaker::Execute(){ fNumClusterTracks = this->LoadMRDTrackReco(i); //Get the track info } + if (LAPPDData_fill) this->LoadLAPPDData(); fPhaseIIMRDClusterTree->Fill(); cluster_num += 1; @@ -902,14 +1071,18 @@ bool PhaseIITreeMaker::Execute(){ if(TriggerProcessing) { - Log("PhaseIITreeMaker Tool: Getting run level information from ANNIEEvent",v_debug,verbosity); + Log("PhaseIITreeMaker Tool: trigger, Getting run level information from ANNIEEvent",v_debug,verbosity); + // m_data->Stores.at("ANNIEEvent")->Print(false); + this->ResetVariables(); m_data->Stores.at("ANNIEEvent")->Get("RunNumber",fRunNumber); m_data->Stores.at("ANNIEEvent")->Get("SubrunNumber",fSubrunNumber); m_data->Stores.at("ANNIEEvent")->Get("RunType",fRunType); m_data->Stores.at("ANNIEEvent")->Get("RunStartTime",fStartTime); - fStartTime_Tree = (ULong64_t) fStartTime; + uint64_t primaryTrigTime = 0; + m_data->Stores.at("ANNIEEvent")->Get("PrimaryTriggerTime", primaryTrigTime); + fStartTime_Tree = (ULong64_t) primaryTrigTime; // ANNIE Event number m_data->Stores.at("ANNIEEvent")->Get("EventNumber",fEventNumber); @@ -923,10 +1096,19 @@ bool PhaseIITreeMaker::Execute(){ fTriggerword = int(trigword_temp); m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); BeamStatus beamstat; - m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + bool get_beamstat = m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + + if(get_beamstat) + { if (beamstat.ok()) fBeamok = 1; else fBeamok = 0; fPot = beamstat.pot(); + }else{ + bool gotfBeamok = m_data->Stores["ANNIEEvent"]->Get("beam_good",fBeamok); + bool gotpot = m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR875",fPot); + if(!gotfBeamok) fBeamok = 0; + if(!gotpot) fPot = -99999; + } m_data->Stores.at("ANNIEEvent")->Get("DataStreams",fDataStreams); m_data->Stores.at("RecoEvent")->Get("PMTMRDCoinc",pmtmrdcoinc); @@ -942,6 +1124,7 @@ bool PhaseIITreeMaker::Execute(){ if (fDataStreams["MRD"]==1) fHasMRD = 1; else fHasMRD = 0; + m_data->Stores.at("ANNIEEvent")->Get("EventTimeMRD",fEventTimeMRD); fEventTimeMRD_Tree = (ULong64_t) fEventTimeMRD.GetNs(); // bool got_mrdtime = m_data->Stores.at("ANNIEEvent")->Get("EventTime",mrd_timestamp); @@ -1013,17 +1196,7 @@ bool PhaseIITreeMaker::Execute(){ // FIll tree with all reconstruction information if (RecoDebug_fill) this->FillRecoDebugInfo(); - if (MuonFitter_fill) - { - Position tmp_vtx(-999,-999,-999); - m_data->CStore.Get("FittedMuonVertex", tmp_vtx); - fRecoMuonVtxX = tmp_vtx.X(); - fRecoMuonVtxY = tmp_vtx.Y(); - fRecoMuonVtxZ = tmp_vtx.Z(); - m_data->CStore.Get("FittedTrackLengthInWater", fRecoTankTrack); - m_data->CStore.Get("RecoMuonKE", fRecoMuonKE); - m_data->CStore.Get("NLyers", fNumMrdLayers); - } + if (LAPPDData_fill) this->LoadLAPPDData(); fPhaseIITrigTree->Fill(); } @@ -1325,25 +1498,61 @@ void PhaseIITreeMaker::ResetVariables() { fDeltaZenith = -9999; fDeltaAngle = -9999; } - - //DIGITS - if (Digit_fill){ - fdigitX.clear(); - fdigitY.clear(); - fdigitZ.clear(); - fdigitT.clear(); - } - //DIGITS - if (MuonFitter_fill) - { - fRecoMuonVtxX = -9999; - fRecoMuonVtxY = -9999; - fRecoMuonVtxZ = -9999; - fRecoTankTrack = -9999; - fRecoMuonKE = -9999; - fNumMrdLayers = -9999; - } + if(LAPPDData_fill){ + LAPPDDataMap.clear(); + LAPPDBeamgate_ns.clear(); + LAPPDTimeStamps_ns.clear(); + LAPPDTimeStampsRaw.clear(); + LAPPDBeamgatesRaw.clear(); + LAPPDOffsets.clear(); + LAPPDTSCorrection.clear(); + LAPPDBGCorrection.clear(); + LAPPDOSInMinusPS.clear(); + + fLAPPD_ID.clear(); + fLAPPD_Beamgate_ns.clear(); + fLAPPD_Timestamp_ns.clear(); + fLAPPD_Beamgate_Raw.clear(); + fLAPPD_Timestamp_Raw.clear(); + fLAPPD_Offset.clear(); + fLAPPD_TSCorrection.clear(); + fLAPPD_BGCorrection.clear(); + fLAPPD_OSInMinusPS.clear(); + + GroupedTrigger.clear(); + + fGroupedTriggerTime.clear(); + fGroupedTriggerWord.clear(); + + lappdPulses.clear(); + lappdHits.clear(); + + fLAPPD_IDs.clear(); + fChannelID.clear(); + fPulsePeakTime.clear(); + fPulseCharge.clear(); + fPulsePeakAmp.clear(); + fPulseStart.clear(); + fPulseEnd.clear(); + fPulseWidth.clear(); + fPulseSide.clear(); + fPulseStripNum.clear(); + + fLAPPDHit_IDs.clear(); + fLAPPDHitChannel.clear(); + fLAPPDHitStrip.clear(); + fLAPPDHitTime.clear(); + fLAPPDHitAmp.clear(); + fLAPPDHitParallelPos.clear(); + fLAPPDHitTransversePos.clear(); + fLAPPDHitP1StartTime.clear(); + fLAPPDHitP2StartTime.clear(); + fLAPPDHitP1EndTime.clear(); + fLAPPDHitP2EndTime.clear(); + + } + } bool PhaseIITreeMaker::LoadTankClusterClassifiers(double cluster_time){ @@ -2309,3 +2518,143 @@ void PhaseIITreeMaker::RecoSummary() { std::cout << " RecoStatus = " << fRecoStatus <::iterator it = LAPPDDataMap.begin(); it != LAPPDDataMap.end(); ++it) { + uint64_t key = it->first; + PsecData psecData = it->second; + + fLAPPD_ID.push_back(psecData.LAPPD_ID); + + fLAPPD_Beamgate_ns.push_back(LAPPDBeamgate_ns[key]); + fLAPPD_Timestamp_ns.push_back(LAPPDTimeStamps_ns[key]); + fLAPPD_Beamgate_Raw.push_back(LAPPDBeamgatesRaw[key]); + fLAPPD_Timestamp_Raw.push_back(LAPPDTimeStampsRaw[key]); + fLAPPD_Offset.push_back(LAPPDOffsets[key]); + fLAPPD_TSCorrection.push_back(LAPPDTSCorrection[key]); + fLAPPD_BGCorrection.push_back(LAPPDBGCorrection[key]); + fLAPPD_OSInMinusPS.push_back(LAPPDOSInMinusPS[key]); + } + + //cout<<"Grouped Trigger Size: "<::iterator it = GroupedTrigger.begin(); it != GroupedTrigger.end(); ++it) { + //cout<<"Grouped Trigger: "<first<<" "<second<first; + uint32_t value = it->second; + + fGroupedTriggerTime.push_back(key); + fGroupedTriggerWord.push_back(value); + } + +} + +void PhaseIITreeMaker::LoadLAPPDData() +{ + m_data->Stores["ANNIEEvent"]->Get("LAPPDDataMap", LAPPDDataMap); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + m_data->Stores["ANNIEEvent"]->Get("LAPPDOffsets", LAPPDOffsets); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTSCorrection", LAPPDTSCorrection); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBGCorrection", LAPPDBGCorrection); + m_data->Stores["ANNIEEvent"]->Get("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + + + m_data->Stores["ANNIEEvent"]->Get("GroupedTrigger", GroupedTrigger); + if(LAPPDDataMap.size() != 0) + { + FillLAPPDData(); + //print the content of fDataStreams, and the size of data map + //cout<<"Found LAPPDData, LAPPDDataMap Size: "<Stores["ANNIEEvent"]->Get("LAPPDPulses", lappdPulses); + if(gotPulse) + { + + std::map>>::iterator it; + for (it = lappdPulses.begin(); it != lappdPulses.end(); it++) + { + int stripno = it->first; + vector> stripPulses = it->second; + + vector pulse0 = stripPulses.at(0); + vector pulse1 = stripPulses.at(1); + for (int i = 0; i < pulse0.size(); i++) + { + fPulseSide.push_back(0); + LAPPDPulse thisPulse = pulse0.at(i); + fLAPPD_IDs.push_back(thisPulse.GetTubeId()); + fChannelID.push_back(thisPulse.GetChannelID()); + fPulseStripNum.push_back(stripno); + fPulsePeakTime.push_back(thisPulse.GetTime()); + fPulseCharge.push_back(thisPulse.GetCharge()); + fPulsePeakAmp.push_back(thisPulse.GetPeak()); + fPulseStart.push_back(thisPulse.GetLowRange()); + fPulseEnd.push_back(thisPulse.GetHiRange()); + fPulseWidth.push_back(thisPulse.GetHiRange() - thisPulse.GetLowRange()); + } + for(int i = 0; iStores["ANNIEEvent"]->Get("LAPPDHits", lappdHits); + + if(gotHit) + { + std::map>::iterator it; + for (it = lappdHits.begin(); it != lappdHits.end(); it++) + { + int stripno = it->first; + vector stripHits = it->second; + for (int i = 0; i < stripHits.size(); i++) + { + LAPPDHit thisHit = stripHits.at(i); + fLAPPDHit_IDs.push_back(thisHit.GetTubeId()); + fLAPPDHitStrip.push_back(stripno); + fLAPPDHitTime.push_back(thisHit.GetTime()); + fLAPPDHitAmp.push_back(thisHit.GetCharge()); + vector position = thisHit.GetPosition(); + /* + XPosTank = position.at(0); + YPosTank = position.at(1); + ZPosTank = position.at(2);*/ + vector localPosition = thisHit.GetLocalPosition(); + fLAPPDHitParallelPos.push_back(localPosition.at(0)); + fLAPPDHitTransversePos.push_back(localPosition.at(1)); + fLAPPDHitP1StartTime.push_back(thisHit.GetPulse1StartTime()); + fLAPPDHitP2StartTime.push_back(thisHit.GetPulse2StartTime()); + fLAPPDHitP1EndTime.push_back(thisHit.GetPulse1LastTime()); + fLAPPDHitP2EndTime.push_back(thisHit.GetPulse2LastTime()); + } + } + } +} diff --git a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h index 91d1d33f2..d4f8fad25 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h @@ -21,6 +21,9 @@ #include "ANNIEalgorithms.h" #include "TimeClass.h" #include "BeamStatus.h" +#include "PsecData.h" +#include "LAPPDPulse.h" +#include "LAPPDHit.h" #include "GenieInfo.h" #include "CLHEP/Random/RandGaussQ.h" @@ -79,6 +82,11 @@ class PhaseIITreeMaker: public Tool { bool LoadBNBtimingMC(double cluster_time); void LoadAllTankHits(bool IsData, bool MCWaveform); void LoadSiPMHits(); + void LoadLAPPDData(); + void FillLAPPDData(); + + void FillLAPPDHit(); + void FillLAPPDPulse(); private: @@ -480,6 +488,69 @@ class PhaseIITreeMaker: public Tool { bool SiPMPulseInfo_fill = 0; bool Digit_fill = 0; bool MuonFitter_fill = 0; + + // LAPPD data variables + bool LAPPDData_fill = 0; + int gotLAPPDNumber; + std::map LAPPDDataMap; + std::map LAPPDBeamgate_ns; + std::map LAPPDTimeStamps_ns; // data and key are the same + std::map LAPPDTimeStampsRaw; + std::map LAPPDBeamgatesRaw; + std::map LAPPDOffsets; + std::map LAPPDTSCorrection; + std::map LAPPDBGCorrection; + std::map LAPPDOSInMinusPS; + + vector fLAPPD_ID; + vector fLAPPD_Beamgate_ns; + vector fLAPPD_Timestamp_ns; + vector fLAPPD_Beamgate_Raw; + vector fLAPPD_Timestamp_Raw; + vector fLAPPD_Offset; + vector fLAPPD_TSCorrection; + vector fLAPPD_BGCorrection; + vector fLAPPD_OSInMinusPS; + + std::map GroupedTrigger; + + vector fGroupedTriggerTime; + vector fGroupedTriggerWord; + + + uint64_t beamInfoTime; + int64_t timeDiff; + double E_TOR860, E_TOR875, THCURR, BTJT2, HP875, VP875, HPTG1, VPTG1, HPTG2, VPTG2, BTH2T2; + + + bool LAPPDReco_fill = 0; + std::map>> lappdPulses; + std::map> lappdHits; + + vector fLAPPD_IDs; + vector fChannelID; + vector fPulsePeakTime; + vector fPulseCharge; + vector fPulsePeakAmp; + vector fPulseStart; + vector fPulseEnd; + vector fPulseWidth; + vector fPulseSide; + vector fPulseStripNum; + + vector fLAPPDHit_IDs; + vector fLAPPDHitChannel; + vector fLAPPDHitStrip; + vector fLAPPDHitTime; + vector fLAPPDHitAmp; + vector fLAPPDHitParallelPos; + vector fLAPPDHitTransversePos; + vector fLAPPDHitP1StartTime; + vector fLAPPDHitP2StartTime; + vector fLAPPDHitP1EndTime; + vector fLAPPDHitP2EndTime; + + }; diff --git a/UserTools/PrintADCTraces/PrintADCTraces.cpp b/UserTools/PrintADCTraces/PrintADCTraces.cpp index c0b96d2ab..a93dc55b1 100644 --- a/UserTools/PrintADCTraces/PrintADCTraces.cpp +++ b/UserTools/PrintADCTraces/PrintADCTraces.cpp @@ -20,12 +20,8 @@ PrintADCTraces::PrintADCTraces():Tool(){} // │ └── ... // └── TraceSummary TTree # metadata // ├── chan # all pulse channel ids -// ├── run # all pulse run numbers -// ├── eventTime # all pulse event times // ├── hitT # all pulse hit times [ns] -// ├── hitPE # all pulse hit charges [pe] -// ├── hitBaseline # all pulse baselines [adc] -// └── hitNoise # all pulse baseline sigma (noise) [adc] +// └── hitPE # all pulse hit charges [pe] bool PrintADCTraces::Initialise(std::string configfile, DataModel &data) @@ -96,12 +92,8 @@ bool PrintADCTraces::Initialise(std::string configfile, DataModel &data) // summary TTree containing global distribution of all saved ADC traces fTraceSummaryTree = new TTree("TraceSummary", "Summary of saved ADC traces"); fTraceSummaryTree->Branch("chan", &fchan); - fTraceSummaryTree->Branch("run", &frun); - fTraceSummaryTree->Branch("eventTime", &feventTime); fTraceSummaryTree->Branch("hitT", &fhitT); fTraceSummaryTree->Branch("hitPE", &fhitPE); - fTraceSummaryTree->Branch("hitBaseline", &fhitBaseline); - fTraceSummaryTree->Branch("hitNoise", &fhitNoise); return true; } @@ -185,10 +177,8 @@ bool PrintADCTraces::Execute() for (const auto& pulse : pulsevec) { - double hitT = pulse.peak_time(); // interpolated hit time [ns] - double hitQ = pulse.charge(); // charge [nQ] - double hitBaseline = pulse.baseline(); // baseline [adc] - double hitNoise = pulse.sigma_baseline(); // noise [adc] + double hitT = pulse.peak_time(); // interpolated hit time + double hitQ = pulse.charge(); // charge in nQ // need to convert from nQ -> PE using SPE conversion map auto spe_it = fChannelKeyToSPEMap.find(chankey); @@ -219,19 +209,17 @@ bool PrintADCTraces::Execute() if (xpts.empty() || ypts.empty()) continue; // create and write to TGraph - TGraph gr(xpts.size(), xpts.data(), ypts.data()); - gr.SetName(grTitle.str().c_str()); + TGraph gr(xpts.size()); + for (size_t i = 0; i < std::min(xpts.size(), ypts.size()); ++i) { + gr.SetPoint(i, xpts[i], ypts[i]); + } gr.SetTitle(grTitle.str().c_str()); gr.Write(); // write to summary TTree fchan = chankey; - frun = fRunNumber; - feventTime = fWaveformTime; - fhitT = hitT; + fhitT = pulse.peak_time(); fhitPE = hitPE; - fhitBaseline = hitBaseline; - fhitNoise = hitNoise; fTraceSummaryTree->Fill(); ++totalGraphs; @@ -251,10 +239,9 @@ bool PrintADCTraces::Finalise() { if (fOutFile) { - if (fTraceSummaryTree) { // write summary to root file + if (fTraceSummaryTree) { // write summary to root file fOutFile->cd(); fTraceSummaryTree->Write(); - fTraceSummaryTree = nullptr; } fOutFile->cd(); @@ -279,4 +266,4 @@ bool PrintADCTraces::Finalise() //------------------------------------------------------------------------------ -// done +// done \ No newline at end of file diff --git a/UserTools/PrintADCTraces/PrintADCTraces.h b/UserTools/PrintADCTraces/PrintADCTraces.h index b2319d7d1..b82890c1d 100644 --- a/UserTools/PrintADCTraces/PrintADCTraces.h +++ b/UserTools/PrintADCTraces/PrintADCTraces.h @@ -31,10 +31,8 @@ class PrintADCTraces: public Tool { TFile* fOutFile = nullptr; // output root file TTree* fTraceSummaryTree = nullptr; // summary TTree in root file - int fchan, frun; // branches in summary TTree - uint64_t feventTime; + int fchan; // branches in summary TTree float fhitT, fhitPE; - float fhitBaseline, fhitNoise; int totalGraphs = 0; // keep track how many TGraphs were written std::map graphsPerChannel; diff --git a/UserTools/PrintADCTraces/README.md b/UserTools/PrintADCTraces/README.md index d0a102d66..e89005b61 100644 --- a/UserTools/PrintADCTraces/README.md +++ b/UserTools/PrintADCTraces/README.md @@ -1,10 +1,6 @@ # PrintADCTraces -`PrintADCTraces` will read hit information (either from the "ClusterMap" or "Hits" from the "ANNIEEvent"), take the stored ADC traces in "RecoADCData", and output the traces to a root file. It will also filter traces/hits within some range of charges or times provided by the user. - -The tool is also useful to assemble metadata of data pulses, such as the calculated baseline and noise. This data (along with the shape of the ADC traces) can be used to analyze the stability of the PMTs over time. - -This tool does not put anything into the store. +`PrintADCTraces` will read the ADC traces in "RecoADCData", and output the pulses to a root file. It will also filter traces/hits within some range of charges or times provided by the user. ## Output rootfile @@ -21,12 +17,8 @@ This tool does not put anything into the store. // │ └── ... // └── TraceSummary TTree # metadata // ├── chan # all pulse channel ids -// ├── run # all pulse run numbers -// ├── eventTime # all pulse event times // ├── hitT # all pulse hit times [ns] -// ├── hitPE # all pulse hit charges [pe] -// ├── hitBaseline # all pulse baselines [adc] -// └── hitNoise # all pulse baseline sigma (noise) [adc] +// └── hitPE # all pulse hit charges [pe] ``` where the TGraph name is given by: ```____``` @@ -38,8 +30,8 @@ where the TGraph name is given by: ```___Stores["ANNIEEvent"]->Get("EventTimeTank", ETT); + int pTW = 0; + bool gotpTW = m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerWord", pTW); + uint64_t pTT = 0; + bool gotpTT = m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerTime", pTT); + + Log("ProcessedLAPPDFilter: Got ETT: " + std::to_string(ETT) + "(" + std::to_string(gotETT) + "), pTW: " + std::to_string(pTW) + "(" + std::to_string(gotpTW) + "), pTT: " + std::to_string(pTT) + "(" + std::to_string(gotpTT) + ")", 5, FilterVerbosity); + + m_data->Stores.at("ANNIEEvent")->Get("DataStreams", DataStreams); + + if (FilterVerbosity > 3) + { + for (auto it = DataStreams.begin(); it != DataStreams.end(); ++it) + { + cout << "DataStream: " << it->first << " " << it->second << ", "; + } + cout << endl; + } + CurrentExeNumber += 1; + + if (filterType == "BeamSelection") + { + + if (CurrentExeNumber % 1000 == 0) + { + cout << "ProcessedLAPPDFilter: CurrentExeNumber: " << CurrentExeNumber << ", passCutEventNumber: " << passCutEventNumber << endl; + } + + // require beam_good + int beam_good = 0; + bool gotBeamGood = m_data->Stores["ANNIEEvent"]->Get("beam_good", beam_good); + if (!gotBeamGood || beam_good != 1) + { + Log("ProcessedLAPPDFilter: not good beam" + std::to_string(beam_good), 2, FilterVerbosity); + return true; + } + // require there is PMT cluster + std::map> *m_all_clusters = nullptr; + bool get_clusters = m_data->CStore.Get("ClusterMap", m_all_clusters); + if (!get_clusters) + { + std::cout << "ProcessedLAPPDFilter tool: No clusters!" << std::endl; + return false; + } + if (!(static_cast(m_all_clusters->size()) > 0)) + { + Log("ProcessedLAPPDFilter: No PMT cluster found!", 4, FilterVerbosity); + return true; + } + // require there is a cluster in the prompt window (2us) + vector clusterTimes; + std::map>::iterator it_cluster_pair; + it_cluster_pair = (*m_all_clusters).begin(); + bool loop_map = true; + while (loop_map) + { + std::vector cluster_hits = it_cluster_pair->second; + double thisClusterTime = it_cluster_pair->first; + clusterTimes.push_back(thisClusterTime); + + it_cluster_pair++; + if (it_cluster_pair == (*m_all_clusters).end()) + loop_map = false; + } + // loop clusterTimes, if there is not any element < 2000, return true + bool found = false; + for (auto it = clusterTimes.begin(); it != clusterTimes.end(); ++it) + { + if (*it < 2000) + { + found = true; + break; + } + } + if (!found) + { + Log("ProcessedLAPPDFilter: No cluster in the prompt window!", 2, FilterVerbosity); + return true; + } + + // require the brightest cluster in the prompt window have charge balance < 0.2 + std::map ClusterChargeBalances; + std::map ClusterMaxPEs; + + bool got_ccb = m_data->Stores.at("ANNIEEvent")->Get("ClusterChargeBalances", ClusterChargeBalances); + bool got_cmpe = m_data->Stores.at("ANNIEEvent")->Get("ClusterMaxPEs", ClusterMaxPEs); + + double max_charge = 0; + double max_charge_cluster_time = 0; + double max_charge_cluster_CB = 1; + for (auto it = ClusterMaxPEs.begin(); it != ClusterMaxPEs.end(); ++it) + { + double cluster_time = it->first; + double charge_balance = ClusterChargeBalances.at(cluster_time); + + if (it->second > max_charge) + { + max_charge = it->second; + max_charge_cluster_time = cluster_time; + max_charge_cluster_CB = charge_balance; + } + } + if (max_charge_cluster_CB > 0.2) + { + Log("ProcessedLAPPDFilter: The brightest cluster in the prompt window has charge balance > 0.2", 2, FilterVerbosity); + return true; + } + + // require there is a MRD track, and the MRD coincidence is true + int numtracksinev = m_data->Stores["MRDTracks"]->Get("NumMrdTracks", numtracksinev); + if (numtracksinev < 1) + { + Log("ProcessedLAPPDFilter: No MRD track!", 2, FilterVerbosity); + return true; + } + + bool pmtmrdcoinc; + bool gotCoinc = m_data->Stores["RecoEvent"]->Get("PMTMRDCoinc", pmtmrdcoinc); + if (!gotCoinc || !pmtmrdcoinc) + { + Log("ProcessedLAPPDFilter: No PMT MRD coincidence!", 2, FilterVerbosity); + return true; + } + + // require there is no veto + if (RequireNoVeto) + { + bool noVeto = false; + bool gotNoVeto = m_data->Stores.at("RecoEvent")->Get("NoVeto", noVeto); + if (!gotNoVeto || !noVeto) + { + Log("ProcessedLAPPDFilter: There is veto!", 2, FilterVerbosity); + return true; + } + } + + // require the Cherenkov light cover the center LAPPD + if (RequireCherenkovCover) + { + vector> PMT_ChannelKeys = {{462, 428, 406, 412}}; + std::vector brightestCluster = m_all_clusters->at(max_charge_cluster_time); + vector PMTKeys; + int coveredPMT = 0; + for (int i = 0; i < brightestCluster.size(); i++) + { + int channel_key = brightestCluster.at(i).GetTubeId(); + PMTKeys.push_back(channel_key); + // check if channel_key is in PMT_ChannelKeys + for (int j = 0; j < PMT_ChannelKeys.size(); j++) + { + if (std::find(PMT_ChannelKeys[j].begin(), PMT_ChannelKeys[j].end(), channel_key) != PMT_ChannelKeys[j].end()) + { + coveredPMT += 1; + break; + } + } + } + if (coveredPMT < 3) + { + Log("ProcessedLAPPDFilter: The Cherenkov light doesn't cover the center LAPPD!", 2, FilterVerbosity); + return true; + } + } + + + GotANNIEEventAndSave(FilteredPMTCluster, PMTClusterDataName); + passCutEventNumber += 1; + } + + if (filterType == "MRDtrack") + { + gotEventMRD = false; + gotEventPMTCluster = false; + + std::map> *m_all_clusters = nullptr; + bool get_clusters = m_data->CStore.Get("ClusterMap", m_all_clusters); + if (!get_clusters) + { + std::cout << "ProcessedLAPPDFilter tool: No clusters found!" << std::endl; + return false; + } + if ((int)m_all_clusters->size() > 0) + gotEventPMTCluster = true; + + if (savePMTClusterEvents && gotEventPMTCluster) + { + GotANNIEEventAndSave(FilteredPMTCluster, PMTClusterDataName); + PMTClusterEventNum += 1; + } + + if (DataStreams["LAPPD"] == false) + { + return true; + } + + + + std::map LAPPDBeamgate_ns; + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + PsecDataNumber += LAPPDBeamgate_ns.size(); + m_data->Stores["ANNIEEvent"]->Set("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + + std::vector> MrdTimeClusters; + bool get_clusters_mrd = m_data->CStore.Get("MrdTimeClusters", MrdTimeClusters); + if (!get_clusters_mrd) + { + std::cout << "ProcessedLAPPDFilter tool: No MRD clusters found! Did you run the TimeClustering tool?" << std::endl; + return false; + } + if (MrdTimeClusters.size() > 0) + gotEventMRD = true; + + bool gotStoreNoVeto = m_data->Stores.at("RecoEvent")->Get("NoVeto", gotEventMRDNoVeto); + if (!gotStoreNoVeto) + { + cout << "The Stage1 Filter doesn't work because it need the Veto information form EventSelector Tool. Please include that." << endl; + return false; + } + + if (saveAllLAPPDEvents) + { + GotANNIEEventAndSave(FilteredAllLAPPD, AllLAPPDDataName); + } + + if (gotEventPMTCluster) + { + EventPMTClusterNumber += 1; + if (FilterVerbosity > 0) + cout << "Got an event with PMT cluster, got event number " << EventPMTClusterNumber << endl; + if (gotEventMRD) + { + GotANNIEEventAndSave(FilteredMRD, MRDDataName); + EventMRDNumber += 1; + if (FilterVerbosity > 0) + cout << "Got an event with PMT cluster, MRD hits, got event number " << EventMRDNumber << endl; + if (gotEventMRDNoVeto) + { + GotANNIEEventAndSave(FilteredMRDNoVeto, MRDNoVetoDataName); + EventMRDNoVetoNumber += 1; + if (FilterVerbosity > 0) + cout << "Got an event with PMT cluster, MRD hits and no veto, got event number " << EventMRDNoVetoNumber << endl; + } + } + + if (CurrentExeNumber % 10 == 0) + { + cout << "Filter event number: " << CurrentExeNumber << ", PsecDataNumber " << PsecDataNumber << ", LAPPD events with PMT clusters: " << EventPMTClusterNumber << ", also with MRD tracks: " << EventMRDNumber << ", also with MRD tracks and no veto: " << EventMRDNoVetoNumber << ", events with PMT cluster (may not have LAPPD): " << PMTClusterEventNum << endl; + } + + m_data->Stores["ANNIEEvent"]->Get("RunNumber", currentRunNumber); + } + } + + if (filterType == "PMTCluster") + { + std::map LAPPDBeamgate_ns; + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + PsecDataNumber += LAPPDBeamgate_ns.size(); + + gotEventPMTCluster = false; + + std::map> *m_all_clusters = nullptr; + bool get_clusters = m_data->CStore.Get("ClusterMap", m_all_clusters); + if (!get_clusters) + { + std::cout << "ProcessedLAPPDFilter tool: No clusters found!" << std::endl; + return false; + } + if ((int)m_all_clusters->size() > 0) + gotEventPMTCluster = true; + + if (gotEventPMTCluster) + { + EventPMTClusterNumber += 1; + if (FilterVerbosity > 0) + cout << "Got an event with PMT cluster, got event number " << EventPMTClusterNumber << endl; + GotANNIEEventAndSave(FilteredMRD, MRDDataName); + if (CurrentExeNumber % 50 == 0) + { + cout << "Filter event number: " << CurrentExeNumber << ", PsecDataNumber " << PsecDataNumber << ", events with PMT clusters: " << EventPMTClusterNumber << endl; + } + + m_data->Stores["ANNIEEvent"]->Get("RunNumber", currentRunNumber); + } + } + + /* + if (filterType == "LAPPDPulsedStripNumber") + { + CurrentExeNumber += 1; + int pulsedStripNumber = 0; + std::vector> LAPPDVectorSide0 = std::vector>(30, std::vector(256)); + // loop the vector. For each strip, loop and find maximum, if the maximum > 15, then pulsedStripNumber += 1 + m_data->Stores["ANNIEEvent"]->Get("LAPPDSigVecSide0", LAPPDVectorSide0); + for (int i = 0; i < 30; i++) + { + double max = 0; + for (int j = 0; j < 256; j++) + { + if (LAPPDVectorSide0[i][j] > max) + max = LAPPDVectorSide0[i][j]; + if (FilterVerbosity > requirePulsedStripNumber) + cout << "LAPPDVectorSide0[" << i << "][" << j << "] = " << LAPPDVectorSide0[i][j] << endl; + } + if (max > requirePulsedAmp) + pulsedStripNumber += 1; + } + if (pulsedStripNumber > requirePulsedStripNumber) + { + GotANNIEEventAndSave(FilteredMRD, MRDDataName); + EventMRDNumber += 1; + } + + if (CurrentExeNumber % 50 == 0) + { + cout << "Filter event number " << CurrentExeNumber << ", pulsedStripNumber more than " << requirePulsedStripNumber << " events " << EventMRDNumber << endl; + } + } + */ + + return true; +} + +bool ProcessedLAPPDFilter::Finalise() +{ + FilteredMRD->Close(); + FilteredMRDNoVeto->Close(); + FilteredAllLAPPD->Close(); + FilteredPMTCluster->Close(); + + FilteredMRD->Delete(); + FilteredMRDNoVeto->Delete(); + FilteredAllLAPPD->Delete(); + FilteredPMTCluster->Delete(); + + if (filterType == "BeamSelection") + { + cout << " ProcessedLAPPDFilter: Finalise" << endl; + cout << "Current exe number: " << CurrentExeNumber << endl; + cout << "Got number of Event: " << passCutEventNumber << endl; + } + + if (filterType == "MRDtrack") + { + cout << "Current Run " << currentRunNumber << endl; + cout << "Filter got " << CurrentExeNumber << " events in total" << endl; // this is the total number of events + cout << "Got " << PsecDataNumber << " psec data objects on all LAPPD" << endl; + cout << "Got " << EventPMTClusterNumber << " events with PMT clusters" << endl; + cout << "Got " << EventMRDNumber << " events with PMT clusters and MRD hits" << endl; + cout << "Got " << EventMRDNoVetoNumber << " events with PMT clusters and MRD hits and no veto" << endl; + cout << "Got " << PMTClusterEventNum << " events with PMT clusters and saved" << endl; + cout << "Saved " << MRDDataName << " successfully" << endl; + cout << "Saved " << MRDNoVetoDataName << " successfully" << endl; + cout << "Saved " << AllLAPPDDataName << " successfully" << endl; + cout << "Saved " << PMTClusterDataName << " successfully" << endl; + + std::ofstream file("FilterStat.txt", std::ios::app); + file << currentRunNumber << " " << CurrentExeNumber << " " << EventPMTClusterNumber << " " << EventMRDNumber << " " << EventMRDNoVetoNumber << " " + << "\n"; + file.close(); + } + if (filterType == "PMTCluster") + { + cout << "Current Run " << currentRunNumber << endl; + cout << "Filter got " << CurrentExeNumber << " events in total" << endl; // this is the total number of events + cout << "Got " << EventPMTClusterNumber << " events with PMT clusters" << endl; + cout << "Saved " << MRDDataName << " successfully" << endl; + } + if (filterType == "LAPPDTiming") + { + cout << "Filter got " << CurrentExeNumber << " events in total" << endl; // this is the total number of events + cout << "Got " << EventMRDNumber << " events in beamgate window" << endl; + cout << "Saved " << MRDDataName << " successfully" << endl; + } + + if (filterType == "LAPPDPulsedStripNumber") + { + cout << "Filter got " << CurrentExeNumber << " events in total" << endl; // this is the total number of events + cout << "Got " << EventMRDNumber << " events with more than 5 pulsed strips" << endl; + cout << "Saved " << MRDDataName << " successfully" << endl; + } + + return true; +} + +bool ProcessedLAPPDFilter::GotANNIEEventAndSave(BoostStore *BS, string savePath) +{ + std::map> *AuxHitsOriginal = nullptr; + std::map> *HitsOriginal = nullptr; + m_data->Stores["ANNIEEvent"]->Get("AuxHits", AuxHitsOriginal); + m_data->Stores["ANNIEEvent"]->Get("Hits", HitsOriginal); + + std::map> *AuxHitsCopy = nullptr; + if (!m_data->Stores["ANNIEEvent"]->Get("AuxHits", AuxHitsOriginal)) + { + std::cerr << "Warning: Could not retrieve AuxHits from ANNIEEvent or AuxHitsOriginal is nullptr. Creating empty AuxHits map." << std::endl; + AuxHitsCopy = new std::map>(); + } + else + { + AuxHitsCopy = new std::map>(*AuxHitsOriginal); + } + std::map> *HitsCopy = nullptr; + if (!m_data->Stores["ANNIEEvent"]->Get("Hits", HitsOriginal)) + { + std::cerr << "Warning: Could not retrieve Hits from ANNIEEvent or HitsOriginal is nullptr. Creating empty Hits map." << std::endl; + HitsCopy = new std::map>(); + } + else + { + HitsCopy = new std::map>(*HitsOriginal); + } + + BS->Set("AuxHits", AuxHitsCopy); + BS->Set("Hits", HitsCopy); + + std::map> TDCData; + BeamStatus BeamStatus; + uint64_t CTCTimestamp, RunStartTime; + std::map DataStreams; + uint32_t EventNumber, TriggerWord; + uint64_t EventTimeTank; + TimeClass EventTimeMRD; + std::map MRDLoopbackTDC; + std::string MRDTriggerType; + std::map> RawAcqSize; + std::map>> RecoADCData, RecoAuxADCData; + int PartNumber, RunNumber, RunType, SubrunNumber, TriggerExtended; + TriggerClass TriggerData; + m_data->Stores["ANNIEEvent"]->Get("TDCData", TDCData); + BS->Set("TDCData", TDCData); + m_data->Stores["ANNIEEvent"]->Get("DataStreams", DataStreams); + BS->Set("DataStreams", DataStreams); + m_data->Stores["ANNIEEvent"]->Get("BeamStatus", BeamStatus); + BS->Set("BeamStatus", BeamStatus); + m_data->Stores["ANNIEEvent"]->Get("RunStartTime", RunStartTime); + BS->Set("RunStartTime", RunStartTime); + m_data->Stores["ANNIEEvent"]->Get("EventNumber", EventNumber); + BS->Set("EventNumber", EventNumber); + m_data->Stores["ANNIEEvent"]->Get("TriggerWord", TriggerWord); + BS->Set("TriggerWord", TriggerWord); + m_data->Stores["ANNIEEvent"]->Get("EventTimeMRD", EventTimeMRD); + BS->Set("EventTimeMRD", EventTimeMRD); + + m_data->Stores["ANNIEEvent"]->Get("EventTimeTank", EventTimeTank); + Log("ProcessedLAPPDFilter: Got EventTimeTank: " + std::to_string(EventTimeTank), 1, FilterVerbosity); + BS->Set("EventTimeTank", EventTimeTank); + Log("ProcessedLAPPDFilter: Set EventTimeTank: " + std::to_string(EventTimeTank), 1, FilterVerbosity); + + m_data->Stores["ANNIEEvent"]->Get("MRDLoopbackTDC", MRDLoopbackTDC); + BS->Set("MRDLoopbackTDC", MRDLoopbackTDC); + m_data->Stores["ANNIEEvent"]->Get("MRDTriggerType", MRDTriggerType); + BS->Set("MRDTriggerType", MRDTriggerType); + m_data->Stores["ANNIEEvent"]->Get("RawAcqSize", RawAcqSize); + BS->Set("RawAcqSize", RawAcqSize); + m_data->Stores["ANNIEEvent"]->Get("RecoADCData", RecoADCData); + BS->Set("RecoADCData", RecoADCData); + m_data->Stores["ANNIEEvent"]->Get("RecoAuxADCData", RecoAuxADCData); + BS->Set("RecoAuxADCData", RecoAuxADCData); + m_data->Stores["ANNIEEvent"]->Get("PartNumber", PartNumber); + BS->Set("PartNumber", PartNumber); + m_data->Stores["ANNIEEvent"]->Get("RunNumber", RunNumber); + BS->Set("RunNumber", RunNumber); + m_data->Stores["ANNIEEvent"]->Get("RunType", RunType); + BS->Set("RunType", RunType); + m_data->Stores["ANNIEEvent"]->Get("SubrunNumber", SubrunNumber); + BS->Set("SubrunNumber", SubrunNumber); + m_data->Stores["ANNIEEvent"]->Get("TriggerExtended", TriggerExtended); + BS->Set("TriggerExtended", TriggerExtended); + m_data->Stores["ANNIEEvent"]->Get("TriggerData", TriggerData); + BS->Set("TriggerData", TriggerData); + m_data->Stores["ANNIEEvent"]->Get("CTCTimestamp", CTCTimestamp); + BS->Set("CTCTimestamp", CTCTimestamp); + + std::map GroupedTrigger; + m_data->Stores["ANNIEEvent"]->Get("GroupedTrigger", GroupedTrigger); + BS->Set("GroupedTrigger", GroupedTrigger); + + int PrimaryTriggerWord; + m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerWord", PrimaryTriggerWord); + BS->Set("PrimaryTriggerWord", PrimaryTriggerWord); + + uint64_t primaryTrigTime; + m_data->Stores["ANNIEEvent"]->Get("PrimaryTriggerTime", primaryTrigTime); + BS->Set("PrimaryTriggerTime", primaryTrigTime); + + bool NCExtended, CCExtended; + m_data->Stores["ANNIEEvent"]->Get("NCExtended", NCExtended); + BS->Set("NCExtended", NCExtended); + m_data->Stores["ANNIEEvent"]->Get("CCExtended", CCExtended); + BS->Set("CCExtended", CCExtended); + + string TriggerType; + m_data->Stores["ANNIEEvent"]->Get("TriggerType", TriggerType); + BS->Set("TriggerType", TriggerType); + + int CTCWordExtended; + m_data->Stores["ANNIEEvent"]->Get("CTCWordExtended", CTCWordExtended); + BS->Set("CTCWordExtended", CTCWordExtended); + + std::map LAPPDDataMap; + std::map LAPPDBeamgate_ns; + std::map LAPPDTimeStamps_ns; // data and key are the same + std::map LAPPDTimeStampsRaw; + std::map LAPPDBeamgatesRaw; + std::map LAPPDOffsets; + std::map LAPPDTSCorrection; + std::map LAPPDBGCorrection; + std::map LAPPDOSInMinusPS; + + m_data->Stores["ANNIEEvent"]->Get("LAPPDDataMap", LAPPDDataMap); + BS->Set("LAPPDDataMap", LAPPDDataMap); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + BS->Set("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + BS->Set("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + BS->Set("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + BS->Set("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + m_data->Stores["ANNIEEvent"]->Get("LAPPDOffsets", LAPPDOffsets); + BS->Set("LAPPDOffsets", LAPPDOffsets); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTSCorrection", LAPPDTSCorrection); + BS->Set("LAPPDTSCorrection", LAPPDTSCorrection); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBGCorrection", LAPPDBGCorrection); + BS->Set("LAPPDBGCorrection", LAPPDBGCorrection); + m_data->Stores["ANNIEEvent"]->Get("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + BS->Set("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + + uint64_t beamInfoTime = 0; + int64_t timeDiff = -9999; + double defaultVal = -9999.; + int beam_good = 0; + double E_TOR860, E_TOR875, THCURR, BTJT2, HP875, VP875, HPTG1, VPTG1, HPTG2, VPTG2, BTH2T2; + double B_BRRMPL, B_BRRMPQ, B_BRRMPS, B_BRRMP; + int bunch_rotation_on; + m_data->Stores["ANNIEEvent"]->Get("BeamInfoTime", beamInfoTime); + BS->Set("BeamInfoTime", beamInfoTime); + m_data->Stores["ANNIEEvent"]->Get("BeamInfoTimeToTriggerDiff", timeDiff); + BS->Set("BeamInfoTimeToTriggerDiff", timeDiff); + m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR860", E_TOR860); + BS->Set("beam_E_TOR860", E_TOR860); + m_data->Stores["ANNIEEvent"]->Get("beam_E_TOR875", E_TOR875); + BS->Set("beam_E_TOR875", E_TOR875); + m_data->Stores["ANNIEEvent"]->Get("beam_THCURR", THCURR); + BS->Set("beam_THCURR", THCURR); + m_data->Stores["ANNIEEvent"]->Get("beam_BTJT2", BTJT2); + BS->Set("beam_BTJT2", BTJT2); + m_data->Stores["ANNIEEvent"]->Get("beam_HP875", HP875); + BS->Set("beam_HP875", HP875); + m_data->Stores["ANNIEEvent"]->Get("beam_VP875", VP875); + BS->Set("beam_VP875", VP875); + m_data->Stores["ANNIEEvent"]->Get("beam_HPTG1", HPTG1); + BS->Set("beam_HPTG1", HPTG1); + m_data->Stores["ANNIEEvent"]->Get("beam_VPTG1", VPTG1); + BS->Set("beam_VPTG1", VPTG1); + m_data->Stores["ANNIEEvent"]->Get("beam_HPTG2", HPTG2); + BS->Set("beam_HPTG2", HPTG2); + m_data->Stores["ANNIEEvent"]->Get("beam_VPTG2", VPTG2); + BS->Set("beam_VPTG2", VPTG2); + m_data->Stores["ANNIEEvent"]->Get("beam_BTH2T2", BTH2T2); + BS->Set("beam_BTH2T2", BTH2T2); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMPL", B_BRRMPL); + BS->Set("beam_B_BRRMPL", B_BRRMPL); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMPQ", B_BRRMPQ); + BS->Set("beam_B_BRRMPQ", B_BRRMPQ); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMPS", B_BRRMPS); + BS->Set("beam_B_BRRMPS", B_BRRMPS); + m_data->Stores["ANNIEEvent"]->Get("beam_B_BRRMP", B_BRRMP); + BS->Set("beam_B_BRRMP", B_BRRMP); + m_data->Stores["ANNIEEvent"]->Get("bunch_rotation_on", bunch_rotation_on); + BS->Set("bunch_rotation_on", bunch_rotation_on); + m_data->Stores["ANNIEEvent"]->Get("beam_good", beam_good); + BS->Set("beam_good", beam_good); + + std::vector RWMRawWaveform; + std::vector BRFRawWaveform; + + m_data->Stores["ANNIEEvent"]->Get("RWMRawWaveform", RWMRawWaveform); + BS->Set("RWMRawWaveform", RWMRawWaveform); + m_data->Stores["ANNIEEvent"]->Get("BRFRawWaveform", BRFRawWaveform); + BS->Set("BRFRawWaveform", BRFRawWaveform); + + std::map LAPPDBG_PPSBefore; + std::map LAPPDBG_PPSAfter; + std::map LAPPDBG_PPSDiff; + std::map LAPPDBG_PPSMissing; + std::map LAPPDTS_PPSBefore; + std::map LAPPDTS_PPSAfter; + std::map LAPPDTS_PPSDiff; + std::map LAPPDTS_PPSMissing; + + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + BS->Set("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + BS->Set("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + BS->Set("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + BS->Set("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + BS->Set("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + BS->Set("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + BS->Set("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + BS->Set("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + + BS->Save(savePath); + if (FilterVerbosity > 2) + cout << "Saved to " << savePath << " successfully" << endl; + BS->Delete(); + + // removd and clean the data pointers from here + /* std::map> *AuxHitsOriginal = nullptr; + std::map> *HitsOriginal = nullptr; + m_data->Stores["ANNIEEvent"]->Get("AuxHits", AuxHitsOriginal); + m_data->Stores["ANNIEEvent"]->Get("Hits", HitsOriginal); + auto AuxHitsCopy = new std::map>(*AuxHitsOriginal); + auto HitsCopy = new std::map>(*HitsOriginal); + BS->Set("AuxHits", AuxHitsCopy); + BS->Set("Hits", HitsCopy); + + AuxHitsCopy->clear(); + HitsCopy->clear(); + delete AuxHitsCopy; + delete HitsCopy;*/ + + return true; +} \ No newline at end of file diff --git a/UserTools/ProcessedLAPPDFilter/ProcessedLAPPDFilter.h b/UserTools/ProcessedLAPPDFilter/ProcessedLAPPDFilter.h new file mode 100644 index 000000000..f2eb31ca9 --- /dev/null +++ b/UserTools/ProcessedLAPPDFilter/ProcessedLAPPDFilter.h @@ -0,0 +1,86 @@ +#ifndef ProcessedLAPPDFilter_H +#define ProcessedLAPPDFilter_H + +#include +#include + +#include "Tool.h" +#include "PsecData.h" +#include "Waveform.h" +#include "BoostStore.h" +#include "Store.h" +#include "ADCPulse.h" +#include "TimeClass.h" +#include "TriggerClass.h" +#include "ANNIEalgorithms.h" +#include "CalibratedADCWaveform.h" +#include "BeamStatus.h" +#include "Geometry.h" + +/** + * \class ProcessedLAPPDFilter + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. + * + * $Author: B.Richards $ + * $Date: 2019/05/28 10:44:00 $ + * Contact: b.richards@qmul.ac.uk + */ +class ProcessedLAPPDFilter : public Tool +{ + +public: + ProcessedLAPPDFilter(); ///< Simple constructor + bool Initialise(std::string configfile, DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + + bool GotANNIEEventAndSave(BoostStore *BS, string savePath); + +private: + std::map DataStreams; + + int FilterVerbosity; + + string MRDDataName; + string MRDNoVetoDataName; + string AllLAPPDDataName; + string PMTClusterDataName; + + string filterType; + + BoostStore *FilteredMRD = nullptr; + BoostStore *FilteredMRDNoVeto = nullptr; + BoostStore *FilteredAllLAPPD = nullptr; + BoostStore *FilteredPMTCluster = nullptr; + + bool gotEventMRD; + bool gotEventMRDNoVeto; + bool gotEventPMTCluster; + + bool saveAllLAPPDEvents; + bool savePMTClusterEvents; + + int EventMRDNumber; + int EventMRDNoVetoNumber; + int EventPMTClusterNumber; + int CurrentExeNumber; + int pairedEventNumber; + int PsecDataNumber; + + + + int currentRunNumber; + + double requirePulsedAmp; + int requirePulsedStripNumber; + + int passCutEventNumber; + int PMTClusterEventNum; + bool RequireNoVeto; + bool RequireCherenkovCover; + + +}; + +#endif diff --git a/UserTools/ProcessedLAPPDFilter/README.md b/UserTools/ProcessedLAPPDFilter/README.md new file mode 100644 index 000000000..689d0864f --- /dev/null +++ b/UserTools/ProcessedLAPPDFilter/README.md @@ -0,0 +1,20 @@ +# ProcessedLAPPDFilter + +ProcessedLAPPDFilter + +## Data + +Describe any data formats ProcessedLAPPDFilter creates, destroys, changes, or analyzes. E.G. + +**RawLAPPDData** `map>>` +* Takes this data from the `ANNIEEvent` store and finds the number of peaks + + +## Configuration + +Describe any configuration variables for ProcessedLAPPDFilter. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/RingCounting/RingCounting.py b/UserTools/RingCounting/RingCounting.py index 4cfd706b9..32ed3aa59 100644 --- a/UserTools/RingCounting/RingCounting.py +++ b/UserTools/RingCounting/RingCounting.py @@ -256,7 +256,7 @@ def predict(self): """ self.m_log.Log(__file__ + " PREDICTING", self.v_message, self.m_verbosity) - self.predicted = self.model.predict(np.reshape(self.cnn_image_pmt, newshape=(-1, 10, 16, 1))) + self.predicted = self.model.predict(np.reshape(self.cnn_image_pmt, newshape=(-1, 10, 16, 1)), verbose=0) ################### diff --git a/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp b/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp index 98ac956f6..81bf64daa 100644 --- a/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp +++ b/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp @@ -67,6 +67,7 @@ bool TriggerDataDecoder::Execute(){ m_data->CStore.Set("NewCTCDataAvailable",false); bool PauseCTCDecoding = false; m_data->CStore.Get("PauseCTCDecoding",PauseCTCDecoding); + if (PauseCTCDecoding){ if(verbosity > 0){ std::cout << "TriggerDataDecoder tool: Pausing trigger decoding to let Tank and MRD data catch up..." << std::endl; @@ -214,6 +215,22 @@ bool TriggerDataDecoder::Finalise(){ StoreC1C2.Set("c2",c2); StoreC1C2.Save(storec1c2.c_str()); }*/ + ofstream trigDebug; + trigDebug.open("TrigDecoderDebug.txt"); + int i = 0; + for (auto it = TimeToTriggerWordMapComplete->begin(); it != TimeToTriggerWordMapComplete->end(); ++it) + { + if (i > 10000) + break; + trigDebug << it->first << " "; + for (auto trig = it->second.begin(); trig != it->second.end(); ++trig) + { + trigDebug << *trig << " "; + } + trigDebug << endl; + i++; + } + trigDebug.close(); return true; } @@ -299,6 +316,7 @@ void TriggerDataDecoder::CheckForRunChange() std::stringstream ss_trig_overlap; ss_trig_overlap << "TrigOverlap_R"< check documentation +version 1_0_0 + +# Folder containing models +#model_path /exp/annie/app/users/dschmid/RingCountingStore/models/ +model_path ./configfiles/RingCounting/ + +# Masked PMTs (to 0) config -> check documentation +pmt_mask november_22 +# Output file +save_to RC_output.csv + diff --git a/configfiles/BeamClusterAnalysis/ToolsConfig b/configfiles/BeamClusterAnalysis/ToolsConfig index 021e2f2f6..a4441e5bb 100644 --- a/configfiles/BeamClusterAnalysis/ToolsConfig +++ b/configfiles/BeamClusterAnalysis/ToolsConfig @@ -1,10 +1,24 @@ myLoadANNIEEvent LoadANNIEEvent ./configfiles/BeamClusterAnalysis/LoadANNIEEventConfig myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig -#myPhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/BeamClusterAnalysis/PhaseIIADCCalibratorConfig -#myPhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/BeamClusterAnalysis/PhaseIIADCHitFinderConfig myTimeClustering TimeClustering configfiles/BeamClusterAnalysis/TimeClusteringConfig myFindMrdTracks FindMrdTracks configfiles/BeamClusterAnalysis/FindMrdTracksConfig myClusterFinder ClusterFinder ./configfiles/BeamClusterAnalysis/ClusterFinderConfig myClusterClassifiers ClusterClassifiers ./configfiles/BeamClusterAnalysis/ClusterClassifiersConfig myEventSelector EventSelector ./configfiles/BeamClusterAnalysis/EventSelectorConfig -myPhaseIITreeMaker PhaseIITreeMaker ./configfiles/BeamClusterAnalysis/PhaseIITreeMakerConfig + + +myDigitBuilder DigitBuilder ./configfiles/BeamClusterAnalysis/DigitBuilderConfig + +LAPPDLoadStore LAPPDLoadStore configfiles/LAPPDProcessedAna/Configs +LAPPDStoreReorder LAPPDStoreReorder configfiles/LAPPDProcessedAna/ConfigStoreReadIn +LAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDProcessedAna/ConfigPreProcess +LAPPDBaseline LAPPDBaseline configfiles/LAPPDProcessedAna/ConfigPreProcess +LAPPDThresReco LAPPDThresReco configfiles/LAPPDProcessedAna/ConfigPlot +#LAPPDPlots LAPPDPlots configfiles/LAPPDProcessedAna/ConfigPlot + +FitRWMWaveform FitRWMWaveform ./configfiles/BeamClusterAnalysis/FitRWMWaveformConfig + +myCNNImage CNNImage ./configfiles/BeamClusterAnalysis/CNNImageConfig +myRingCounting PythonScript configfiles/BeamClusterAnalysis/RingCountingConfig + +ANNIEEventTreeMaker ANNIEEventTreeMaker ./configfiles/BeamClusterAnalysis/ANNIEEventTreeMakerConfig diff --git a/configfiles/BeamClusterAnalysis/config.py b/configfiles/BeamClusterAnalysis/config.py new file mode 100644 index 000000000..79cdf5135 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/config.py @@ -0,0 +1,96 @@ +import sys + +run = sys.argv[1] +pi = sys.argv[2] +pf = sys.argv[3] +run_type = sys.argv[4] + +# Create TreeMaker config and ToolsConfig based on run type + +# ------------------------------------------- +file = open('ANNIEEventTreeMakerConfig', "w") + +file.write('ANNIEEventTreeMakerVerbosity 0\n') +file.write('\n') +file.write('fillAllTriggers 1\n') +file.write('fill_singleTrigger 0\n') +file.write('fill_singleTriggerWord 0\n') +file.write('fillLAPPDEventsOnly 0\n') +file.write('TankCluster_fill 1\n') +file.write('cluster_TankHitInfo_fill 1\n') +file.write('\n') +file.write('OutputFile BeamCluster_' + str(run) + '_' + str(pi) + '_' + str(pf) + '.ntuple.root\n') +file.write('TankClusterProcessing 1\n') +file.write('TriggerProcessing 1\n') +file.write('TankHitInfo_fill 1\n') +file.write('\n') + +if run_type == 'beam' or run_type == 'cosmic' or run_type == 'beam_39': + file.write('MRDClusterProcessing 1\n') + file.write('MRDHitInfo_fill 1\n') + file.write('MRDReco_fill 1\n') +else: + file.write('MRDClusterProcessing 0\n') + file.write('MRDHitInfo_fill 0\n') + file.write('MRDReco_fill 0\n') +file.write('\n') + +file.write('SiPMPulseInfo_fill 0\n') +file.write('fillCleanEventsOnly 0\n') +file.write('MCTruth_fill 0\n') +file.write('Reco_fill 1\n') +file.write('TankReco_fill 0\n') +file.write('RecoDebug_fill 0\n') +file.write('muonTruthRecoDiff_fill 0\n') +file.write('isData 1\n') +file.write('HasGenie 0\n') +file.write('RingCounting_fill 0\n') +file.write('LAPPD_MC_fill 0\n') +file.write('\n') + +if run_type == 'beam' or run_type == 'laser' or run_type == 'beam_39': + file.write('LAPPDData_fill 1\n') + file.write('LAPPDReco_fill 1\n') + file.write('LAPPD_PPS_fill 1\n') + file.write('LAPPD_Waveform_fill 0\n') +else: + file.write('LAPPDData_fill 0\n') + file.write('LAPPDReco_fill 0\n') + file.write('LAPPD_PPS_fill 0\n') + file.write('LAPPD_Waveform_fill 0\n') + +if run_type == 'beam' or run_type == 'beam_39': + file.write('RWMBRF_fill 1\n') +else: + file.write('RWMBRF_fill 0\n') + +file.close() + + +# ------------------------------------------- +file2 = open('ToolsConfig', "w") + +file2.write('myLoadANNIEEvent LoadANNIEEvent ./configfiles/BeamClusterAnalysis/LoadANNIEEventConfig\n') +file2.write('myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig\n') + +if run_type == 'beam' or run_type == 'cosmic' or run_type == 'beam_39': + file2.write('myTimeClustering TimeClustering configfiles/BeamClusterAnalysis/TimeClusteringConfig\n') + file2.write('myFindMrdTracks FindMrdTracks configfiles/BeamClusterAnalysis/FindMrdTracksConfig\n') + +file2.write('myClusterFinder ClusterFinder ./configfiles/BeamClusterAnalysis/ClusterFinderConfig\n') +file2.write('myClusterClassifiers ClusterClassifiers ./configfiles/BeamClusterAnalysis/ClusterClassifiersConfig\n') +file2.write('myEventSelector EventSelector ./configfiles/BeamClusterAnalysis/EventSelectorConfig\n') + +if run_type == 'beam' or run_type == 'laser' or run_type == 'beam_39': + file2.write('LAPPDLoadStore LAPPDLoadStore configfiles/LAPPDProcessedAna/Configs\n') + file2.write('LAPPDStoreReorder LAPPDStoreReorder configfiles/LAPPDProcessedAna/ConfigStoreReadIn\n') + file2.write('LAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDProcessedAna/ConfigPreProcess\n') + file2.write('LAPPDBaseline LAPPDBaseline configfiles/LAPPDProcessedAna/ConfigPreProcess\n') + file2.write('LAPPDThresReco LAPPDThresReco configfiles/LAPPDProcessedAna/ConfigPlot\n') + +if run_type == 'beam' or run_type == 'beam_39': + file2.write('FitRWMWaveform FitRWMWaveform ./configfiles/BeamClusterAnalysis/FitRWMWaveformConfig\n') + +file2.write('ANNIEEventTreeMaker ANNIEEventTreeMaker ./configfiles/BeamClusterAnalysis/ANNIEEventTreeMakerConfig\n') + +file2.close() diff --git a/configfiles/BeamClusterAnalysis/configLAPPD.py b/configfiles/BeamClusterAnalysis/configLAPPD.py new file mode 100644 index 000000000..ac9439e3d --- /dev/null +++ b/configfiles/BeamClusterAnalysis/configLAPPD.py @@ -0,0 +1,61 @@ +import sys + +run = sys.argv[1] +pi = sys.argv[2] +pf = sys.argv[3] +run_type = sys.argv[4] + +# Runs on LAPPD filtered information to produce condensed BeamCluster ntuples with only events containing LAPPDs + +file = open('ANNIEEventTreeMakerConfig', "w") + +file.write('ANNIEEventTreeMakerVerbosity 0\n') +file.write('\n') +file.write('fillAllTriggers 1\n') +file.write('fill_singleTrigger 0\n') +file.write('fill_singleTriggerWord 0\n') +file.write('fillLAPPDEventsOnly 0\n') +file.write('TankCluster_fill 1\n') +file.write('cluster_TankHitInfo_fill 1\n') +file.write('\n') +file.write('OutputFile BeamCluster_LAPPD_' + str(run) + '_' + str(pi) + '_' + str(pf) + '.lappd.root\n') +file.write('TankClusterProcessing 1\n') +file.write('TriggerProcessing 1\n') +file.write('TankHitInfo_fill 1\n') +file.write('\n') + +# if we are running the LAPPDs at this stage, it is either a laser or beam run. Only beam runs need MRD info +if run_type == 'beam' or run_type == 'beam_39': + file.write('MRDClusterProcessing 1\n') + file.write('MRDHitInfo_fill 1\n') + file.write('MRDReco_fill 1\n') +else: + file.write('MRDClusterProcessing 0\n') + file.write('MRDHitInfo_fill 0\n') + file.write('MRDReco_fill 0\n') +file.write('\n') + +file.write('SiPMPulseInfo_fill 0\n') +file.write('fillCleanEventsOnly 0\n') +file.write('MCTruth_fill 0\n') +file.write('Reco_fill 1\n') +file.write('TankReco_fill 0\n') +file.write('RecoDebug_fill 0\n') +file.write('muonTruthRecoDiff_fill 0\n') +file.write('isData 1\n') +file.write('HasGenie 0\n') +file.write('RingCounting_fill 0\n') +file.write('LAPPD_MC_fill 0\n') +file.write('\n') + +file.write('LAPPDData_fill 1\n') +file.write('LAPPDReco_fill 1\n') +file.write('LAPPD_PPS_fill 1\n') +file.write('LAPPD_Waveform_fill 0\n') + +if run_type == 'beam' or run_type == 'beam_39': + file.write('RWMBRF_fill 1\n') +else: + file.write('RWMBRF_fill 0\n') + +file.close() diff --git a/configfiles/BeamClusterAnalysis/my_inputs.txt b/configfiles/BeamClusterAnalysis/my_inputs.txt index e58972378..c63be866a 100644 --- a/configfiles/BeamClusterAnalysis/my_inputs.txt +++ b/configfiles/BeamClusterAnalysis/my_inputs.txt @@ -1,173 +1 @@ -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p0 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p1 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p2 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p3 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p4 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p5 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p6 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p7 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p8 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p9 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p10 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p11 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p12 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p13 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p14 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p15 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p16 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p17 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p18 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p19 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p20 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p21 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p22 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p23 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p24 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p25 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p26 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p27 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p28 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p29 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p30 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p31 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p32 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p33 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p34 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p35 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p36 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p37 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p38 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p39 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p40 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p41 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p42 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p43 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p44 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p45 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p46 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p47 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p48 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p49 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p50 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p51 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p52 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p53 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p54 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p55 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p56 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p57 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p58 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p59 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p60 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p61 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p62 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p63 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p64 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p65 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p66 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p67 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p68 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p69 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p70 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p71 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p72 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p73 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p74 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p75 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p76 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p77 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p78 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p79 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p80 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p81 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p82 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p83 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p84 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p85 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p86 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p87 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p88 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p89 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p90 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p91 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p92 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p93 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p94 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p95 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p96 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p97 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p98 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p99 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p100 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p101 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p102 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p103 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p104 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p105 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p106 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p107 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p108 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p109 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p110 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p111 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p112 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p113 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p114 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p115 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p116 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p117 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p118 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p119 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p120 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p121 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p122 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p123 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p124 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p125 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p126 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p127 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p128 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p129 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p130 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p131 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p132 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p133 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p134 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p135 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p136 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p137 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p138 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p139 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p140 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p141 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p142 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p143 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p144 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p145 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p146 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p147 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p148 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p149 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p150 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p151 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p152 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p153 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p154 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p155 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p156 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p157 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p158 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p159 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p160 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p161 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p162 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p163 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p164 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p165 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p166 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p167 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p168 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p169 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p170 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p171 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p172 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/AnalysisFile/FilteredLAPPD_BeamSelection_Pedestal2022 diff --git a/configfiles/BeamClusterAnalysisMC/ANNIEEventTreeMakerConfig b/configfiles/BeamClusterAnalysisMC/ANNIEEventTreeMakerConfig new file mode 100644 index 000000000..3917232a3 --- /dev/null +++ b/configfiles/BeamClusterAnalysisMC/ANNIEEventTreeMakerConfig @@ -0,0 +1,35 @@ +ANNIEEventTreeMakerVerbosity 0 + +OutputFile ANNIETree_MC.root + + +fillAllTriggers 1 +fill_singleTrigger 0 +fillLAPPDEventsOnly 0 +TankCluster_fill 1 +cluster_TankHitInfo_fill 1 + +TankReco_fill 0 +RingCounting_fill 1 + +TankClusterProcessing 1 +MRDClusterProcessing 1 +TriggerProcessing 1 +TankHitInfo_fill 1 +MRDHitInfo_fill 1 +MRDReco_fill 1 +SiPMPulseInfo_fill 0 +fillCleanEventsOnly 0 +MCTruth_fill 1 +Reco_fill 0 +RecoDebug_fill 0 +muonTruthRecoDiff_fill 0 +isData 0 +HasGenie 1 + +LAPPDData_fill 0 +LAPPDReco_fill 0 +RWMBRF_fill 0 +LAPPD_PPS_fill 0 +LAPPD_Waveform_fill 0 +LAPPD_MC_fill 1 diff --git a/configfiles/BeamClusterAnalysisMC/CNNImageConfig b/configfiles/BeamClusterAnalysisMC/CNNImageConfig new file mode 100644 index 000000000..e6e997fa5 --- /dev/null +++ b/configfiles/BeamClusterAnalysisMC/CNNImageConfig @@ -0,0 +1,15 @@ +# CNNImage config file + +verbosity 1 +DataMode Normal #options: Normal / Charge-Weighted / TimeEvolution +SaveMode Static #options: Static / Geometric / PMT-wise +DimensionX 16 #choose something suitable (32/64/...) +DimensionY 10 #choose something suitable (32/64/...) +OutputFile cnnimage_electron_la_sE_1_94 +MCStaticMapping configfiles/CNNImage/mc_cnnimage_mapping.csv +DataStaticMapping configfiles/CNNImage/data_cnnimage_mapping.csv +DimensionLAPPD 5 #Size of the LAPPD pannal +IncludeTopBottom 1 +DetectorConf ANNIEp2v7 #specify the detector version used in simulation +useLAPPDs 0 +WriteToFile 0 diff --git a/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig b/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig index e0d3c4120..db22be6ca 100644 --- a/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig +++ b/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig @@ -3,10 +3,9 @@ verbosity 0 HitStore MCHits #Either MCHits or Hits (accessed in ANNIEEvent store) OutputFile BeamRun_ClusterFinder_DefaultOutput #Output root prefix name for the current run -ClusterFindingWindow 40 # in ns, size of the window used to "clusterize" +ClusterFindingWindow 50 # in ns, size of the window used to "clusterize" AcqTimeWindow 70000 # in ns, size of the acquisition window -ClusterIntegrationWindow 40 # in ns, all hits with +/- 1/2 of this window are considered in the cluster +ClusterIntegrationWindow 50 # in ns, all hits with +/- 1/2 of this window are considered in the cluster MinHitsPerCluster 5 # group of hits are considered clusters above this amount of hits end_of_window_time_cut 0.95 # from o to 1, length of the window you want to loop over with respect to acq. window (1 for full window, 0.95 for 95% from the start) Plots2D 0 #Draw 2D charge-vs-time plots? -MC_pulse_width 35 # width of MC "pulse" in which to integrate true photon hits - all true photon hits on a single PMT will be combined into a "pulse" of this width diff --git a/configfiles/BeamClusterAnalysisMC/DigitBuilderConfig b/configfiles/BeamClusterAnalysisMC/DigitBuilderConfig new file mode 100644 index 000000000..ca0839c95 --- /dev/null +++ b/configfiles/BeamClusterAnalysisMC/DigitBuilderConfig @@ -0,0 +1,11 @@ +# DigitBuilder config file + +verbosity 0 +ParametricModel 1 +#Reading in MC files +IsMC 1 +# There are three configurations: "PMT_only", "LAPPD_only", "All" +PhotoDetectorConfiguration PMT_only +#File must be in /pnfs/ space when loading on Fermilab cluster +LAPPDIDFile ./configfiles/VertexReco/PhaseIIRecoTruth/LAPPDIDs.txt +DigitChargeThr 0 diff --git a/configfiles/BeamClusterAnalysisMC/EventSelectorConfig b/configfiles/BeamClusterAnalysisMC/EventSelectorConfig index ed6a89cdc..bdd72f2f2 100644 --- a/configfiles/BeamClusterAnalysisMC/EventSelectorConfig +++ b/configfiles/BeamClusterAnalysisMC/EventSelectorConfig @@ -1,6 +1,6 @@ # EventSelector config file -verbosity 5 +verbosity 0 MCPMTVolCut 0 MCFVCut 0 MCMRDCut 0 diff --git a/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig b/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig index 4bd3619c4..83a66a9f3 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig @@ -1,4 +1,4 @@ -verbosity 2 +verbosity 0 # Refers to format of flux file used to generate GENIE sample (bnb or gsimple) FluxVersion 1 # use 0 to load genie files based on bnb_annie_0000.root etc files (bnb/redecay/dk2nu flux format) @@ -8,7 +8,8 @@ FluxVersion 1 # use 0 to load genie files based on bnb_annie_00 # Path to directory of GENIE files #FileDir NA # special option to load path from associated WCSim (Not recommended) #FileDir /pnfs/annie/persistent/simulations/genie3/G1810a0211a/standard/ -FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 +#FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 +FileDir /pnfs/annie/persistent/simulations/genie3/G1810a0211a/standard/tank # Name of GENIE file to open FilePattern gntp.99.ghep.root # gntp.[run_number].ghep.root @@ -21,4 +22,4 @@ ManualFileMatching 1 # 0 (false) - no manual matching, 1 (true) - us FileEvents 1000 # 1000 for James' WCSim files, 500 for Marcus' files # Number to offset the first loaded GENIE event (for usage without ManualFileMatching) - 0 by default -EventOffset 0 +EventOffset 8000 diff --git a/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig b/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig index a25d47f59..27f6a4070 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig @@ -1,13 +1,17 @@ #LoadWCSim Config File # all variables retrieved with m_variables.Get() must be defined here! -verbose 1 +verbose 0 # WCSim collaboration samples using GENIE (from James): #InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard//pmt/wcsim_0.X.Y.root # where X = run number for the corresponding GENIE file (gntp.X.ghep.root) # Y = offset multiple for GENIE event number -InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.1.9.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.1.9.root + +#InputFile /pnfs/annie/persistent/simulations/wcsim/wcsim_ANNIEp2v7_beam/pmt-files/wcsim_beam_gst_1_99_0.199.root + +InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/pmt/wcsim_0.99.1.root WCSimVersion 3 ## should reflect the WCSim version of the files being loaded HistoricTriggeroffset 0 ## time offset of digits relative to the trigger diff --git a/configfiles/BeamClusterAnalysisMC/LoadWCSimLAPPDConfig b/configfiles/BeamClusterAnalysisMC/LoadWCSimLAPPDConfig index 8548f52d4..4655cb1f0 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadWCSimLAPPDConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadWCSimLAPPDConfig @@ -1,14 +1,17 @@ #LoadWCSimLAPPD Config File # all variables retrieved with m_variables.Get() must be defined here! -verbose 1 +verbose 0 #InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_lappd_0.1.9.root #InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_ambe_port5_z0_lappd_0.root -InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/lappd-files/LAPPD_wcsim_beam_gst_1046_38_0.5438.root +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/lappd-files/LAPPD_wcsim_beam_gst_1046_38_0.5438.root #InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/lappd-files/LAPPD_wcsim_beam_gst_1079_9_0.9009.root #InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_michel_1000_lappd_0.root #/pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_throughgoing/wcsim_throughgoing_muon_R2614_lappd_0.0.root +#InputFile /pnfs/annie/persistent/simulations/wcsim/wcsim_ANNIEp2v7_beam/lappd-files/LAPPD_wcsim_beam_gst_1_99_0.199.root +InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/lappd/wcsim_lappd_0.99.1.root + WCSimVersion 3 ## should reflect the WCSim version of the files being loaded InnerStructureRadius 1.3545 ## octagonal inner structure radius in m (from drawings 106.64") DrawDebugGraphs 0 ## whether to draw TPolyMarker3D's of hits diff --git a/configfiles/BeamClusterAnalysisMC/MCParticlePropertiesConfig b/configfiles/BeamClusterAnalysisMC/MCParticlePropertiesConfig index 4313fccdf..019526011 100644 --- a/configfiles/BeamClusterAnalysisMC/MCParticlePropertiesConfig +++ b/configfiles/BeamClusterAnalysisMC/MCParticlePropertiesConfig @@ -1,3 +1,3 @@ # MCParticleProperties configuration file -verbosity 1 +verbosity 0 diff --git a/configfiles/BeamClusterAnalysisMC/MCRecoEventLoaderConfig b/configfiles/BeamClusterAnalysisMC/MCRecoEventLoaderConfig index 2a6cadb72..96923c44a 100644 --- a/configfiles/BeamClusterAnalysisMC/MCRecoEventLoaderConfig +++ b/configfiles/BeamClusterAnalysisMC/MCRecoEventLoaderConfig @@ -1,6 +1,6 @@ # MCRecoEventLoader config file -verbosity 1 +verbosity 0 GetPionKaonInfo 1 GetNRings 1 ParticleID 13 diff --git a/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig b/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig index 316b98195..609cc818f 100644 --- a/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig +++ b/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig @@ -1,6 +1,8 @@ verbose 5 -OutputFile MCBeam.ntuple.root +#OutputFile MCBeam_Gst_new_Run9000_NoSplitSubTriggers.ntuple.root +OutputFile MCBeam_Gst_G1810a0211a_ntuple.root + TankClusterProcessing 1 MRDClusterProcessing 1 TriggerProcessing 1 @@ -18,4 +20,3 @@ Reweight_fill 0 muonTruthRecoDiff_fill 0 IsData 0 HasGenie 1 -HasBNBtimingMC 1 diff --git a/configfiles/BeamClusterAnalysisMC/RingCountingConfig b/configfiles/BeamClusterAnalysisMC/RingCountingConfig new file mode 100644 index 000000000..c7598a105 --- /dev/null +++ b/configfiles/BeamClusterAnalysisMC/RingCountingConfig @@ -0,0 +1,24 @@ +PythonScript RingCounting + +InitialiseFunction Initialise +ExecuteFunction Execute +FinaliseFunction Finalise + +verbose 1 + +# analysis specific settings +# +# Define file containing (multiple) filepath(s) to be loaded +load_from_file 0 +files_to_load configfiles/RingCounting/RC_files_to_load.txt +# Model version -> check documentation +version 1_0_0 +# Folder containing models +# model_path /exp/annie/app/users/dschmid/RingCountingStore/models/ +model_path ./configfiles/RingCounting/ + +# Masked PMTs (to 0) config -> check documentation +pmt_mask november_22 +# Output file +save_to RC_output.csv + diff --git a/configfiles/BeamClusterAnalysisMC/TimeClusteringConfig b/configfiles/BeamClusterAnalysisMC/TimeClusteringConfig index 82798f033..6eb6634f4 100644 --- a/configfiles/BeamClusterAnalysisMC/TimeClusteringConfig +++ b/configfiles/BeamClusterAnalysisMC/TimeClusteringConfig @@ -1,6 +1,6 @@ #TimeClustering config file -verbosity 1 +verbosity 0 MinDigitsForTrack 4 MaxMrdSubEventDuration 40 MinSubeventTimeSep 40 diff --git a/configfiles/BeamClusterAnalysisMC/ToolsConfig b/configfiles/BeamClusterAnalysisMC/ToolsConfig index 4913dd192..d6c7b96f4 100644 --- a/configfiles/BeamClusterAnalysisMC/ToolsConfig +++ b/configfiles/BeamClusterAnalysisMC/ToolsConfig @@ -4,10 +4,17 @@ myLoadWCSimLAPPD LoadWCSimLAPPD ./configfiles/BeamClusterAnalysisMC/LoadWCSimLAP myLoadGenieEvent LoadGenieEvent ./configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig myMCParticleProperties MCParticleProperties ./configfiles/BeamClusterAnalysisMC/MCParticlePropertiesConfig myMCRecoEventLoader MCRecoEventLoader ./configfiles/BeamClusterAnalysisMC/MCRecoEventLoaderConfig + +myDigitBuilder DigitBuilder ./configfiles/BeamClusterAnalysisMC/DigitBuilderConfig + myTimeClustering TimeClustering configfiles/BeamClusterAnalysisMC/TimeClusteringConfig myFindMrdTracks FindMrdTracks configfiles/BeamClusterAnalysisMC/FindMrdTracksConfig myClusterFinder ClusterFinder ./configfiles/BeamClusterAnalysisMC/ClusterFinderConfig myClusterClassifiers ClusterClassifiers ./configfiles/BeamClusterAnalysisMC/ClusterClassifiersConfig myEventSelector EventSelector ./configfiles/BeamClusterAnalysisMC/EventSelectorConfig -myAssignBunchTimingMC AssignBunchTimingMC ./configfiles/BeamClusterAnalysisMC/AssignBunchTimingMCConfig -myPhaseIITreeMaker PhaseIITreeMaker ./configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig +#myPhaseIITreeMaker PhaseIITreeMaker ./configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig + +myCNNImage CNNImage ./configfiles/BeamClusterAnalysisMC/CNNImageConfig +myRingCounting PythonScript configfiles/BeamClusterAnalysisMC/RingCountingConfig + +myANNIEEventTreeMaker ANNIEEventTreeMaker ./configfiles/BeamClusterAnalysisMC/ANNIEEventTreeMakerConfig diff --git a/configfiles/BeamClusterAnalysisMC/my_inputs.txt b/configfiles/BeamClusterAnalysisMC/my_inputs.txt deleted file mode 100644 index 974bc6755..000000000 --- a/configfiles/BeamClusterAnalysisMC/my_inputs.txt +++ /dev/null @@ -1,40 +0,0 @@ -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p0 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p1 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p2 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p3 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p4 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p5 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p6 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p7 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p8 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p9 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p10 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p11 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p12 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p13 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p14 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p15 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p16 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p17 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p18 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p19 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p20 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p21 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p22 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p23 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p24 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p25 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p26 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p27 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p28 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p29 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p30 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p31 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p32 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p33 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p34 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p35 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p36 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p37 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p38 -/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2630/ProcessedRawData_TankAndMRDAndCTC_R2630S0p39 diff --git a/configfiles/BeamFetcherV2/LoadRawDataConfig b/configfiles/BeamFetcherV2/LoadRawDataConfig index cff346d06..b018c823d 100644 --- a/configfiles/BeamFetcherV2/LoadRawDataConfig +++ b/configfiles/BeamFetcherV2/LoadRawDataConfig @@ -1,4 +1,5 @@ verbosity 11 +#BuildType TankAndMRDAndCTC BuildType CTC Mode FileList InputFile ./configfiles/BeamFetcherV2/my_files.txt diff --git a/configfiles/BeamFetcherV2/README.md b/configfiles/BeamFetcherV2/README.md index 3c4bbe337..78d3e2015 100644 --- a/configfiles/BeamFetcherV2/README.md +++ b/configfiles/BeamFetcherV2/README.md @@ -4,6 +4,22 @@ #Description ********************** -See the BeamFetcherV2 tool for description/usage. +Configure files are simple text files for passing variables to the Tools. + +Text files are read by the Store class (src/Store) and automatically assigned to an internal map for the relevant Tool to use. + + +************************ +#Usage +************************ + +Any line starting with a "#" will be ignored by the Store, as will blank lines. + +Variables should be stored one per line as follows: + + +Name Value #Comments + + +Note: Only one value is permitted per name and they are stored in a string stream and template cast back to the type given. -Loads CTC triggers from the TriggerDataDecoder tool, then fetches the beam database entries through queries based on the CTC trigger timestamps. diff --git a/configfiles/EventBuilder/ANNIEEventBuilderConfig b/configfiles/EventBuilder/ANNIEEventBuilderConfig index 6d59474bf..736ce9c98 100644 --- a/configfiles/EventBuilder/ANNIEEventBuilderConfig +++ b/configfiles/EventBuilder/ANNIEEventBuilderConfig @@ -1,4 +1,4 @@ -verbosity 0 +verbosity 1 BuildType TankAndMRDAndCTC ProcessedFilesBasename ProcessedRawData @@ -14,7 +14,7 @@ OrphanFileBase OrphanStore MaxStreamMatchingTimeSeparation 60 # seconds. If one stream is ahead of the others, pause reading SaveRawData 0 -StoreBeamStatus 0 +StoreBeamStatus 1 BuildStage1Data 0 SaveSeparatePartfiles 1 diff --git a/configfiles/EventBuilder/LoadRawDataConfig b/configfiles/EventBuilder/LoadRawDataConfig index 658744545..3ebf29085 100644 --- a/configfiles/EventBuilder/LoadRawDataConfig +++ b/configfiles/EventBuilder/LoadRawDataConfig @@ -1,4 +1,4 @@ -verbosity 0 +verbosity 1 BuildType TankAndMRDAndCTC #BuildType CTC Mode FileList diff --git a/configfiles/EventBuilder/README.md b/configfiles/EventBuilder/README.md index 6d0350575..089e9c8a2 100644 --- a/configfiles/EventBuilder/README.md +++ b/configfiles/EventBuilder/README.md @@ -4,7 +4,7 @@ ## Description ********************** -The `EventBuilder` toolchain is used to create ANNIEEvents. The toolchain reads in RAWData files, time match, and creates processed ANNIEEvents with Tank, CTC, MRD, and Beam information (no LAPPD information is included in this toolchain). This toolchain replaces the `DataDecoder` toolchain which is now considered depreciated. +The `EventBuilder` toolchain is used to event build for ANNIE. The toolchain reads in RAWData files, time match, and creates processed ANNIEEvents with Tank, CTC, and MRD information (currently no LAPPD information is included). This toolchain consolidated efforts to create an official event building toolchain, and should replace the `DataDecoder` toolchain which is now considered depreciated. Please consult the following ANNIE wiki page on how to event build: https://cdcvs.fnal.gov/redmine/projects/annie_experiment/wiki/Event_Building_with_ToolAnalysis @@ -20,8 +20,6 @@ LoadRawData PMTDataDecoder MRDDataDecoder TriggerDataDecoder -BeamFetcherV2 -BeamQuality PhaseIIADCCalibrator PhaseIIADCHitFinder SaveConfigInfo diff --git a/configfiles/EventBuilder/my_files.txt b/configfiles/EventBuilder/my_files.txt index 8c8399ef2..2dce56d16 100644 --- a/configfiles/EventBuilder/my_files.txt +++ b/configfiles/EventBuilder/my_files.txt @@ -1,2 +1,20 @@ -/pnfs/annie/persistent/raw/raw/4314/RAWDataR4314S0p0 -/pnfs/annie/persistent/raw/raw/4314/RAWDataR4314S0p1 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p0 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p1 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p2 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p3 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p4 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p5 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p6 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p7 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p8 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p9 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p10 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p11 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p12 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p13 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p14 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p15 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p16 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p17 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p18 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p19 diff --git a/configfiles/EventBuilderRaw/LoadRawDataConfig b/configfiles/EventBuilderRaw/LoadRawDataConfig index 050c4681e..ffaf99fbd 100644 --- a/configfiles/EventBuilderRaw/LoadRawDataConfig +++ b/configfiles/EventBuilderRaw/LoadRawDataConfig @@ -1,8 +1,9 @@ verbosity 0 BuildType TankAndCTC +#BuildType CTC Mode FileList -InputFile ./configfiles/EventBuilderRaw/my_files.txt +InputFile ./configfiles/DataDecoder/my_files.txt DummyRunInfo 1 StoreTrigOverlap 0 -ReadTrigOverlap 0 -StoreRawData 1 +ReadTrigOverlap 1 +StoreRawData 0 diff --git a/configfiles/EventBuilderV2/DefaultTriggerMask.txt b/configfiles/EventBuilderV2/DefaultTriggerMask.txt new file mode 100644 index 000000000..398850355 --- /dev/null +++ b/configfiles/EventBuilderV2/DefaultTriggerMask.txt @@ -0,0 +1,10 @@ +#Triggers are given by Jonathan; place one number per line. Values are index + 1 +#4+1: Delayed beam. 32+1: LED trigger. 34+1: AmBe and Cosmic trigger. 35+1: MRD_CR_Trigger. 30+1: LED_Start. 45+1, 46+1: Laser. 14+1: AmBe external trigger +5 +15 +36 +31 +33 +35 +46 +47 diff --git a/configfiles/EventBuilderV2/EBLAPPDConfig b/configfiles/EventBuilderV2/EBLAPPDConfig new file mode 100644 index 000000000..a81b1ce94 --- /dev/null +++ b/configfiles/EventBuilderV2/EBLAPPDConfig @@ -0,0 +1,7 @@ +verbosityEBLAPPD 0 +matchTargetTrigger 14 +matchTolerance_ns 400000 +#matchTolerance_ns 10000 +exePerMatch 500 + +matchToAllTriggers 0 diff --git a/configfiles/EventBuilderV2/EBLoadRawConfig b/configfiles/EventBuilderV2/EBLoadRawConfig new file mode 100644 index 000000000..083ae9111 --- /dev/null +++ b/configfiles/EventBuilderV2/EBLoadRawConfig @@ -0,0 +1,10 @@ +verbosityEBLoadRaw 2 +ReadTriggerOverlap 1 + +InputFile ./configfiles/EventBuilderV2/my_files.txt + +LoadPMT 1 +LoadMRD 1 +LoadCTC 1 +LoadLAPPD 1 + diff --git a/configfiles/EventBuilderV2/EBMRDConfig b/configfiles/EventBuilderV2/EBMRDConfig new file mode 100644 index 000000000..a4797b1f1 --- /dev/null +++ b/configfiles/EventBuilderV2/EBMRDConfig @@ -0,0 +1,5 @@ +verbosityEBMRD 0 +matchTargetTrigger 8 +matchTolerance_ns 3000000 +matchToAllTriggers 0 +exePerMatch 500 diff --git a/configfiles/EventBuilderV2/EBPMTConfig b/configfiles/EventBuilderV2/EBPMTConfig new file mode 100644 index 000000000..57bb72693 --- /dev/null +++ b/configfiles/EventBuilderV2/EBPMTConfig @@ -0,0 +1,4 @@ +verbosityEBPMT 0 +matchTargetTrigger 46 +matchTolerance_ns 1000 +matchToAllTriggers 1 diff --git a/configfiles/EventBuilderV2/EBSaverConfig b/configfiles/EventBuilderV2/EBSaverConfig new file mode 100644 index 000000000..7cf77b14f --- /dev/null +++ b/configfiles/EventBuilderV2/EBSaverConfig @@ -0,0 +1,10 @@ +verbosityEBSaver 1 + +savePMT 1 +saveMRD 1 +saveCTC 1 +saveLAPPD 1 +saveRunInfo 1 +saveBeamInfo 1 + +beamInfoFileName beamfetcher_tree.root diff --git a/configfiles/EventBuilderV2/EBTriggerGrouperConfig b/configfiles/EventBuilderV2/EBTriggerGrouperConfig new file mode 100644 index 000000000..22535618a --- /dev/null +++ b/configfiles/EventBuilderV2/EBTriggerGrouperConfig @@ -0,0 +1,30 @@ +verbosityEBTG 0 + +# beam triggers are always there, even in AmBe runs. We know they are meaningless to group beam trigger when we know there is 100% no beam, but again redundancy is not bad if it's not harmful +GroupMode beam +GroupTolerance 3000000 +GroupTrigWord 14 //undelayed beam + +groupBeam 1 +BeamTolerance 25000000 + +groupCosmic 1 +CosmicTriggerMain 36 + +groupLaser 1 +LaserTolerance 10000 + +groupLED 1 +#LEDTriggerMain 31 +#LEDTolerance 10000 + +groupAmBe 1 +AmBeTolerance 10000 # 10us for testing +AmBeTriggerMain 11 + +groupPPS 0 + +groupNuMI 1 + +maxNumAllowedInBuffer 20000 + diff --git a/configfiles/EventBuilderV2/LAPPDLoadStoreConfig b/configfiles/EventBuilderV2/LAPPDLoadStoreConfig new file mode 100644 index 000000000..daa420ebe --- /dev/null +++ b/configfiles/EventBuilderV2/LAPPDLoadStoreConfig @@ -0,0 +1,39 @@ + General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 0 +Nboards 6 #Number of pedestal files to be read in +PedinputfileTXT ../Pedestals/Laser2024Feb/P +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + + +ReadStore 0 +num_vector_data 7795 +num_vector_pps 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 1 +loadOffsets 1 + + diff --git a/configfiles/EventBuilderV2/MRDDataDecoderConfig b/configfiles/EventBuilderV2/MRDDataDecoderConfig new file mode 100644 index 000000000..d9937ca9a --- /dev/null +++ b/configfiles/EventBuilderV2/MRDDataDecoderConfig @@ -0,0 +1,2 @@ +verbosity 0 +DaylightSavingsSpring 1 diff --git a/configfiles/EventBuilderV2/PMTDataDecoderConfig b/configfiles/EventBuilderV2/PMTDataDecoderConfig new file mode 100644 index 000000000..cca7bb6b5 --- /dev/null +++ b/configfiles/EventBuilderV2/PMTDataDecoderConfig @@ -0,0 +1,5 @@ +verbosity 1 +ADCCountsToBuildWaves 0 +Mode Offline +OffsetVME03 0 +OffsetVME01 0 diff --git a/configfiles/EventBuilderV2/PhaseIIADCCalibratorConfig b/configfiles/EventBuilderV2/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..158dc6ed1 --- /dev/null +++ b/configfiles/EventBuilderV2/PhaseIIADCCalibratorConfig @@ -0,0 +1,15 @@ +# PhaseIIADCCalibrator config file + +verbosity 0 + +BaselineEstimationType ze3ra_multi +NumBaselineSamples 15 +NumSubWaveforms 10 + +SamplesPerBaselineEstimate 2000 +BaselineUncertaintyTolerance 2 +PCritical 0.01 +MakeCalLEDWaveforms 0 + +EventBuilding 1 +ExecutesPerBuild 10 diff --git a/configfiles/EventBuilderV2/PhaseIIADCHitFinderConfig b/configfiles/EventBuilderV2/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..991f5d222 --- /dev/null +++ b/configfiles/EventBuilderV2/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 diff --git a/configfiles/EventBuilderV2/SaveConfigInfoConfig b/configfiles/EventBuilderV2/SaveConfigInfoConfig new file mode 100644 index 000000000..569dcf758 --- /dev/null +++ b/configfiles/EventBuilderV2/SaveConfigInfoConfig @@ -0,0 +1,3 @@ +verbosity 5 +OutFileName config_info.txt +FullDepth 0 diff --git a/configfiles/EventBuilderV2/ToolChainConfig b/configfiles/EventBuilderV2/ToolChainConfig new file mode 100644 index 000000000..b661e1dfd --- /dev/null +++ b/configfiles/EventBuilderV2/ToolChainConfig @@ -0,0 +1,23 @@ +#ToolChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File ./configfiles/EventBuilderV2/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/EventBuilderV2/ToolsConfig b/configfiles/EventBuilderV2/ToolsConfig new file mode 100644 index 000000000..007d55c76 --- /dev/null +++ b/configfiles/EventBuilderV2/ToolsConfig @@ -0,0 +1,24 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +EBLoadRaw EBLoadRaw ./configfiles/EventBuilderV2/EBLoadRawConfig + + +PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilderV2/PMTDataDecoderConfig +MRDDataDecoder MRDDataDecoder ./configfiles/EventBuilderV2/MRDDataDecoderConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilderV2/TriggerDataDecoderConfig +LAPPDLoadStore LAPPDLoadStore ./configfiles/EventBuilderV2/LAPPDLoadStoreConfig + + +PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilderV2/PhaseIIADCCalibratorConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilderV2/PhaseIIADCHitFinderConfig + + +EBTriggerGrouper EBTriggerGrouper ./configfiles/EventBuilderV2/EBTriggerGrouperConfig +EBPMT EBPMT ./configfiles/EventBuilderV2/EBPMTConfig +EBMRD EBMRD ./configfiles/EventBuilderV2/EBMRDConfig +EBLAPPD EBLAPPD ./configfiles/EventBuilderV2/EBLAPPDConfig + +SaveConfigInfo SaveConfigInfo ./configfiles/EventBuilderV2/SaveConfigInfoConfig + +EBSaver EBSaver ./configfiles/EventBuilderV2/EBSaverConfig + + diff --git a/configfiles/EventBuilderV2/TriggerDataDecoderConfig b/configfiles/EventBuilderV2/TriggerDataDecoderConfig new file mode 100644 index 000000000..a8ef6641f --- /dev/null +++ b/configfiles/EventBuilderV2/TriggerDataDecoderConfig @@ -0,0 +1,3 @@ +verbosity 0 +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/EventBuilderV2/my_files.txt b/configfiles/EventBuilderV2/my_files.txt new file mode 100644 index 000000000..7697d0d84 --- /dev/null +++ b/configfiles/EventBuilderV2/my_files.txt @@ -0,0 +1,3 @@ +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p0 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p1 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p2 diff --git a/configfiles/EventBuilderV2_AmBe/EBLAPPDConfig b/configfiles/EventBuilderV2_AmBe/EBLAPPDConfig new file mode 100644 index 000000000..a81b1ce94 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/EBLAPPDConfig @@ -0,0 +1,7 @@ +verbosityEBLAPPD 0 +matchTargetTrigger 14 +matchTolerance_ns 400000 +#matchTolerance_ns 10000 +exePerMatch 500 + +matchToAllTriggers 0 diff --git a/configfiles/EventBuilderV2_AmBe/EBLoadRawConfig b/configfiles/EventBuilderV2_AmBe/EBLoadRawConfig new file mode 100644 index 000000000..422353c62 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/EBLoadRawConfig @@ -0,0 +1,10 @@ +verbosityEBLoadRaw 2 +ReadTriggerOverlap 1 + +InputFile ./configfiles/EventBuilderV2_AmBe/my_files.txt + +LoadPMT 1 +LoadMRD 0 +LoadCTC 1 +LoadLAPPD 0 + diff --git a/configfiles/EventBuilderV2_AmBe/EBMRDConfig b/configfiles/EventBuilderV2_AmBe/EBMRDConfig new file mode 100644 index 000000000..a4797b1f1 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/EBMRDConfig @@ -0,0 +1,5 @@ +verbosityEBMRD 0 +matchTargetTrigger 8 +matchTolerance_ns 3000000 +matchToAllTriggers 0 +exePerMatch 500 diff --git a/configfiles/EventBuilderV2_AmBe/EBPMTConfig b/configfiles/EventBuilderV2_AmBe/EBPMTConfig new file mode 100644 index 000000000..57bb72693 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/EBPMTConfig @@ -0,0 +1,4 @@ +verbosityEBPMT 0 +matchTargetTrigger 46 +matchTolerance_ns 1000 +matchToAllTriggers 1 diff --git a/configfiles/EventBuilderV2_AmBe/EBSaverConfig b/configfiles/EventBuilderV2_AmBe/EBSaverConfig new file mode 100644 index 000000000..d3e1e75c7 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/EBSaverConfig @@ -0,0 +1,10 @@ +verbosityEBSaver 1 + +savePMT 1 +saveMRD 0 +saveCTC 1 +saveLAPPD 0 +saveRunInfo 1 +saveBeamInfo 0 + +beamInfoFileName beamfetcher_tree.root diff --git a/configfiles/EventBuilderV2_AmBe/EBTriggerGrouperConfig b/configfiles/EventBuilderV2_AmBe/EBTriggerGrouperConfig new file mode 100644 index 000000000..b00af8388 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/EBTriggerGrouperConfig @@ -0,0 +1,28 @@ +verbosityEBTG 0 +GroupMode beam +GroupTolerance 3000000 +GroupTrigWord 14 //undelayed beam + +groupBeam 0 +BeamTolerance 25000000 + +groupCosmic 0 +CosmicTriggerMain 36 + +groupLaser 0 +LaserTolerance 10000 + +groupLED 0 +#LEDTriggerMain 31 +#LEDTolerance 10000 + +groupAmBe 1 +AmBeTolerance 10000 # 10us for testing +AmBeTriggerMain 11 + +groupPPS 0 + +groupNuMI 0 + +maxNumAllowedInBuffer 20000 + diff --git a/configfiles/EventBuilderV2_AmBe/LAPPDLoadStoreConfig b/configfiles/EventBuilderV2_AmBe/LAPPDLoadStoreConfig new file mode 100644 index 000000000..daa420ebe --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/LAPPDLoadStoreConfig @@ -0,0 +1,39 @@ + General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 0 +Nboards 6 #Number of pedestal files to be read in +PedinputfileTXT ../Pedestals/Laser2024Feb/P +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + + +ReadStore 0 +num_vector_data 7795 +num_vector_pps 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 1 +loadOffsets 1 + + diff --git a/configfiles/EventBuilderV2_AmBe/MRDDataDecoderConfig b/configfiles/EventBuilderV2_AmBe/MRDDataDecoderConfig new file mode 100644 index 000000000..d9937ca9a --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/MRDDataDecoderConfig @@ -0,0 +1,2 @@ +verbosity 0 +DaylightSavingsSpring 1 diff --git a/configfiles/EventBuilderV2_AmBe/PMTDataDecoderConfig b/configfiles/EventBuilderV2_AmBe/PMTDataDecoderConfig new file mode 100644 index 000000000..cca7bb6b5 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/PMTDataDecoderConfig @@ -0,0 +1,5 @@ +verbosity 1 +ADCCountsToBuildWaves 0 +Mode Offline +OffsetVME03 0 +OffsetVME01 0 diff --git a/configfiles/EventBuilderV2_AmBe/PhaseIIADCCalibratorConfig b/configfiles/EventBuilderV2_AmBe/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..158dc6ed1 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/PhaseIIADCCalibratorConfig @@ -0,0 +1,15 @@ +# PhaseIIADCCalibrator config file + +verbosity 0 + +BaselineEstimationType ze3ra_multi +NumBaselineSamples 15 +NumSubWaveforms 10 + +SamplesPerBaselineEstimate 2000 +BaselineUncertaintyTolerance 2 +PCritical 0.01 +MakeCalLEDWaveforms 0 + +EventBuilding 1 +ExecutesPerBuild 10 diff --git a/configfiles/EventBuilderV2_AmBe/PhaseIIADCHitFinderConfig b/configfiles/EventBuilderV2_AmBe/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..991f5d222 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 diff --git a/configfiles/EventBuilderV2_AmBe/SaveConfigInfoConfig b/configfiles/EventBuilderV2_AmBe/SaveConfigInfoConfig new file mode 100644 index 000000000..569dcf758 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/SaveConfigInfoConfig @@ -0,0 +1,3 @@ +verbosity 5 +OutFileName config_info.txt +FullDepth 0 diff --git a/configfiles/EventBuilderV2_AmBe/ToolChainConfig b/configfiles/EventBuilderV2_AmBe/ToolChainConfig new file mode 100644 index 000000000..f3b457d9c --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/ToolChainConfig @@ -0,0 +1,23 @@ +#ToolChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File ./configfiles/EventBuilderV2_AmBe/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/EventBuilderV2_AmBe/ToolsConfig b/configfiles/EventBuilderV2_AmBe/ToolsConfig new file mode 100644 index 000000000..47ef4d26f --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/ToolsConfig @@ -0,0 +1,21 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +EBLoadRaw EBLoadRaw ./configfiles/EventBuilderV2_AmBe/EBLoadRawConfig + +PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilderV2_AmBe/PMTDataDecoderConfig +#MRDDataDecoder MRDDataDecoder ./configfiles/EventBuilderV2_AmBe/MRDDataDecoderConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilderV2_AmBe/TriggerDataDecoderConfig +#LAPPDLoadStore LAPPDLoadStore ./configfiles/EventBuilderV2_AmBe/LAPPDLoadStoreConfig + +PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilderV2_AmBe/PhaseIIADCCalibratorConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilderV2_AmBe/PhaseIIADCHitFinderConfig + +EBTriggerGrouper EBTriggerGrouper ./configfiles/EventBuilderV2_AmBe/EBTriggerGrouperConfig +EBPMT EBPMT ./configfiles/EventBuilderV2_AmBe/EBPMTConfig +#EBMRD EBMRD ./configfiles/EventBuilderV2_AmBe/EBMRDConfig +#EBLAPPD EBLAPPD ./configfiles/EventBuilderV2_AmBe/EBLAPPDConfig + +SaveConfigInfo SaveConfigInfo ./configfiles/EventBuilderV2_AmBe/SaveConfigInfoConfig + +EBSaver EBSaver ./configfiles/EventBuilderV2_AmBe/EBSaverConfig + + diff --git a/configfiles/EventBuilderV2_AmBe/TriggerDataDecoderConfig b/configfiles/EventBuilderV2_AmBe/TriggerDataDecoderConfig new file mode 100644 index 000000000..a8ef6641f --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/TriggerDataDecoderConfig @@ -0,0 +1,3 @@ +verbosity 0 +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/EventBuilderV2_AmBe/my_files.txt b/configfiles/EventBuilderV2_AmBe/my_files.txt new file mode 100644 index 000000000..7697d0d84 --- /dev/null +++ b/configfiles/EventBuilderV2_AmBe/my_files.txt @@ -0,0 +1,3 @@ +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p0 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p1 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p2 diff --git a/configfiles/EventBuilderV2_LED/EBLoadRawConfig b/configfiles/EventBuilderV2_LED/EBLoadRawConfig new file mode 100644 index 000000000..31ddd80ea --- /dev/null +++ b/configfiles/EventBuilderV2_LED/EBLoadRawConfig @@ -0,0 +1,10 @@ +verbosityEBLoadRaw 2 +ReadTriggerOverlap 1 + +InputFile ./configfiles/EventBuilderV2_LED/my_files.txt + +LoadPMT 1 +LoadMRD 0 +LoadCTC 1 +LoadLAPPD 0 + diff --git a/configfiles/EventBuilderV2_LED/EBPMTConfig b/configfiles/EventBuilderV2_LED/EBPMTConfig new file mode 100644 index 000000000..57bb72693 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/EBPMTConfig @@ -0,0 +1,4 @@ +verbosityEBPMT 0 +matchTargetTrigger 46 +matchTolerance_ns 1000 +matchToAllTriggers 1 diff --git a/configfiles/EventBuilderV2_LED/EBSaverConfig b/configfiles/EventBuilderV2_LED/EBSaverConfig new file mode 100644 index 000000000..d3e1e75c7 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/EBSaverConfig @@ -0,0 +1,10 @@ +verbosityEBSaver 1 + +savePMT 1 +saveMRD 0 +saveCTC 1 +saveLAPPD 0 +saveRunInfo 1 +saveBeamInfo 0 + +beamInfoFileName beamfetcher_tree.root diff --git a/configfiles/EventBuilderV2_LED/EBTriggerGrouperConfig b/configfiles/EventBuilderV2_LED/EBTriggerGrouperConfig new file mode 100644 index 000000000..11dbb7506 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/EBTriggerGrouperConfig @@ -0,0 +1,28 @@ +verbosityEBTG 0 +GroupMode beam +GroupTolerance 3000000 +GroupTrigWord 14 # undelayed beam + +groupBeam 0 +BeamTolerance 25000000 + +groupCosmic 0 +CosmicTriggerMain 36 + +groupLaser 0 +LaserTolerance 10000 + +groupLED 1 +LEDTriggerMain 31 +LEDTolerance 10000 + +groupAmBe 0 +AmBeTolerance 10000 # 10us for testing +AmBeTriggerMain 11 + +groupPPS 0 + +groupNuMI 0 + +maxNumAllowedInBuffer 20000 + diff --git a/configfiles/EventBuilderV2_LED/PMTDataDecoderConfig b/configfiles/EventBuilderV2_LED/PMTDataDecoderConfig new file mode 100644 index 000000000..cca7bb6b5 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/PMTDataDecoderConfig @@ -0,0 +1,5 @@ +verbosity 1 +ADCCountsToBuildWaves 0 +Mode Offline +OffsetVME03 0 +OffsetVME01 0 diff --git a/configfiles/EventBuilderV2_LED/PhaseIIADCCalibratorConfig b/configfiles/EventBuilderV2_LED/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..158dc6ed1 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/PhaseIIADCCalibratorConfig @@ -0,0 +1,15 @@ +# PhaseIIADCCalibrator config file + +verbosity 0 + +BaselineEstimationType ze3ra_multi +NumBaselineSamples 15 +NumSubWaveforms 10 + +SamplesPerBaselineEstimate 2000 +BaselineUncertaintyTolerance 2 +PCritical 0.01 +MakeCalLEDWaveforms 0 + +EventBuilding 1 +ExecutesPerBuild 10 diff --git a/configfiles/EventBuilderV2_LED/PhaseIIADCHitFinderConfig b/configfiles/EventBuilderV2_LED/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..991f5d222 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 diff --git a/configfiles/EventBuilderV2_LED/SaveConfigInfoConfig b/configfiles/EventBuilderV2_LED/SaveConfigInfoConfig new file mode 100644 index 000000000..569dcf758 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/SaveConfigInfoConfig @@ -0,0 +1,3 @@ +verbosity 5 +OutFileName config_info.txt +FullDepth 0 diff --git a/configfiles/EventBuilderV2_LED/ToolChainConfig b/configfiles/EventBuilderV2_LED/ToolChainConfig new file mode 100644 index 000000000..b6cc94954 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/ToolChainConfig @@ -0,0 +1,23 @@ +#ToolChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File ./configfiles/EventBuilderV2_LED/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/EventBuilderV2_LED/ToolsConfig b/configfiles/EventBuilderV2_LED/ToolsConfig new file mode 100644 index 000000000..6fd615c39 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/ToolsConfig @@ -0,0 +1,12 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +EBLoadRaw EBLoadRaw ./configfiles/EventBuilderV2_LED/EBLoadRawConfig +PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilderV2_LED/PMTDataDecoderConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilderV2_LED/TriggerDataDecoderConfig +PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilderV2_LED/PhaseIIADCCalibratorConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilderV2_LED/PhaseIIADCHitFinderConfig +EBTriggerGrouper EBTriggerGrouper ./configfiles/EventBuilderV2_LED/EBTriggerGrouperConfig +EBPMT EBPMT ./configfiles/EventBuilderV2_LED/EBPMTConfig +SaveConfigInfo SaveConfigInfo ./configfiles/EventBuilderV2_LED/SaveConfigInfoConfig +EBSaver EBSaver ./configfiles/EventBuilderV2_LED/EBSaverConfig + + diff --git a/configfiles/EventBuilderV2_LED/TriggerDataDecoderConfig b/configfiles/EventBuilderV2_LED/TriggerDataDecoderConfig new file mode 100644 index 000000000..a8ef6641f --- /dev/null +++ b/configfiles/EventBuilderV2_LED/TriggerDataDecoderConfig @@ -0,0 +1,3 @@ +verbosity 0 +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/EventBuilderV2_LED/my_files.txt b/configfiles/EventBuilderV2_LED/my_files.txt new file mode 100644 index 000000000..7697d0d84 --- /dev/null +++ b/configfiles/EventBuilderV2_LED/my_files.txt @@ -0,0 +1,3 @@ +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p0 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p1 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p2 diff --git a/configfiles/EventBuilderV2_cosmic/EBLAPPDConfig b/configfiles/EventBuilderV2_cosmic/EBLAPPDConfig new file mode 100644 index 000000000..a81b1ce94 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/EBLAPPDConfig @@ -0,0 +1,7 @@ +verbosityEBLAPPD 0 +matchTargetTrigger 14 +matchTolerance_ns 400000 +#matchTolerance_ns 10000 +exePerMatch 500 + +matchToAllTriggers 0 diff --git a/configfiles/EventBuilderV2_cosmic/EBLoadRawConfig b/configfiles/EventBuilderV2_cosmic/EBLoadRawConfig new file mode 100644 index 000000000..e7567be01 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/EBLoadRawConfig @@ -0,0 +1,10 @@ +verbosityEBLoadRaw 2 +ReadTriggerOverlap 1 + +InputFile ./configfiles/EventBuilderV2_cosmic/my_files.txt + +LoadPMT 1 +LoadMRD 1 +LoadCTC 1 +LoadLAPPD 0 + diff --git a/configfiles/EventBuilderV2_cosmic/EBMRDConfig b/configfiles/EventBuilderV2_cosmic/EBMRDConfig new file mode 100644 index 000000000..5edc61080 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/EBMRDConfig @@ -0,0 +1,5 @@ +verbosityEBMRD 0 +matchTargetTrigger 36 +matchTolerance_ns 3000000 +matchToAllTriggers 0 +exePerMatch 500 diff --git a/configfiles/EventBuilderV2_cosmic/EBPMTConfig b/configfiles/EventBuilderV2_cosmic/EBPMTConfig new file mode 100644 index 000000000..57bb72693 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/EBPMTConfig @@ -0,0 +1,4 @@ +verbosityEBPMT 0 +matchTargetTrigger 46 +matchTolerance_ns 1000 +matchToAllTriggers 1 diff --git a/configfiles/EventBuilderV2_cosmic/EBSaverConfig b/configfiles/EventBuilderV2_cosmic/EBSaverConfig new file mode 100644 index 000000000..09378e248 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/EBSaverConfig @@ -0,0 +1,10 @@ +verbosityEBSaver 1 + +savePMT 1 +saveMRD 1 +saveCTC 1 +saveLAPPD 0 +saveRunInfo 1 +saveBeamInfo 0 + +beamInfoFileName beamfetcher_tree.root diff --git a/configfiles/EventBuilderV2_cosmic/EBTriggerGrouperConfig b/configfiles/EventBuilderV2_cosmic/EBTriggerGrouperConfig new file mode 100644 index 000000000..0d8a2cae2 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/EBTriggerGrouperConfig @@ -0,0 +1,28 @@ +verbosityEBTG 0 +GroupMode beam +GroupTolerance 3000000 +GroupTrigWord 14 //undelayed beam + +groupBeam 0 +BeamTolerance 25000000 + +groupCosmic 1 +CosmicTriggerMain 36 + +groupLaser 0 +LaserTolerance 10000 + +groupLED 0 +#LEDTriggerMain 31 +#LEDTolerance 10000 + +groupAmBe 0 +AmBeTolerance 10000 # 10us for testing +AmBeTriggerMain 11 + +groupPPS 0 + +groupNuMI 0 + +maxNumAllowedInBuffer 20000 + diff --git a/configfiles/EventBuilderV2_cosmic/LAPPDLoadStoreConfig b/configfiles/EventBuilderV2_cosmic/LAPPDLoadStoreConfig new file mode 100644 index 000000000..daa420ebe --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/LAPPDLoadStoreConfig @@ -0,0 +1,39 @@ + General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 0 +Nboards 6 #Number of pedestal files to be read in +PedinputfileTXT ../Pedestals/Laser2024Feb/P +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + + +ReadStore 0 +num_vector_data 7795 +num_vector_pps 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 1 +loadOffsets 1 + + diff --git a/configfiles/EventBuilderV2_cosmic/MRDDataDecoderConfig b/configfiles/EventBuilderV2_cosmic/MRDDataDecoderConfig new file mode 100644 index 000000000..d9937ca9a --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/MRDDataDecoderConfig @@ -0,0 +1,2 @@ +verbosity 0 +DaylightSavingsSpring 1 diff --git a/configfiles/EventBuilderV2_cosmic/PMTDataDecoderConfig b/configfiles/EventBuilderV2_cosmic/PMTDataDecoderConfig new file mode 100644 index 000000000..cca7bb6b5 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/PMTDataDecoderConfig @@ -0,0 +1,5 @@ +verbosity 1 +ADCCountsToBuildWaves 0 +Mode Offline +OffsetVME03 0 +OffsetVME01 0 diff --git a/configfiles/EventBuilderV2_cosmic/PhaseIIADCCalibratorConfig b/configfiles/EventBuilderV2_cosmic/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..158dc6ed1 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/PhaseIIADCCalibratorConfig @@ -0,0 +1,15 @@ +# PhaseIIADCCalibrator config file + +verbosity 0 + +BaselineEstimationType ze3ra_multi +NumBaselineSamples 15 +NumSubWaveforms 10 + +SamplesPerBaselineEstimate 2000 +BaselineUncertaintyTolerance 2 +PCritical 0.01 +MakeCalLEDWaveforms 0 + +EventBuilding 1 +ExecutesPerBuild 10 diff --git a/configfiles/EventBuilderV2_cosmic/PhaseIIADCHitFinderConfig b/configfiles/EventBuilderV2_cosmic/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..991f5d222 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 diff --git a/configfiles/EventBuilderV2_cosmic/SaveConfigInfoConfig b/configfiles/EventBuilderV2_cosmic/SaveConfigInfoConfig new file mode 100644 index 000000000..569dcf758 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/SaveConfigInfoConfig @@ -0,0 +1,3 @@ +verbosity 5 +OutFileName config_info.txt +FullDepth 0 diff --git a/configfiles/EventBuilderV2_cosmic/ToolChainConfig b/configfiles/EventBuilderV2_cosmic/ToolChainConfig new file mode 100644 index 000000000..03ab2dfe1 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/ToolChainConfig @@ -0,0 +1,23 @@ +#ToolChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File ./configfiles/EventBuilderV2_cosmic/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/EventBuilderV2_cosmic/ToolsConfig b/configfiles/EventBuilderV2_cosmic/ToolsConfig new file mode 100644 index 000000000..22adf1923 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/ToolsConfig @@ -0,0 +1,24 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +EBLoadRaw EBLoadRaw ./configfiles/EventBuilderV2_cosmic/EBLoadRawConfig + + +PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilderV2_cosmic/PMTDataDecoderConfig +MRDDataDecoder MRDDataDecoder ./configfiles/EventBuilderV2_cosmic/MRDDataDecoderConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilderV2_cosmic/TriggerDataDecoderConfig +#LAPPDLoadStore LAPPDLoadStore ./configfiles/EventBuilderV2_cosmic/LAPPDLoadStoreConfig + + +PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilderV2_cosmic/PhaseIIADCCalibratorConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilderV2_cosmic/PhaseIIADCHitFinderConfig + + +EBTriggerGrouper EBTriggerGrouper ./configfiles/EventBuilderV2_cosmic/EBTriggerGrouperConfig +EBPMT EBPMT ./configfiles/EventBuilderV2_cosmic/EBPMTConfig +EBMRD EBMRD ./configfiles/EventBuilderV2_cosmic/EBMRDConfig +#EBLAPPD EBLAPPD ./configfiles/EventBuilderV2_cosmic/EBLAPPDConfig + +SaveConfigInfo SaveConfigInfo ./configfiles/EventBuilderV2_cosmic/SaveConfigInfoConfig + +EBSaver EBSaver ./configfiles/EventBuilderV2_cosmic/EBSaverConfig + + diff --git a/configfiles/EventBuilderV2_cosmic/TriggerDataDecoderConfig b/configfiles/EventBuilderV2_cosmic/TriggerDataDecoderConfig new file mode 100644 index 000000000..a8ef6641f --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/TriggerDataDecoderConfig @@ -0,0 +1,3 @@ +verbosity 0 +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/EventBuilderV2_cosmic/my_files.txt b/configfiles/EventBuilderV2_cosmic/my_files.txt new file mode 100644 index 000000000..2792b0b48 --- /dev/null +++ b/configfiles/EventBuilderV2_cosmic/my_files.txt @@ -0,0 +1,14 @@ +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p0 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p1 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p2 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p3 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p4 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p5 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p6 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p7 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p8 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p9 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p10 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p11 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p12 +/pnfs/annie/persistent/raw/raw/5088/RAWDataR5088S0p13 diff --git a/configfiles/EventBuilderV2_laser/EBLAPPDConfig b/configfiles/EventBuilderV2_laser/EBLAPPDConfig new file mode 100644 index 000000000..a81b1ce94 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/EBLAPPDConfig @@ -0,0 +1,7 @@ +verbosityEBLAPPD 0 +matchTargetTrigger 14 +matchTolerance_ns 400000 +#matchTolerance_ns 10000 +exePerMatch 500 + +matchToAllTriggers 0 diff --git a/configfiles/EventBuilderV2_laser/EBLoadRawConfig b/configfiles/EventBuilderV2_laser/EBLoadRawConfig new file mode 100644 index 000000000..7901c4de7 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/EBLoadRawConfig @@ -0,0 +1,10 @@ +verbosityEBLoadRaw 2 +ReadTriggerOverlap 1 + +InputFile ./configfiles/EventBuilderV2_laser/my_files.txt + +LoadPMT 1 +LoadMRD 0 +LoadCTC 1 +LoadLAPPD 1 + diff --git a/configfiles/EventBuilderV2_laser/EBMRDConfig b/configfiles/EventBuilderV2_laser/EBMRDConfig new file mode 100644 index 000000000..a4797b1f1 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/EBMRDConfig @@ -0,0 +1,5 @@ +verbosityEBMRD 0 +matchTargetTrigger 8 +matchTolerance_ns 3000000 +matchToAllTriggers 0 +exePerMatch 500 diff --git a/configfiles/EventBuilderV2_laser/EBPMTConfig b/configfiles/EventBuilderV2_laser/EBPMTConfig new file mode 100644 index 000000000..57bb72693 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/EBPMTConfig @@ -0,0 +1,4 @@ +verbosityEBPMT 0 +matchTargetTrigger 46 +matchTolerance_ns 1000 +matchToAllTriggers 1 diff --git a/configfiles/EventBuilderV2_laser/EBSaverConfig b/configfiles/EventBuilderV2_laser/EBSaverConfig new file mode 100644 index 000000000..7483a7a8d --- /dev/null +++ b/configfiles/EventBuilderV2_laser/EBSaverConfig @@ -0,0 +1,10 @@ +verbosityEBSaver 1 + +savePMT 1 +saveMRD 0 +saveCTC 1 +saveLAPPD 1 +saveRunInfo 1 +saveBeamInfo 0 + +beamInfoFileName beamfetcher_tree.root diff --git a/configfiles/EventBuilderV2_laser/EBTriggerGrouperConfig b/configfiles/EventBuilderV2_laser/EBTriggerGrouperConfig new file mode 100644 index 000000000..87e6e3976 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/EBTriggerGrouperConfig @@ -0,0 +1,30 @@ +verbosityEBTG 0 + +# beam triggers are always there, even in AmBe runs. We know they are meaningless to group beam trigger when we know there is 100% no beam, but again redundancy is not bad if it's not harmful +GroupMode beam +GroupTolerance 3000000 +GroupTrigWord 14 //undelayed beam + +groupBeam 0 +BeamTolerance 25000000 + +groupCosmic 0 +CosmicTriggerMain 36 + +groupLaser 1 +LaserTolerance 10000 + +groupLED 0 +#LEDTriggerMain 31 +#LEDTolerance 10000 + +groupAmBe 0 +AmBeTolerance 10000 # 10us for testing +AmBeTriggerMain 11 + +groupPPS 0 + +groupNuMI 0 + +maxNumAllowedInBuffer 20000 + diff --git a/configfiles/EventBuilderV2_laser/LAPPDLoadStoreConfig b/configfiles/EventBuilderV2_laser/LAPPDLoadStoreConfig new file mode 100644 index 000000000..daa420ebe --- /dev/null +++ b/configfiles/EventBuilderV2_laser/LAPPDLoadStoreConfig @@ -0,0 +1,39 @@ + General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 0 +Nboards 6 #Number of pedestal files to be read in +PedinputfileTXT ../Pedestals/Laser2024Feb/P +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + + +ReadStore 0 +num_vector_data 7795 +num_vector_pps 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 1 +loadOffsets 1 + + diff --git a/configfiles/EventBuilderV2_laser/MRDDataDecoderConfig b/configfiles/EventBuilderV2_laser/MRDDataDecoderConfig new file mode 100644 index 000000000..d9937ca9a --- /dev/null +++ b/configfiles/EventBuilderV2_laser/MRDDataDecoderConfig @@ -0,0 +1,2 @@ +verbosity 0 +DaylightSavingsSpring 1 diff --git a/configfiles/EventBuilderV2_laser/PMTDataDecoderConfig b/configfiles/EventBuilderV2_laser/PMTDataDecoderConfig new file mode 100644 index 000000000..cca7bb6b5 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/PMTDataDecoderConfig @@ -0,0 +1,5 @@ +verbosity 1 +ADCCountsToBuildWaves 0 +Mode Offline +OffsetVME03 0 +OffsetVME01 0 diff --git a/configfiles/EventBuilderV2_laser/PhaseIIADCCalibratorConfig b/configfiles/EventBuilderV2_laser/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..158dc6ed1 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/PhaseIIADCCalibratorConfig @@ -0,0 +1,15 @@ +# PhaseIIADCCalibrator config file + +verbosity 0 + +BaselineEstimationType ze3ra_multi +NumBaselineSamples 15 +NumSubWaveforms 10 + +SamplesPerBaselineEstimate 2000 +BaselineUncertaintyTolerance 2 +PCritical 0.01 +MakeCalLEDWaveforms 0 + +EventBuilding 1 +ExecutesPerBuild 10 diff --git a/configfiles/EventBuilderV2_laser/PhaseIIADCHitFinderConfig b/configfiles/EventBuilderV2_laser/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..991f5d222 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 diff --git a/configfiles/EventBuilderV2_laser/SaveConfigInfoConfig b/configfiles/EventBuilderV2_laser/SaveConfigInfoConfig new file mode 100644 index 000000000..569dcf758 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/SaveConfigInfoConfig @@ -0,0 +1,3 @@ +verbosity 5 +OutFileName config_info.txt +FullDepth 0 diff --git a/configfiles/EventBuilderV2_laser/ToolChainConfig b/configfiles/EventBuilderV2_laser/ToolChainConfig new file mode 100644 index 000000000..51af536df --- /dev/null +++ b/configfiles/EventBuilderV2_laser/ToolChainConfig @@ -0,0 +1,23 @@ +#ToolChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File ./configfiles/EventBuilderV2_laser/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/EventBuilderV2_laser/ToolsConfig b/configfiles/EventBuilderV2_laser/ToolsConfig new file mode 100644 index 000000000..47a99a73a --- /dev/null +++ b/configfiles/EventBuilderV2_laser/ToolsConfig @@ -0,0 +1,24 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +EBLoadRaw EBLoadRaw ./configfiles/EventBuilderV2_laser/EBLoadRawConfig + + +PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilderV2_laser/PMTDataDecoderConfig +#MRDDataDecoder MRDDataDecoder ./configfiles/EventBuilderV2_laser/MRDDataDecoderConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilderV2_laser/TriggerDataDecoderConfig +LAPPDLoadStore LAPPDLoadStore ./configfiles/EventBuilderV2_laser/LAPPDLoadStoreConfig + + +PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilderV2_laser/PhaseIIADCCalibratorConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilderV2_laser/PhaseIIADCHitFinderConfig + + +EBTriggerGrouper EBTriggerGrouper ./configfiles/EventBuilderV2_laser/EBTriggerGrouperConfig +EBPMT EBPMT ./configfiles/EventBuilderV2_laser/EBPMTConfig +#EBMRD EBMRD ./configfiles/EventBuilderV2_laser/EBMRDConfig +EBLAPPD EBLAPPD ./configfiles/EventBuilderV2_laser/EBLAPPDConfig + +SaveConfigInfo SaveConfigInfo ./configfiles/EventBuilderV2_laser/SaveConfigInfoConfig + +EBSaver EBSaver ./configfiles/EventBuilderV2_laser/EBSaverConfig + + diff --git a/configfiles/EventBuilderV2_laser/TriggerDataDecoderConfig b/configfiles/EventBuilderV2_laser/TriggerDataDecoderConfig new file mode 100644 index 000000000..a8ef6641f --- /dev/null +++ b/configfiles/EventBuilderV2_laser/TriggerDataDecoderConfig @@ -0,0 +1,3 @@ +verbosity 0 +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/EventBuilderV2_laser/my_files.txt b/configfiles/EventBuilderV2_laser/my_files.txt new file mode 100644 index 000000000..7697d0d84 --- /dev/null +++ b/configfiles/EventBuilderV2_laser/my_files.txt @@ -0,0 +1,3 @@ +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p0 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p1 +/pnfs/annie/persistent/raw/raw/4499/RAWDataR4499S0p2 diff --git a/configfiles/LAPPDASCIIAna/ConfigGeo b/configfiles/LAPPDASCIIAna/ConfigGeo new file mode 100644 index 000000000..ffe0ca918 --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ConfigGeo @@ -0,0 +1,11 @@ +#LoadGeometry +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LAPPDana/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +LAPPDMerging 0 + diff --git a/configfiles/LAPPDASCIIAna/ConfigPlot b/configfiles/LAPPDASCIIAna/ConfigPlot new file mode 100755 index 000000000..09d8e0e63 --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ConfigPlot @@ -0,0 +1,139 @@ +oldLaser 0 #1 for old data, 0 for new trigger boards + +#LAPPDBaselineSubtract +BLSInputWavLabel AlignedLAPPDData +BaselineSubstractVerbosityLevel 0 +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +LowBLfitrange 25; +HiBLfitrange 60; +TrigLowBLfitrange 30 +TrigHiBLfitrange 100 +BLSOutputWavLabel ABLSLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindPeak +FindPeakVerbosity 0 +FiltPeakInputWavLabel FiltLAPPDData +RawPeakInputWavLabel LAPPDWaveforms +BLSPeakInputWavLabel ABLSLAPPDData +FindPeakOutLabel SimpleRecoLAPPDPulses +TotThreshold 15. +MinimumTot 900. +Deltat 100. + +# General Parameters +Nsamples 256 +SampleSize 100 +NChannels 60 + +#LAPPDPlotWaveForms +requireT0signal 0 +SaveByChannel 1 +#PlotWavLabel RawLAPPDData +#PlotWavLabel LAPPDWaveforms +PlotWavLabel BLsubtractedLAPPDData +#PlotWavLabel AlignedLAPPDData +switchBit 0 + +outfile WaveForms_ablsub.root +NHistos 200 +SaveSingleStrip 0 +SingleStripNo 9 +plotLow -10 +plotHigh 20 + +#LAPPDPlotWaveForms2D +outfile2D RawDataWaveForms_2D.root +plot2DrecoPulseInputLabel thresRecoLAPPDPulses +plot2DrecoHitInputLabel thresRecoLAPPDHits +includeRecoPulses 1 +includeRecoHits 1 +plotAdditionalPart 1 +titleSize 0.04 +canvasMargin 0.15 +canvasTitleOffset 1 +#LAPPDSelectPlot2D +LAPPDSelectPlotWaveform2DLabel LAPPDWaveforms +SelectOutfile2D LAPPDSelectPlot.root +MRDTrackExistSelection 0 +verbosityPlot2D 10 +colorContour 255 +useDefaultPalette 1 +colorPalette 112 + + + +#LAPPDThresReco +LAPPDThresRecoVerbosity 0 +verbosity 0 +printHitsTXT 0 +threshold 10 +minPulseWidth 10 +#thresRecoInputWaveLabel AlignedLAPPDData +ThresRecoInputWaveLabel BLsubtractedLAPPDData +#thresRecoInputWaveLabel LAPPDWaveforms + +ThresRecoOutputPulseLabel LAPPDPulses +ThresRecoOutputHitLabel LAPPDHits +useMaxTime 1 # 1: use max bin as pulse time, 0: use gaus fit bin as pulse peak time +#signalSpeedOnStrip 0.6667 +signalSpeedOnStrip 0.567 #1.69982/2.99792 +triggerBoardDelay 0 +loadPrintMRDinfo 0 +useRange 0 #set this to 0 for using pulse start time as the saved pulse time, 1 for high, -1 for using peak time +plusClockBit 0 + +savePositionOnStrip 1 +LoadLAPPDMapInfo 1 + +#LAPPDStackStrip +verbosityStackStrip 0 +StackOutputFileName stacked.root +#StackInputWaveLabel BLsubtractedLAPPDData +StackInputWaveLabel RawLAPPDData +#StackInputWaveLabel LAPPDWaveforms +StackStripNumber 1 +StackStripSide 0 + +#LAPPDPlotWaveForms +NHistos 200 +SaveByChannel 0 +SaveSingleStrip 0 +SingleStripNo 1 +requireT0signal 0 + + +#LAPPDTreeMaker +treeMakerVerbosity 0 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree.root + + +#LAPPDPlots +LAPPDPlotInputWaveLabel BLsubtractedLAPPDData +#LAPPDPlotInputWaveLabel LAPPDWaveforms +#LAPPDPlotInputWaveLabel AlignedLAPPDData +#LAPPDPlotInputWaveLabel RawLAPPDData +LAPPDPlotsVerbosity 0 +CanvasXSubPlotNumber 2 +CanvasYSubPlotNumber 2 +canvasMargin 0.1 +drawHighThreshold 50 +drawLowThreshold -10 +BinHistMin -10 +BinHistMax 50 +BinHistNumber 100 + +CanvasWidth 1000 +CanvasHeight 500 + +maxDrawEventNumber 100 + +DrawBinHist 1 +printEventNumber 50 +printLAPPDNumber 1 +printEventWaveform 1 + +LoadLAPPDMap 1 diff --git a/configfiles/LAPPDASCIIAna/ConfigPreProcess b/configfiles/LAPPDASCIIAna/ConfigPreProcess new file mode 100755 index 000000000..e344db0f6 --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ConfigPreProcess @@ -0,0 +1,65 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +Folder ../Data/3655/ +#Folder ../Data/2022-06-10/ + +#LAPPDBaselineSubtract +BaselineSubstractVerbosityLevel 0 +TrigChannel1 1005 +TrigChannel2 1035 +#BLSInputWavLabel LAPPDWaveforms #LAPPDWaveforms +BLSInputWavLabel AlignedLAPPDData +#BLSInputWavLabel RawLAPPDData + +LowBLfitrange 0 +HiBLfitrange 60 +TrigLowBLfitrange 110 +TrigHiBLfitrange 160 +BLSOutputWavLabel BLsubtractedLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindT0 +FindT0Verbosity 0 +#FindT0InputWavLabel BLsubtractedLAPPDData +#FindT0InputWavLabel RawLAPPDData +FindT0InputWavLabel LAPPDWaveforms +OneBoardShift 0 +OneBoardShiftValue 16 +LoadLAPPDMap 1 + +TrigEarlyCut 20 +TrigLateCut 200 +T0channelNo 1005 +T0channelNo1 1005 +T0channelNo2 1005 +T0signalmax -100. +T0signalthreshold -50. +T0signalmaxOld 50. #Older data uses a positive going signal +T0signalthresholdOld 80. #Older data uses a positive going signal +T0offset 0 +FindT0OutputWavLabel AlignedLAPPDData +GlobalShiftT0 200 +#Added by Marc +Triggerdefault 5 +LAPPDOffset 1000 + +#LAPPDPlotWaveForms +requireT0signal 0 +SaveByChannel 1 +PlotWavLabel BLsubtractedLAPPDData +#PlotWavLabel LAPPDWaveforms +outfile WaveForms_rawblsub.root +NHistos 400 +SaveSingleStrip 0 +SingleStripNo 9 + + + + + + + + diff --git a/configfiles/LAPPDASCIIAna/ConfigStoreReadIn b/configfiles/LAPPDASCIIAna/ConfigStoreReadIn new file mode 100755 index 000000000..79f2d2fa7 --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ConfigStoreReadIn @@ -0,0 +1,42 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 +#StoreInputFile /pnfs/annie/persistent/users/redwards/data/filtered_lappd/R3649-R3844/LAPPDEventsBeamgateMRDTrack/FilteredEvents_LAPPDEventsBeamgateMRDTrack_R3649-R3844 + +LAPPDStoreReadInVerbosity 0 + +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +PedinputfileTXT ../Pedestals/swapLAPPD/Pedestal +#PedinputfileTXT ../Pedestals/change/Pedestal + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + +#LAPPDReorderData +LAPPDReorderVerbosityLevel 0 +ReorderInputWavLabel RawLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 0 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +LoadLAPPDMap 1 diff --git a/configfiles/LAPPDASCIIAna/ConfigTXT b/configfiles/LAPPDASCIIAna/ConfigTXT new file mode 100644 index 000000000..2165cbef3 --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ConfigTXT @@ -0,0 +1,94 @@ +#General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 0 +MultiLAPPDMap 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +#PedinputfileTXT ../Pedestals/LAPPD645839/P +#PedFileNameTXT ../Pedestals/LAPPD40/P +#PedinputfileTXT /pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/Pedestal/2022_LAPPD40/P + + +ReadStorePdeFile 0 +loadFromStoreDirectly 0 + + +#LAPPDLoadTXT + +DoPedSubtract 1 +LAPPDLoadTXTVerbosity 1 +#PedFileNameTXT ../Pedestals/LAPPD40/P +PedFileNameTXT /exp/annie/app/users/yuefeng/MyTools/Pedestals/pedTest/P +DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/20210107_singlePE_500k_in_parts/Data_20210701_1.txt + + +#PedFileNameTXT /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/PEDS_ACDC_board +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2023-10-24/2023-10-24/LaserON_2300V_strip28/Ascii20232410_135201.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD1.0/Ascii20221702_100345.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD2.0/Ascii20221702_101913.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD4.0/merged_file.txt + + +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_singlePE_selfTrig_HiStat_2022-10-13/singlePE/forceTrig/merged_file.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_ND20abs_25abs_30abs_2022-08-30/OD3.0abs/merged_file.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_singlePE_selfTrig_HiStat_2022-10-13/singlePE/selfTrig_DAC0_1.253V/merged_file.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_ND37abs_47abs_2022-09-01/OD4.7abs/merged_file.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_ND35abs_40abs_45abs_2022-08-31/OD4.0abs/merged_file.txt +#PedFileNameTXT /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/pedestal/P + + +#LAPPDReorderData +ReorderVerbosityLevel 0 +#ReorderInputWavLabel RawLAPPDData +ReorderInputWavLabel AlignedLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 180 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 0 +loadOffsets 0 +LoadBuiltPPSInfo 1 +num_vector_data 7795 +num_vector_pps 16 + +#LAPPDTreeMaker +LoadPulse 1 +LoadHit 1 +LoadWaveform 1 +LoadLAPPDDataTimeStamp 1 +LoadPPSTimestamp 0 +LoadRunInfoRaw 0 +LoadRunInfoANNIEEvent 1 + +treeMakerVerbosity 0 +MultiLAPPDMapTreeMaker 1 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree_processedAna.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 diff --git a/configfiles/LAPPDASCIIAna/Configs b/configfiles/LAPPDASCIIAna/Configs new file mode 100644 index 000000000..1f3cadc0e --- /dev/null +++ b/configfiles/LAPPDASCIIAna/Configs @@ -0,0 +1,74 @@ +#General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 0 +MultiLAPPDMap 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +#PedinputfileTXT ../Pedestals/LAPPD645839/P +PedinputfileTXT ../Pedestals/LAPPD40/P + +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + +ReadStorePdeFile 0 +loadFromStoreDirectly 0 + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + +#LAPPDReorderData +ReorderVerbosityLevel 0 +#ReorderInputWavLabel RawLAPPDData +ReorderInputWavLabel AlignedLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 180 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 0 +loadOffsets 0 +LoadBuiltPPSInfo 1 +num_vector_data 7795 +num_vector_pps 16 + +#LAPPDTreeMaker +LoadPulse 1 +LoadHit 1 +LoadWaveform 1 +LoadLAPPDDataTimeStamp 1 +LoadPPSTimestamp 0 +LoadRunInfoRaw 0 +LoadRunInfoANNIEEvent 1 + +treeMakerVerbosity 0 +MultiLAPPDMapTreeMaker 0 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree_ASCIIAna.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 +loadPrintMRDinfo 0 + diff --git a/configfiles/LAPPDASCIIAna/TimeClusteringConfig b/configfiles/LAPPDASCIIAna/TimeClusteringConfig new file mode 100644 index 000000000..e778247fc --- /dev/null +++ b/configfiles/LAPPDASCIIAna/TimeClusteringConfig @@ -0,0 +1,13 @@ +#TimeClustering config file + +verbosity 0 +MinDigitsForTrack 3 +MaxMrdSubEventDuration 30 +MinSubeventTimeSep 30 +MakeMrdDigitTimePlot 0 +LaunchTApplication 0 +IsData 1 +#OutputROOTFile TimeClustering_MRDTest28_cluster40ns +OutputROOTFile STEC_TimeClusteringOut +MapChankey_WCSimID ./configfiles/SimpleTankEnergyCalibrator/MRD_Chankey_WCSimID.dat + diff --git a/configfiles/LAPPDASCIIAna/ToolChainConfig b/configfiles/LAPPDASCIIAna/ToolChainConfig new file mode 100644 index 000000000..94933514a --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ToolChainConfig @@ -0,0 +1,24 @@ + +#ToollChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### Ignore these settings for local analysis +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File configfiles/LAPPDASCIIAna/ToolsConfig ## list of tools to run and their config files + +##### Run Type ##### +Inline 200 ## number of Execute steps in program, -1 infinite loop that is ended by user +Interactive 0 ## set to 1 if you want to run the code interactively + diff --git a/configfiles/LAPPDASCIIAna/ToolsConfig b/configfiles/LAPPDASCIIAna/ToolsConfig new file mode 100644 index 000000000..19db2afd1 --- /dev/null +++ b/configfiles/LAPPDASCIIAna/ToolsConfig @@ -0,0 +1,14 @@ +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig + + +LAPPDLoadTXT LAPPDLoadTXT configfiles/LAPPDASCIIAna/ConfigTXT + +LAPPDStoreReorder LAPPDStoreReorder configfiles/LAPPDASCIIAna/ConfigStoreReadIn + +LAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDASCIIAna/ConfigPreProcess +LAPPDBaseline LAPPDBaseline configfiles/LAPPDASCIIAna/ConfigPreProcess +LAPPDPlots LAPPDPlots configfiles/LAPPDASCIIAna/ConfigPlot + +LAPPDThresReco LAPPDThresReco configfiles/LAPPDASCIIAna/ConfigPlot + +LAPPDTreeMaker LAPPDTreeMaker configfiles/LAPPDASCIIAna/Configs diff --git a/configfiles/LAPPDASCIIAnaFor151/ConfigGeo b/configfiles/LAPPDASCIIAnaFor151/ConfigGeo new file mode 100644 index 000000000..ffe0ca918 --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ConfigGeo @@ -0,0 +1,11 @@ +#LoadGeometry +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LAPPDana/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +LAPPDMerging 0 + diff --git a/configfiles/LAPPDASCIIAnaFor151/ConfigPlot b/configfiles/LAPPDASCIIAnaFor151/ConfigPlot new file mode 100755 index 000000000..7e56507ef --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ConfigPlot @@ -0,0 +1,133 @@ +oldLaser 0 #1 for old data, 0 for new trigger boards + +#LAPPDBaselineSubtract +BLSInputWavLabel AlignedLAPPDData +BaselineSubstractVerbosityLevel 0 +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +LowBLfitrange 25; +HiBLfitrange 60; +TrigLowBLfitrange 30 +TrigHiBLfitrange 100 +BLSOutputWavLabel ABLSLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindPeak +FindPeakVerbosity 0 +FiltPeakInputWavLabel FiltLAPPDData +RawPeakInputWavLabel LAPPDWaveforms +BLSPeakInputWavLabel ABLSLAPPDData +FindPeakOutLabel SimpleRecoLAPPDPulses +TotThreshold 15. +MinimumTot 900. +Deltat 100. + +# General Parameters +Nsamples 256 +SampleSize 100 +NChannels 60 + + +outfile WaveForms_ablsub.root +NHistos 200 +SaveSingleStrip 0 +SingleStripNo 9 +plotLow -10 +plotHigh 20 + +#LAPPDPlotWaveForms2D +outfile2D RawDataWaveForms_2D.root +plot2DrecoPulseInputLabel thresRecoLAPPDPulses +plot2DrecoHitInputLabel thresRecoLAPPDHits +includeRecoPulses 1 +includeRecoHits 1 +plotAdditionalPart 1 +titleSize 0.04 +canvasMargin 0.15 +canvasTitleOffset 1 +#LAPPDSelectPlot2D +LAPPDSelectPlotWaveform2DLabel LAPPDWaveforms +SelectOutfile2D LAPPDSelectPlot.root +MRDTrackExistSelection 0 +verbosityPlot2D 10 +colorContour 255 +useDefaultPalette 1 +colorPalette 112 + + + +#LAPPDThresReco +LAPPDThresRecoVerbosity 0 +verbosity 0 +printHitsTXT 0 +threshold 10 +minPulseWidth 10 +#thresRecoInputWaveLabel AlignedLAPPDData +ThresRecoInputWaveLabel BLsubtractedLAPPDData +#thresRecoInputWaveLabel LAPPDWaveforms + +ThresRecoOutputPulseLabel LAPPDPulses +ThresRecoOutputHitLabel LAPPDHits +useMaxTime 1 # 1: use max bin as pulse time, 0: use gaus fit bin as pulse peak time +#signalSpeedOnStrip 0.6667 +signalSpeedOnStrip 0.567 #1.69982/2.99792 +triggerBoardDelay 0 +loadPrintMRDinfo 0 +useRange 0 #set this to 0 for using pulse start time as the saved pulse time, 1 for high, -1 for using peak time +plusClockBit 0 + +savePositionOnStrip 1 +LoadLAPPDMapInfo 1 + +#LAPPDStackStrip +verbosityStackStrip 0 +StackOutputFileName stacked.root +#StackInputWaveLabel BLsubtractedLAPPDData +StackInputWaveLabel RawLAPPDData +#StackInputWaveLabel LAPPDWaveforms +StackStripNumber 1 +StackStripSide 0 + +#LAPPDPlotWaveForms +NHistos 200 +SaveByChannel 0 +SaveSingleStrip 0 +SingleStripNo 1 +requireT0signal 0 + + +#LAPPDTreeMaker +treeMakerVerbosity 0 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree.root + + +#LAPPDPlots +#LAPPDPlotInputWaveLabel BLsubtractedLAPPDData +#LAPPDPlotInputWaveLabel LAPPDWaveforms +#LAPPDPlotInputWaveLabel AlignedLAPPDData +#LAPPDPlotInputWaveLabel RawLAPPDData +LAPPDPlotInputWaveLabel BLandTALAPPDData + +LAPPDPlotsVerbosity 0 +CanvasXSubPlotNumber 2 +CanvasYSubPlotNumber 2 +canvasMargin 0.1 +drawHighThreshold 50 +drawLowThreshold -20 +BinHistMin -30 +BinHistMax 200 +BinHistNumber 100 + +CanvasWidth 1000 +CanvasHeight 500 + +maxDrawEventNumber 200 + +DrawBinHist 1 +printEventNumber 1000 +printLAPPDNumber 1 +printEventWaveform 1 + +LoadLAPPDMap 1 diff --git a/configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess b/configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess new file mode 100755 index 000000000..d637eadcb --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess @@ -0,0 +1,48 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +Folder ../Data/3655/ +#Folder ../Data/2022-06-10/ + +#LAPPDBaselineSubtract +BaselineSubstractVerbosityLevel 0 +TrigChannel1 1005 +TrigChannel2 1035 +#BLSInputWavLabel LAPPDWaveforms #LAPPDWaveforms +BLSInputWavLabel AlignedLAPPDData +#BLSInputWavLabel RawLAPPDData + +LowBLfitrange 50 +HiBLfitrange 100 +TrigLowBLfitrange 50 +TrigHiBLfitrange 100 +BLSOutputWavLabel BLsubtractedLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindT0 +FindT0Verbosity 0 +#FindT0InputWavLabel BLsubtractedLAPPDData +#FindT0InputWavLabel RawLAPPDData +FindT0InputWavLabel LAPPDWaveforms +OneBoardShift 0 +OneBoardShiftValue 16 +LoadLAPPDMap 1 + +TrigEarlyCut 20 +TrigLateCut 200 +T0channelNo 1005 +T0channelNo1 1005 +T0channelNo2 1005 +T0signalmax -130. +T0signalthreshold -50. +T0signalmaxOld 50. #Older data uses a positive going signal +T0signalthresholdOld 80. #Older data uses a positive going signal +T0offset 0 +FindT0OutputWavLabel AlignedLAPPDData +GlobalShiftT0 80 +#Added by Marc +Triggerdefault 5 +LAPPDOffset 1000 + diff --git a/configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess2 b/configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess2 new file mode 100755 index 000000000..b639f3d31 --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess2 @@ -0,0 +1,68 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +Folder ../Data/3655/ +#Folder ../Data/2022-06-10/ + +#LAPPDBaselineSubtract +BaselineSubstractVerbosityLevel 0 +TrigChannel1 1005 +TrigChannel2 1035 +#BLSInputWavLabel LAPPDWaveforms #LAPPDWaveforms +BLSInputWavLabel AlignedLAPPDData +#BLSInputWavLabel RawLAPPDData + +LowBLfitrange 0 +HiBLfitrange 60 +TrigLowBLfitrange 50 +TrigHiBLfitrange 150 +BLSOutputWavLabel BLsubtractedLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindT0 +FindT0Verbosity 0 +FindT0InputWavLabel BLsubtractedLAPPDData +#FindT0InputWavLabel RawLAPPDData +#FindT0InputWavLabel LAPPDWaveforms + +OneBoardShift 0 +OneBoardShiftValue 16 +LoadLAPPDMap 1 + +TrigEarlyCut 20 +TrigLateCut 200 +T0channelNo 1005 +T0channelNo1 1005 +T0channelNo2 1005 +T0signalmax -100. +T0signalthreshold -50. +T0signalmaxOld 50. #Older data uses a positive going signal +T0signalthresholdOld 80. #Older data uses a positive going signal +T0offset 0 +#FindT0OutputWavLabel AlignedLAPPDData +FindT0OutputWavLabel BLandTALAPPDData + +GlobalShiftT0 80 +#Added by Marc +Triggerdefault 5 +LAPPDOffset 1000 + +#LAPPDPlotWaveForms +requireT0signal 0 +SaveByChannel 1 +PlotWavLabel BLsubtractedLAPPDData +#PlotWavLabel LAPPDWaveforms +outfile WaveForms_rawblsub.root +NHistos 400 +SaveSingleStrip 0 +SingleStripNo 9 + + + + + + + + diff --git a/configfiles/LAPPDASCIIAnaFor151/ConfigStoreReadIn b/configfiles/LAPPDASCIIAnaFor151/ConfigStoreReadIn new file mode 100755 index 000000000..52521f447 --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ConfigStoreReadIn @@ -0,0 +1,23 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + + + +#LAPPDReorderData +LAPPDReorderVerbosityLevel 0 +ReorderInputWavLabel RawLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 0 + +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +SelectSingleLAPPD false +SelectedLAPPD 0 diff --git a/configfiles/LAPPDASCIIAnaFor151/ConfigTXT b/configfiles/LAPPDASCIIAnaFor151/ConfigTXT new file mode 100644 index 000000000..ad6a75e1b --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ConfigTXT @@ -0,0 +1,108 @@ +#General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 0 +MultiLAPPDMap 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +#PedinputfileTXT ../Pedestals/LAPPD645839/P +#PedinputfileTXT ../Pedestals/LAPPD40/P +#PedinputfileTXT /pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/Pedestal/2023_LAPPD40/P + + +ReadStorePdeFile 0 +loadFromStoreDirectly 0 + + +#LAPPDLoadTXT + +DoPedSubtract 1 +LAPPDLoadTXTVerbosity 1 +#PedFileNameTXT ../Pedestals/LAPPD40/P +#PedFileNameTXT /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/PEDS_ACDC_board +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2023-10-24/2023-10-24/LaserON_2300V_strip28/Ascii20232410_135201.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD1.0/Ascii20221702_100345.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD2.0/Ascii20221702_101913.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD3.0/Ascii20221702_103605.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD3.5/Ascii20221702_142206.txt + + +# LAPPD 151 +#PedFileNameTXT /pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/Pedestal/LAPPD151/pedestal_2024_8_15/P +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD151/2024-08-21/forcedTrigger_nd1p8/Ascii20240408_124303.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD151/2024-08-21/forcedTrigger_nd2p2/Ascii20240408_112022.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD151/2024-08-21/forcedTrigger_nd2p0/Ascii20240408_114859.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD151/2024-08-22/forcedTrigger_nd3p5/Ascii20240508_144350.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD151/2024-08-22/forcedTrigger_nd4p5/Ascii20240508_153057.txt + + +# 40 +PedFileNameTXT /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/PEDS_ACDC_board +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2023-10-24/2023-10-24/LaserON_2300V_strip28/Ascii20232410_135201.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD1.0/Ascii20221702_100345.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD2.0/Ascii20221702_101913.txt +DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD40/2022-02-17_LaserNDfilterScan/NDfilterScan_15mV/OD4.0/merged_file.txt + + +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_singlePE_selfTrig_HiStat_2022-10-13/singlePE/forceTrig/merged_file.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_ND37abs_47abs_2022-09-01/OD4.7abs/merged_file.txt +#DataFileName /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/LAPPD64_ND35abs_40abs_45abs_2022-08-31/OD4.0abs/merged_file.txt +#PedFileNameTXT /pnfs/annie/persistent/LAPPDData/LAPPD64/sPE/pedestal/P + + +oldLaser 0 + +#LAPPDReorderData +ReorderVerbosityLevel 0 +#ReorderInputWavLabel RawLAPPDData +ReorderInputWavLabel AlignedLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 180 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 0 +loadOffsets 0 +LoadBuiltPPSInfo 1 +num_vector_data 7795 +num_vector_pps 16 + +#LAPPDTreeMaker +LoadPulse 1 +LoadHit 1 +LoadWaveform 1 +LoadLAPPDDataTimeStamp 1 +LoadPPSTimestamp 0 +LoadRunInfoRaw 0 +LoadRunInfoANNIEEvent 1 + +treeMakerVerbosity 0 +MultiLAPPDMapTreeMaker 1 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree_processedAna.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 diff --git a/configfiles/LAPPDASCIIAnaFor151/Configs b/configfiles/LAPPDASCIIAnaFor151/Configs new file mode 100644 index 000000000..1f3cadc0e --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/Configs @@ -0,0 +1,74 @@ +#General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 0 +MultiLAPPDMap 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +#PedinputfileTXT ../Pedestals/LAPPD645839/P +PedinputfileTXT ../Pedestals/LAPPD40/P + +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + +ReadStorePdeFile 0 +loadFromStoreDirectly 0 + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + +#LAPPDReorderData +ReorderVerbosityLevel 0 +#ReorderInputWavLabel RawLAPPDData +ReorderInputWavLabel AlignedLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 180 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 0 +loadOffsets 0 +LoadBuiltPPSInfo 1 +num_vector_data 7795 +num_vector_pps 16 + +#LAPPDTreeMaker +LoadPulse 1 +LoadHit 1 +LoadWaveform 1 +LoadLAPPDDataTimeStamp 1 +LoadPPSTimestamp 0 +LoadRunInfoRaw 0 +LoadRunInfoANNIEEvent 1 + +treeMakerVerbosity 0 +MultiLAPPDMapTreeMaker 0 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree_ASCIIAna.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 +loadPrintMRDinfo 0 + diff --git a/configfiles/LAPPDASCIIAnaFor151/TimeClusteringConfig b/configfiles/LAPPDASCIIAnaFor151/TimeClusteringConfig new file mode 100644 index 000000000..e778247fc --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/TimeClusteringConfig @@ -0,0 +1,13 @@ +#TimeClustering config file + +verbosity 0 +MinDigitsForTrack 3 +MaxMrdSubEventDuration 30 +MinSubeventTimeSep 30 +MakeMrdDigitTimePlot 0 +LaunchTApplication 0 +IsData 1 +#OutputROOTFile TimeClustering_MRDTest28_cluster40ns +OutputROOTFile STEC_TimeClusteringOut +MapChankey_WCSimID ./configfiles/SimpleTankEnergyCalibrator/MRD_Chankey_WCSimID.dat + diff --git a/configfiles/LAPPDASCIIAnaFor151/ToolChainConfig b/configfiles/LAPPDASCIIAnaFor151/ToolChainConfig new file mode 100644 index 000000000..83eadfc77 --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ToolChainConfig @@ -0,0 +1,24 @@ + +#ToollChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### Ignore these settings for local analysis +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File configfiles/LAPPDASCIIAnaFor151/ToolsConfig ## list of tools to run and their config files + +##### Run Type ##### +Inline -1 ## number of Execute steps in program, -1 infinite loop that is ended by user +Interactive 0 ## set to 1 if you want to run the code interactively + diff --git a/configfiles/LAPPDASCIIAnaFor151/ToolsConfig b/configfiles/LAPPDASCIIAnaFor151/ToolsConfig new file mode 100644 index 000000000..f2f465487 --- /dev/null +++ b/configfiles/LAPPDASCIIAnaFor151/ToolsConfig @@ -0,0 +1,18 @@ +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig + + +LAPPDLoadTXT LAPPDLoadTXT configfiles/LAPPDASCIIAnaFor151/ConfigTXT + +LAPPDStoreReorder LAPPDStoreReorder configfiles/LAPPDASCIIAnaFor151/ConfigStoreReadIn + +LAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess +LAPPDBaseline LAPPDBaseline configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess + +secondLAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDASCIIAnaFor151/ConfigPreProcess2 + +LAPPDPlots LAPPDPlots configfiles/LAPPDASCIIAnaFor151/ConfigPlot + + +LAPPDThresReco LAPPDThresReco configfiles/LAPPDASCIIAnaFor151/ConfigPlot + +LAPPDTreeMaker LAPPDTreeMaker configfiles/LAPPDASCIIAnaFor151/Configs diff --git a/configfiles/LAPPDProcessedAna/ConfigPlot b/configfiles/LAPPDProcessedAna/ConfigPlot index 5156f6b55..72c8b9721 100755 --- a/configfiles/LAPPDProcessedAna/ConfigPlot +++ b/configfiles/LAPPDProcessedAna/ConfigPlot @@ -37,7 +37,7 @@ PlotWavLabel BLsubtractedLAPPDData switchBit 0 outfile WaveForms_ablsub.root -NHistos 200 +NHistos 10 SaveSingleStrip 0 SingleStripNo 9 plotLow -10 @@ -69,7 +69,7 @@ LAPPDThresRecoVerbosity 0 verbosity 0 printHitsTXT 0 threshold 10 -minPulseWidth 5 +minPulseWidth 10 #thresRecoInputWaveLabel AlignedLAPPDData ThresRecoInputWaveLabel BLsubtractedLAPPDData #thresRecoInputWaveLabel LAPPDWaveforms @@ -81,7 +81,7 @@ useMaxTime 1 # 1: use max bin as pulse time, 0: use gaus fit bin as pulse peak signalSpeedOnStrip 0.567 #1.69982/2.99792 triggerBoardDelay 0 loadPrintMRDinfo 0 -useRange 0 #set this to 0 for using pulse start time as the saved pulse time, 1 for high, -1 for using peak time +useRange 0 #For hit reco, using which time from pulse to form the hit time, set this to 0 for using pulse start time for the saved hit time, 1 for high, -1 for using peak time plusClockBit 0 savePositionOnStrip 1 @@ -97,7 +97,7 @@ StackStripNumber 1 StackStripSide 0 #LAPPDPlotWaveForms -NHistos 200 +NHistos 10 SaveByChannel 0 SaveSingleStrip 0 SingleStripNo 1 @@ -126,7 +126,7 @@ drawLowThreshold -20 CanvasWidth 1000 CanvasHeight 500 -maxDrawEventNumber 200 +maxDrawEventNumber 100 DrawBinHist 1 printEventNumber 0 diff --git a/configfiles/LAPPDProcessedFilter/ClusterClassifiersConfig b/configfiles/LAPPDProcessedFilter/ClusterClassifiersConfig new file mode 100644 index 000000000..752200268 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/ClusterClassifiersConfig @@ -0,0 +1 @@ +verbosity 0 diff --git a/configfiles/LAPPDProcessedFilter/ClusterFinderConfig b/configfiles/LAPPDProcessedFilter/ClusterFinderConfig new file mode 100644 index 000000000..c25b028f1 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/ClusterFinderConfig @@ -0,0 +1,12 @@ +# ClusterFinder Config File + +verbosity 0 +HitStore Hits #Either MCHits or Hits (accessed in ANNIEEvent store) +OutputFile BeamRun_ClusterFinder_DefaultOutput #Output root prefix name for the current run +ClusterFindingWindow 40 # in ns, size of the window used to "clusterize" +AcqTimeWindow 70000 # in ns, size of the acquisition window +ClusterIntegrationWindow 40 # in ns, all hits with +/- 1/2 of this window are considered in the cluster +MinHitsPerCluster 10 # group of hits are considered clusters above this amount of hits +end_of_window_time_cut 0.95 # from o to 1, length of the window you want to loop over with respect to acq. window (1 for full window, 0.95 for 95% from the start) +Plots2D 0 #Draw 2D charge-vs-time plots? +ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat diff --git a/configfiles/LAPPDProcessedFilter/ConfigGeo b/configfiles/LAPPDProcessedFilter/ConfigGeo new file mode 100644 index 000000000..ffe0ca918 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/ConfigGeo @@ -0,0 +1,11 @@ +#LoadGeometry +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LAPPDana/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +LAPPDMerging 0 + diff --git a/configfiles/LAPPDProcessedFilter/EventSelectorConfig b/configfiles/LAPPDProcessedFilter/EventSelectorConfig new file mode 100644 index 000000000..a711f08bf --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/EventSelectorConfig @@ -0,0 +1,29 @@ +# EventSelector config file + +verbosity 0 +MCPMTVolCut 0 +MCFVCut 0 +MCMRDCut 0 +MCPiKCut 0 +MCIsMuonCut 0 +MCIsElectronCut 0 +MCIsSingleRingCut 0 +MCIsMultiRingCut 0 +MCProjectedMRDHit 0 +MCEnergyCut 0 +Emin 0 #Minimum energy in MeV +Emax 1000 #Maximum energy in MeV +MRDRecoCut 0 +RecoPMTVolCut 0 +RecoFVCut 0 +NHitCut 0 +NHitmin 4 #Minimum number of hit digits +PMTMRDCoincCut 0 +PMTMRDOffset 755 +PromptTrigOnly 0 +TriggerWord -1 +SaveStatusToStore 1 +NoVeto 0 +Veto 0 +ThroughGoing 0 +IsMC 0 #MC or Data? diff --git a/configfiles/LAPPDProcessedFilter/FindMrdTracksConfig b/configfiles/LAPPDProcessedFilter/FindMrdTracksConfig new file mode 100644 index 000000000..5ba5e8f77 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/FindMrdTracksConfig @@ -0,0 +1,12 @@ +# FindMrdTracks Config File +# all variables retrieved with m_variables.Get() must be defined here! + +verbosity 0 +IsData 1 +OutputDirectory . +OutputFile STEC_MRDTracks_cluster40ns +DrawTruthTracks 0 # whether to add MC Truth track info for drawing in MrdPaddlePlot Tool + ## note you need to run that tool to actually view the tracks! +WriteTracksToFile 0 # should the track information be written to a ROOT-file? +SelectTriggerType 0 #should the loaded data be filtered by trigger type? +TriggerType Beam #options: Cosmic, Beam, No Loopback diff --git a/configfiles/LAPPDProcessedFilter/LoadANNIEEventConfig b/configfiles/LAPPDProcessedFilter/LoadANNIEEventConfig new file mode 100644 index 000000000..ad0298064 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/LoadANNIEEventConfig @@ -0,0 +1,6 @@ +verbose 1 + +FileForListOfInputs configfiles/LAPPDProcessedFilter/list.txt + +EventOffset 0 +GlobalEvNr 1 diff --git a/configfiles/LAPPDProcessedFilter/ProcessedLAPPDFilterConfig b/configfiles/LAPPDProcessedFilter/ProcessedLAPPDFilterConfig new file mode 100644 index 000000000..0598cb709 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/ProcessedLAPPDFilterConfig @@ -0,0 +1,15 @@ +FilterVerbosity 0 + +saveAllLAPPDEvents 1 +savePMTClusterEvents 0 + +filterType MRDtrack + +#filterType BeamSelection + +RequireNoVeto 1 +RequireCherenkovCover 1 + + +requirePulsedAmp 15 +requirePulsedStripNumber 7 diff --git a/configfiles/LAPPDProcessedFilter/TimeClusteringConfig b/configfiles/LAPPDProcessedFilter/TimeClusteringConfig new file mode 100644 index 000000000..e778247fc --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/TimeClusteringConfig @@ -0,0 +1,13 @@ +#TimeClustering config file + +verbosity 0 +MinDigitsForTrack 3 +MaxMrdSubEventDuration 30 +MinSubeventTimeSep 30 +MakeMrdDigitTimePlot 0 +LaunchTApplication 0 +IsData 1 +#OutputROOTFile TimeClustering_MRDTest28_cluster40ns +OutputROOTFile STEC_TimeClusteringOut +MapChankey_WCSimID ./configfiles/SimpleTankEnergyCalibrator/MRD_Chankey_WCSimID.dat + diff --git a/configfiles/LAPPDProcessedFilter/ToolChainConfig b/configfiles/LAPPDProcessedFilter/ToolChainConfig new file mode 100644 index 000000000..f0ebd361f --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/ToolChainConfig @@ -0,0 +1,24 @@ + +#ToollChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### Ignore these settings for local analysis +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File configfiles/LAPPDProcessedFilter/ToolsConfig ## list of tools to run and their config files + +##### Run Type ##### +Inline -1 ## number of Execute steps in program, -1 infinite loop that is ended by user +Interactive 0 ## set to 1 if you want to run the code interactively + diff --git a/configfiles/LAPPDProcessedFilter/ToolsConfig b/configfiles/LAPPDProcessedFilter/ToolsConfig new file mode 100644 index 000000000..40c906fca --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/ToolsConfig @@ -0,0 +1,13 @@ +LoadANNIEEvent LoadANNIEEvent configfiles/LAPPDProcessedFilter/LoadANNIEEventConfig +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig + +myTimeClustering TimeClustering configfiles/LAPPDProcessedFilter/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/LAPPDProcessedFilter/FindMrdTracksConfig +myClusterFinder ClusterFinder ./configfiles/LAPPDProcessedFilter/ClusterFinderConfig +myClusterClassifiers ClusterClassifiers ./configfiles/LAPPDProcessedFilter/ClusterClassifiersConfig +myEventSelector EventSelector ./configfiles/LAPPDProcessedFilter/EventSelectorConfig + + +ProcessedLAPPDFilter ProcessedLAPPDFilter configfiles/LAPPDProcessedFilter/ProcessedLAPPDFilterConfig + + diff --git a/configfiles/LAPPDProcessedFilter/list.txt b/configfiles/LAPPDProcessedFilter/list.txt new file mode 100644 index 000000000..706800615 --- /dev/null +++ b/configfiles/LAPPDProcessedFilter/list.txt @@ -0,0 +1 @@ +/exp/annie/app/users/yuefeng/MyForkANNIE/MyForkRewiriting/testPRTA/ToolAnalysis/FilteredLAPPD_BeamSelection_Pedestal2023 diff --git a/configfiles/LAPPDRaw/ConfigGeo b/configfiles/LAPPDRaw/ConfigGeo new file mode 100644 index 000000000..ffe0ca918 --- /dev/null +++ b/configfiles/LAPPDRaw/ConfigGeo @@ -0,0 +1,11 @@ +#LoadGeometry +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LAPPDana/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +LAPPDMerging 0 + diff --git a/configfiles/LAPPDRaw/ConfigPlot b/configfiles/LAPPDRaw/ConfigPlot new file mode 100755 index 000000000..562cc91a2 --- /dev/null +++ b/configfiles/LAPPDRaw/ConfigPlot @@ -0,0 +1,130 @@ +oldLaser 0 #1 for old data, 0 for new trigger boards + +#LAPPDBaselineSubtract +BLSInputWavLabel AlignedLAPPDData +BaselineSubstractVerbosityLevel 0 +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +LowBLfitrange 25; +HiBLfitrange 60; +TrigLowBLfitrange 30 +TrigHiBLfitrange 100 +BLSOutputWavLabel ABLSLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindPeak +FindPeakVerbosity 0 +FiltPeakInputWavLabel FiltLAPPDData +RawPeakInputWavLabel LAPPDWaveforms +BLSPeakInputWavLabel ABLSLAPPDData +FindPeakOutLabel SimpleRecoLAPPDPulses +TotThreshold 15. +MinimumTot 900. +Deltat 100. + +# General Parameters +Nsamples 256 +SampleSize 100 +NChannels 60 + +#LAPPDPlotWaveForms +requireT0signal 0 +SaveByChannel 1 +#PlotWavLabel RawLAPPDData +#PlotWavLabel LAPPDWaveforms +PlotWavLabel BLsubtractedLAPPDData +#PlotWavLabel AlignedLAPPDData +switchBit 0 + +outfile WaveForms_ablsub.root +NHistos 200 +SaveSingleStrip 0 +SingleStripNo 9 +plotLow -10 +plotHigh 20 + +#LAPPDPlotWaveForms2D +outfile2D RawDataWaveForms_2D.root +plot2DrecoPulseInputLabel thresRecoLAPPDPulses +plot2DrecoHitInputLabel thresRecoLAPPDHits +includeRecoPulses 1 +includeRecoHits 1 +plotAdditionalPart 1 +titleSize 0.04 +canvasMargin 0.15 +canvasTitleOffset 1 +#LAPPDSelectPlot2D +LAPPDSelectPlotWaveform2DLabel LAPPDWaveforms +SelectOutfile2D LAPPDSelectPlot.root +MRDTrackExistSelection 0 +verbosityPlot2D 10 +colorContour 255 +useDefaultPalette 1 +colorPalette 112 + + + +#LAPPDThresReco +LAPPDThresRecoVerbosity 0 +verbosity 0 +printHitsTXT 0 +threshold 10 +minPulseWidth 10 +#thresRecoInputWaveLabel AlignedLAPPDData +ThresRecoInputWaveLabel BLsubtractedLAPPDData +#thresRecoInputWaveLabel LAPPDWaveforms + +ThresRecoOutputPulseLabel LAPPDPulses +ThresRecoOutputHitLabel LAPPDHits +useMaxTime 1 +#signalSpeedOnStrip 0.6667 +signalSpeedOnStrip 0.567 #1.69982/2.99792 +triggerBoardDelay 0 +loadPrintMRDinfo 1 +useRange -1 #set this to 0 for using pulse start time as the saved pulse time, 1 for high, -1 for using peak time +plusClockBit 0 + +savePositionOnStrip 1 + + +#LAPPDStackStrip +verbosityStackStrip 0 +StackOutputFileName stacked.root +#StackInputWaveLabel BLsubtractedLAPPDData +StackInputWaveLabel RawLAPPDData +#StackInputWaveLabel LAPPDWaveforms +StackStripNumber 1 +StackStripSide 0 + +#LAPPDPlotWaveForms +NHistos 200 +SaveByChannel 0 +SaveSingleStrip 0 +SingleStripNo 1 +requireT0signal 0 + + +#LAPPDTreeMaker +treeMakerVerbosity 0 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree.root + + + +#LAPPDPlots +LAPPDPlotInputWaveLabel BLsubtractedLAPPDData +LAPPDPlotsVerbosity 0 +CanvasXSubPlotNumber 2 +CanvasYSubPlotNumber 2 +canvasMargin 0.1 +drawHighThreshold 50 +drawLowThreshold -20 + +CanvasWidth 1000 +CanvasHeight 500 + +maxDrawEventNumber 50 + +DrawBinHist 1 +LoadLAPPDMap 1 diff --git a/configfiles/LAPPDRaw/ConfigPreProcess b/configfiles/LAPPDRaw/ConfigPreProcess new file mode 100755 index 000000000..ee2a71e11 --- /dev/null +++ b/configfiles/LAPPDRaw/ConfigPreProcess @@ -0,0 +1,65 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +LAPPDchannelOffset 1000 +Folder ../Data/3655/ +#Folder ../Data/2022-06-10/ + +#LAPPDBaselineSubtract +BaselineSubstractVerbosityLevel 0 +TrigChannel1 1005 +TrigChannel2 1035 +#BLSInputWavLabel LAPPDWaveforms #LAPPDWaveforms +BLSInputWavLabel AlignedLAPPDData +#BLSInputWavLabel RawLAPPDData + +LowBLfitrange 0 +HiBLfitrange 60 +TrigLowBLfitrange 110 +TrigHiBLfitrange 160 +BLSOutputWavLabel BLsubtractedLAPPDData +oldLaserTrigAmpRange 40 + +#LAPPDFindT0 +FindT0Verbosity 0 +#FindT0InputWavLabel BLsubtractedLAPPDData +#FindT0InputWavLabel RawLAPPDData +FindT0InputWavLabel LAPPDWaveforms +OneBoardShift 0 +OneBoardShiftValue 16 + + +TrigEarlyCut 20 +TrigLateCut 200 +T0channelNo 1005 +T0channelNo1 1005 +T0channelNo2 1005 +T0signalmax -100. +T0signalthreshold -50. +T0signalmaxOld 50. #Older data uses a positive going signal +T0signalthresholdOld 80. #Older data uses a positive going signal +T0offset 0 +FindT0OutputWavLabel AlignedLAPPDData +GlobalShiftT0 0 +#Added by Marc +Triggerdefault 5 +LAPPDOffset 1000 + +#LAPPDPlotWaveForms +requireT0signal 0 +SaveByChannel 1 +PlotWavLabel BLsubtractedLAPPDData +#PlotWavLabel LAPPDWaveforms +outfile WaveForms_rawblsub.root +NHistos 400 +SaveSingleStrip 0 +SingleStripNo 9 + + + + + + + + diff --git a/configfiles/LAPPDRaw/ConfigStoreReadIn b/configfiles/LAPPDRaw/ConfigStoreReadIn new file mode 100755 index 000000000..c55ae7ea0 --- /dev/null +++ b/configfiles/LAPPDRaw/ConfigStoreReadIn @@ -0,0 +1,43 @@ +# General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 +#StoreInputFile /pnfs/annie/persistent/users/redwards/data/filtered_lappd/R3649-R3844/LAPPDEventsBeamgateMRDTrack/FilteredEvents_LAPPDEventsBeamgateMRDTrack_R3649-R3844 + +LAPPDStoreReadInVerbosity 0 + +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +PedinputfileTXT ../Pedestals/swapLAPPD/Pedestal +#PedinputfileTXT ../Pedestals/change/Pedestal + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + +#LAPPDReorderData +LAPPDReorderVerbosityLevel 0 +ReorderVerbosityLevel 10 +ReorderInputWavLabel RawLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 150 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 + diff --git a/configfiles/LAPPDRaw/Configs b/configfiles/LAPPDRaw/Configs new file mode 100644 index 000000000..d160269fa --- /dev/null +++ b/configfiles/LAPPDRaw/Configs @@ -0,0 +1,68 @@ + General Parameters +Nsamples 256 #Number of samples in a waveform +SampleSize 100 #Sample size for baseline substraction +TrigChannel 5 #Specified channel the trigger signal will be on +NUM_VECTOR_PPS 16 #Fixed PPS vector size +NUM_VECTOR_DATA 7795 #Fixed DATA vector size +NUM_VECTOR_METADATA 103 #Fixed META vector size +LAPPDchannelOffset 1000 +NChannels 30 + +LAPPDStoreReadInVerbosity 0 + +mergingModeReadIn 0 +RawDataInputWavLabel RawWaveform +RawDataOutputWavLabel RawLAPPDData +BoardIndexLabel BoardIndex #Label of the vector of read out boards + +PsecReceiveMode 1 +stopEntries 10000000000 + +DoPedSubtraction 1 +Nboards 6 #Number of pedestal files to be read in +#PedinputfileTXT ../Pedestals/swapLAPPD/Pedestal +#PedinputfileTXT ../Pedestals/run3xxx/Pedestal +PedinputfileTXT ../Pedestals/LAPPD640392/P +PSECinputfile /pnfs/annie/persistent/processed/LAPPD40Merged/FinalVersion_withRawTS/FilteredData_PMT_MRDtrack_noveto_15mV_7strips_3xxx_104 + + +Pedinputfile1 ../Pedestals/PEDS_ACDC_board0.txt +Pedinputfile2 ../Pedestals/PEDS_ACDC_board1.txt + +#LAPPDReorderData +ReorderVerbosityLevel 0 +#ReorderInputWavLabel RawLAPPDData +ReorderInputWavLabel AlignedLAPPDData +ReorderOutputWavLabel LAPPDWaveforms +DelayOffset 0 +GlobalShift 180 + +ReadStore 0 +NUM_VECTOR_DATA 7795 +NUM_VECTOR_PPS 16 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 1 +loadOffsets 0 +num_vector_data 7795 +num_vector_pps 16 + +#LAPPDTreeMaker +LoadPulse 1 +LoadHit 1 +LoadWaveform 1 +LoadLAPPDDataTimeStamp 1 +LoadPPSTimestamp 1 +LoadRunInfoRaw 1 +LoadRunInfoANNIEEvent 0 + +treeMakerVerbosity 0 + +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 diff --git a/configfiles/LAPPDRaw/DefaultTriggerMask.txt b/configfiles/LAPPDRaw/DefaultTriggerMask.txt new file mode 100644 index 000000000..002014f0f --- /dev/null +++ b/configfiles/LAPPDRaw/DefaultTriggerMask.txt @@ -0,0 +1,7 @@ +#Triggers are given by Jonathan; place one number per line. Values are index + 1 +#4+1: Delayed beam. 32+1: LED trigger. 34+1: AmBe and Cosmic trigger. 35+1: MRD_CR_Trigger. 30+1: LED_Start +3 +5 +8 +14 +32 diff --git a/configfiles/LAPPDRaw/LoadRawDataConfig b/configfiles/LAPPDRaw/LoadRawDataConfig new file mode 100644 index 000000000..0caf97dbc --- /dev/null +++ b/configfiles/LAPPDRaw/LoadRawDataConfig @@ -0,0 +1,12 @@ +verbosity 0 +BuildType LAPPDAndCTC +Mode FileList + + +InputFile ./configfiles/LAPPDRaw/list.txt + + +DummyRunInfo 1 +StoreTrigOverlap 0 +ReadTrigOverlap 0 +StoreRawData 0 diff --git a/configfiles/LAPPDRaw/ToolChainConfig b/configfiles/LAPPDRaw/ToolChainConfig new file mode 100644 index 000000000..6bccc8861 --- /dev/null +++ b/configfiles/LAPPDRaw/ToolChainConfig @@ -0,0 +1,24 @@ + +#ToollChain dynamic setup file + +##### Runtime Paramiters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandeled errors only, 2= exit on unhandeled errors and handeled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + +###### Service discovery ##### Ignore these settings for local analysis +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File configfiles/LAPPDRaw/ToolsConfig ## list of tools to run and their config files + +##### Run Type ##### +Inline -1 ## number of Execute steps in program, -1 infinite loop that is ended by user +Interactive 0 ## set to 1 if you want to run the code interactively + diff --git a/configfiles/LAPPDRaw/ToolsConfig b/configfiles/LAPPDRaw/ToolsConfig new file mode 100644 index 000000000..a9c7536e8 --- /dev/null +++ b/configfiles/LAPPDRaw/ToolsConfig @@ -0,0 +1,19 @@ +#LoadGeometry LoadGeometry configfiles/LAPPDRaw/ConfigGeo +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig +LoadRawData LoadRawData configfiles/LAPPDRaw/LoadRawDataConfig + +#TriggerDataDecoder TriggerDataDecoder configfiles/LAPPDRaw/TriggerDataDecoderConfig + +LAPPDLoadStore LAPPDLoadStore configfiles/LAPPDRaw/Configs +LAPPDStoreReorder LAPPDStoreReorder configfiles/LAPPDRaw/ConfigStoreReadIn + +LAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDRaw/ConfigPreProcess +LAPPDBaseline LAPPDBaseline configfiles/LAPPDRaw/ConfigPreProcess +LAPPDPlots LAPPDPlots configfiles/LAPPDRaw/ConfigPlot + +LAPPDThresReco LAPPDThresReco configfiles/LAPPDRaw/ConfigPlot + +LAPPDTreeMaker LAPPDTreeMaker configfiles/LAPPDRaw/Configs + + + diff --git a/configfiles/LAPPDRaw/TriggerDataDecoderConfig b/configfiles/LAPPDRaw/TriggerDataDecoderConfig new file mode 100644 index 000000000..22aa89a31 --- /dev/null +++ b/configfiles/LAPPDRaw/TriggerDataDecoderConfig @@ -0,0 +1,4 @@ +verbosity 0 +#TriggerMaskFile ./configfiles/LAPPDBeamAnalysis/LAPPDRaw/DefaultTriggerMask.txt +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/LAPPDRaw/list.txt b/configfiles/LAPPDRaw/list.txt new file mode 100644 index 000000000..337ffd617 --- /dev/null +++ b/configfiles/LAPPDRaw/list.txt @@ -0,0 +1,5 @@ +/pnfs/annie/persistent/raw/raw/4920/RAWDataR4920S0p0 +/pnfs/annie/persistent/raw/raw/4920/RAWDataR4920S0p1 +/pnfs/annie/persistent/raw/raw/4920/RAWDataR4920S0p2 +/pnfs/annie/persistent/raw/raw/4920/RAWDataR4920S0p3 +/pnfs/annie/persistent/raw/raw/4920/RAWDataR4920S0p4 diff --git a/configfiles/LAPPD_EB/my_files.txt b/configfiles/LAPPD_EB/my_files.txt index d047a0162..8504035cc 100644 --- a/configfiles/LAPPD_EB/my_files.txt +++ b/configfiles/LAPPD_EB/my_files.txt @@ -1,50 +1,6 @@ -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p0 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p1 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p2 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p3 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p4 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p5 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p6 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p7 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p8 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p9 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p10 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p11 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p12 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p13 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p14 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p15 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p16 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p17 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p18 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p19 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p20 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p21 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p22 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p23 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p24 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p25 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p26 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p27 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p28 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p29 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p30 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p31 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p32 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p33 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p34 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p35 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p36 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p37 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p38 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p39 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p40 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p41 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p42 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p43 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p44 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p45 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p46 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p47 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p48 -/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p49 +/pnfs/annie/persistent/raw/raw/4169/RAWDataR4169S0p0 +/pnfs/annie/persistent/raw/raw/4169/RAWDataR4169S0p1 +/pnfs/annie/persistent/raw/raw/4169/RAWDataR4169S0p2 +/pnfs/annie/persistent/raw/raw/4169/RAWDataR4169S0p3 +/pnfs/annie/persistent/raw/raw/4169/RAWDataR4169S0p4 +/pnfs/annie/persistent/raw/raw/4169/RAWDataR4169S0p5 diff --git a/configfiles/LoadGeometry/TankPMTTimingOffsets.csv b/configfiles/LoadGeometry/TankPMTTimingOffsets.csv index b1f16ff3f..3aca644cb 100644 --- a/configfiles/LoadGeometry/TankPMTTimingOffsets.csv +++ b/configfiles/LoadGeometry/TankPMTTimingOffsets.csv @@ -74,7 +74,7 @@ 413,Barrel,4.1,1.27,ok 414,Barrel,16.84,1.32,ok 415,Barrel,12.67,0.97,ok -416,Barrel,0,0,inactive +416,Barrel,0,0,unreliable 417,Barrel,7.98,1.45,ok 418,Barrel,7.96,2.28,unreliable 419,Barrel,17.9,1.92,ok diff --git a/configfiles/PreProcessTrigOverlap/LoadRawDataConfig b/configfiles/PreProcessTrigOverlap/LoadRawDataConfig index 7d78a212b..925e72867 100644 --- a/configfiles/PreProcessTrigOverlap/LoadRawDataConfig +++ b/configfiles/PreProcessTrigOverlap/LoadRawDataConfig @@ -1,4 +1,4 @@ -verbosity 11 +verbosity 0 BuildType CTC Mode FileList InputFile ./configfiles/PreProcessTrigOverlap/my_files.txt diff --git a/configfiles/PreProcessTrigOverlap/TriggerDataDecoderConfig b/configfiles/PreProcessTrigOverlap/TriggerDataDecoderConfig index 00b6bc1e6..dd31e177e 100644 --- a/configfiles/PreProcessTrigOverlap/TriggerDataDecoderConfig +++ b/configfiles/PreProcessTrigOverlap/TriggerDataDecoderConfig @@ -1,5 +1,5 @@ -verbosity 2 -TriggerMaskFile ./configfiles/EventBuilder/DefaultTriggerMask.txt -StoreTrigOverlap 1 +verbosity 0 +#TriggerMaskFile ./configfiles/EventBuilder/DefaultTriggerMask.txt +StoreTrigOverlap 0 ReadTrigOverlap 0 UseCStore 0 diff --git a/configfiles/PreProcessTrigOverlap/my_files.txt b/configfiles/PreProcessTrigOverlap/my_files.txt index 8c8399ef2..c42d21e0c 100644 --- a/configfiles/PreProcessTrigOverlap/my_files.txt +++ b/configfiles/PreProcessTrigOverlap/my_files.txt @@ -1,2 +1,13 @@ -/pnfs/annie/persistent/raw/raw/4314/RAWDataR4314S0p0 -/pnfs/annie/persistent/raw/raw/4314/RAWDataR4314S0p1 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p0 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p1 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p2 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p3 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p4 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p5 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p6 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p7 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p8 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p9 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p10 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p11 +/pnfs/annie/persistent/raw/raw/3815/RAWDataR3815S0p12 diff --git a/configfiles/PrintADCTraces/PrintADCTracesConfig b/configfiles/PrintADCTraces/PrintADCTracesConfig index 223d13be8..804a380df 100644 --- a/configfiles/PrintADCTraces/PrintADCTracesConfig +++ b/configfiles/PrintADCTraces/PrintADCTracesConfig @@ -1,8 +1,8 @@ verbosity 0 -hitPE_min 0 # minimum hit charge [pe] to include in the root file -hitPE_max 2.5 # maximum hit charge [pe] to include in the root file - # omitting both of these will not impose a charge selection +hitPE_min 0.5 # minimum hit charge [pe] to include in the root file +hitPE_max 1.5 # maximum hit charge [pe] to include in the root file + # omitting both of these will not impose a charge selection hitT_min 0 # minimum hit time [ns] to include in the root file hitT_max 2000 # maximum hit time [ns] to include in the root file @@ -14,6 +14,4 @@ MaxTraces 10000 # maximum number of traces to include in the roo MaxTracesPerChannel 100 # maximum number of traces per channel to include in the root file # if set to '0' or left undefined, it will not impose a limit -useClusterHits 0 # fill root file with traces from clustered hits rather than from all event "Hits" - OutputFilename ADCTraces.root # name of the output root file \ No newline at end of file diff --git a/configfiles/PrintADCTraces/README.md b/configfiles/PrintADCTraces/README.md index 33abd3962..e9185a0dc 100644 --- a/configfiles/PrintADCTraces/README.md +++ b/configfiles/PrintADCTraces/README.md @@ -1,6 +1,6 @@ # PrintADCTraces -`PrintADCTraces` toolchain will read the ADC traces in "RecoADCData", and output the pulses (and the pulse metadata such as the baseline, charge, time, etc...) to a root file. It will also filter traces/hits within some range of charges or times provided by the user. +`PrintADCTraces` toolchain will read the ADC traces in "RecoADCData", and output the pulses to a root file. It will also filter traces/hits within some range of charges or times provided by the user. ## Output rootfile @@ -17,12 +17,8 @@ // │ └── ... // └── TraceSummary TTree # metadata // ├── chan # all pulse channel ids -// ├── run # all pulse run numbers -// ├── eventTime # all pulse event times // ├── hitT # all pulse hit times [ns] -// ├── hitPE # all pulse hit charges [pe] -// ├── hitBaseline # all pulse baselines [adc] -// └── hitNoise # all pulse baseline sigma (noise) [adc] +// └── hitPE # all pulse hit charges [pe] ``` where the TGraph name is given by: ```____``` @@ -35,7 +31,7 @@ where the TGraph name is given by: ```___` diff --git a/configfiles/PrintADCTraces/ToolsConfig b/configfiles/PrintADCTraces/ToolsConfig index 1e9497f16..38ac2af03 100644 --- a/configfiles/PrintADCTraces/ToolsConfig +++ b/configfiles/PrintADCTraces/ToolsConfig @@ -1,4 +1,3 @@ -LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig LoadANNIEEvent LoadANNIEEvent ./configfiles/PrintADCTraces/LoadANNIEEventConfig -#ClusterFinder ClusterFinder ./configfiles/PrintADCTraces/ClusterFinderConfig +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig PrintADCTraces PrintADCTraces ./configfiles/PrintADCTraces/PrintADCTracesConfig diff --git a/configfiles/PrintADCTraces/create_my_inputs.sh b/configfiles/PrintADCTraces/create_my_inputs.sh new file mode 100644 index 000000000..3e200e3c3 --- /dev/null +++ b/configfiles/PrintADCTraces/create_my_inputs.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +if [[ -z "$1" ]]; then + echo "" + echo "##############################" + echo "Error: No run number provided." + echo "Usage: $0 " + echo "" + exit 1 +fi + +run=$1 + +output_file="my_inputs.txt" +processed_dir="/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R${run}/" + +find "$processed_dir" -type f -name "Processed*" | sort -t'/' -k2V > "$output_file" + +echo "done" diff --git a/configfiles/PrintADCTraces/my_inputs.txt b/configfiles/PrintADCTraces/my_inputs.txt index 463a08792..c63be866a 100644 --- a/configfiles/PrintADCTraces/my_inputs.txt +++ b/configfiles/PrintADCTraces/my_inputs.txt @@ -1,10 +1 @@ -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p0 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p1 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p2 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p3 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p4 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p5 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p6 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p7 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p8 -/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p9 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/AnalysisFile/FilteredLAPPD_BeamSelection_Pedestal2022 diff --git a/configfiles/PrintANNIEEvent/ToolChainConfig b/configfiles/PrintANNIEEvent/ToolChainConfig index c1502264a..0b59861a9 100644 --- a/configfiles/PrintANNIEEvent/ToolChainConfig +++ b/configfiles/PrintANNIEEvent/ToolChainConfig @@ -21,6 +21,6 @@ service_kick_sec -1 Tools_File configfiles/PrintANNIEEvent/ToolsConfig ## list of tools to run and their config files ##### Run Type ##### -Inline -1 ## number of Execute steps in program, -1 infinite loop that is ended by user +Inline 20 ## number of Execute steps in program, -1 infinite loop that is ended by user Interactive 0 ## set to 1 if you want to run the code interactively diff --git a/configfiles/PrintANNIEEvent/my_inputs.txt b/configfiles/PrintANNIEEvent/my_inputs.txt index 9fdca0389..49ccbb759 100644 --- a/configfiles/PrintANNIEEvent/my_inputs.txt +++ b/configfiles/PrintANNIEEvent/my_inputs.txt @@ -1 +1 @@ -/pnfs/annie/persistent/users/mnieslon/data/processed_hits/R2421/ProcessedRawData_TankAndMRDAndCTC_R2421S0p0 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/R3832/FilteredAllLAPPDData_3832_0_49 diff --git a/configfiles/RingCounting/RC_model_v1_0_0.model/keras_metadata.pb b/configfiles/RingCounting/RC_model_v1_0_0.model/keras_metadata.pb new file mode 100644 index 000000000..39da4b4f8 --- /dev/null +++ b/configfiles/RingCounting/RC_model_v1_0_0.model/keras_metadata.pb @@ -0,0 +1,38 @@ + +root"_tf_keras_network*{"name": "model_23", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "class_name": "Functional", "config": {"name": "model_23", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10, 16, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "charge"}, "name": "charge", "inbound_nodes": []}, {"class_name": "Conv2D", "config": {"name": "conv2d_40", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_40", "inbound_nodes": [[["charge", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_50", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "name": "dropout_50", "inbound_nodes": [[["conv2d_40", 0, 0, {}]]]}, {"class_name": "Activation", "config": {"name": "activation_40", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_40", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}}}, "name": "activation_40", "inbound_nodes": [[["dropout_50", 0, 0, {}]]]}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_30", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_30", "inbound_nodes": [[["activation_40", 0, 0, {}]]]}, {"class_name": "Conv2D", "config": {"name": "conv2d_41", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_41", "inbound_nodes": [[["max_pooling2d_30", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_51", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_51", "inbound_nodes": [[["conv2d_41", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_40", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_40", "inbound_nodes": [[["dropout_51", 0, 0, {}]]]}, {"class_name": "Activation", "config": {"name": "activation_41", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_41", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}}}, "name": "activation_41", "inbound_nodes": [[["batch_normalization_40", 0, 0, {}]]]}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_31", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_31", "inbound_nodes": [[["activation_41", 0, 0, {}]]]}, {"class_name": "Conv2D", "config": {"name": "conv2d_42", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_42", "inbound_nodes": [[["max_pooling2d_31", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_52", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_52", "inbound_nodes": [[["conv2d_42", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_41", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_41", "inbound_nodes": [[["dropout_52", 0, 0, {}]]]}, {"class_name": "Activation", "config": {"name": "activation_42", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_42", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}}}, "name": "activation_42", "inbound_nodes": [[["batch_normalization_41", 0, 0, {}]]]}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_32", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_32", "inbound_nodes": [[["activation_42", 0, 0, {}]]]}, {"class_name": "Conv2D", "config": {"name": "conv2d_43", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_43", "inbound_nodes": [[["max_pooling2d_32", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_53", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_53", "inbound_nodes": [[["conv2d_43", 0, 0, {}]]]}, {"class_name": "Activation", "config": {"name": "activation_43", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_43", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}}}, "name": "activation_43", "inbound_nodes": [[["dropout_53", 0, 0, {}]]]}, {"class_name": "Flatten", "config": {"name": "flatten_10", "trainable": true, "dtype": "float32", "data_format": "channels_last"}, "name": "flatten_10", "inbound_nodes": [[["activation_43", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_30", "trainable": true, "dtype": "float32", "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_30", "inbound_nodes": [[["flatten_10", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_42", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_42", "inbound_nodes": [[["dense_30", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_31", "trainable": true, "dtype": "float32", "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_31", "inbound_nodes": [[["batch_normalization_42", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_54", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_54", "inbound_nodes": [[["dense_31", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_43", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_43", "inbound_nodes": [[["dropout_54", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_32", "trainable": true, "dtype": "float32", "units": 2, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_32", "inbound_nodes": [[["batch_normalization_43", 0, 0, {}]]]}, {"class_name": "Activation", "config": {"name": "pred", "trainable": true, "dtype": "float32", "activation": "softmax"}, "name": "pred", "inbound_nodes": [[["dense_32", 0, 0, {}]]]}], "input_layers": [["charge", 0, 0]], "output_layers": [["pred", 0, 0]]}, "shared_object_id": 60, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, 10, 16, 1]}, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, 10, 16, 1]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 10, 16, 1]}, "float32", "charge"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 10, 16, 1]}, "float32", "charge"]}, "keras_version": "2.7.0", "backend": "tensorflow", "model_config": {"class_name": "Functional", "config": {"name": "model_23", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10, 16, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "charge"}, "name": "charge", "inbound_nodes": [], "shared_object_id": 0}, {"class_name": "Conv2D", "config": {"name": "conv2d_40", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_40", "inbound_nodes": [[["charge", 0, 0, {}]]], "shared_object_id": 3}, {"class_name": "Dropout", "config": {"name": "dropout_50", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "name": "dropout_50", "inbound_nodes": [[["conv2d_40", 0, 0, {}]]], "shared_object_id": 4}, {"class_name": "Activation", "config": {"name": "activation_40", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_40", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 5}}, "name": "activation_40", "inbound_nodes": [[["dropout_50", 0, 0, {}]]], "shared_object_id": 6}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_30", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_30", "inbound_nodes": [[["activation_40", 0, 0, {}]]], "shared_object_id": 7}, {"class_name": "Conv2D", "config": {"name": "conv2d_41", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 8}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 9}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_41", "inbound_nodes": [[["max_pooling2d_30", 0, 0, {}]]], "shared_object_id": 10}, {"class_name": "Dropout", "config": {"name": "dropout_51", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_51", "inbound_nodes": [[["conv2d_41", 0, 0, {}]]], "shared_object_id": 11}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_40", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 12}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 13}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 14}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 15}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_40", "inbound_nodes": [[["dropout_51", 0, 0, {}]]], "shared_object_id": 16}, {"class_name": "Activation", "config": {"name": "activation_41", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_41", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 17}}, "name": "activation_41", "inbound_nodes": [[["batch_normalization_40", 0, 0, {}]]], "shared_object_id": 18}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_31", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_31", "inbound_nodes": [[["activation_41", 0, 0, {}]]], "shared_object_id": 19}, {"class_name": "Conv2D", "config": {"name": "conv2d_42", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 20}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 21}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_42", "inbound_nodes": [[["max_pooling2d_31", 0, 0, {}]]], "shared_object_id": 22}, {"class_name": "Dropout", "config": {"name": "dropout_52", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_52", "inbound_nodes": [[["conv2d_42", 0, 0, {}]]], "shared_object_id": 23}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_41", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 24}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 25}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 26}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 27}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_41", "inbound_nodes": [[["dropout_52", 0, 0, {}]]], "shared_object_id": 28}, {"class_name": "Activation", "config": {"name": "activation_42", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_42", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 29}}, "name": "activation_42", "inbound_nodes": [[["batch_normalization_41", 0, 0, {}]]], "shared_object_id": 30}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_32", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "name": "max_pooling2d_32", "inbound_nodes": [[["activation_42", 0, 0, {}]]], "shared_object_id": 31}, {"class_name": "Conv2D", "config": {"name": "conv2d_43", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 32}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 33}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv2d_43", "inbound_nodes": [[["max_pooling2d_32", 0, 0, {}]]], "shared_object_id": 34}, {"class_name": "Dropout", "config": {"name": "dropout_53", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_53", "inbound_nodes": [[["conv2d_43", 0, 0, {}]]], "shared_object_id": 35}, {"class_name": "Activation", "config": {"name": "activation_43", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_43", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 36}}, "name": "activation_43", "inbound_nodes": [[["dropout_53", 0, 0, {}]]], "shared_object_id": 37}, {"class_name": "Flatten", "config": {"name": "flatten_10", "trainable": true, "dtype": "float32", "data_format": "channels_last"}, "name": "flatten_10", "inbound_nodes": [[["activation_43", 0, 0, {}]]], "shared_object_id": 38}, {"class_name": "Dense", "config": {"name": "dense_30", "trainable": true, "dtype": "float32", "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 39}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 40}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_30", "inbound_nodes": [[["flatten_10", 0, 0, {}]]], "shared_object_id": 41}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_42", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 42}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 43}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 44}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 45}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_42", "inbound_nodes": [[["dense_30", 0, 0, {}]]], "shared_object_id": 46}, {"class_name": "Dense", "config": {"name": "dense_31", "trainable": true, "dtype": "float32", "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 47}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 48}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_31", "inbound_nodes": [[["batch_normalization_42", 0, 0, {}]]], "shared_object_id": 49}, {"class_name": "Dropout", "config": {"name": "dropout_54", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "name": "dropout_54", "inbound_nodes": [[["dense_31", 0, 0, {}]]], "shared_object_id": 50}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_43", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 51}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 52}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 53}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 54}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_43", "inbound_nodes": [[["dropout_54", 0, 0, {}]]], "shared_object_id": 55}, {"class_name": "Dense", "config": {"name": "dense_32", "trainable": true, "dtype": "float32", "units": 2, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 56}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 57}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_32", "inbound_nodes": [[["batch_normalization_43", 0, 0, {}]]], "shared_object_id": 58}, {"class_name": "Activation", "config": {"name": "pred", "trainable": true, "dtype": "float32", "activation": "softmax"}, "name": "pred", "inbound_nodes": [[["dense_32", 0, 0, {}]]], "shared_object_id": 59}], "input_layers": [["charge", 0, 0]], "output_layers": [["pred", 0, 0]]}}, "training_config": {"loss": "binary_crossentropy", "metrics": [[{"class_name": "MeanMetricWrapper", "config": {"name": "accuracy", "dtype": "float32", "fn": "categorical_accuracy"}, "shared_object_id": 62}]], "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 9.999999747378752e-05, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2 + root.layer-0"_tf_keras_input_layer*{"class_name": "InputLayer", "name": "charge", "dtype": "float32", "sparse": false, "ragged": false, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 10, 16, 1]}, "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 10, 16, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "charge"}}2 + root.layer_with_weights-0"_tf_keras_layer* {"name": "conv2d_40", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv2D", "config": {"name": "conv2d_40", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["charge", 0, 0, {}]]], "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 1}}, "shared_object_id": 63}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 10, 16, 1]}}2 + root.layer-2"_tf_keras_layer*{"name": "dropout_50", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_50", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv2d_40", 0, 0, {}]]], "shared_object_id": 4}2 + root.layer-3"_tf_keras_layer*{"name": "activation_40", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Activation", "config": {"name": "activation_40", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_40", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 5}}, "inbound_nodes": [[["dropout_50", 0, 0, {}]]], "shared_object_id": 6}2 + root.layer-4"_tf_keras_layer*{"name": "max_pooling2d_30", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_30", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "inbound_nodes": [[["activation_40", 0, 0, {}]]], "shared_object_id": 7, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 64}}2 + +root.layer_with_weights-1"_tf_keras_layer* {"name": "conv2d_41", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv2D", "config": {"name": "conv2d_41", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 8}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 9}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["max_pooling2d_30", 0, 0, {}]]], "shared_object_id": 10, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 64}}, "shared_object_id": 65}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 5, 8, 64]}}2 + root.layer-6"_tf_keras_layer*{"name": "dropout_51", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_51", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv2d_41", 0, 0, {}]]], "shared_object_id": 11}2 + root.layer_with_weights-2"_tf_keras_layer* {"name": "batch_normalization_40", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_40", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 12}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 13}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 14}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 15}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_51", 0, 0, {}]]], "shared_object_id": 16, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {"3": 128}}, "shared_object_id": 66}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 5, 8, 128]}}2 +  root.layer-8"_tf_keras_layer*{"name": "activation_41", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Activation", "config": {"name": "activation_41", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_41", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 17}}, "inbound_nodes": [[["batch_normalization_40", 0, 0, {}]]], "shared_object_id": 18}2 + + root.layer-9"_tf_keras_layer*{"name": "max_pooling2d_31", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_31", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "inbound_nodes": [[["activation_41", 0, 0, {}]]], "shared_object_id": 19, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 67}}2 + + root.layer_with_weights-3"_tf_keras_layer* {"name": "conv2d_42", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv2D", "config": {"name": "conv2d_42", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 20}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 21}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["max_pooling2d_31", 0, 0, {}]]], "shared_object_id": 22, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 128}}, "shared_object_id": 68}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 2, 4, 128]}}2 +  root.layer-11"_tf_keras_layer*{"name": "dropout_52", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_52", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv2d_42", 0, 0, {}]]], "shared_object_id": 23}2 +  root.layer_with_weights-4"_tf_keras_layer* {"name": "batch_normalization_41", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_41", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 24}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 25}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 26}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 27}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_52", 0, 0, {}]]], "shared_object_id": 28, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {"3": 256}}, "shared_object_id": 69}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 2, 4, 256]}}2 + root.layer-13"_tf_keras_layer*{"name": "activation_42", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Activation", "config": {"name": "activation_42", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_42", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 29}}, "inbound_nodes": [[["batch_normalization_41", 0, 0, {}]]], "shared_object_id": 30}2 + root.layer-14"_tf_keras_layer*{"name": "max_pooling2d_32", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_32", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "inbound_nodes": [[["activation_42", 0, 0, {}]]], "shared_object_id": 31, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 70}}2 + +root.layer_with_weights-5"_tf_keras_layer* {"name": "conv2d_43", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv2D", "config": {"name": "conv2d_43", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 32}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 33}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["max_pooling2d_32", 0, 0, {}]]], "shared_object_id": 34, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 256}}, "shared_object_id": 71}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 1, 2, 256]}}2 + root.layer-16"_tf_keras_layer*{"name": "dropout_53", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_53", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv2d_43", 0, 0, {}]]], "shared_object_id": 35}2 + root.layer-17"_tf_keras_layer*{"name": "activation_43", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Activation", "config": {"name": "activation_43", "trainable": true, "dtype": "float32", "activation": {"class_name": "ReLU", "config": {"name": "re_lu_43", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 36}}, "inbound_nodes": [[["dropout_53", 0, 0, {}]]], "shared_object_id": 37}2 + root.layer-18"_tf_keras_layer*{"name": "flatten_10", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Flatten", "config": {"name": "flatten_10", "trainable": true, "dtype": "float32", "data_format": "channels_last"}, "inbound_nodes": [[["activation_43", 0, 0, {}]]], "shared_object_id": 38, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 1, "axes": {}}, "shared_object_id": 72}}2 +root.layer_with_weights-6"_tf_keras_layer*{"name": "dense_30", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_30", "trainable": true, "dtype": "float32", "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 39}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 40}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["flatten_10", 0, 0, {}]]], "shared_object_id": 41, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 512}}, "shared_object_id": 73}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 512]}}2 + root.layer_with_weights-7"_tf_keras_layer* {"name": "batch_normalization_42", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_42", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 42}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 43}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 44}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 45}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dense_30", 0, 0, {}]]], "shared_object_id": 46, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 2, "max_ndim": null, "min_ndim": null, "axes": {"1": 128}}, "shared_object_id": 74}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128]}}2 +root.layer_with_weights-8"_tf_keras_layer*{"name": "dense_31", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_31", "trainable": true, "dtype": "float32", "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 47}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 48}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_42", 0, 0, {}]]], "shared_object_id": 49, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 128}}, "shared_object_id": 75}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128]}}2 + root.layer-22"_tf_keras_layer*{"name": "dropout_54", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_54", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "inbound_nodes": [[["dense_31", 0, 0, {}]]], "shared_object_id": 50}2 + root.layer_with_weights-9"_tf_keras_layer* {"name": "batch_normalization_43", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_43", "trainable": true, "dtype": "float32", "axis": [1], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 51}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 52}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 53}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 54}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_54", 0, 0, {}]]], "shared_object_id": 55, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 2, "max_ndim": null, "min_ndim": null, "axes": {"1": 128}}, "shared_object_id": 76}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128]}}2 +root.layer_with_weights-10"_tf_keras_layer*{"name": "dense_32", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_32", "trainable": true, "dtype": "float32", "units": 2, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 56}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 57}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_43", 0, 0, {}]]], "shared_object_id": 58, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 128}}, "shared_object_id": 77}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128]}}2 + root.layer-25"_tf_keras_layer*{"name": "pred", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Activation", "config": {"name": "pred", "trainable": true, "dtype": "float32", "activation": "softmax"}, "inbound_nodes": [[["dense_32", 0, 0, {}]]], "shared_object_id": 59}2 ++root.layer-3.activation"_tf_keras_layer*{"name": "re_lu_40", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ReLU", "config": {"name": "re_lu_40", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 5}2 +Groot.layer-8.activation"_tf_keras_layer*{"name": "re_lu_41", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ReLU", "config": {"name": "re_lu_41", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 17}2 +croot.layer-13.activation"_tf_keras_layer*{"name": "re_lu_42", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ReLU", "config": {"name": "re_lu_42", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 29}2 +vroot.layer-17.activation"_tf_keras_layer*{"name": "re_lu_43", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ReLU", "config": {"name": "re_lu_43", "trainable": true, "dtype": "float32", "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "shared_object_id": 36}2 +root.keras_api.metrics.0"_tf_keras_metric*{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 78}2 +root.keras_api.metrics.1"_tf_keras_metric*{"class_name": "MeanMetricWrapper", "name": "accuracy", "dtype": "float32", "config": {"name": "accuracy", "dtype": "float32", "fn": "categorical_accuracy"}, "shared_object_id": 62}2 \ No newline at end of file diff --git a/configfiles/RingCounting/RC_model_v1_0_0.model/saved_model.pb b/configfiles/RingCounting/RC_model_v1_0_0.model/saved_model.pb new file mode 100644 index 000000000..a9c2cce3b Binary files /dev/null and b/configfiles/RingCounting/RC_model_v1_0_0.model/saved_model.pb differ diff --git a/configfiles/RingCounting/RC_model_v1_0_0.model/variables/variables.data-00000-of-00001 b/configfiles/RingCounting/RC_model_v1_0_0.model/variables/variables.data-00000-of-00001 new file mode 100644 index 000000000..b4ad9836c Binary files /dev/null and b/configfiles/RingCounting/RC_model_v1_0_0.model/variables/variables.data-00000-of-00001 differ diff --git a/configfiles/RingCounting/RC_model_v1_0_0.model/variables/variables.index b/configfiles/RingCounting/RC_model_v1_0_0.model/variables/variables.index new file mode 100644 index 000000000..35c795f17 Binary files /dev/null and b/configfiles/RingCounting/RC_model_v1_0_0.model/variables/variables.index differ diff --git a/offsetFit_MultipleLAPPD.cpp b/offsetFit_MultipleLAPPD.cpp new file mode 100644 index 000000000..769023467 --- /dev/null +++ b/offsetFit_MultipleLAPPD.cpp @@ -0,0 +1,1272 @@ +// This is a script for offset fitting, use it on the output LAPPDTree.root +// This script require all LAPPD events appear in sequence, and all CTC events appear in sequence +/* procedure: + 1. load LAPPDTree.root (TODO: or use LAPPDTree_runNumber.root) + 2. load TimeStamp tree, get run number and part file number + 3. for each unique run number and part file number, do fit: + 4. in this file, for each LAPPD ID: + 5. loop TimeStamp tree + load data timestamp + load data beamgate + load PPS for board 0 and board 1 + 6. loop Trig (or GTrig) tree + load CTC PPS (word = 32) + load target trigger word + + 7. Find the number of resets in LAPPD PPS: + There must be at least one event in each reset. + Based on the event index order, only fit before the reset which doesn't have data event. + Save the data event and PPS index order. + + 8. Use the target trigger word, fit the offset + 9. save the offset for this LAPPD ID, run number, part file number, index, reset number. + 10. Print info to txt file + +Laser trigger word: 47 +Undelayed beam trigger word: 14 + +root -l -q 'offsetFit_MultipleLAPPD.cpp("LAPPDTree.root", 14, 1, 10, 0)' +root -l -q 'offsetFit_MultipleLAPPD.cpp("LAPPDTree.root", 47, 0, 10, 0)' +*/ +#include +#include +#include +#include +#include +#include +#include "TFile.h" +#include "TTree.h" +#include "TH2D.h" +#include "TH1D.h" +#include "TString.h" + +vector> fitInThisReset( + const std::vector &LAPPDDataTimeStampUL, + const std::vector &LAPPDDataBeamgateUL, + const std::vector &LAPPD_PPS, + const int fitTargetTriggerWord, + const std::vector &CTCTrigger, + const std::vector &CTCPPS, + const ULong64_t PPSDeltaT) +{ + cout << "***************************************" << endl; + cout << "Fitting in this reset with:" << endl; + cout << "LAPPDDataTimeStampUL size: " << LAPPDDataTimeStampUL.size() << endl; + cout << "LAPPDDataBeamgateUL size: " << LAPPDDataBeamgateUL.size() << endl; + cout << "LAPPD_PPS size: " << LAPPD_PPS.size() << endl; + cout << "CTCTrigger size: " << CTCTrigger.size() << endl; + cout << "CTCPPS size: " << CTCPPS.size() << endl; + cout << "PPSDeltaT: " << PPSDeltaT << endl; // in ps + // for this input PPS, fit an offset + // return the offset and other information in order + // precedure: + // 1. check drift + // 2. shift the timestmap and beamgate based on drift + // 3. fit the offset + + std::vector PPSInterval_ACDC; + + for (int i = 1; i < LAPPD_PPS.size(); i++) + { + + double diff = static_cast(LAPPD_PPS[i] - LAPPD_PPS[i - 1]); + cout< 2 microseconds + cout<<"PPSInterval_ACDC["< 2) + { + h->Fill(PPSInterval_ACDC[i]); // fill in microseconds + cout << "Fill histogram: PPSInterval_ACDC[" << i << "]: " << PPSInterval_ACDC[i] << endl; + } + } + + TF1 *gausf = new TF1("gausf", "gaus", 0, 1E3); + h->Fit(gausf, "Q"); // Q for quiet mode + ULong64_t drift = static_cast(gausf->GetParameter(1) * 1E3 * 1E3); // drift in ps + ULong64_t trueInterval = PPSDeltaT - drift; + std::cout << "Gaussian Drift in ps is " << drift << std::endl; + std::cout << "True PPS interval in ps is " << trueInterval << std::endl; + delete gausf; + delete h; + // initialize variables need for fitting + int orphanCount = 0; // count the number that how many data event timestamp doesn't matched to a target trigger within an interval. + std::map>> DerivationMap; + cout << "LAPPD_PPS.size() " << LAPPD_PPS.size() << " CTCPPS.size() " << CTCPPS.size() << endl; + for (int i = 0; i < LAPPD_PPS.size(); i++) + { + if (i > 5) + { + if (i % static_cast(LAPPD_PPS.size() / 5) == 0) + cout << "Fitting PPS " << i << " of " << LAPPD_PPS.size() << endl; + } + ULong64_t LAPPD_PPS_ns = LAPPD_PPS.at(i) / 1000; + ULong64_t LAPPD_PPS_truncated_ps = LAPPD_PPS.at(i) % 1000; + + for (int j = 0; j < CTCPPS.size(); j++) + { + + vector diffSum; + ULong64_t offsetNow_ns = 0; + if (drift == 0) + { + offsetNow_ns = CTCPPS.at(j) - LAPPD_PPS_ns; + } + else + { + double LAPPD_PPS_ns_dd = static_cast(LAPPD_PPS_ns); + double driftScaling = LAPPD_PPS_ns_dd / (trueInterval / 1000); + ULong64_t totalDriftedClock = static_cast(drift * driftScaling / 1000); + offsetNow_ns = CTCPPS.at(j) - (LAPPD_PPS_ns + totalDriftedClock); + if (i < 3 && j < 3) + cout<<"totalDriftedClock in ns = "< notOrphanIndex; + vector ctcPairedIndex; + vector ctcOrphanPairedIndex; + + for (int lappdb = 0; lappdb < LAPPDDataBeamgateUL.size(); lappdb++) + { + ULong64_t TS_ns = LAPPDDataTimeStampUL.at(lappdb) / 1000; + ULong64_t TS_truncated_ps = LAPPDDataTimeStampUL.at(lappdb) % 1000; + // if fit for the undelayed beam trigger, use BG + if (fitTargetTriggerWord == 14) + { + TS_ns = LAPPDDataBeamgateUL.at(lappdb) / 1000; + TS_truncated_ps = LAPPDDataBeamgateUL.at(lappdb) % 1000; + } + + ULong64_t driftCorrectionForTS = 0; + if (drift != 0) + { + double TS_ns_dd = static_cast(TS_ns); + double driftScaling = TS_ns_dd / (trueInterval / 1000); + driftCorrectionForTS = static_cast(drift * driftScaling / 1000); + if(lappdb<3 && i<3 && j<3) + cout<::max(); + bool useThisValue = true; + int minPairIndex = 0; + string reason = "none"; + Long64_t first_derivation = 0; + int minIndex = 0; + double useValue = true; + + // find the best match of target trigger to this TS, in ns level. + for (int ctcb = 0; ctcb < CTCTrigger.size(); ctcb++) + { + ULong64_t CTCTrigger_ns = CTCTrigger.at(ctcb); + Long64_t diff = CTCTrigger_ns - DriftCorrectedTS_ns; + if (diff < 0) + diff = -diff; + + if (diff < minMatchDiff) + { + minMatchDiff = diff; + minPairIndex = ctcb; + } + + Long64_t LastBound = diff - minMatchDiff; + if (LastBound < 0) + LastBound = -LastBound; + Long64_t FirstBound = diff - first_derivation; + if (FirstBound < 0) + FirstBound = -FirstBound; + + // save the dt for the first matching to determin the matching position in range. + if (ctcb == 0) + first_derivation = diff; + + if (ctcb == CTCTrigger.size() - 1 && LastBound / 1E9 < 0.01) + { + useValue = false; + reason = "When matching the last TS, this diff is too close to (or even is) the minMatchDiff at index " + std::to_string(minPairIndex) + " in " + std::to_string(CTCTrigger.size()) + ". All LAPPD TS is out of the end of CTC trigger range"; + } + if (ctcb == CTCTrigger.size() - 1 && FirstBound / 1E9 < 0.01) + { + useValue = false; + reason = "When matching the last TS, this diff is too close to (or even is) the first_derivation at index " + std::to_string(minPairIndex) + " in " + std::to_string(CTCTrigger.size()) + ". All LAPPD TS is out of the beginning of CTC trigger range"; + } + } + + if (useValue) + { + diffSum.push_back(minMatchDiff); + double minAllowedDiff = 0; + double maxAllowedDiff = 100E3; + if (fitTargetTriggerWord == 14) + { + minAllowedDiff = 322E3; + maxAllowedDiff = 326E3; + } + if (minMatchDiff > maxAllowedDiff || minMatchDiff < minAllowedDiff) + { + // TODO: adjust the limit for laser. + orphanCount += 1; + ctcOrphanPairedIndex.push_back(minPairIndex); + } + else + { + notOrphanIndex.push_back(lappdb); + ctcPairedIndex.push_back(minPairIndex); + } + } + else + { + orphanCount += 1; + } + } + + double mean_dev = 0; + for (int k = 0; k < diffSum.size(); k++) + { + mean_dev += diffSum[k]; + } + if (diffSum.size() > 0) + mean_dev = mean_dev / diffSum.size(); + + double mean_dev_noOrphan = 0; + for (int k = 0; k < notOrphanIndex.size(); k++) + { + if (fitTargetTriggerWord == 14) + { + if (diffSum.at(k) > 322E3 && diffSum.at(k) < 326E3) + mean_dev_noOrphan += diffSum[notOrphanIndex[k]]; + } + else + { + mean_dev_noOrphan += diffSum[notOrphanIndex[k]]; + } + } + if ((diffSum.size() - orphanCount) != 0) + { + mean_dev_noOrphan = mean_dev_noOrphan / (diffSum.size() - orphanCount); + } + else + { + mean_dev_noOrphan = -1; // if all timestamps are out of the range, set it to -1 + } + + bool increMean_dev = false; + int maxAttempts = 1000; + int attemptCount = 0; + + if (mean_dev > 0) + { + int increament_dev = 0; + while (true) + { + // TODO + auto iter = DerivationMap.find(mean_dev); + if (iter == DerivationMap.end() || iter->second.empty()) + { + vector Info = {i, j, orphanCount, static_cast(mean_dev_noOrphan * 1000), increament_dev}; + DerivationMap[mean_dev].push_back(Info); + DerivationMap[mean_dev].push_back(notOrphanIndex); + DerivationMap[mean_dev].push_back(ctcPairedIndex); + DerivationMap[mean_dev].push_back(ctcOrphanPairedIndex); + break; + } + else + { + increament_dev += 1; + mean_dev += 0.001; // if the mean_dev is already in the map, increase it by 1ps + attemptCount += 1; + if (attemptCount > maxAttempts) + break; + } + } + } + } + } + // finish matching, found the minimum mean_dev in the map, extract the matching information + double min_mean_dev = std::numeric_limits::max(); + int final_i = 0; + int final_j = 0; + int gotOrphanCount = 0; + double gotMin_mean_dev_noOrphan = 0; + double increament_times = 0; + vector final_notOrphanIndex; + vector final_ctcPairedIndex; + vector final_ctcOrphanIndex; + for (const auto &minIter : DerivationMap) + { + if (minIter.first > 10 && minIter.first < min_mean_dev) + { + min_mean_dev = minIter.first; + final_i = minIter.second[0][0]; + final_j = minIter.second[0][1]; + gotOrphanCount = minIter.second[0][2]; + gotMin_mean_dev_noOrphan = static_cast(minIter.second[0][3] / 1000); + increament_times = minIter.second[0][4]; + final_notOrphanIndex = minIter.second[1]; + final_ctcPairedIndex = minIter.second[2]; + final_ctcOrphanIndex = minIter.second[3]; + } + } + + ULong64_t final_offset_ns = 0; + ULong64_t final_offset_ps_negative = 0; + if (drift == 0) + { + final_offset_ns = CTCPPS.at(final_j) - (LAPPD_PPS.at(final_i) / 1000); + final_offset_ps_negative = LAPPD_PPS.at(final_i) % 1000; + } + else + { + ULong64_t LAPPD_PPS_ns = LAPPD_PPS.at(final_i) / 1000; + ULong64_t LAPPD_PPS_truncated_ps = LAPPD_PPS.at(final_i) % 1000; + double driftScaling = static_cast(LAPPD_PPS_ns) / (trueInterval / 1000); // this is the same drift scaling as in the matching loop + ULong64_t totalDriftedClock = static_cast(drift * driftScaling / 1000); + cout< TimeStampRaw; + vector BeamGateRaw; + vector TimeStamp_ns; + vector BeamGate_ns; + vector TimeStamp_ps; + vector BeamGate_ps; + vector EventIndex; + vector EventDeviation_ns; + vector CTCTriggerIndex; + vector CTCTriggerTimeStamp_ns; + vector BeamGate_correction_tick; + vector TimeStamp_correction_tick; + vector PPS_tick_correction; // if timestamp falls in between of PPS i and i+1, corrected timestamp = timestamp + PPS_tick_correction[i] + vector LAPPD_PPS_missing_ticks; + vector LAPPD_PPS_interval_ticks; + + vector BG_PPSBefore; + vector BG_PPSAfter; + vector BG_PPSDiff; + vector BG_PPSMiss; + vector TS_PPSBefore; + vector TS_PPSAfter; + vector TS_PPSDiff; + vector TS_PPSMiss; + + vector TS_driftCorrection_ns; + vector BG_driftCorrection_ns; + + // calculate the missing ticks for each LAPPD PPS + PPS_tick_correction.push_back(0); + LAPPD_PPS_missing_ticks.push_back(0); + LAPPD_PPS_interval_ticks.push_back(0); + ULong64_t intervalTicks = 320000000 * (PPSDeltaT / 1000 / 1E9); + for (int i = 1; i < LAPPD_PPS.size(); i++) + { + ULong64_t thisPPS = LAPPD_PPS.at(i) / 3125; + ULong64_t prevPPS = LAPPD_PPS.at(i - 1) / 3125; + long long thisInterval = thisPPS - prevPPS; + long long thisMissingTicks = intervalTicks - thisInterval; + LAPPD_PPS_interval_ticks.push_back(thisInterval); + + // if the difference between this PPS and previous PPS is > intervalTicks-20 and < intervalTicks+5, + // the missed value is thisInterval - intervalTicks + // push this value plus the sum of previous missing ticks to the vector + // else just push the sum of previous missing ticks + long long sumOfPreviousMissingTicks = 0; + for (int j = 0; j < LAPPD_PPS_missing_ticks.size(); j++) + { + sumOfPreviousMissingTicks += LAPPD_PPS_missing_ticks.at(j); + } + + if (thisMissingTicks > -20 && thisMissingTicks < 20) + { + LAPPD_PPS_missing_ticks.push_back(thisMissingTicks); + PPS_tick_correction.push_back(thisMissingTicks + sumOfPreviousMissingTicks); + } + else + { + // some time one pps might be wired, but the combination of two is ok. + bool combined = false; + // if there are missing PPS, interval is like 22399999990 % 3200000000 = 3199999990 + long long pInterval = thisInterval % intervalTicks; + long long missingPTicks = 0; + if (intervalTicks - pInterval < 30) + missingPTicks = intervalTicks - pInterval; + else if (pInterval < 30) + missingPTicks = -pInterval; + ////// + if (missingPTicks == 1 || missingPTicks == -1) + { + cout << "Found missing tick is " << missingPTicks << ",continue." << endl; + LAPPD_PPS_missing_ticks.push_back(0); + PPS_tick_correction.push_back(sumOfPreviousMissingTicks); + continue; + } + + if (missingPTicks != 0) + { + LAPPD_PPS_missing_ticks.push_back(missingPTicks); + PPS_tick_correction.push_back(missingPTicks + sumOfPreviousMissingTicks); + combined = true; + cout << "Pushing PPS correction " << i << ", this PPS interval tick is " << thisInterval << ", missing ticks: " << thisMissingTicks << ", push missing " << LAPPD_PPS_missing_ticks.at(i) << ", push correction " << PPS_tick_correction.at(i) << endl; + continue; + } + + // if one PPS is not recoreded correctly, like one interval is 1574262436, followed by a 4825737559 + // then 1574262436 + 4825737559 = 6399999995 = 3200000000 * 2 - 5 + long long nextInterval = 0; + if (i < LAPPD_PPS.size() - 1) + { + nextInterval = LAPPD_PPS.at(i + 1) / 3125 - thisPPS; + long long combinedMissingTicks = intervalTicks - (nextInterval + thisInterval) % intervalTicks; + if (combinedMissingTicks > -30 && combinedMissingTicks < 30) + { + LAPPD_PPS_missing_ticks.push_back(combinedMissingTicks); + PPS_tick_correction.push_back(combinedMissingTicks + sumOfPreviousMissingTicks); + combined = true; + cout << "Pushing PPS correction " << i << ", this PPS interval tick is " << thisInterval << ", missing ticks: " << thisMissingTicks << ", push missing " << LAPPD_PPS_missing_ticks.at(i) << ", push correction " << PPS_tick_correction.at(i) << endl; + continue; + } + } + + if (!combined) + { + LAPPD_PPS_missing_ticks.push_back(0); + PPS_tick_correction.push_back(sumOfPreviousMissingTicks); + } + } + cout << "Pushing PPS correction " << i << ", this PPS interval tick is " << thisInterval << ", missing ticks: " << thisMissingTicks << ", push missing " << LAPPD_PPS_missing_ticks.at(i) << ", push correction " << PPS_tick_correction.at(i) << endl; + } + + // loop all data events, plus the offset, save the event time and beamgate time + // fing the closest CTC trigger, also save all information + cout << "Start saving results. PPS size: " << LAPPD_PPS.size() << ", beamgate size: " << LAPPDDataBeamgateUL.size() << endl; + cout << "First PPS: " << LAPPD_PPS.at(0) / 3125 << ", Last PPS: " << LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125 << endl; + cout << "First BG: " << LAPPDDataBeamgateUL.at(0) / 3125 << ", Last BG: " << LAPPDDataBeamgateUL.at(LAPPDDataBeamgateUL.size() - 1) / 3125 << endl; + cout << "First TS: " << LAPPDDataTimeStampUL.at(0) / 3125 << ", Last TS: " << LAPPDDataTimeStampUL.at(LAPPDDataTimeStampUL.size() - 1) / 3125 << endl; + + for (int l = 0; l < LAPPDDataTimeStampUL.size(); l++) + { + ULong64_t TS_ns = LAPPDDataTimeStampUL.at(l) / 1000; + ULong64_t TS_truncated_ps = LAPPDDataTimeStampUL.at(l) % 1000; + ULong64_t BG_ns = LAPPDDataBeamgateUL.at(l) / 1000; + ULong64_t BG_truncated_ps = LAPPDDataBeamgateUL.at(l) % 1000; + ULong64_t driftCorrectionForTS = 0; + ULong64_t driftCorrectionForBG = 0; + if (drift != 0) + { + + double driftScaling = static_cast(TS_ns) / (trueInterval / 1000); + driftCorrectionForTS = static_cast(drift/ 1000 * driftScaling ); + double driftScalingBG = static_cast(BG_ns) / (trueInterval / 1000); + driftCorrectionForBG = static_cast(drift/ 1000 * driftScalingBG ); + cout<<"drift = "< LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125) + { + BeamGate_correction_tick.push_back(PPS_tick_correction.at(LAPPD_PPS.size() - 1) + 1000); + cout << "BGraw = " << LAPPDDataBeamgateUL.at(l) / 3125 << ", pps = " << LAPPD_PPS.at(LAPPD_PPS.size() - 1) << ", pps/3125 = " << LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125 << endl; + BGFound = true; + } + if (!BGFound && LAPPDDataBeamgateUL.at(l) / 3125 < LAPPD_PPS.at(0) / 3125) + { + BeamGate_correction_tick.push_back(0 + 1000); + cout << "BGraw less than pps0" << endl; + BGFound = true; + } + if (!TSFound || !BGFound) + { + cout << "Error: PPS not found for event " << l << ", TSFound: " << TSFound << ", BGFound: " << BGFound << endl; + } + /* + cout << "******Found result:" << endl; + cout << "LAPPDDataTimeStampUL.at(" << l << "): " << LAPPDDataTimeStampUL.at(l)/3125 << endl; + cout << "LAPPDDataBeamgateUL.at(" << l << "): " << LAPPDDataBeamgateUL.at(l)/3125 << endl; + cout << "TS_ns: " << TS_ns << endl; + cout << "BG_ns: " << BG_ns << endl; + cout << "final_offset_ns: " << final_offset_ns << endl; + cout << "drift: " << drift << endl; + cout << "TS driftscaling: " << TS_ns / trueInterval / 1000 << endl; + cout << "DriftCorrectedTS_ns: " << DriftCorrectedTS_ns << endl; + cout << "TS_truncated_ps: " << TS_truncated_ps << endl; + cout << "DriftCorrectedBG_ns: " << DriftCorrectedBG_ns << endl; + cout << "BG_truncated_ps: " << BG_truncated_ps << endl; + cout << "Found min_mean_dev_match: " << min_mean_dev_match << endl; + cout << "MatchedIndex: " << matchedIndex << endl; + cout << "CTCTrigger.at(" << matchedIndex << "): " << CTCTrigger.at(matchedIndex) << endl; + cout << "BeamGate_correction_tick at " << l << ": " << BeamGate_correction_tick.at(l) << endl; + cout << "TimeStamp_correction_tick at " << l << ": " << TimeStamp_correction_tick.at(l) << endl; + */ + + // for this LAPPDDataBeamgateUL.at(l), in the LAPPD_PPS vector, find it's closest PPS before and after, and also calculate the time difference between them, and the missing tick between them. + // save as BG_PPSBefore_tick, BG_PPSAfter_tick, BG_PPSDiff_tick, BG_PPSMissing_tick + // Do the same thing for LAPPDDataTimeStampUL.at(l), save as TS_PPSBefore_tick, TS_PPSAfter_tick, TS_PPSDiff_tick, TS_PPSMissing_tick + + ULong64_t BG_PPSBefore_tick = 0; + ULong64_t BG_PPSAfter_tick = 0; + ULong64_t BG_PPSDiff_tick = 0; + ULong64_t BG_PPSMissing_tick = 0; + + ULong64_t TS_PPSBefore_tick = 0; + ULong64_t TS_PPSAfter_tick = 0; + ULong64_t TS_PPSDiff_tick = 0; + ULong64_t TS_PPSMissing_tick = 0; + // if the first PPS is later than beamgate, then set before = 0, after is the first, diff is the first, missing is the first + + cout << "Start finding PPS before and after the beamgate" << endl; + + if ((LAPPD_PPS.at(0) / 3125 > LAPPDDataBeamgateUL.at(l) / 3125) || (LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125 < LAPPDDataBeamgateUL.at(l) / 3125)) + { + if (LAPPD_PPS.at(0) / 3125 > LAPPDDataBeamgateUL.at(l) / 3125) + { + BG_PPSBefore_tick = 0; + BG_PPSAfter_tick = LAPPD_PPS.at(0) / 3125; + BG_PPSDiff_tick = LAPPD_PPS.at(0) / 3125; + BG_PPSMissing_tick = LAPPD_PPS.at(0) / 3125; + cout << "First PPS is later than beamgate, before is 0, after is the first, diff is the first, missing is the first" << endl; + } + // if the last PPS is earlier than beamgate, then set before is the last, after = 0, diff is the last, missing is the last + if (LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125 < LAPPDDataBeamgateUL.at(l) / 3125) + { + BG_PPSBefore_tick = LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125; + BG_PPSAfter_tick = 0; + BG_PPSDiff_tick = LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125; + BG_PPSMissing_tick = LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125; + cout << "Last PPS is earlier than beamgate, before is the last, after is 0, diff is the last, missing is the last" << endl; + } + } + else + { + // if the first PPS is earlier than beamgate, and the last PPS is later than beamgate, then find the closest PPS before and after + for (int i = 0; i < LAPPD_PPS.size() - 1; i++) + { + if (LAPPD_PPS.at(i) / 3125 < LAPPDDataBeamgateUL.at(l) / 3125 && LAPPD_PPS.at(i + 1) / 3125 > LAPPDDataBeamgateUL.at(l) / 3125) + { + BG_PPSBefore_tick = LAPPD_PPS.at(i) / 3125; + BG_PPSAfter_tick = LAPPD_PPS.at(i + 1) / 3125; + BG_PPSDiff_tick = LAPPD_PPS.at(i + 1) / 3125 - LAPPD_PPS.at(i) / 3125; + ULong64_t DiffTick = (LAPPD_PPS.at(i + 1) - LAPPD_PPS.at(i)) / 3125 - 1000; + BG_PPSMissing_tick = 3200000000 - DiffTick; + cout << "Found PPS before and after the beamgate, before: " << BG_PPSBefore_tick << ", after: " << BG_PPSAfter_tick << ", diff: " << BG_PPSDiff_tick << ", missing: " << BG_PPSMissing_tick << endl; + break; + } + } + } + + // do the samething for timestamp + cout << "Start finding PPS before and after the timestamp" << endl; + + if ((LAPPD_PPS.at(0) / 3125 > LAPPDDataTimeStampUL.at(l) / 3125) || (LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125 < LAPPDDataTimeStampUL.at(l) / 3125)) + { + if (LAPPD_PPS.at(0) / 3125 > LAPPDDataTimeStampUL.at(l) / 3125) + { + TS_PPSBefore_tick = 0; + TS_PPSAfter_tick = LAPPD_PPS.at(0) / 3125; + TS_PPSDiff_tick = LAPPD_PPS.at(0) / 3125; + TS_PPSMissing_tick = LAPPD_PPS.at(0) / 3125; + cout << "First PPS is later than timestamp, before is 0, after is the first, diff is the first, missing is the first" << endl; + } + if (LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125 < LAPPDDataTimeStampUL.at(l) / 3125) + { + TS_PPSBefore_tick = LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125; + TS_PPSAfter_tick = 0; + TS_PPSDiff_tick = LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125; + TS_PPSMissing_tick = LAPPD_PPS.at(LAPPD_PPS.size() - 1) / 3125; + cout << "Last PPS is earlier than timestamp, before is the last, after is 0, diff is the last, missing is the last" << endl; + } + } + else + { + for (int i = 0; i < LAPPD_PPS.size() - 1; i++) + { + if (LAPPD_PPS.at(i) / 3125 < LAPPDDataTimeStampUL.at(l) / 3125 && LAPPD_PPS.at(i + 1) / 3125 > LAPPDDataTimeStampUL.at(l) / 3125) + { + TS_PPSBefore_tick = LAPPD_PPS.at(i) / 3125; + TS_PPSAfter_tick = LAPPD_PPS.at(i + 1) / 3125; + TS_PPSDiff_tick = LAPPD_PPS.at(i + 1) / 3125 - LAPPD_PPS.at(i) / 3125; + ULong64_t DiffTick = (LAPPD_PPS.at(i + 1) - LAPPD_PPS.at(i)) / 3125 - 1000; + TS_PPSMissing_tick = 3200000000 - DiffTick; + cout << "Found PPS before and after the timestamp, before: " << TS_PPSBefore_tick << ", after: " << TS_PPSAfter_tick << ", diff: " << TS_PPSDiff_tick << ", missing: " << TS_PPSMissing_tick << endl; + break; + } + } + } + + TimeStampRaw.push_back(LAPPDDataTimeStampUL.at(l) / 3125); + BeamGateRaw.push_back(LAPPDDataBeamgateUL.at(l) / 3125); + TimeStamp_ns.push_back(DriftCorrectedTS_ns); + BeamGate_ns.push_back(DriftCorrectedBG_ns); + TimeStamp_ps.push_back(TS_truncated_ps); + BeamGate_ps.push_back(BG_truncated_ps); + EventIndex.push_back(l); + EventDeviation_ns.push_back(min_mean_dev_match); + // to get ps, should minus the TS_truncated_ps + CTCTriggerIndex.push_back(matchedIndex); + CTCTriggerTimeStamp_ns.push_back(CTCTrigger.at(matchedIndex)); + + BG_PPSBefore.push_back(BG_PPSBefore_tick); + BG_PPSAfter.push_back(BG_PPSAfter_tick); + BG_PPSDiff.push_back(BG_PPSDiff_tick); + BG_PPSMiss.push_back(BG_PPSMissing_tick); + TS_PPSBefore.push_back(TS_PPSBefore_tick); + TS_PPSAfter.push_back(TS_PPSAfter_tick); + TS_PPSDiff.push_back(TS_PPSDiff_tick); + TS_PPSMiss.push_back(TS_PPSMissing_tick); + + TS_driftCorrection_ns.push_back(driftCorrectionForTS); + BG_driftCorrection_ns.push_back(driftCorrectionForBG); + } + ULong64_t totalEventNumber = LAPPDDataTimeStampUL.size(); + ULong64_t gotOrphanCount_out = gotOrphanCount; + ULong64_t gotMin_mean_dev_noOrphan_out = gotMin_mean_dev_noOrphan; + ULong64_t increament_times_out = increament_times; + ULong64_t min_mean_dev_out = min_mean_dev; + ULong64_t final_i_out = final_i; + ULong64_t final_j_out = final_j; + ULong64_t drift_out = drift; + + vector FitInfo = {final_offset_ns, final_offset_ps_negative, gotOrphanCount_out, gotMin_mean_dev_noOrphan_out, increament_times_out, min_mean_dev_out, final_i_out, final_j_out, totalEventNumber, drift_out}; + + vector> Result = {FitInfo, TimeStampRaw, BeamGateRaw, TimeStamp_ns, BeamGate_ns, TimeStamp_ps, BeamGate_ps, EventIndex, EventDeviation_ns, CTCTriggerIndex, CTCTriggerTimeStamp_ns, BeamGate_correction_tick, TimeStamp_correction_tick, LAPPD_PPS_interval_ticks, BG_PPSBefore, BG_PPSAfter, BG_PPSDiff, BG_PPSMiss, TS_PPSBefore, TS_PPSAfter, TS_PPSDiff, TS_PPSMiss, TS_driftCorrection_ns, BG_driftCorrection_ns}; + return Result; +} + +vector> fitInPartFile(TTree *lappdTree, TTree *triggerTree, int runNumber, int subRunNumber, int partFileNumber, int LAPPD_ID, int fitTargetTriggerWord, bool triggerGrouped, int intervalInSecond) +{ + cout << "***************************************" << endl; + cout << "Fitting in run " << runNumber << ", sub run " << subRunNumber << ", part file " << partFileNumber << " for LAPPD ID " << LAPPD_ID << endl; + + vector LAPPD_PPS0; + vector LAPPD_PPS1; + vector LAPPDDataTimeStampUL; + vector LAPPDDataBeamgateUL; + + vector CTCTargetTimeStamp; + vector CTCPPSTimeStamp; + + int LAPPD_ID_inTree; + int runNumber_inTree; + int subRunNumber_inTree; + int partFileNumber_inTree; + + ULong64_t ppsTime0; + ULong64_t ppsTime1; + ULong64_t LAPPDTimeStampUL; + ULong64_t LAPPDBeamgateUL; + ULong64_t LAPPDDataTimestamp; + ULong64_t LAPPDDataBeamgate; + double LAPPDDataTimestampFloat; + double LAPPDDataBeamgateFloat; + + vector *CTCTriggerWord = nullptr; + ULong64_t CTCTimeStamp; + vector *groupedTriggerWords = nullptr; + vector *groupedTriggerTimestamps = nullptr; + + lappdTree->SetBranchAddress("RunNumber", &runNumber_inTree); + lappdTree->SetBranchAddress("SubRunNumber", &subRunNumber_inTree); + lappdTree->SetBranchAddress("PartFileNumber", &partFileNumber_inTree); + lappdTree->SetBranchAddress("LAPPD_ID", &LAPPD_ID_inTree); + lappdTree->SetBranchAddress("LAPPDDataTimeStampUL", &LAPPDTimeStampUL); + lappdTree->SetBranchAddress("LAPPDDataBeamgateUL", &LAPPDBeamgateUL); + lappdTree->SetBranchAddress("LAPPDDataTimestamp", &LAPPDDataTimestamp); + lappdTree->SetBranchAddress("LAPPDDataBeamgate", &LAPPDDataBeamgate); + lappdTree->SetBranchAddress("LAPPDDataTimestampFloat", &LAPPDDataTimestampFloat); + lappdTree->SetBranchAddress("LAPPDDataBeamgateFloat", &LAPPDDataBeamgateFloat); + lappdTree->SetBranchAddress("ppsTime0", &ppsTime0); + lappdTree->SetBranchAddress("ppsTime1", &ppsTime1); + + // triggerTree->Print(); + triggerTree->SetBranchAddress("RunNumber", &runNumber_inTree); + triggerTree->SetBranchAddress("SubRunNumber", &subRunNumber_inTree); + triggerTree->SetBranchAddress("PartFileNumber", &partFileNumber_inTree); + if (triggerGrouped) + { + triggerTree->SetBranchAddress("gTrigWord", &groupedTriggerWords); + triggerTree->SetBranchAddress("gTrigTime", &groupedTriggerTimestamps); + } + else + { + triggerTree->SetBranchAddress("CTCTriggerWord", &CTCTriggerWord); + triggerTree->SetBranchAddress("CTCTimeStamp", &CTCTimeStamp); + } + + int l_nEntries = lappdTree->GetEntries(); + int t_nEntries = triggerTree->GetEntries(); + int repeatedPPSNumber0 = -1; + int repeatedPPSNumber1 = -1; + + // 5. loop TimeStamp tree + for (int i = 0; i < l_nEntries; i++) + { + lappdTree->GetEntry(i); + // if(i<100) + // cout<<"LAPPD_ID_inTree: "<(LAPPDTimeStampUL * 1000 / 8 * 25) / 1E9 / 1000 << ", Beamgate: " << static_cast(LAPPDBeamgateUL * 1000 / 8 * 25) / 1E9 / 1000 << endl; + LAPPDDataTimeStampUL.push_back(LAPPDTimeStampUL * 1000 / 8 * 25); + LAPPDDataBeamgateUL.push_back(LAPPDBeamgateUL * 1000 / 8 * 25); + /* + cout << "LAPPDDataTimestamp: " << LAPPDDataTimestamp << ", LAPPDDataBeamgate: " << LAPPDDataBeamgate << endl; + cout << "LAPPDDataTimestampFloat: " << LAPPDDataTimestampFloat << ", LAPPDDataBeamgateFloat: " << LAPPDDataBeamgateFloat << endl; + ULong64_t ULTS = LAPPDTimeStampUL*1000/8*25; + double DTS = static_cast(LAPPDDataTimestamp); + double plusDTS = DTS + LAPPDDataTimestampFloat; + ULong64_t ULBG = LAPPDBeamgateUL*1000/8*25; + double DBG = static_cast(LAPPDDataBeamgate); + double plusDBG = DBG + LAPPDDataBeamgateFloat; + cout << std::fixed << " ULTS: " << ULTS << ", DTS: " << DTS << ", plusDTS: " << plusDTS << endl; + cout << std::fixed << " ULBG: " << ULBG << ", DBG: " << DBG << ", plusDBG: " << plusDBG << endl; + cout << endl; + */ + } + else if (LAPPDTimeStampUL == 0) + { + // cout << "ppsTime0: " << ppsTime0 << ", ppsTime1: " << ppsTime1 << endl; + if (LAPPD_PPS0.size() == 0) + LAPPD_PPS0.push_back(ppsTime0 * 1000 / 8 * 25); + if (LAPPD_PPS1.size() == 0) + LAPPD_PPS1.push_back(ppsTime1 * 1000 / 8 * 25); + if (LAPPD_PPS0.size() > 0 && ppsTime0 * 1000 / 8 * 25 != LAPPD_PPS0.at(LAPPD_PPS0.size() - 1)) + LAPPD_PPS0.push_back(ppsTime0 * 1000 / 8 * 25); + else + repeatedPPSNumber0 += 1; + if (LAPPD_PPS1.size() > 0 && ppsTime1 * 1000 / 8 * 25 != LAPPD_PPS1.at(LAPPD_PPS1.size() - 1)) + LAPPD_PPS1.push_back(ppsTime1 * 1000 / 8 * 25); + else + repeatedPPSNumber1 += 1; + } + } + } + cout << "repeatedPPSNumber0: " << repeatedPPSNumber0 << ", loaded PPS0 size: " << LAPPD_PPS0.size() << endl; + cout << "repeatedPPSNumber1: " << repeatedPPSNumber1 << ", loaded PPS1 size: " << LAPPD_PPS1.size() << endl; + + // 6. loop Trig (or GTrig) tree + for (int i = 0; i < t_nEntries; i++) + { + triggerTree->GetEntry(i); + if (runNumber_inTree == runNumber && subRunNumber_inTree == subRunNumber && partFileNumber_inTree == partFileNumber) + { + // cout<<"triggerGrouped: "<size(); j++) + { + // cout<<"At j = "<at(j)<<", fitTargetTriggerWord: "<at(j) == fitTargetTriggerWord) + CTCTargetTimeStamp.push_back(groupedTriggerTimestamps->at(j)); + if (groupedTriggerWords->at(j) == 32) + CTCPPSTimeStamp.push_back(groupedTriggerTimestamps->at(j)); + } + } + else + { + for (int j = 0; j < CTCTriggerWord->size(); j++) + { + if (CTCTriggerWord->at(j) == fitTargetTriggerWord) + CTCTargetTimeStamp.push_back(CTCTimeStamp); + if (CTCTriggerWord->at(j) == 32) + CTCPPSTimeStamp.push_back(CTCTimeStamp); + } + } + } + } + cout << "Vector for partfile " << partFileNumber << " for LAPPD ID " << LAPPD_ID << " loaded." << endl; + cout << "LAPPDDataTimeStampUL in ps size: " << LAPPDDataTimeStampUL.size() << endl; + cout << "LAPPDDataBeamgateUL in ps size: " << LAPPDDataBeamgateUL.size() << endl; + cout << "LAPPD_PPS0 size: " << LAPPD_PPS0.size() << endl; + cout << "LAPPD_PPS1 size: " << LAPPD_PPS1.size() << endl; + cout << "CTCTargetTimeStamp size: " << CTCTargetTimeStamp.size() << endl; + cout << "CTCPPSTimeStamp size: " << CTCPPSTimeStamp.size() << endl; + // 7. Find the number of resets in LAPPD PPS: + int LAPPDDataFitStopIndex = 0; + int resetNumber = 0; + // first check is there a reset, if no, set the LAPPDDataFitStopIndex to the size of LAPPDDataTimeStampUL + // if all PPS in this part file was increamented, then there is no reset + for (int i = 1; i < LAPPD_PPS0.size(); i++) + { + if (LAPPD_PPS0[i] < LAPPD_PPS0[i - 1]) + { + resetNumber += 1; + cout << "For LAPPD ID " << LAPPD_ID << ", run number " << runNumber << ", sub run number " << subRunNumber << ", part file number " << partFileNumber << ", reset " + << " found at PPS_ACDC0 index " << i << endl; + break; + } + } + for (int i = 1; i < LAPPD_PPS1.size(); i++) + { + if (LAPPD_PPS1[i] < LAPPD_PPS1[i - 1]) + { + resetNumber += 1; + cout << "For LAPPD ID " << LAPPD_ID << ", run number " << runNumber << ", sub run number " << subRunNumber << ", part file number " << partFileNumber << ", reset " + << " found at PPS_ACDC1 index " << i << endl; + break; + } + } + if (resetNumber == 0) + cout << "For LAPPD ID " << LAPPD_ID << ", run number " << runNumber << ", sub run number " << subRunNumber << ", part file number " << partFileNumber << ", no reset found." << endl; + + // if reset found, loop the timestamp in order to find the LAPPDDataFitStopIndex + // + if (resetNumber != 0) + { + for (int i = 1; i < LAPPDDataTimeStampUL.size(); i++) + { + if (LAPPDDataTimeStampUL[i] < LAPPDDataTimeStampUL[i - 1]) + { + LAPPDDataFitStopIndex = i - 1; + break; + } + } + // TODO: extend this to later offsets + } + // 8. Use the target trigger word, fit the offset + // TODO: fit for each reset + vector> ResultTotal; + if (LAPPDDataTimeStampUL.size() == LAPPDDataBeamgateUL.size()) + { + if (LAPPD_PPS0.size() == 0 || LAPPD_PPS1.size() == 0) + { + cout << "Error: PPS0 or PPS1 is empty, return empty result." << endl; + return ResultTotal; + } + vector> ResultACDC0 = fitInThisReset(LAPPDDataTimeStampUL, LAPPDDataBeamgateUL, LAPPD_PPS0, fitTargetTriggerWord, CTCTargetTimeStamp, CTCPPSTimeStamp, intervalInSecond * 1E9 * 1000); + vector> ResultACDC1 = fitInThisReset(LAPPDDataTimeStampUL, LAPPDDataBeamgateUL, LAPPD_PPS1, fitTargetTriggerWord, CTCTargetTimeStamp, CTCPPSTimeStamp, intervalInSecond * 1E9 * 1000); + + // 9. save the offset for this LAPPD ID, run number, part file number, index, reset number. + + cout << "Fitting in part file " << partFileNumber << " for LAPPD ID " << LAPPD_ID << " done." << endl; + + // Combine ResultACDC0 and ResultACDC1 to ResultTotal + for (int i = 0; i < ResultACDC0.size(); i++) + { + ResultTotal.push_back(ResultACDC0[i]); + } + for (int i = 0; i < ResultACDC1.size(); i++) + { + ResultTotal.push_back(ResultACDC1[i]); + } + } + return ResultTotal; +} + +void offsetFit_MultipleLAPPD(string fileName, int fitTargetTriggerWord, bool triggerGrouped, int intervalInSecond, int processPFNumber) +{ + // 1. load LAPPDTree.root + const string file = fileName; + TFile *f = new TFile(file.c_str(), "READ"); + if (!f->IsOpen()) + { + std::cerr << "Error: cannot open file " << file << std::endl; + return; + } + + std::cout << "Opened file " << file << std::endl; + + std::ofstream outputOffset("offset.txt"); + + outputOffset << "runNumber" + << "\t" + << "subRunNumber" + << "\t" + << "partFileNumber" + << "\t" + << "resetNumber" + << "\t" + << "LAPPD_ID" + << "\t" + << "offset_ACDC0_ns" + << "\t" + << "offset_ACDC1_ns" + << "\t" + << "offset_ACDC0_ps_negative" + << "\t" + << "offset_ACDC1_ps_negative" + << "\t" + << "gotOrphanCount_ACDC0" + << "\t" + << "gotOrphanCount_ACDC1" + << "\t" + << "EventNumInThisPartFile" + << "\t" + << "min_mean_dev_noOrphan_ACDC0" + << "\t" + << "min_mean_dev_noOrphan_ACDC1" + << "\t" + << "increament_times_ACDC0" + << "\t" + << "increament_times_ACDC1" + << "\t" + << "min_mean_dev_ACDC0" + << "\t" + << "min_mean_dev_ACDC1" + << std::endl; + + // 2. load TimeStamp tree, get run number and part file number + TTree *TSTree = (TTree *)f->Get("TimeStamp"); + TTree *CTCTree = (TTree *)f->Get("Trig"); + TTree *GCTCTree = (TTree *)f->Get("GTrig"); + int runNumber; + int subRunNumber; + int partFileNumber; + int LAPPD_ID; + ULong64_t ppsCount0; + TSTree->SetBranchAddress("RunNumber", &runNumber); + TSTree->SetBranchAddress("SubRunNumber", &subRunNumber); + TSTree->SetBranchAddress("PartFileNumber", &partFileNumber); + TSTree->SetBranchAddress("LAPPD_ID", &LAPPD_ID); + TSTree->SetBranchAddress("ppsCount0", &ppsCount0); + std::vector> loopInfo; + int nEntries = TSTree->GetEntries(); + for (int i = 0; i < nEntries; i++) + { + TSTree->GetEntry(i); + // if this entry is PPS event, continue. + if (ppsCount0 != 0) + continue; + vector info = {runNumber, subRunNumber, partFileNumber, LAPPD_ID}; + // find if this info is already in loopInfo + bool found = std::find_if(loopInfo.begin(), loopInfo.end(), [&info](const std::vector &vec) + { + return vec == info; // compare vec and info + }) != loopInfo.end(); // if find_if doesn't return end,found + + if (!found) + loopInfo.push_back(info); + } + + // 3. for each unique run number and part file number + // 4. in this file, for each LAPPD ID + // do fit: + std::map>> ResultMap; + std::vector>::iterator it; + int pfNumber = 0; + for (it = loopInfo.begin(); it != loopInfo.end(); it++) + { + int runNumber = (*it)[0]; + int subRunNumber = (*it)[1]; + int partFileNumber = (*it)[2]; + int LAPPD_ID = (*it)[3]; + if (processPFNumber != 0) + { + if (pfNumber >= processPFNumber) + break; + } + + vector> Result; + if (!triggerGrouped) + { // cout<<"trigger not grouped"<> Result = {FitInfo, TimeStampRaw, BeamGateRaw, TimeStamp_ns, BeamGate_ns, TimeStamp_ps, BeamGate_ps, EventIndex, EventDeviation_ns, CTCTriggerIndex, CTCTriggerTimeStamp_ns,BeamGate_correction_tick,TimeStamp_correction_tick}; + vector FitInfo = {final_offset_ns, final_offset_ps_negative, gotOrphanCount, gotMin_mean_dev_noOrphan, increament_times, min_mean_dev, final_i, final_j, totalEventNumber}; + vector TimeStampRaw; + vector BeamGateRaw; + vector TimeStamp_ns; + vector BeamGate_ns; + vector TimeStamp_ps; + vector BeamGate_ps; + vector EventIndex; + vector EventDeviation_ns; + vector CTCTriggerIndex; + vector CTCTriggerTimeStamp_ns; + vector BeamGate_correction_tick; + vector TimeStamp_correction_tick; + */ + // Loop the ResultMap, save the result to a root tree in a root file + cout << "Start saving the result to root file and txt file..." << endl; + TFile *fOut = new TFile("offsetFitResult.root", "RECREATE"); + TTree *tOut = new TTree("Events", "Events"); + int runNumber_out; + int subRunNumber_out; + int partFileNumber_out; + int LAPPD_ID_out; + ULong64_t EventIndex; + ULong64_t EventNumberInThisPartFile; + ULong64_t final_offset_ns_0; + ULong64_t final_offset_ns_1; + ULong64_t final_offset_ps_negative_0; + ULong64_t final_offset_ps_negative_1; + double drift0; + double drift1; + ULong64_t gotOrphanCount_0; + ULong64_t gotOrphanCount_1; + ULong64_t gotMin_mean_dev_noOrphan_0; + ULong64_t gotMin_mean_dev_noOrphan_1; + ULong64_t increament_times_0; + ULong64_t increament_times_1; + ULong64_t min_mean_dev_0; + ULong64_t min_mean_dev_1; + ULong64_t TimeStampRaw; + ULong64_t BeamGateRaw; + ULong64_t TimeStamp_ns; + ULong64_t BeamGate_ns; + ULong64_t TimeStamp_ps; + ULong64_t BeamGate_ps; + ULong64_t EventDeviation_ns_0; + ULong64_t EventDeviation_ns_1; + ULong64_t CTCTriggerIndex; + ULong64_t CTCTriggerTimeStamp_ns; + long long BGMinusTrigger_ns; + long long BGCorrection_tick; + long long TSCorrection_tick; + ULong64_t LAPPD_PPS_interval_ticks; + ULong64_t BG_PPSBefore_tick; + ULong64_t BG_PPSAfter_tick; + ULong64_t BG_PPSDiff_tick; + ULong64_t BG_PPSMissing_tick; + ULong64_t TS_PPSBefore_tick; + ULong64_t TS_PPSAfter_tick; + ULong64_t TS_PPSDiff_tick; + ULong64_t TS_PPSMissing_tick; + + ULong64_t TS_driftCorrection_ns; + ULong64_t BG_driftCorrection_ns; + + tOut->Branch("runNumber", &runNumber_out, "runNumber/I"); + tOut->Branch("subRunNumber", &subRunNumber_out, "subRunNumber/I"); + tOut->Branch("partFileNumber", &partFileNumber_out, "partFileNumber/I"); + tOut->Branch("LAPPD_ID", &LAPPD_ID_out, "LAPPD_ID/I"); + tOut->Branch("EventIndex", &EventIndex, "EventIndex/l"); + tOut->Branch("EventNumInThisPF", &EventNumberInThisPartFile, "EventNumInThisPF/l"); + tOut->Branch("final_offset_ns_0", &final_offset_ns_0, "final_offset_ns_0/l"); + tOut->Branch("final_offset_ns_1", &final_offset_ns_1, "final_offset_ns_1/l"); + tOut->Branch("final_offset_ps_negative_0", &final_offset_ps_negative_0, "final_offset_ps_negative_0/l"); + tOut->Branch("final_offset_ps_negative_1", &final_offset_ps_negative_1, "final_offset_ps_negative_1/l"); + tOut->Branch("drift0", &drift0, "drift0/D"); + tOut->Branch("drift1", &drift1, "drift1/D"); + tOut->Branch("gotOrphanCount_0", &gotOrphanCount_0, "gotOrphanCount_0/l"); + tOut->Branch("gotOrphanCount_1", &gotOrphanCount_1, "gotOrphanCount_1/l"); + tOut->Branch("gotMin_mean_dev_noOrphan_0", &gotMin_mean_dev_noOrphan_0, "gotMin_mean_dev_noOrphan_0/l"); + tOut->Branch("gotMin_mean_dev_noOrphan_1", &gotMin_mean_dev_noOrphan_1, "gotMin_mean_dev_noOrphan_1/l"); + tOut->Branch("increament_times_0", &increament_times_0, "increament_times_0/l"); + tOut->Branch("increament_times_1", &increament_times_1, "increament_times_1/l"); + tOut->Branch("min_mean_dev_0", &min_mean_dev_0, "min_mean_dev_0/l"); + tOut->Branch("min_mean_dev_1", &min_mean_dev_1, "min_mean_dev_1/l"); + tOut->Branch("TimeStampRaw", &TimeStampRaw, "TimeStampRaw/l"); + tOut->Branch("BeamGateRaw", &BeamGateRaw, "BeamGateRaw/l"); + tOut->Branch("TimeStamp_ns", &TimeStamp_ns, "TimeStamp_ns/l"); + tOut->Branch("BeamGate_ns", &BeamGate_ns, "BeamGate_ns/l"); + tOut->Branch("TimeStamp_ps", &TimeStamp_ps, "TimeStamp_ps/l"); + tOut->Branch("BeamGate_ps", &BeamGate_ps, "BeamGate_ps/l"); + tOut->Branch("EventDeviation_ns_0", &EventDeviation_ns_0, "EventDeviation_ns_0/l"); + tOut->Branch("EventDeviation_ns_1", &EventDeviation_ns_1, "EventDeviation_ns_1/l"); + tOut->Branch("CTCTriggerIndex", &CTCTriggerIndex, "CTCTriggerIndex/l"); + tOut->Branch("CTCTriggerTimeStamp_ns", &CTCTriggerTimeStamp_ns, "CTCTriggerTimeStamp_ns/l"); + tOut->Branch("BGMinusTrigger_ns", &BGMinusTrigger_ns, "BGMinusTrigger_ns/L"); + tOut->Branch("BGCorrection_tick", &BGCorrection_tick, "BGCorrection_tick/l"); + tOut->Branch("TSCorrection_tick", &TSCorrection_tick, "TSCorrection_tick/l"); + tOut->Branch("LAPPD_PPS_interval_ticks", &LAPPD_PPS_interval_ticks, "LAPPD_PPS_interval_ticks/l"); + tOut->Branch("BG_PPSBefore_tick", &BG_PPSBefore_tick, "BG_PPSBefore_tick/l"); + tOut->Branch("BG_PPSAfter_tick", &BG_PPSAfter_tick, "BG_PPSAfter_tick/l"); + tOut->Branch("BG_PPSDiff_tick", &BG_PPSDiff_tick, "BG_PPSDiff_tick/l"); + tOut->Branch("BG_PPSMissing_tick", &BG_PPSMissing_tick, "BG_PPSMissing_tick/l"); + tOut->Branch("TS_PPSBefore_tick", &TS_PPSBefore_tick, "TS_PPSBefore_tick/l"); + tOut->Branch("TS_PPSAfter_tick", &TS_PPSAfter_tick, "TS_PPSAfter_tick/l"); + tOut->Branch("TS_PPSDiff_tick", &TS_PPSDiff_tick, "TS_PPSDiff_tick/l"); + tOut->Branch("TS_PPSMissing_tick", &TS_PPSMissing_tick, "TS_PPSMissing_tick/l"); + tOut->Branch("TS_driftCorrection_ns", &TS_driftCorrection_ns, "TS_driftCorrection_ns/l"); + tOut->Branch("BG_driftCorrection_ns", &BG_driftCorrection_ns, "BG_driftCorrection_ns/l"); + + std::ofstream outputEvents("outputEvents.txt"); + for (auto it = ResultMap.begin(); it != ResultMap.end(); it++) + { + string key = it->first; + vector> Result = it->second; + + if (Result.size() == 0) + continue; + + runNumber_out = std::stoi(key.substr(0, key.find("_"))); + subRunNumber_out = std::stoi(key.substr(key.find("_") + 1, key.find("_", key.find("_") + 1) - key.find("_") - 1)); + partFileNumber_out = std::stoi(key.substr(key.find("_", key.find("_") + 1) + 1, key.find("_", key.find("_", key.find("_") + 1) + 1) - key.find("_", key.find("_") + 1) - 1)); + LAPPD_ID_out = std::stoi(key.substr(key.find("_", key.find("_", key.find("_") + 1) + 1) + 1, key.size() - key.find("_", key.find("_", key.find("_") + 1) + 1) - 1)); + final_offset_ns_0 = Result[0][0]; + final_offset_ns_1 = Result[24][0]; + final_offset_ps_negative_0 = Result[0][1]; + final_offset_ps_negative_1 = Result[24][1]; + gotOrphanCount_0 = Result[0][2]; + gotOrphanCount_1 = Result[24][2]; + gotMin_mean_dev_noOrphan_0 = Result[0][3]; + gotMin_mean_dev_noOrphan_1 = Result[24][3]; + increament_times_0 = Result[0][4]; + increament_times_1 = Result[24][4]; + min_mean_dev_0 = Result[0][5]; + min_mean_dev_1 = Result[24][5]; + EventNumberInThisPartFile = Result[0][8]; + drift0 = Result[0][9]; + drift1 = Result[24][9]; + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + // vector> Result = {FitInfo, TimeStampRaw, BeamGateRaw, TimeStamp_ns, BeamGate_ns, TimeStamp_ps, BeamGate_ps, EventIndex, EventDeviation_ns, CTCTriggerIndex, CTCTriggerTimeStamp_ns, BeamGate_correction_tick, TimeStamp_correction_tick, LAPPD_PPS_interval_ticks, BG_PPSBefore, BG_PPSAfter, BG_PPSDiff, BG_PPSMiss, TS_PPSBefore, TS_PPSAfter, TS_PPSDiff, TS_PPSMiss}; + // any Result[x] , if x>13, x = x + 8 + for (int j = 0; j < Result[1].size(); j++) + { + long long BGTdiff = Result[4][j] - Result[10][j] - 325250; + // cout<<"BGTDiff: "<Fill(); + } + outputOffset << runNumber_out << "\t" << subRunNumber_out << "\t" << partFileNumber_out << "\t" << 0 << "\t" << LAPPD_ID_out << "\t" << final_offset_ns_0 << "\t" << final_offset_ns_1 << "\t" << final_offset_ps_negative_0 << "\t" << final_offset_ps_negative_1 << "\t" << gotOrphanCount_0 << "\t" << gotOrphanCount_1 << "\t" << EventNumberInThisPartFile << "\t" << gotMin_mean_dev_noOrphan_0 << "\t" << gotMin_mean_dev_noOrphan_1 << "\t" << increament_times_0 << "\t" << increament_times_1 << "\t" << min_mean_dev_0 << "\t" << min_mean_dev_1 << std::endl; + } + outputOffset.close(); + fOut->cd(); + tOut->Write(); + fOut->Close(); + cout << "Result saved." << endl; +}