From d32a15dbb59ab127a1281c4a6f75b53ae9b03dcf Mon Sep 17 00:00:00 2001 From: fengyvoid Date: Sun, 19 Jan 2025 22:11:27 -0600 Subject: [PATCH] Add LAPPDLoadStore tool for EventBuildingV2 tool chain The LAPPDHit and LAPPDPulse.h are for LAPPD so they are included in this PR --- DataModel/LAPPDHit.h | 176 +- DataModel/LAPPDPulse.h | 15 + UserTools/Factory/Factory.cpp | 1 + UserTools/LAPPDLoadStore/LAPPDLoadStore.cpp | 1640 +++++++++++++++++++ UserTools/LAPPDLoadStore/LAPPDLoadStore.h | 179 ++ UserTools/LAPPDLoadStore/README.md | 20 + UserTools/Unity.h | 1 + 7 files changed, 1971 insertions(+), 61 deletions(-) create mode 100644 UserTools/LAPPDLoadStore/LAPPDLoadStore.cpp create mode 100644 UserTools/LAPPDLoadStore/LAPPDLoadStore.h create mode 100644 UserTools/LAPPDLoadStore/README.md diff --git a/DataModel/LAPPDHit.h b/DataModel/LAPPDHit.h index d125bc46f..251ac38b8 100755 --- a/DataModel/LAPPDHit.h +++ b/DataModel/LAPPDHit.h @@ -2,100 +2,154 @@ #ifndef LAPPDHITCLASS_H #define LAPPDHITCLASS_H -#include -#include +#include +#include "LAPPDPulse.h" +#include using std::cout; using std::endl; -class LAPPDHit : public Hit{ - +class LAPPDHit : public Hit +{ + friend class boost::serialization::access; - - public: - LAPPDHit() : Hit(), Position(0), LocalPosition(0) {serialise=true;} - LAPPDHit(int thetubeid, double thetime, double thecharge, std::vector theposition, std::vector thelocalposition) : Hit(thetubeid,thetime,thecharge), Position(theposition), LocalPosition(thelocalposition) {serialise=true;} + +public: + LAPPDHit() : Hit(), Position(0), LocalPosition(0) { serialise = true; } + LAPPDHit(int thetubeid, double thetime, double thecharge, std::vector theposition, std::vector thelocalposition) : Hit(thetubeid, thetime, thecharge), Position(theposition), LocalPosition(thelocalposition) { serialise = true; } + LAPPDHit(int thetubeid, double thetime, double thecharge, std::vector theposition, std::vector thelocalposition, double pulse1LastTime, double pulse2LastTime, double pulse1StartTime, double pulse2StartTime) : Hit(thetubeid, thetime, thecharge), Position(theposition), LocalPosition(thelocalposition) + { + serialise = true; + Pulse1LastTime = pulse1LastTime; + Pulse2LastTime = pulse2LastTime; + Pulse1StartTime = pulse1StartTime; + Pulse2StartTime = pulse2StartTime; + } + LAPPDHit(int thetubeid, double thetime, double thecharge, std::vector theposition, std::vector thelocalposition, double pulse1LastTime, double pulse2LastTime, double pulse1StartTime, double pulse2StartTime, LAPPDPulse p1, LAPPDPulse p2) : Hit(thetubeid, thetime, thecharge), Position(theposition), LocalPosition(thelocalposition) + { + serialise = true; + Pulse1LastTime = pulse1LastTime; + Pulse2LastTime = pulse2LastTime; + Pulse1StartTime = pulse1StartTime; + Pulse2StartTime = pulse2StartTime; + pulse1 = p1; + pulse2 = p2; + } + virtual ~LAPPDHit(){}; - - inline std::vector GetPosition() const {return Position;} - inline std::vector GetLocalPosition() const {return LocalPosition;} - inline void SetPosition(std::vector pos){Position=pos;} - inline void SetLocalPosition(std::vector locpos){LocalPosition=locpos;} - - bool Print() { - cout<<"TubeId : "< GetPosition() const { return Position; } + inline std::vector GetLocalPosition() const { return LocalPosition; } + inline void SetPosition(std::vector pos) { Position = pos; } + inline void SetLocalPosition(std::vector locpos) { LocalPosition = locpos; } + inline double GetPulse1LastTime() const { return Pulse1LastTime; } + inline double GetPulse2LastTime() const { return Pulse2LastTime; } + inline double GetPulse1StartTime() const { return Pulse1StartTime; } + inline double GetPulse2StartTime() const { return Pulse2StartTime; } + inline LAPPDPulse GetPulse1() const { return pulse1; } + inline LAPPDPulse GetPulse2() const { return pulse2; } + + bool Print() + { + cout << "TubeId : " << TubeId << endl; + cout << "Time : " << Time << endl; + cout << "X Pos : " << Position.at(0) << endl; + cout << "Y Pos : " << Position.at(1) << endl; + cout << "Z Pos : " << Position.at(2) << endl; + cout << "Parallel Pos : " << LocalPosition.at(0) << endl; + cout << "Transverse Pos : " << LocalPosition.at(1) << endl; + cout << "Charge : " << Charge << endl; return true; } - - protected: + +protected: std::vector Position; std::vector LocalPosition; - - template void serialize(Archive & ar, const unsigned int version){ - if(serialise){ + double Pulse1LastTime; + double Pulse2LastTime; + double Pulse1StartTime; + double Pulse2StartTime; + LAPPDPulse pulse1; + LAPPDPulse pulse2; + + template + void serialize(Archive &ar, const unsigned int version) + { + if (serialise) + { ar & TubeId; ar & Time; ar & Position; ar & LocalPosition; ar & Charge; + + ar & Pulse1LastTime; + ar & Pulse2LastTime; + ar & Pulse1StartTime; + ar & Pulse2StartTime; + ar & pulse1; + ar & pulse2; } } }; // Derived classes -class MCLAPPDHit : public LAPPDHit{ - +class MCLAPPDHit : public LAPPDHit +{ + friend class boost::serialization::access; - - public: - MCLAPPDHit() : LAPPDHit(), Parents(std::vector{}) {serialise=true;} - MCLAPPDHit(int thetubeid, double thetime, double thecharge, std::vector theposition, std::vector thelocalposition, std::vector theparents) : LAPPDHit(thetubeid, thetime, thecharge,theposition,thelocalposition), Parents(theparents) {serialise=true;} - - const std::vector* GetParents() const { return &Parents; } - void SetParents(std::vector parentsin){ Parents = parentsin; } - - bool Print() { - cout<<"TubeId : "<{}) { serialise = true; } + MCLAPPDHit(int thetubeid, double thetime, double thecharge, std::vector theposition, std::vector thelocalposition, std::vector theparents) : LAPPDHit(thetubeid, thetime, thecharge, theposition, thelocalposition), Parents(theparents) { serialise = true; } + + const std::vector *GetParents() const { return &Parents; } + void SetParents(std::vector parentsin) { Parents = parentsin; } + + bool Print() + { + cout << "TubeId : " << TubeId << endl; + cout << "Time : " << Time << endl; + cout << "X Pos : " << Position.at(0) << endl; + cout << "Y Pos : " << Position.at(1) << endl; + cout << "Z Pos : " << Position.at(2) << endl; + cout << "Parallel Pos : " << LocalPosition.at(0) << endl; + cout << "Transverse Pos : " << LocalPosition.at(1) << endl; + cout << "Charge : " << Charge << endl; + if (Parents.size()) + { + cout << "Parent MCPartice indices: {"; + for (int parenti = 0; parenti < (int)Parents.size(); ++parenti) + { + cout << Parents.at(parenti); + if ((parenti + 1) < (int)Parents.size()) + cout << ", "; } - cout<<"}"< void serialize(Archive & ar, const unsigned int version){ - if(serialise){ + + template + void serialize(Archive &ar, const unsigned int version) + { + if (serialise) + { ar & TubeId; ar & Time; ar & Position; ar & LocalPosition; ar & Charge; // n.b. at time of writing MCHit stores no additional persistent members - // - it only adds parent MCParticle indices, and these aren't saved... + // - it only adds parent MCParticle indices, and these aren't saved... } } - - protected: + +protected: std::vector Parents; }; diff --git a/DataModel/LAPPDPulse.h b/DataModel/LAPPDPulse.h index e18dfcfa5..8aff68195 100755 --- a/DataModel/LAPPDPulse.h +++ b/DataModel/LAPPDPulse.h @@ -22,12 +22,20 @@ class LAPPDPulse : public Hit{ inline void SetChannelID(int channelid){ChannelID=channelid;} inline void SetPeak(double peak){Peak=peak;} inline void SetRange(double low, double hi){LowRange=low; HiRange=hi;} + inline void SetHalfHeightTime(double half){halfHeightTime=half;} + inline double GetHalfHeightTime(){return halfHeightTime;} + inline void SetHalfEndTime(double half){halfEndTime=half;} + inline double GetHalfEndTime(){return halfEndTime;} + inline void SetBaseline(double base){baseline=base;} + inline double GetBaseline(){return baseline;} bool Print() { cout<<"TubeId : "< void serialize(Archive & ar, const unsigned int version){ @@ -47,6 +59,9 @@ class LAPPDPulse : public Hit{ ar & Peak; ar & LowRange; ar & HiRange; + ar & halfHeightTime; + ar & halfEndTime; + ar & baseline; } } }; diff --git a/UserTools/Factory/Factory.cpp b/UserTools/Factory/Factory.cpp index c986c48b7..2a4a1fb6a 100644 --- a/UserTools/Factory/Factory.cpp +++ b/UserTools/Factory/Factory.cpp @@ -174,5 +174,6 @@ 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=="LAPPDLoadStore") ret=new LAPPDLoadStore; return ret; } diff --git a/UserTools/LAPPDLoadStore/LAPPDLoadStore.cpp b/UserTools/LAPPDLoadStore/LAPPDLoadStore.cpp new file mode 100644 index 000000000..d41d16ab3 --- /dev/null +++ b/UserTools/LAPPDLoadStore/LAPPDLoadStore.cpp @@ -0,0 +1,1640 @@ +#include "LAPPDLoadStore.h" + +LAPPDLoadStore::LAPPDLoadStore() : Tool() {} + +bool LAPPDLoadStore::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 + retval = 0; + eventNo = 0; + CLOCK_to_NSEC = 3.125; // 3.125 ns per clock cycle + errorEventsNumber = 0; + // Control variables that you get from the config file, for this tool + m_variables.Get("ReadStore", ReadStore); + m_variables.Get("Nboards", Nboards); + m_variables.Get("StorePedinputfile", PedFileName); + m_variables.Get("PedinputfileTXT", PedFileNameTXT); + m_variables.Get("DoPedSubtraction", DoPedSubtract); + m_variables.Get("LAPPDStoreReadInVerbosity", LAPPDStoreReadInVerbosity); + m_variables.Get("num_vector_data", num_vector_data); + m_variables.Get("num_vector_pps", num_vector_pps); + m_variables.Get("SelectSingleLAPPD", SelectSingleLAPPD); + m_variables.Get("SelectedLAPPD", SelectedLAPPD); + mergingModeReadIn = false; + m_variables.Get("mergingModeReadIn", mergingModeReadIn); + ReadStorePdeFile = false; + m_variables.Get("ReadStorePdeFile", ReadStorePdeFile); + MultiLAPPDMap = false; + m_variables.Get("MultiLAPPDMap", MultiLAPPDMap); + loadPSEC = true; + m_variables.Get("loadPSEC", loadPSEC); + loadPPS = false; + m_variables.Get("loadPPS", loadPPS); + loadOffsets = false; + m_variables.Get("loadOffsets", loadOffsets); + LoadBuiltPPSInfo = true; + m_variables.Get("LoadBuiltPPSInfo", LoadBuiltPPSInfo); + loadFromStoreDirectly = false; + m_variables.Get("loadFromStoreDirectly", loadFromStoreDirectly); + // Control variables in this tool, initialized in this tool + NonEmptyEvents = 0; + NonEmptyDataEvents = 0; + PPSnumber = 0; + mergedEvent = false; + isFiltered = false; + isBLsub = false; + isCFD = false; + // Global Control variables that you get from the config file + m_variables.Get("stopEntries", stopEntries); + m_variables.Get("PsecReceiveMode", PsecReceiveMode); + m_variables.Get("RawDataOutputWavLabel", OutputWavLabel); + m_variables.Get("RawDataInputWavLabel", InputWavLabel); + m_variables.Get("NChannels", NChannels); + m_variables.Get("Nsamples", Nsamples); + m_variables.Get("TrigChannel", TrigChannel); + m_variables.Get("SampleSize", SampleSize); + m_variables.Get("LAPPDchannelOffset", LAPPDchannelOffset); + // Data variables + // Data variables you get from other tools (it not initialized in execute) + // Data variables you use in this tool + m_variables.Get("PSECinputfile", NewFileName); + // Verbosity + // Details on channels, samples and max vector sizes and trigger channel + m_variables.Get("Nsamples", Nsamples); + m_variables.Get("TrigChannel", TrigChannel); + + runNumber = 0; + subRunNumber = 0; + partFileNumber = 0; + eventNumberInPF = 0; + + ReadStore = 0; + + // get data file + /* + if (ReadStore == 1) + { + // get data from a StoreFile in ANNIEEvent format + m_data->Stores["ANNIEEvent"] = new BoostStore(false, 2); + m_data->Stores["ANNIEEvent"]->Initialise(NewFileName); + cout << "LAPPDStoreReadIn Reading new ANNIEevent from " << NewFileName << endl; + } + else if (ReadStore == 0) + { // get data from previous chain, or m_data + cout << "LAPPDStoreReadIn Using ANNIEevent or CStore" << endl; + }*/ + // Grab all pedestal files and prepare the map channel|pedestal-vector for substraction + if (DoPedSubtract == 1) + { + PedestalValues = new std::map>; + /*if (ReadStorePdeFile) + { + m_data->Stores["PedestalFile"] = new BoostStore(false, 2); + bool ret = false; + if (FILE *file = fopen(PedFileName.c_str(), "r")) + { + fclose(file); + ret = true; + cout << "Using Store Pedestal File" << endl; + } + if (ret) + { + m_data->Stores["PedestalFile"]->Initialise(PedFileName); + long Pedentries; + m_data->Stores["PedestalFile"]->Header->Get("TotalEntries", Pedentries); + if (LAPPDStoreReadInVerbosity > 0) + cout << PedFileName << " got " << Pedentries << endl; + m_data->Stores["PedestalFile"]->Get("PedestalMap", PedestalValues); + } + } + else*/ + { + for (int i = 0; i < Nboards; i++) + { + if (LAPPDStoreReadInVerbosity > 0) + cout << "Reading Pedestal File " << PedFileNameTXT << " " << i << endl; + ReadPedestals(i); + } + } + if (LAPPDStoreReadInVerbosity > 0) + cout << "PEDSIZES: " << PedestalValues->size() << " " << PedestalValues->at(0).size() << " " << PedestalValues->at(4).at(5) << endl; + } + + // set some control variables for later tools + m_data->CStore.Set("SelectSingleLAPPD", SelectSingleLAPPD); + 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_data->Stores["ANNIEEvent"]->Set("isFiltered", isFiltered); + m_data->Stores["ANNIEEvent"]->Set("isBLsubtracted", isBLsub); + m_data->Stores["ANNIEEvent"]->Set("isCFD", isCFD); + + LAPPDEventIndex_ID = {0, 0, 0, 0, 0}; // initialize for five LAPPDs + if (loadOffsets) + LoadOffsetsAndCorrections(); + if (LAPPDStoreReadInVerbosity > 11) + debugStoreReadIn.open("debugStoreReadIn.txt"); + + return true; +} + +void LAPPDLoadStore::CleanDataObjects() +{ + LAPPD_ID = -9999; + Raw_buffer.clear(); + Parse_buffer.clear(); + ReadBoards.clear(); + data.clear(); + meta.clear(); + pps.clear(); + LAPPDWaveforms.clear(); + EventType = -9999; + LAPPDana = false; + ParaBoards.clear(); + meta.clear(); + LAPPDWaveforms.clear(); + data.clear(); + Parse_buffer.clear(); + // LAPPDDataMap.clear(); + // DataStreams.clear(); + runInfoLoaded = false; + + LAPPD_IDs.clear(); + LAPPDLoadedTimeStampsRaw.clear(); + LAPPDLoadedBeamgatesRaw.clear(); + LAPPDLoadedOffsets.clear(); + LAPPDLoadedTSCorrections.clear(); + LAPPDLoadedBGCorrections.clear(); + LAPPDLoadedOSInMinusPS.clear(); +} + +bool LAPPDLoadStore::Execute() +{ + // 1. clean data variables + // 2. decide loading data or not, load the data from PsecData dat to tool + // 3. parse and pass data to later tools + + CleanDataObjects(); + m_data->CStore.Set("LAPPD_new_event", false); + + if (MultiLAPPDMap) + { + bool gotDataStream = m_data->Stores["ANNIEEvent"]->Get("DataStreams", DataStreams); + bool getMap = m_data->Stores["ANNIEEvent"]->Get("LAPPDDataMap", LAPPDDataMap); + if (getMap && DataStreams["LAPPD"] == true && LAPPDDataMap.size() > 0) + { + // cout << "Outside, size of LAPPDDatamap = " << LAPPDDataMap.size() << endl; + 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 (LoadBuiltPPSInfo) + { + bool gotBG_PPSBefore = m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + bool gotBG_PPSAfter = m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + bool gotBG_PPSDiff = m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + bool gotBG_PPSMissing = m_data->Stores["ANNIEEvent"]->Get("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + bool gotTS_PPSBefore = m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + bool gotTS_PPSAfter = m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + bool gotTS_PPSDiff = m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + bool gotTS_PPSMissing = m_data->Stores["ANNIEEvent"]->Get("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + if (LAPPDStoreReadInVerbosity > 3) + { + cout << "LAPPDLoadStore: gotOffsets = " << gotOffsets << ", gotBG_PPSBefore = " << gotBG_PPSBefore << ", gotTS_PPSBefore = " << gotTS_PPSBefore << endl; + cout << "Size of LAPPDDataMap = " << LAPPDDataMap.size() << ", LAPPDOffsets = " << LAPPDOffsets.size() << ", LAPPDBG_PPSBefore = " << LAPPDBG_PPSBefore.size() << ", LAPPDTS_PPSBefore = " << LAPPDTS_PPSBefore.size() << endl; + + cout << "gotBG_PPSBefore = " << gotBG_PPSBefore << ", gotBG_PPSAfter = " << gotBG_PPSAfter << ", gotBG_PPSDiff = " << gotBG_PPSDiff << ", gotBG_PPSMissing = " << gotBG_PPSMissing << endl; + cout << "gotTS_PPSBefore = " << gotTS_PPSBefore << ", gotTS_PPSAfter = " << gotTS_PPSAfter << ", gotTS_PPSDiff = " << gotTS_PPSDiff << ", gotTS_PPSMissing = " << gotTS_PPSMissing << endl; + } + } + } + else + { + return true; + } + } + + // decide loading data or not, set to LAPPDana for later tools + LAPPDana = LoadData(); + m_data->CStore.Set("LAPPDana", LAPPDana); + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDana for loading was set to " << LAPPDana << endl; + if (!LAPPDana) + { + // not loading data, return + return true; + } + + if (!MultiLAPPDMap) + { + // parse and pass data to later tools + int frametype = static_cast(Raw_buffer.size() / ReadBoards.size()); + if (frametype != num_vector_data && frametype != num_vector_pps) + { + cout << "Problem identifying the frametype, size of raw vector was " << Raw_buffer.size() << endl; + cout << "It was expected to be either " << num_vector_data * ReadBoards.size() << " or " << num_vector_pps * ReadBoards.size() << endl; + cout << "Please check manually!" << endl; + LAPPDana = false; + m_data->CStore.Set("LAPPDana", LAPPDana); + m_data->CStore.Set("LAPPDPPShere", LAPPDana); + return true; + } + + if (frametype == num_vector_pps && loadPPS) + { + // if it's PPS, don't to anything relate to merging + m_data->CStore.Set("LAPPDanaData", false); + // set LAPPDana to false + LAPPDana = false; + m_data->CStore.Set("LAPPDana", LAPPDana); + ParsePPSData(); + m_data->CStore.Set("LAPPD_ID", LAPPD_ID); + m_data->Stores["ANNIEEvent"]->Set("LAPPD_ID", LAPPD_ID); + m_data->CStore.Set("LoadingPPS", true); + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn: PPS data loaded, LAPPDanaData is false, set LAPPDana to false" << endl; + return true; + } + + if (frametype == num_vector_data && loadPSEC) + { + m_data->CStore.Set("LAPPDanaData", true); + bool parsData = ParsePSECData(); + LoadRunInfo(); + runInfoLoaded = true; + LAPPDana = parsData; + m_data->CStore.Set("LAPPDana", LAPPDana); + m_data->CStore.Set("LoadingPPS", false); + + if (!parsData) + { + cout << "LAPPDStoreReadIn: PSEC data parsing failed, set LAPPDana to false and return" << endl; + + return true; + } + NonEmptyDataEvents += 1; + } + + // parsing finished, do pedestal subtraction + DoPedestalSubtract(); + // save some timestamps relate to this event, for later using + SaveTimeStamps(); + + vector ReadedBoards; + vector ACDCReadedLAPPDID; + for (auto it = ReadBoards.begin(); it != ReadBoards.end(); it++) + { + ReadedBoards.push_back(*it); + ACDCReadedLAPPDID.push_back(LAPPD_ID); + // cout << "ReadedBoards loaded with " << *it << endl; + } + + if (LAPPDStoreReadInVerbosity > 0) + cout << "*************************END LAPPDStoreReadIn************************************" << endl; + m_data->CStore.Set("LAPPD_ID", LAPPD_ID); + m_data->Stores["ANNIEEvent"]->Set("LAPPD_ID", LAPPD_ID); + m_data->Stores["ANNIEEvent"]->Set("RawLAPPDData", LAPPDWaveforms); // leave this only for the merger tool + m_data->Stores["ANNIEEvent"]->Set("MergeLAPPDPsec", LAPPDWaveforms); + m_data->Stores["ANNIEEvent"]->Set("ACDCmetadata", meta); + m_data->Stores["ANNIEEvent"]->Set("ACDCboards", ReadBoards); + m_data->Stores["ANNIEEvent"]->Set("SortedBoards", ParaBoards); + m_data->Stores["ANNIEEvent"]->Set("TriggerChannelBase", TrigChannel); + m_data->Stores["ANNIEEvent"]->Set("ACDCReadedLAPPDID", ACDCReadedLAPPDID); + m_data->Stores["ANNIEEvent"]->Set("ReadedBoards", ReadedBoards); + + m_data->CStore.Set("NewLAPPDDataAvailable", true); + if (LAPPDStoreReadInVerbosity > 11) + debugStoreReadIn << " Set NewLAPPDDataAvailable to true" << endl; + + NonEmptyEvents += 1; + eventNo++; + if (LAPPDStoreReadInVerbosity > 2) + { + cout << "Finish LAPPDStoreReadIn, Printing the ANNIEEvent" << endl; + m_data->Stores["ANNIEEvent"]->Print(false); + } + } + else + { + // if we are reading multiple LAPPD data from one ANNIEEvent + // assume we only have PSEC data in ANNIEEvent, no PPS event. + // loop the map, for each PSEC data, do the same loading and parsing. + // load the waveform by using LAPPD_ID * board_number * channel_number as the key + + // data was already loaded in the LoadData() + + vector ReadedBoards; + vector ACDCReadedLAPPDID; + + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn: LAPPDDataMap has " << LAPPDDataMap.size() << " LAPPD PSEC data " << endl; + bool ValidDataLoaded = false; + std::map::iterator it; + for (it = LAPPDDataMap.begin(); it != LAPPDDataMap.end(); it++) + { + ParaBoards.clear(); + uint64_t time = it->first; + PsecData dat = it->second; + ReadBoards = dat.BoardIndex; // From the data, board index is not related to the LAPPD_ID! WHY use this way? + Raw_buffer = dat.RawWaveform; + LAPPD_ID = dat.LAPPD_ID; + if (LAPPD_ID != SelectedLAPPD && SelectSingleLAPPD) + continue; + + if (Raw_buffer.size() == 0 || ReadBoards.size() == 0) + { + m_data->CStore.Set("LAPPDana", false); + cout << "LAPPD Load Store, find Raw buffer size == 0 or ReadBoards size == 0" << endl; + continue; + // return true; + } + + if (LAPPDStoreReadInVerbosity > 0) + { + // print ReadBoards + cout << "LAPPD ID " << LAPPD_ID << " ReadBoards size is " << ReadBoards.size() << ", data: " << endl; + for (auto it = ReadBoards.begin(); it != ReadBoards.end(); it++) + { + cout << ", " << *it; + } + cout << endl; + } + + // push all elements in ReadBoards to ReadedBoards + for (auto it = ReadBoards.begin(); it != ReadBoards.end(); it++) + { + ReadedBoards.push_back(*it); + ACDCReadedLAPPDID.push_back(LAPPD_ID); + // cout << "ReadedBoards loaded with " << *it << endl; + } + + int frametype = static_cast(Raw_buffer.size() / ReadBoards.size()); + if (frametype != num_vector_data) + { + cout << "LAPPDStoreReadIn: For LAPPD_ID " << LAPPD_ID << " frametype is not num_vector_data, skip this LAPPD" << endl; + continue; + } + m_data->CStore.Set("LAPPDanaData", true); + if (LAPPDStoreReadInVerbosity > 3) + { + cout << "Before parsing data, printing size and element in ReadBoards, ReadedBoards, ParaBoards" << endl; + cout << "ReadBoards size is " << ReadBoards.size() << endl; + for (auto it = ReadBoards.begin(); it != ReadBoards.end(); it++) + { + cout << ", " << *it; + } + cout << endl; + cout << "ReadedBoards size is " << ReadedBoards.size() << endl; + for (auto it = ReadedBoards.begin(); it != ReadedBoards.end(); it++) + { + cout << ", " << *it; + } + cout << endl; + cout << "ParaBoards size is " << ParaBoards.size() << endl; + for (auto it = ParaBoards.begin(); it != ParaBoards.end(); it++) + { + cout << ", " << *it; + } + cout << endl; + } + bool parsData = ParsePSECData(); // TODO: now assuming all boards just has 30 channels. Need to be changed for gen 2 + if (parsData) + { + ValidDataLoaded = true; + if (LAPPDStoreReadInVerbosity > 2) + cout << "LAPPDLoadStore: Loaded LAPPD data for LAPPD_ID " << LAPPD_ID << " at time " << time << endl; + LAPPDLoadedTimeStamps.push_back(time); + LAPPD_IDs.push_back(LAPPD_ID); + // print the size of LAPPDTimeStampsRaw, print all keys in it + if (LAPPDStoreReadInVerbosity > 0) + { + cout << "LAPPDTimeStampsRaw size is " << LAPPDTimeStampsRaw.size() << endl; + for (auto it = LAPPDTimeStampsRaw.begin(); it != LAPPDTimeStampsRaw.end(); it++) + { + cout << "LAPPDTimeStampsRaw key is " << it->first << endl; + } + } + // print the size of LAPPDOffsets, print all keys in it + if (LAPPDStoreReadInVerbosity > 0) + { + cout << "LAPPDOffsets size is " << LAPPDOffsets.size() << endl; + for (auto it = LAPPDOffsets.begin(); it != LAPPDOffsets.end(); it++) + { + cout << "LAPPDOffsets key is " << it->first << endl; + } + } + + LAPPDLoadedTimeStampsRaw.push_back(LAPPDTimeStampsRaw.at(time)); + LAPPDLoadedBeamgatesRaw.push_back(LAPPDBeamgatesRaw.at(time)); + LAPPDLoadedOffsets.push_back(LAPPDOffsets.at(time)); + LAPPDLoadedTSCorrections.push_back(LAPPDTSCorrection.at(time)); + LAPPDLoadedBGCorrections.push_back(LAPPDBGCorrection.at(time)); + LAPPDLoadedOSInMinusPS.push_back(LAPPDOSInMinusPS.at(time)); + + if (LAPPDStoreReadInVerbosity > 2) + cout << "parsing finished for LAPPD_ID " << LAPPD_ID << " at time " << time << endl; + + if (LoadBuiltPPSInfo) + { + LAPPDLoadedBG_PPSBefore.push_back(LAPPDBG_PPSBefore.at(time)); + LAPPDLoadedBG_PPSAfter.push_back(LAPPDBG_PPSAfter.at(time)); + LAPPDLoadedBG_PPSDiff.push_back(LAPPDBG_PPSDiff.at(time)); + LAPPDLoadedBG_PPSMissing.push_back(LAPPDBG_PPSMissing.at(time)); + LAPPDLoadedTS_PPSBefore.push_back(LAPPDTS_PPSBefore.at(time)); + LAPPDLoadedTS_PPSAfter.push_back(LAPPDTS_PPSAfter.at(time)); + LAPPDLoadedTS_PPSDiff.push_back(LAPPDTS_PPSDiff.at(time)); + LAPPDLoadedTS_PPSMissing.push_back(LAPPDTS_PPSMissing.at(time)); + + if (LAPPDTS_PPSMissing.at(time) != LAPPDBG_PPSMissing.at(time) && ((LAPPDTS_PPSMissing.at(time) > -100 && LAPPDTS_PPSMissing.at(time) < 100) || (LAPPDBG_PPSMissing.at(time) > -100 && LAPPDBG_PPSMissing.at(time) < 100))) + { + cout << "LAPPDLoadStore: PPS missing number is not the same on BG and TS for LAPPD_ID " << LAPPD_ID << " at time " << time << ", BG: " << LAPPDBG_PPSMissing.at(time) << ", TS: " << LAPPDTS_PPSMissing.at(time) << endl; + cout << "LAPPDLoadStore: BG_PPSDiff: " << LAPPDBG_PPSDiff.at(time) << ", TS_PPSDiff: " << LAPPDTS_PPSDiff.at(time) << endl; + } + } + } + NonEmptyEvents += 1; + NonEmptyDataEvents += 1; + } + eventNo++; + LAPPDana = ValidDataLoaded; + m_data->CStore.Set("LAPPDana", LAPPDana); + DoPedestalSubtract(); + + m_data->Stores["ANNIEEvent"]->Set("RawLAPPDData", LAPPDWaveforms); // leave this only for the merger tool + m_data->Stores["ANNIEEvent"]->Set("LAPPD_IDs", LAPPD_IDs); + m_data->Stores["ANNIEEvent"]->Set("LAPPDLoadedTimeStamps", LAPPDLoadedTimeStamps); + m_data->Stores["ANNIEEvent"]->Set("ACDCboards", ReadedBoards); + m_data->Stores["ANNIEEvent"]->Set("ACDCReadedLAPPDID", ACDCReadedLAPPDID); + m_data->Stores["ANNIEEvent"]->Set("ACDCmetadata", meta); + + m_data->Stores["ANNIEEvent"]->Set("LAPPDDataMap", LAPPDDataMap); + + m_data->Stores["ANNIEEvent"]->Set("LAPPDBeamgate_ns", LAPPDBeamgate_ns); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTimeStamps_ns", LAPPDTimeStamps_ns); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTimeStampsRaw", LAPPDTimeStampsRaw); + m_data->Stores["ANNIEEvent"]->Set("LAPPDBeamgatesRaw", LAPPDBeamgatesRaw); + m_data->Stores["ANNIEEvent"]->Set("LAPPDOffsets", LAPPDOffsets); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTSCorrection", LAPPDTSCorrection); + m_data->Stores["ANNIEEvent"]->Set("LAPPDBGCorrection", LAPPDBGCorrection); + m_data->Stores["ANNIEEvent"]->Set("LAPPDOSInMinusPS", LAPPDOSInMinusPS); + if (LoadBuiltPPSInfo) + { + m_data->Stores["ANNIEEvent"]->Set("LAPPDBG_PPSBefore", LAPPDBG_PPSBefore); + m_data->Stores["ANNIEEvent"]->Set("LAPPDBG_PPSAfter", LAPPDBG_PPSAfter); + m_data->Stores["ANNIEEvent"]->Set("LAPPDBG_PPSDiff", LAPPDBG_PPSDiff); + m_data->Stores["ANNIEEvent"]->Set("LAPPDBG_PPSMissing", LAPPDBG_PPSMissing); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTS_PPSBefore", LAPPDTS_PPSBefore); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTS_PPSAfter", LAPPDTS_PPSAfter); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTS_PPSDiff", LAPPDTS_PPSDiff); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTS_PPSMissing", LAPPDTS_PPSMissing); + } + // TODO: save other timestamps, variables and metadata for later use + + if (eventNo % 100 == 0) + { + cout << "LAPPDLoadStore: Loaded " << eventNo << " events, " << NonEmptyDataEvents << " non empty LAPPD PSEC data loaded from all LAPPDs" << endl; + } + } + + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDLoadStore: Finished loading LAPPD data" << endl; + + return true; +} + +bool LAPPDLoadStore::Finalise() +{ + cout << "\033[1;34mLAPPDLoadStore: Finalising\033[0m" << endl; + cout << "LAPPDLoadStore: Got pps event in total: " << PPSnumber << endl; + cout << "LAPPDLoadStore: Got error data or PPS events in total: " << errorEventsNumber << endl; + cout << "LAPPDLoadStore: Got non empty data and PPS events in total: " << NonEmptyEvents << endl; + cout << "LAPPDLoadStore: Got non empty data events in total: " << NonEmptyDataEvents << endl; + cout << "LAPPDLoadStore: End at event number: " << eventNo << endl; + return true; +} + +bool LAPPDLoadStore::ReadPedestals(int boardNo) +{ + + if (LAPPDStoreReadInVerbosity > 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; + PedFile.open(LoadName); // final name: PedFileNameTXT + boardNo + .txt + if (!PedFile.is_open()) + { + cout << "Failed to open " << LoadName << "!" << endl; + return false; + } + if (LAPPDStoreReadInVerbosity > 0) + cout << "Opened 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++; + int tempValue = stoi(stempValue, 0, 10); + if (sampleNo == 0) + { + vector tempPed; + tempPed.push_back(tempValue); + // cout<<"First time: "<insert(pair>(channelNo, tempPed)); + if (LAPPDStoreReadInVerbosity > 0) + cout << "Inserting pedestal at channelNo " << channelNo << endl; + // newboard=false; + } + else + { + // cout<<"Following time: "<count(channelNo)<find(channelNo))->second)).push_back(tempValue); + } + + channelNo++; + } + sampleNo++; + } + if (LAPPDStoreReadInVerbosity > 0) + cout << "FINAL SAMPLE NUMBER: " << PedestalValues->size() << " " << (((PedestalValues->find(0))->second)).size() << endl; + PedFile.close(); + return true; +} + +bool LAPPDLoadStore::MakePedestals() +{ + + // Empty for now... + // should be moved to ASCII readin? + + return true; +} + +int LAPPDLoadStore::getParsedMeta(std::vector buffer, int BoardId) +{ + // Catch empty buffers + if (buffer.size() == 0) + { + std::cout << "You tried to parse ACDC data without pulling/setting an ACDC buffer" << std::endl; + return -1; + } + + // Prepare the Metadata vector + // meta.clear(); + + // Helpers + int chip_count = 0; + + // Indicator words for the start/end of the metadata + const unsigned short startword = 0xBA11; + unsigned short endword = 0xFACE; + unsigned short endoffile = 0x4321; + + // Empty metadata map for each Psec chip + map> PsecInfo; + + // Empty trigger metadata map for each Psec chip + map> PsecTriggerInfo; + unsigned short CombinedTriggerRateCount; + + // Empty vector with positions of aboves startword + vector start_indices = + { + 1539, 3091, 4643, 6195, 7747}; + + // Fill the psec info map + vector::iterator bit; + for (int i : start_indices) + { + // Write the first word after the startword + bit = buffer.begin() + (i + 1); + + // As long as the endword isn't reached copy metadata words into a vector and add to map + vector InfoWord; + while (*bit != endword && *bit != endoffile && InfoWord.size() < 14) + { + InfoWord.push_back(*bit); + ++bit; + } + PsecInfo.insert(pair>(chip_count, InfoWord)); + chip_count++; + } + + // Fill the psec trigger info map + for (int chip = 0; chip < NUM_PSEC; chip++) + { + for (int ch = 0; ch < NUM_CH / NUM_PSEC; ch++) + { + if (LAPPDStoreReadInVerbosity > 10) + cout << "parsing meta step1-1" << endl; + // Find the trigger data at begin + last_metadata_start + 13_info_words + 1_end_word + 1 + bit = buffer.begin() + start_indices[4] + 13 + 1 + 1 + ch + (chip * (NUM_CH / NUM_PSEC)); + if (LAPPDStoreReadInVerbosity > 10) + cout << "parsing meta step1-2" << endl; + PsecTriggerInfo[chip].push_back(*bit); + } + } + + if (LAPPDStoreReadInVerbosity > 10) + cout << "parsing meta step1.5" << endl; + // Fill the combined trigger + CombinedTriggerRateCount = buffer[7792]; + + //---------------------------------------------------------- + // Start the metadata parsing + + meta.push_back(BoardId); + for (int CHIP = 0; CHIP < NUM_PSEC; CHIP++) + { + meta.push_back((0xDCB0 | CHIP)); + // cout<<"size of info word is "< 10) + cout << "parsing meta step2-1 infoword " << INFOWORD << endl; + if (PsecInfo[CHIP].size() < 13) + { + NonEmptyEvents = NonEmptyEvents - 1; + NonEmptyDataEvents = NonEmptyDataEvents - 1; + cout << "meta data parsing wrong! PsecInfo[CHIP].size() < 13" << endl; + m_data->CStore.Set("LAPPDana", false); + return 1; + } + + try + { + meta.push_back(PsecInfo[CHIP][INFOWORD]); + } + catch (...) + { + NonEmptyEvents = NonEmptyEvents - 1; + NonEmptyDataEvents = NonEmptyDataEvents - 1; + cout << "meta data parsing wrong! meta.push_back(PsecInfo[CHIP][INFOWORD]);" << endl; + m_data->CStore.Set("LAPPDana", false); + return 1; + } + } + for (int TRIGGERWORD = 0; TRIGGERWORD < 6; TRIGGERWORD++) + { + if (LAPPDStoreReadInVerbosity > 10) + cout << "parsing meta step2-2 trigger word" << endl; + + if (PsecTriggerInfo[CHIP].size() < 6) + { + NonEmptyEvents = NonEmptyEvents - 1; + NonEmptyDataEvents = NonEmptyDataEvents - 1; + cout << "meta data parsing wrong! PsecTriggerInfo[CHIP].size() < 6" << endl; + m_data->CStore.Set("LAPPDana", false); + return 1; + } + + try + { + meta.push_back(PsecTriggerInfo[CHIP][TRIGGERWORD]); + } + catch (...) + { + NonEmptyEvents = NonEmptyEvents - 1; + NonEmptyDataEvents = NonEmptyDataEvents - 1; + cout << "meta data parsing wrong! meta.push_back(PsecTriggerInfo[CHIP][TRIGGERWORD]);" << endl; + m_data->CStore.Set("LAPPDana", false); + return 1; + } + } + } + + meta.push_back(CombinedTriggerRateCount); + meta.push_back(0xeeee); + return 0; +} + +int LAPPDLoadStore::getParsedData(std::vector buffer, int ch_start) +{ + // Catch empty buffers + if (buffer.size() == 0) + { + std::cout << "You tried to parse ACDC data without pulling/setting an ACDC buffer" << std::endl; + return -1; + } + + // Helpers + int DistanceFromZero; + int channel_count = 0; + + // Indicator words for the start/end of the metadata + const unsigned short startword = 0xF005; + unsigned short endword = 0xBA11; + unsigned short endoffile = 0x4321; + + // Empty vector with positions of aboves startword + vector start_indices = + { + 2, 1554, 3106, 4658, 6210}; + + // Fill data map + vector::iterator bit; + for (int i : start_indices) + { + // Write the first word after the startword + bit = buffer.begin() + (i + 1); + + // As long as the endword isn't reached copy metadata words into a vector and add to map + vector InfoWord; + while (*bit != endword && *bit != endoffile) + { + InfoWord.push_back((unsigned short)*bit); + if (InfoWord.size() == NUM_SAMP) + { + data.insert(pair>(ch_start + channel_count, InfoWord)); + if (LAPPDStoreReadInVerbosity > 5) + cout << "inserted data to channel " << ch_start + channel_count << endl; + InfoWord.clear(); + channel_count++; + } + ++bit; + } + } + + return 0; +} + +bool LAPPDLoadStore::LoadData() +{ + // TODO: when looping in Stores["ANNIEEvent"], the multiple PSEC data will be saved in std::map LAPPDDatas; + // so we need to loop the map to get all data and waveforms, using the LAPPD_ID, board number, channel number to form a global channel-waveform map + // then loop all waveforms based on channel number + + if (loadFromStoreDirectly) + m_data->Stores["ANNIEEvent"]->GetEntry(eventNo); + if (LAPPDStoreReadInVerbosity > 2) + cout << "Got eventNo " << eventNo << endl; + + // if loaded enough events, stop the loop and return false + if (NonEmptyEvents == stopEntries || NonEmptyEvents > stopEntries || NonEmptyDataEvents == stopEntries || NonEmptyDataEvents > stopEntries) + { + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn: NonEmptyEvents is " << NonEmptyEvents << ", NonEmptyDataEvents is " << NonEmptyDataEvents << ", stopEntries is " << stopEntries << ", stop the loop" << endl; + m_data->vars.Set("StopLoop", 1); + return false; + } + + // if (mergedEvent) + // DataStreams["LAPPD"] = true; + + // print the load information: DataStreams["LAPPD"] value, PsecReceiveMode, MultiLAPPDMap + if (LAPPDStoreReadInVerbosity > 0) + { + cout << "LAPPDStoreReadIn: DataStreams[LAPPD] is " << DataStreams["LAPPD"] << ", PsecReceiveMode is " << PsecReceiveMode << ", MultiLAPPDMap is " << MultiLAPPDMap << endl; + } + + if (loadPSEC || loadPPS) + { // if load any kind of data + // if there is no LAPPD data in event store, and not getting data from CStore, return false, don't load + if (!DataStreams["LAPPD"] && PsecReceiveMode == 0 && !MultiLAPPDMap) // if doesn't have datastream, not reveive data from raw data store (PsecReceiveMode), not loading multiple LAPPD map from processed data + { + return false; + } + else if (PsecReceiveMode == 1 && !MultiLAPPDMap) // no LAPPD data in event store, but load from CStore (for merging LAPPD to ANNIEEvent) + { // only get PSEC object from CStore + // if loading from raw data, and the loading was set to pause, return false + bool LAPPDRawLoadingPaused = false; + m_data->CStore.Get("PauseLAPPDDecoding", LAPPDRawLoadingPaused); + if (LAPPDRawLoadingPaused) + { + m_data->CStore.Set("NewLAPPDDataAvailable", false); + return false; + } + + PsecData dat; + bool getData = m_data->CStore.Get("LAPPDData", dat); + if (getData) + { + m_data->CStore.Set("StoreLoadedLAPPDData", dat); + } + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn: getting LAPPDData from CStore" << endl; + bool mergingLoad; + // if in merging mode, but no LAPPD data in CStore, return false, don't load + m_data->CStore.Get("LAPPDanaData", mergingLoad); + if (!mergingLoad && mergingModeReadIn) + { + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn: mergingMode is true but LAPPDanaData is false, set LAPPDana to false" << endl; + return false; + } + if (getData) + { + vector errorcodes = dat.errorcodes; + if (errorcodes.size() == 1 && errorcodes[0] == 0x00000000) + { + if (LAPPDStoreReadInVerbosity > 1) + printf("No errorcodes found all good: 0x%08x\n", errorcodes[0]); + } + else + { + printf("When Loading PPS: Errorcodes found: %li\n", errorcodes.size()); + for (unsigned int k = 0; k < errorcodes.size(); k++) + { + printf("Errorcode: 0x%08x\n", errorcodes[k]); + } + errorEventsNumber++; + return false; + } + ReadBoards = dat.BoardIndex; + Raw_buffer = dat.RawWaveform; + if (Raw_buffer.size() == 0 || ReadBoards.size() == 0) + { + cout << "LAPPD Load Store, find Raw buffer size == 0 or ReadBoards size == 0" << endl; + return false; + } + LAPPD_ID = dat.LAPPD_ID; + if (LAPPD_ID != SelectedLAPPD && SelectSingleLAPPD) + return false; + m_data->CStore.Set("PsecTimestamp", dat.Timestamp); + if (LAPPDStoreReadInVerbosity > 2) + { + cout << " Got Data " << endl; + dat.Print(); + } + int frameType = static_cast(Raw_buffer.size() / ReadBoards.size()); + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn: got Data from CStore, frame type is " << frameType << endl; + if (loadPSEC) + { + if (frameType == num_vector_data) + { + m_data->CStore.Set("LoadingPPS", false); + return true; + } + } + if (loadPPS) + { + if (frameType == num_vector_pps) + { + m_data->CStore.Set("LoadingPPS", true); + return true; + } + } + return false; + } + else + { + return false; + } + } + else if (DataStreams["LAPPD"] && PsecReceiveMode == 0 && !MultiLAPPDMap) // if load single lappd data at ID 0, require Datastream, not receive from cstore, not in multiLAPPDMap mode + { + PsecData dat; + m_data->Stores["ANNIEEvent"]->Get("LAPPDData", dat); + ReadBoards = dat.BoardIndex; + Raw_buffer = dat.RawWaveform; + LAPPD_ID = dat.LAPPD_ID; + if (LAPPD_ID != SelectedLAPPD && SelectSingleLAPPD) + return false; + m_data->CStore.Set("PsecTimestamp", dat.Timestamp); + + if (Raw_buffer.size() != 0 || ReadBoards.size() != 0) + { + if (LAPPDStoreReadInVerbosity > 0) + { + cout << "Getting data length format" << static_cast(Raw_buffer.size() / ReadBoards.size()) << ", psec timestamp is " << dat.Timestamp << endl; + cout << "ReadBoards size " << ReadBoards.size() << " Raw_buffer size " << Raw_buffer.size() << " LAPPD_ID " << LAPPD_ID << endl; + } + } + else + { + cout << "LAPPDStoreReadIn: loading data with raw buffer size 0 or ReadBoards size 0, skip loading" << endl; + cout << "ReadBoards size " << ReadBoards.size() << " Raw_buffer size " << Raw_buffer.size() << " LAPPD_ID " << LAPPD_ID << endl; + + return false; + } + return true; + } + else if (DataStreams["LAPPD"] && PsecReceiveMode == 0 && MultiLAPPDMap) // if not receive from cstore, and load multi lappd map + { + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDLoadStore: Loading multiple LAPPD data from ANNIEEvent" << "Inside, size of LAPPDDatamap = " << LAPPDDataMap.size() << endl; + + if (LAPPDDataMap.size() == 0) + { + cout << "what happened?" << endl; + return false; + } + + return true; + } + } + return false; // if not any of the above, return false +} + +void LAPPDLoadStore::ParsePPSData() +{ + if (LAPPDStoreReadInVerbosity > 0) + cout << "Loading PPS frame size " << pps.size() << endl; + std::vector pps = Raw_buffer; + std::vector pps_vector; + std::vector pps_count_vector; + + unsigned long pps_timestamp = 0; + unsigned long ppscount = 0; + for (int s = 0; s < ReadBoards.size(); s++) + { + unsigned short pps_63_48 = pps.at(2 + 16 * s); + unsigned short pps_47_32 = pps.at(3 + 16 * s); + unsigned short pps_31_16 = pps.at(4 + 16 * s); + unsigned short pps_15_0 = pps.at(5 + 16 * s); + std::bitset<16> bits_pps_63_48(pps_63_48); + std::bitset<16> bits_pps_47_32(pps_47_32); + std::bitset<16> bits_pps_31_16(pps_31_16); + std::bitset<16> bits_pps_15_0(pps_15_0); + unsigned long pps_63_0 = (static_cast(pps_63_48) << 48) + (static_cast(pps_47_32) << 32) + (static_cast(pps_31_16) << 16) + (static_cast(pps_15_0)); + if (LAPPDStoreReadInVerbosity > 0) + std::cout << "pps combined: " << pps_63_0 << std::endl; + std::bitset<64> bits_pps_63_0(pps_63_0); + // pps_timestamp = pps_63_0 * (CLOCK_to_NSEC); // NOTE: Don't do convert to ns because of the precision, do this in later tools + pps_timestamp = pps_63_0; + // LAPPDPPS->push_back(pps_timestamp); + if (LAPPDStoreReadInVerbosity > 0) + std::cout << "Adding timestamp " << pps_timestamp << " to LAPPDPPS" << std::endl; + pps_vector.push_back(pps_timestamp); + + unsigned short ppscount_31_16 = pps.at(8 + 16 * s); + unsigned short ppscount_15_0 = pps.at(9 + 16 * s); + std::bitset<16> bits_ppscount_31_16(ppscount_31_16); + std::bitset<16> bits_ppscount_15_0(ppscount_15_0); + unsigned long ppscount_31_0 = (static_cast(ppscount_31_16) << 16) + (static_cast(ppscount_15_0)); + if (LAPPDStoreReadInVerbosity > 0) + std::cout << "pps count combined: " << ppscount_31_0 << std::endl; + std::bitset<32> bits_ppscount_31_0(ppscount_31_0); + ppscount = ppscount_31_0; + pps_count_vector.push_back(ppscount); + + if (LAPPDStoreReadInVerbosity > 8) + { + // Print the bitsets + cout << "******************************" << endl; + std::cout << "printing ACDC " << s << ": " << endl; + std::cout << "bits_pps_63_48: " << bits_pps_63_48 << std::endl; + std::cout << "bits_pps_47_32: " << bits_pps_47_32 << std::endl; + std::cout << "bits_pps_31_16: " << bits_pps_31_16 << std::endl; + std::cout << "bits_pps_15_0: " << bits_pps_15_0 << std::endl; + // Print the unsigned shorts + std::cout << "pps_63_48: " << pps_63_48 << std::endl; + std::cout << "pps_47_32: " << pps_47_32 << std::endl; + std::cout << "pps_31_16: " << pps_31_16 << std::endl; + std::cout << "pps_15_0: " << pps_15_0 << std::endl; + std::cout << "pps_63_0: " << pps_63_0 << std::endl; + std::cout << "pps_63_0 after conversion in double: " << pps_timestamp << endl; + + for (int x = 0; x < 16; x++) + { + std::bitset<16> bit_pps_here(pps.at(x + 16 * s)); + cout << "unsigned short at " << x << " : " << pps.at(x + 16 * s) << ", bit at " << x << " is: " << bit_pps_here << endl; + ; + } + } + } + + // double ppsDiff = static_cast(pps_vector.at(0)) - static_cast(pps_vector.at(1)); + unsigned long ppsDiff = pps_vector.at(0) - pps_vector.at(1); + m_data->CStore.Set("LAPPDPPScount0", pps_count_vector.at(0)); + m_data->CStore.Set("LAPPDPPScount1", pps_count_vector.at(1)); + m_data->CStore.Set("LAPPDPPScount", pps_count_vector); + m_data->CStore.Set("LAPPDPPSDiff0to1", ppsDiff); + m_data->CStore.Set("LAPPDPPSVector", pps_vector); + + m_data->CStore.Set("LAPPDPPStimestamp0", pps_vector.at(0)); + m_data->CStore.Set("LAPPDPPStimestamp1", pps_vector.at(1)); + m_data->CStore.Set("LAPPDPPShere", true); + m_data->CStore.Set("LAPPD_ID", LAPPD_ID); + + PPSnumber++; +} + +bool LAPPDLoadStore::ParsePSECData() +{ + if (LAPPDStoreReadInVerbosity > 0) + std::cout << "PSEC Data Frame was read! Starting the parsing!" << std::endl; + + // while loading single PsecData Object, parse the data by LAPPDID and number of boards on each LAPPD and channel on each board + // Create a vector of paraphrased board indices + // the board indices goes with LAPPD ID. For example, LAPPD ID = 2, we will have board = 4,5 + // this need to be converted to 0,1 + int nbi = ReadBoards.size(); + if (LAPPDStoreReadInVerbosity > 0 && nbi != 2) + cout << "Number of board is " << nbi << endl; + if (nbi == 0) + { + cout << "LAPPDStoreReadIn: error here! number of board is 0" << endl; + errorEventsNumber++; + return false; + } + if (nbi % 2 != 0) + { + errorEventsNumber++; + cout << "LAPPDStoreReadIn: uneven number of boards in this event" << endl; + if (nbi == 1) + { + ParaBoards.push_back(ReadBoards[0]); + } + else + { + return false; + } + } + else + { + for (int cbi = 0; cbi < nbi; cbi++) + { + ParaBoards.push_back(cbi); + if (LAPPDStoreReadInVerbosity > 2) + cout << "Board " << cbi << " is added to the list of boards to be parsed!" << endl; + } + } + // loop all boards, 0, 1 + if (LAPPDStoreReadInVerbosity > 2) + { + cout << "ParaBoards size is " << ParaBoards.size() << endl; + for (int i = 0; i < ParaBoards.size(); i++) + { + cout << "ParaBoards " << i << " is " << ParaBoards[i] << endl; + } + } + for (int i = 0; i < ParaBoards.size(); i++) + { + int bi = ParaBoards.at(i) % 2; + Parse_buffer.clear(); + if (LAPPDStoreReadInVerbosity > 2) + std::cout << "Parsing board with ReadBoards ID" << ReadBoards[bi] << std::endl; + // Go over all ACDC board data frames by seperating them + int frametype = static_cast(Raw_buffer.size() / ReadBoards.size()); + for (int c = bi * frametype; c < (bi + 1) * frametype; c++) + { + Parse_buffer.push_back(Raw_buffer[c]); + } + if (LAPPDStoreReadInVerbosity > 2) + std::cout << "Data for " << i << "_th board with board number = " << ReadBoards[bi] << " was grabbed!" << std::endl; + + // Grab the parsed data and give it to a global variable 'data' + // insert the data start with channel number 30*ReadBoards[bi] + // for instance, when bi=0 , LAPPD ID = 2, ReadBoards[bi] = 4, insert to channel number start with 120, to 150 + int channelShift = bi * NUM_CH + LAPPD_ID * NUM_CH * 2; + retval = getParsedData(Parse_buffer, channelShift); //(because there are only 2 boards, so it's 0*30 or 1*30). Inserting the channel number start from this then ++ to 30 + if (retval == 0) + { + if (LAPPDStoreReadInVerbosity > 2) + std::cout << "Data for board with number = " << ReadBoards[bi] << " was parsed with channel shift " << channelShift << endl; + // Grab the parsed metadata and give it to a global variable 'meta' + retval = getParsedMeta(Parse_buffer, bi + LAPPD_ID * 2); + if (retval != 0) + { + std::cout << "Meta parsing went wrong! " << retval << endl; + return false; + } + else + { + if (LAPPDStoreReadInVerbosity > 2) + std::cout << "Meta for board " << ReadBoards[bi] << " was parsed!" << std::endl; + } + } + else + { + std::cout << "Parsing went wrong! " << retval << endl; + return false; + } + } + + + LAPPDEventIndex_ID[LAPPD_ID] += 1; + if (LAPPDStoreReadInVerbosity > 1) + { + cout << "Adding one new event with LAPPD_ID = " << LAPPD_ID << " to the LAPPDEventIndex_ID, now it is: " << endl; + for (int i = 0; i < LAPPDEventIndex_ID.size(); i++) + { + cout << LAPPDEventIndex_ID[i] << ", " << endl; + } + cout << endl; + } + + if (LAPPDStoreReadInVerbosity > 2) + cout << "Parsed all boards for this event finished" << endl; + return true; +} + +bool LAPPDLoadStore::DoPedestalSubtract() +{ + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDLoadStore::DoPedestalSubtract()" << endl; + if (DoPedSubtract == 0) + return true; + Waveform tmpWave; + vector> VecTmpWave; + int pedval, val; + if (LAPPDStoreReadInVerbosity > 3) + { + // print the size of data and all keys, and the size of PedestalValues and all keys + cout << "Size of data is " << data.size() << endl; + for (std::map>::iterator it = data.begin(); it != data.end(); ++it) // looping over the data map by channel number, from 0 to 60 + { + cout << it->first << ", "; + } + cout << endl; + cout << "Size of PedestalValues is " << PedestalValues->size() << endl; + for (auto it = PedestalValues->begin(); it != PedestalValues->end(); ++it) // looping over the data map by channel number, from 0 to 60 + { + cout << it->first << ", "; + } + cout << endl; + } + // Loop over data stream + for (std::map>::iterator it = data.begin(); it != data.end(); ++it) // looping over the data map by channel number, from 0 to 60 + { + int wrongPedChannel = 0; + if (LAPPDStoreReadInVerbosity > 5) + cout << "Do Pedestal sub at Channel " << it->first; + + for (int kvec = 0; kvec < it->second.size(); kvec++) + { // loop all data point in this channel + if (DoPedSubtract == 1) + { + auto iter = PedestalValues->find((it->first)); + if (kvec == 0 && LAPPDStoreReadInVerbosity > 5) + cout << std::fixed << ", found PedestalValues for channel " << it->first << " with value = " << iter->second.at(0); + if (iter != PedestalValues->end() && iter->second.size() > kvec) + { + pedval = iter->second.at(kvec); + } + else + { + pedval = 0; + wrongPedChannel = (it->first); + } + } + else + { + pedval = 0; + } + val = it->second.at(kvec); + tmpWave.PushSample(0.3 * (double)(val - pedval)); + if (LAPPDStoreReadInVerbosity > 5 && kvec < 10) + cout << ", " << val << "-" << pedval << "=" << 0.3 * (double)(val - pedval); + } + if (wrongPedChannel != 0) + cout << "Pedestal value not found for channel " << wrongPedChannel << "with it->first channel" << it->first << ", LAPPD channel shift " << LAPPD_ID * 60 << endl; + + VecTmpWave.push_back(tmpWave); + + unsigned long pushChannelNo = (unsigned long)it->first; + LAPPDWaveforms.insert(pair>>(pushChannelNo, VecTmpWave)); + // cout<<", Pushed to LAPPDWaveforms with channel number "< 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); + 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)); + std::bitset<64> bits_beamgate_63_0(beamgate_63_0); + unsigned long beamgate_timestamp = beamgate_63_0 * (CLOCK_to_NSEC); + m_data->CStore.Set("LAPPDbeamgate", beamgate_timestamp); + m_data->CStore.Set("LAPPDBeamgate_Raw", beamgate_63_0); + + unsigned long BGTruncation = beamgate_63_0 % 8; + unsigned long BGTruncated = beamgate_63_0 - BGTruncation; + unsigned long BGInt = BGTruncated / 8 * 25; + unsigned long BGIntTruncation = BGTruncation * 3; + // save these two to CStore + double BGFloat = BGTruncation * 0.125; + unsigned long BGIntCombined = BGInt + BGIntTruncation; + m_data->CStore.Set("LAPPDBGIntCombined", BGIntCombined); + m_data->CStore.Set("LAPPDBGFloat", BGFloat); + + unsigned short timestamp_63_48 = meta.at(70); + unsigned short timestamp_47_32 = meta.at(50); + unsigned short timestamp_31_16 = meta.at(30); + unsigned short timestamp_15_0 = meta.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); + 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)); + unsigned long lappd_timestamp = timestamp_63_0 * (CLOCK_to_NSEC); + m_data->CStore.Set("LAPPDtimestamp", lappd_timestamp); + m_data->CStore.Set("LAPPDTimestamp_Raw", timestamp_63_0); + + unsigned long TSTruncation = timestamp_63_0 % 8; + unsigned long TSTruncated = timestamp_63_0 - TSTruncation; + unsigned long TSInt = TSTruncated / 8 * 25; + unsigned long TSIntTruncation = TSTruncation * 3; + // save these two to CStore + double TSFloat = TSTruncation * 0.125; + unsigned long TSIntCombined = TSInt + TSIntTruncation; + m_data->CStore.Set("LAPPDTSIntCombined", TSIntCombined); + m_data->CStore.Set("LAPPDTSFloat", TSFloat); + + m_data->Stores["ANNIEEvent"]->Set("LAPPDbeamgate", beamgate_timestamp); // in ns + m_data->Stores["ANNIEEvent"]->Set("LAPPDtimestamp", lappd_timestamp); // in ns + m_data->Stores["ANNIEEvent"]->Set("LAPPDBeamgate_Raw", beamgate_63_0); + m_data->Stores["ANNIEEvent"]->Set("LAPPDTimestamp_Raw", timestamp_63_0); + + if (LAPPDStoreReadInVerbosity > 11) + debugStoreReadIn << eventNo << " LAPPDStoreReadIn, Saving timestamps, beamgate_timestamp: " << beamgate_63_0 << ", lappd_timestamp: " << timestamp_63_0 << endl; + + if (loadOffsets && runInfoLoaded) + { + // run number + sub run number + partfile number + LAPPD_ID to make a string key + // TODO: need to add a reset number here after got everything work + // search it in the maps, then load + SaveOffsets(); + } + m_data->CStore.Set("LAPPD_new_event", true); +} + +void LAPPDLoadStore::SaveOffsets() +{ + int LoadingOffsetID = LAPPD_ID; + if(LoadingOffsetID+1 > LAPPDEventIndex_ID.size()) + { + LAPPDEventIndex_ID.resize(LoadingOffsetID+1); + } + int GetOffsetIndex_byID = LAPPDEventIndex_ID[LoadingOffsetID]; + if(LAPPDStoreReadInVerbosity>0) + cout << "LAPPDStoreReadIn, SavingOffsets, LoadingOffset for LAPPD_ID: " << LoadingOffsetID << ", OffsetIndex of this event: " << GetOffsetIndex_byID << endl; + + std::string key = std::to_string(runNumber) + "_" + std::to_string(subRunNumber) + "_" + std::to_string(partFileNumber) + "_" + std::to_string(LAPPD_ID); + + int LAPPDBGCorrection = 0; + int LAPPDTSCorrection = 0; + int LAPPDOffset_minus_ps = 0; + uint64_t LAPPDOffset = 0; + + uint64_t BG_PPSBefore = 0; + uint64_t BG_PPSAfter = 0; + uint64_t BG_PPSDiff = 0; + uint64_t TS_PPSBefore = 0; + uint64_t TS_PPSAfter = 0; + uint64_t TS_PPSDiff = 0; + int BG_PPSMissing = 0; + int TS_PPSMissing = 0; + + // Check if the key exists and the index is within range for BGCorrections + if (BGCorrections.find(key) != BGCorrections.end() && GetOffsetIndex_byID < BGCorrections[key].size()) + { + LAPPDBGCorrection = BGCorrections[key][GetOffsetIndex_byID]; + } + else + { + if (BGCorrections.find(key) == BGCorrections.end()) + { + std::cerr << "Error: Key not found in BGCorrections: " << key << std::endl; + } + else + { + std::cerr << "Error: GetOffsetIndex_byID out of range for BGCorrections with key: " << key << std::endl; + } + } + + // Repeat the checks for TSCorrections, Offsets_minus_ps, and Offsets + if (TSCorrections.find(key) != TSCorrections.end() && GetOffsetIndex_byID < TSCorrections[key].size()) + { + LAPPDTSCorrection = TSCorrections[key][GetOffsetIndex_byID]; + } + else + { + if (TSCorrections.find(key) == TSCorrections.end()) + { + std::cerr << "Error: Key not found in TSCorrections: " << key << std::endl; + } + else + { + std::cerr << "Error: GetOffsetIndex_byID out of range for TSCorrections with key: " << key << std::endl; + } + } + + if (Offsets_minus_ps.find(key) != Offsets_minus_ps.end() && GetOffsetIndex_byID < Offsets_minus_ps[key].size()) + { + LAPPDOffset_minus_ps = Offsets_minus_ps[key][GetOffsetIndex_byID]; + } + else + { + if (Offsets_minus_ps.find(key) == Offsets_minus_ps.end()) + { + std::cerr << "Error: Key not found in Offsets_minus_ps: " << key << std::endl; + } + else + { + std::cerr << "Error: GetOffsetIndex_byID out of range for Offsets_minus_ps with key: " << key << std::endl; + } + } + + if (Offsets.find(key) != Offsets.end() && GetOffsetIndex_byID < Offsets[key].size()) + { + LAPPDOffset = Offsets[key][GetOffsetIndex_byID]; + } + else + { + if (Offsets.find(key) == Offsets.end()) + { + std::cerr << "Error: Key not found in Offsets: " << key << std::endl; + } + else + { + std::cerr << "Error: GetOffsetIndex_byID out of range for Offsets with key: " << key << std::endl; + } + } + + if (BG_PPSBefore_loaded.find(key) != BG_PPSBefore_loaded.end() && GetOffsetIndex_byID < BG_PPSBefore_loaded[key].size()) + { + BG_PPSBefore = BG_PPSBefore_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (BG_PPSBefore_loaded.find(key) == BG_PPSBefore_loaded.end()) + std::cerr << "Error: Key not found in BG_PPSBefore_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for BG_PPSBefore_loaded with key: " << key << std::endl; + } + + if (BG_PPSAfter_loaded.find(key) != BG_PPSAfter_loaded.end() && GetOffsetIndex_byID < BG_PPSAfter_loaded[key].size()) + { + BG_PPSAfter = BG_PPSAfter_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (BG_PPSAfter_loaded.find(key) == BG_PPSAfter_loaded.end()) + std::cerr << "Error: Key not found in BG_PPSAfter_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for BG_PPSAfter_loaded with key: " << key << std::endl; + } + + if (BG_PPSDiff_loaded.find(key) != BG_PPSDiff_loaded.end() && GetOffsetIndex_byID < BG_PPSDiff_loaded[key].size()) + { + BG_PPSDiff = BG_PPSDiff_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (BG_PPSDiff_loaded.find(key) == BG_PPSDiff_loaded.end()) + std::cerr << "Error: Key not found in BG_PPSDiff_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for BG_PPSDiff_loaded with key: " << key << std::endl; + } + + if (BG_PPSMissing_loaded.find(key) != BG_PPSMissing_loaded.end() && GetOffsetIndex_byID < BG_PPSMissing_loaded[key].size()) + { + BG_PPSMissing = BG_PPSMissing_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (BG_PPSMissing_loaded.find(key) == BG_PPSMissing_loaded.end()) + std::cerr << "Error: Key not found in BG_PPSMissing_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for BG_PPSMissing_loaded with key: " << key << std::endl; + } + + if (TS_PPSBefore_loaded.find(key) != TS_PPSBefore_loaded.end() && GetOffsetIndex_byID < TS_PPSBefore_loaded[key].size()) + { + TS_PPSBefore = TS_PPSBefore_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (TS_PPSBefore_loaded.find(key) == TS_PPSBefore_loaded.end()) + std::cerr << "Error: Key not found in TS_PPSBefore_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for TS_PPSBefore_loaded with key: " << key << std::endl; + } + + if (TS_PPSAfter_loaded.find(key) != TS_PPSAfter_loaded.end() && GetOffsetIndex_byID < TS_PPSAfter_loaded[key].size()) + { + TS_PPSAfter = TS_PPSAfter_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (TS_PPSAfter_loaded.find(key) == TS_PPSAfter_loaded.end()) + std::cerr << "Error: Key not found in TS_PPSAfter_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for TS_PPSAfter_loaded with key: " << key << std::endl; + } + + if (TS_PPSDiff_loaded.find(key) != TS_PPSDiff_loaded.end() && GetOffsetIndex_byID < TS_PPSDiff_loaded[key].size()) + { + TS_PPSDiff = TS_PPSDiff_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (TS_PPSDiff_loaded.find(key) == TS_PPSDiff_loaded.end()) + std::cerr << "Error: Key not found in TS_PPSDiff_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for TS_PPSDiff_loaded with key: " << key << std::endl; + } + + if (TS_PPSMissing_loaded.find(key) != TS_PPSMissing_loaded.end() && GetOffsetIndex_byID < TS_PPSMissing_loaded[key].size()) + { + TS_PPSMissing = TS_PPSMissing_loaded[key][GetOffsetIndex_byID]; + } + else + { + if (TS_PPSMissing_loaded.find(key) == TS_PPSMissing_loaded.end()) + std::cerr << "Error: Key not found in TS_PPSMissing_loaded: " << key << std::endl; + else + std::cerr << "Error: GetOffsetIndex_byID out of range for TS_PPSMissing_loaded with key: " << key << std::endl; + } + + // start to fill data + m_data->CStore.Set("LAPPDBGCorrection", LAPPDBGCorrection); + m_data->CStore.Set("LAPPDTSCorrection", LAPPDTSCorrection); + m_data->CStore.Set("LAPPDOffset", LAPPDOffset); + m_data->CStore.Set("LAPPDOffset_minus_ps", LAPPDOffset_minus_ps); + + m_data->CStore.Set("BG_PPSBefore", BG_PPSBefore); + m_data->CStore.Set("BG_PPSAfter", BG_PPSAfter); + m_data->CStore.Set("BG_PPSDiff", BG_PPSDiff); + m_data->CStore.Set("BG_PPSMissing", BG_PPSMissing); + m_data->CStore.Set("TS_PPSBefore", TS_PPSBefore); + m_data->CStore.Set("TS_PPSAfter", TS_PPSAfter); + m_data->CStore.Set("TS_PPSDiff", TS_PPSDiff); + m_data->CStore.Set("TS_PPSMissing", TS_PPSMissing); + + if (TS_PPSMissing != BG_PPSMissing) + { + cout << "LAPPDLoadStore: BG_PPSMissing != TS_PPSMissing, BG_PPSMissing: " << BG_PPSMissing << ", TS_PPSMissing: " << TS_PPSMissing << endl; + } + + // cout << "LAPPDStoreReadIn, Saving offsets and corrections, key: " << key << ", LAPPDOffset: " << LAPPDOffset << ", LAPPDOffset_minus_ps: " << LAPPDOffset_minus_ps << ", LAPPDBGCorrection: " << LAPPDBGCorrection << ", LAPPDTSCorrection: " << LAPPDTSCorrection << ", BG_PPSBefore: " << BG_PPSBefore << ", BG_PPSAfter: " << BG_PPSAfter << ", BG_PPSDiff: " << BG_PPSDiff << ", BG_PPSMissing: " << BG_PPSMissing << ", TS_PPSBefore: " << TS_PPSBefore << ", TS_PPSAfter: " << TS_PPSAfter << ", TS_PPSDiff: " << TS_PPSDiff << ", TS_PPSMissing: " << TS_PPSMissing << endl; + + if (LAPPDStoreReadInVerbosity > 11) + debugStoreReadIn << eventNo << "+LAPPDStoreReadIn, Saving offsets and corrections, key: " << key << ", LAPPDOffset: " << LAPPDOffset << ", LAPPDOffset_minus_ps: " << LAPPDOffset_minus_ps << ", LAPPDBGCorrection: " << LAPPDBGCorrection << ", LAPPDTSCorrection: " << LAPPDTSCorrection << endl; +} + +void LAPPDLoadStore::LoadOffsetsAndCorrections() +{ + // load here from the root tree to: + /* + std::map> Offsets; //Loaded offset, use string = run number + sub run number + partfile number as key. + std::map> Offsets_minus_ps; //offset in ps, use offset - this/1e3 as the real offset + std::map> BGCorrections; //Loaded BGcorrections, same key as Offsets, but offset saved on event by event basis in that part file, in unit of ticks + std::map> TSCorrections; //TS corrections, in unit of ticks + */ + + TFile *file = new TFile("offsetFitResult.root", "READ"); + TTree *tree; + file->GetObject("Events", tree); + + if (!tree) + { + std::cerr << "LAPPDStoreReadIn Loading offsets, Tree not found!" << std::endl; + return; + } + + int runNumber, subRunNumber, partFileNumber, LAPPD_ID; + ULong64_t final_offset_ns_0, final_offset_ps_negative_0, EventIndex; + ULong64_t BGCorrection_tick, TSCorrection_tick; + + 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; + + tree->SetBranchAddress("runNumber", &runNumber); + tree->SetBranchAddress("subRunNumber", &subRunNumber); + tree->SetBranchAddress("partFileNumber", &partFileNumber); + tree->SetBranchAddress("LAPPD_ID", &LAPPD_ID); + tree->SetBranchAddress("EventIndex", &EventIndex); + tree->SetBranchAddress("final_offset_ns_0", &final_offset_ns_0); + tree->SetBranchAddress("final_offset_ps_negative_0", &final_offset_ps_negative_0); + tree->SetBranchAddress("BGCorrection_tick", &BGCorrection_tick); + tree->SetBranchAddress("TSCorrection_tick", &TSCorrection_tick); + tree->SetBranchAddress("BG_PPSBefore_tick", &BG_PPSBefore_tick); + tree->SetBranchAddress("BG_PPSAfter_tick", &BG_PPSAfter_tick); + tree->SetBranchAddress("BG_PPSDiff_tick", &BG_PPSDiff_tick); + tree->SetBranchAddress("BG_PPSMissing_tick", &BG_PPSMissing_tick); + tree->SetBranchAddress("TS_PPSBefore_tick", &TS_PPSBefore_tick); + tree->SetBranchAddress("TS_PPSAfter_tick", &TS_PPSAfter_tick); + tree->SetBranchAddress("TS_PPSDiff_tick", &TS_PPSDiff_tick); + tree->SetBranchAddress("TS_PPSMissing_tick", &TS_PPSMissing_tick); + tree->SetBranchAddress("TS_driftCorrection_ns", &TS_driftCorrection_ns); + tree->SetBranchAddress("BG_driftCorrection_ns", &BG_driftCorrection_ns); + + Long64_t nentries = tree->GetEntries(); + cout << "LAPPDStoreReadIn Loading offsets and corrections, total entries: " << nentries << endl; + for (Long64_t i = 0; i < nentries; ++i) + { + tree->GetEntry(i); + + std::string key = std::to_string(runNumber) + "_" + std::to_string(subRunNumber) + "_" + std::to_string(partFileNumber) + "_" + std::to_string(LAPPD_ID); + + // Prepare the vector sizes for each map + if (Offsets[key].size() <= EventIndex) + { + Offsets[key].resize(EventIndex + 1); + Offsets_minus_ps[key].resize(EventIndex + 1); + BGCorrections[key].resize(EventIndex + 1); + TSCorrections[key].resize(EventIndex + 1); + BG_PPSBefore_loaded[key].resize(EventIndex + 1); + BG_PPSAfter_loaded[key].resize(EventIndex + 1); + BG_PPSDiff_loaded[key].resize(EventIndex + 1); + BG_PPSMissing_loaded[key].resize(EventIndex + 1); + TS_PPSBefore_loaded[key].resize(EventIndex + 1); + TS_PPSAfter_loaded[key].resize(EventIndex + 1); + TS_PPSDiff_loaded[key].resize(EventIndex + 1); + TS_PPSMissing_loaded[key].resize(EventIndex + 1); + } + + // Now using EventIndex to place each event correctly + Offsets[key][EventIndex] = final_offset_ns_0 + TS_driftCorrection_ns; + Offsets_minus_ps[key][EventIndex] = static_cast(final_offset_ps_negative_0); + BGCorrections[key][EventIndex] = static_cast(BGCorrection_tick) - 1000; + TSCorrections[key][EventIndex] = static_cast(TSCorrection_tick) - 1000; + + BG_PPSBefore_loaded[key][EventIndex] = BG_PPSBefore_tick; + BG_PPSAfter_loaded[key][EventIndex] = BG_PPSAfter_tick; + BG_PPSDiff_loaded[key][EventIndex] = BG_PPSDiff_tick; + BG_PPSMissing_loaded[key][EventIndex] = static_cast(BG_PPSMissing_tick) - 1000; + TS_PPSBefore_loaded[key][EventIndex] = TS_PPSBefore_tick; + TS_PPSAfter_loaded[key][EventIndex] = TS_PPSAfter_tick; + TS_PPSDiff_loaded[key][EventIndex] = TS_PPSDiff_tick; + TS_PPSMissing_loaded[key][EventIndex] = static_cast(TS_PPSMissing_tick) - 1000; + + if (nentries > 10 && i % (static_cast(nentries / 10)) == 0) + { + cout << "LAPPDStoreReadIn Loading offsets and corrections, " << i << " entries loaded" << endl; + cout << "Printing key: " << key << ", EventIndex: " << EventIndex << ", final_offset_ns_0: " << final_offset_ns_0 << ", final_offset_ps_negative_0: " << final_offset_ps_negative_0 << ", BGCorrection_tick: " << BGCorrection_tick << ", TSCorrection_tick: " << TSCorrection_tick << ", BG_PPSMissing_tick: " << BG_PPSMissing_tick << ", TS_PPSMissing_tick: " << TS_PPSMissing_tick << ", TS_driftCorrection_ns: " << TS_driftCorrection_ns << ", BG_driftCorrection_ns: " << BG_driftCorrection_ns << endl; + } + } + + file->Close(); + delete file; + + // The data structures are now correctly filled and can be used as needed. +} + +void LAPPDLoadStore::LoadRunInfo() +{ + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn, Loading run info" << endl; + int PFNumberBeforeGet = partFileNumber; + m_data->CStore.Get("rawFileNumber", partFileNumber); + m_data->CStore.Get("runNumber", runNumber); + m_data->CStore.Get("subrunNumber", subRunNumber); + + if (partFileNumber != PFNumberBeforeGet) + { + eventNumberInPF = 0; + // also set all value of LAPPDEventIndex_ID to be 0 + for (int i = 0; i < LAPPDEventIndex_ID.size(); i++) + { + LAPPDEventIndex_ID[i] = 0; + } + } + else + { + eventNumberInPF++; + } + if (LAPPDStoreReadInVerbosity > 0) + cout << "LAPPDStoreReadIn, Loaded run info, runNumber: " << runNumber << ", subRunNumber: " << subRunNumber << ", partFileNumber: " << partFileNumber << ", eventNumberInPF: " << eventNumberInPF << endl; +} diff --git a/UserTools/LAPPDLoadStore/LAPPDLoadStore.h b/UserTools/LAPPDLoadStore/LAPPDLoadStore.h new file mode 100644 index 000000000..3deb5eea4 --- /dev/null +++ b/UserTools/LAPPDLoadStore/LAPPDLoadStore.h @@ -0,0 +1,179 @@ +#ifndef LAPPDLoadStore_H +#define LAPPDLoadStore_H + +#include +#include +#include +#include +#include +#include "Tool.h" +#include "PsecData.h" +#include "TFile.h" +#include "TTree.h" + +#define NUM_CH 30 +#define NUM_PSEC 5 +#define NUM_SAMP 256 + +using namespace std; +/** + * \class LAPPDLoadStore + * + * Load LAPPD PSEC data and PPS data from BoostStore. + * + */ +class LAPPDLoadStore : public Tool +{ + +public: + LAPPDLoadStore(); ///< 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 ReadPedestals(int boardNo); ///< Read in the Pedestal Files + bool MakePedestals(); ///< Make a Pedestal File + + int getParsedData(vector buffer, int ch_start); + int getParsedMeta(vector buffer, int BoardId); + + void CleanDataObjects(); + bool LoadData(); + bool ParsePSECData(); + void ParsePPSData(); + bool DoPedestalSubtract(); + void SaveTimeStamps(); // save some timestamps relate to this event + void LoadOffsetsAndCorrections(); + void LoadRunInfo(); + void SaveOffsets(); + +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 ReadStore; // read data from a StoreFile (tool chain start with this tool rather than LoadANNIEEvent) + int Nboards; // total number of boards to load pedestal file, LAPPD number * 2 + string PedFileName; // store format pedestal file name + string PedFileNameTXT; // txt format pedestal file name + int DoPedSubtract; // 1: do pedestal subtraction, 0: don't do pedestal subtraction + int LAPPDStoreReadInVerbosity; + int num_vector_data; + int num_vector_pps; + bool SelectSingleLAPPD; + int SelectedLAPPD; + bool mergingModeReadIn; + bool ReadStorePdeFile; + bool MultiLAPPDMap; // loading map of multiple LAPPDs from ANNIEEvent + bool loadOffsets; + bool LoadBuiltPPSInfo; + bool loadFromStoreDirectly; + // Variables that you need in the tool + int retval; // track the data parsing and meta parsing status + int eventNo; + double CLOCK_to_NSEC; + int errorEventsNumber; + bool runInfoLoaded; + + // 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 stopEntries; // stop tool chain after loading this number of PSEC data events + int NonEmptyEvents; // count how many non empty data events were loaded + int NonEmptyDataEvents; // count how many non empty data events were loaded + bool PsecReceiveMode; // Get PSEC data from CStore or Stores["ANNIEEvent"]. 1: CStore, 0: Stores["ANNIEEvent"] + string OutputWavLabel; + string InputWavLabel; + int NChannels; + int Nsamples; + int TrigChannel; + double SampleSize; + int LAPPDchannelOffset; + int PPSnumber; + bool loadPPS; + bool loadPSEC; + bool mergedEvent; // in some merged Event, the LAPPD events was merged to ANNIEEvent, but the data stream was not changed to be true. use this = 1 to read it + bool LAPPDana; // run other LAPPD tools + // Variables that you need in the tool + bool isCFD; + bool isBLsub; + bool isFiltered; + int EventType; // 0: PSEC, 1: PPS + // 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 + int LAPPD_ID; + vector LAPPD_IDs; + vector LAPPDLoadedTimeStamps; + vector LAPPDLoadedTimeStampsRaw; + vector LAPPDLoadedBeamgatesRaw; + vector LAPPDLoadedOffsets; + vector LAPPDLoadedTSCorrections; + vector LAPPDLoadedBGCorrections; + vector LAPPDLoadedOSInMinusPS; + vector LAPPDLoadedBG_PPSBefore; + vector LAPPDLoadedBG_PPSAfter; + vector LAPPDLoadedBG_PPSDiff; + vector LAPPDLoadedBG_PPSMissing; + vector LAPPDLoadedTS_PPSBefore; + vector LAPPDLoadedTS_PPSAfter; + vector LAPPDLoadedTS_PPSDiff; + vector LAPPDLoadedTS_PPSMissing; + + vector ParaBoards; // save the board index for this PsecData + std::map>> LAPPDWaveforms; + + // This tool, data variables (only used in this tool, every thing that is an data object) + ifstream PedFile; // stream for reading in the Pedestal Files + string NewFileName; // name of the new Data File + std::map> *PedestalValues; + std::vector Raw_buffer; + std::vector Parse_buffer; + std::vector ReadBoards; + std::map> data; + vector meta; + vector pps; + vector LAPPD_ID_Channel; // for each LAPPD, how many channels on it's each board + vector LAPPD_ID_BoardNumber; // for each LAPPD, how many boards with it + 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 DataStreams; + std::vector LAPPDEventIndex_ID; // for each LAPPD ID, count the index of current loaded event + // For example, this part file may have a ID=0 event, b ID=1 event, while loading data object c and loaded 3 ID=0 and 4 ID=1, I may have + // LAPPDEventIndex_ID = {3, 4} + + // save PPS info for the second order correction + 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; + + // data variables don't need to be cleared in each loop + // these are loaded offset for event building + std::map> Offsets; // Loaded offset, use string = run number + sub run number + partfile number as key. + std::map> Offsets_minus_ps; // offset in ps, use offset - this/1e3 as the real offset + std::map> BGCorrections; // Loaded BGcorrections, same key as Offsets, but offset saved on event by event basis in that part file, in unit of ticks + std::map> TSCorrections; // TS corrections, in unit of ticks + std::map> BG_PPSBefore_loaded; // BG PPS before, in unit of ticks + std::map> BG_PPSAfter_loaded; // BG PPS after, in unit of ticks + std::map> BG_PPSDiff_loaded; // BG PPS Diff + std::map> BG_PPSMissing_loaded; // BG PPS Missing + std::map> TS_PPSBefore_loaded; // TS PPS before, in unit of ticks + std::map> TS_PPSAfter_loaded; // TS PPS after, in unit of ticks + std::map> TS_PPSDiff_loaded; // TS PPS Diff + std::map> TS_PPSMissing_loaded; // TS PPS Missing + + int runNumber; + int subRunNumber; + int partFileNumber; + int eventNumberInPF; + std::ofstream debugStoreReadIn; +}; + +#endif diff --git a/UserTools/LAPPDLoadStore/README.md b/UserTools/LAPPDLoadStore/README.md new file mode 100644 index 000000000..ec08cbc11 --- /dev/null +++ b/UserTools/LAPPDLoadStore/README.md @@ -0,0 +1,20 @@ +# LAPPDLoadStore + +LAPPDLoadStore + +## Data + +Describe any data formats LAPPDLoadStore 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 LAPPDLoadStore. + +``` +param1 value1 +param2 value2 +``` diff --git a/UserTools/Unity.h b/UserTools/Unity.h index 7e64d4e9b..829eae786 100644 --- a/UserTools/Unity.h +++ b/UserTools/Unity.h @@ -182,3 +182,4 @@ #include "PrintDQ.h" #include "AssignBunchTimingMC.h" #include "FitRWMWaveform.h" +#include "LAPPDLoadStore.h"