diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..3d4c3df93 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,12 @@ +## Describe your changes + +## Checklist before submitting your PR +- [ ] This PR implements a single change (one new/modified Tool, or a set of changes to implement one new/modified feature) +- [ ] This PR alters the minimum number of files to affect this change +- [ ] If this PR includes a new Tool, a README and minimal demonstration ToolChain is provided +- [ ] If a new Tool/ToolChain requires model or configuration files, their paths are not hard-coded, and means of generating those files is described in the readme, with examples provided on /pnfs/annie/persistent +- [ ] For every `new` usage, there is a reason the data must be on the heap +- [ ] For every `new` there is a `delete`, unless I explicitly know why (e.g. ROOT or a BoostStore takes ownership) + +## Additional Material +Attach any validation or demonstration files here. You may also link to relavant docdb articles. diff --git a/.github/workflows/tempbuild.yml b/.github/workflows/tempbuild.yml index 210b82506..c9c2a4393 100644 --- a/.github/workflows/tempbuild.yml +++ b/.github/workflows/tempbuild.yml @@ -27,37 +27,78 @@ jobs: sudo rm -rf \ /usr/share/dotnet /usr/local/lib/android /opt/ghc \ /usr/local/share/powershell /usr/share/swift /usr/local/.ghcup \ - /usr/lib/jvm /usr/local/share/boost || true + /usr/lib/jvm /usr/local/share/boost sudo rm -rf "$AGENT_TOOLSDIRECTORY"; echo "some directories deleted" - sudo apt install aptitude -y >/dev/null 2>&1 - sudo apt-get update >/dev/null 2>&1 - sudo aptitude purge aria2 ansible azure-cli shellcheck rpm xorriso zsync \ - esl-erlang firefox gfortran-8 gfortran-9 google-chrome-stable \ - google-cloud-sdk google-cloud-cli imagemagick \ - libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \ - mercurial apt-transport-https mono-complete libmysqlclient \ - unixodbc-dev yarn chrpath libssl-dev libxft-dev \ - libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev \ - snmp pollinate libpq-dev postgresql-client powershell ruby-full \ - sphinxsearch subversion mongodb-org azure-cli microsoft-edge-stable \ - -y -f >/dev/null 2>&1 - sudo aptitude purge google-cloud-sdk -f -y >/dev/null 2>&1 - sudo aptitude purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true - sudo apt purge microsoft-edge-stable -f -y >/dev/null 2>&1 || true - sudo aptitude purge google-chrome-stable -f -y >/dev/null 2>&1 || true - sudo aptitude purge '~n ^mysql' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^php' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^dotnet' -f -y >/dev/null 2>&1 - sudo aptitude purge '~n ^temurin' -f -y >/dev/null 2>&1 - sudo apt-get autoremove -y >/dev/null 2>&1 - sudo apt-get autoclean -y >/dev/null 2>&1 + sudo apt-get update --allow-releaseinfo-change + echo "apt-get update: $?" + sudo apt install aptitude -y >/dev/null + echo "aptitude install: $?" + sudo aptitude purge aria2 -f -y >/dev/null || true + sudo aptitude purge ansible -f -y >/dev/null || true + sudo aptitude purge azure-cli -f -y >/dev/null || true + sudo aptitude purge shellcheck -f -y >/dev/null || true + sudo aptitude purge rpm -f -y >/dev/null || true + sudo aptitude purge xorriso -f -y >/dev/null || true + sudo aptitude purge zsync -f -y >/dev/null || true + sudo aptitude purge esl-erlang -f -y >/dev/null || true + sudo aptitude purge firefox -f -y >/dev/null || true + sudo aptitude purge gfortran-8 -f -y >/dev/null || true + sudo aptitude purge gfortran-9 -f -y >/dev/null || true + sudo aptitude purge google-chrome-stable -f -y >/dev/null || true + sudo aptitude purge google-cloud-sdk -f -y >/dev/null || true + sudo aptitude purge google-cloud-cli -f -y >/dev/null || true + sudo aptitude purge imagemagick -f -y >/dev/null || true + sudo aptitude purge libmagickcore-dev -f -y >/dev/null || true + sudo aptitude purge libmagickwand-dev -f -y >/dev/null || true + sudo aptitude purge libmagic-dev -f -y >/dev/null || true + sudo aptitude purge ant -f -y >/dev/null || true + sudo aptitude purge ant-optional -f -y >/dev/null || true + sudo aptitude purge kubectl -f -y >/dev/null || true + sudo aptitude purge mercurial -f -y >/dev/null || true + sudo aptitude purge apt-transport-https -f -y >/dev/null || true + sudo aptitude purge mono-complete -f -y >/dev/null || true + sudo aptitude purge libmysqlclient -f -y >/dev/null || true + sudo aptitude purge unixodbc-dev -f -y >/dev/null || true + sudo aptitude purge yarn -f -y >/dev/null || true + sudo aptitude purge chrpath -f -y >/dev/null || true + sudo aptitude purge libssl-dev -f -y >/dev/null || true + sudo aptitude purge libxft-dev -f -y >/dev/null || true + sudo aptitude purge libfreetype6 -f -y >/dev/null || true + sudo aptitude purge libfreetype6-dev -f -y >/dev/null || true + sudo aptitude purge libfontconfig1 -f -y >/dev/null || true + sudo aptitude purge libfontconfig1-dev -f -y >/dev/null || true + sudo aptitude purge snmp -f -y >/dev/null || true + sudo aptitude purge pollinate -f -y >/dev/null || true + sudo aptitude purge libpq-dev -f -y >/dev/null || true + sudo aptitude purge postgresql-client -f -y >/dev/null || true + sudo aptitude purge powershell -f -y >/dev/null || true + sudo aptitude purge ruby -full -f -y >/dev/null || true + sudo aptitude purge sphinxsearch -f -y >/dev/null || true + sudo aptitude purge subversion -f -y >/dev/null || true + sudo aptitude purge mongodb-org -f -y >/dev/null || true + sudo aptitude purge azure-cli -f -y >/dev/null || true + sudo aptitude purge microsoft-edge-stable -f -y >/dev/null || true + sudo aptitude purge '~n ^mysql' -f -y >/dev/null || true + sudo aptitude purge '~n ^php' -f -y >/dev/null || true + sudo aptitude purge '~n ^dotnet' -f -y >/dev/null || true + sudo aptitude purge '~n ^temurin' -f -y >/dev/null || true echo "some packages purged" + sudo apt-get autoremove -y >/dev/null + sudo apt-get autoclean -y >/dev/null + echo "done apt autoremove and autoclean" + sudo rm -rf /opt/microsoft # 783M + sudo rm -rf /usr/lib/llvm-* # 1900M + sudo rm -rf /usr/local/julia* # 1008M + sudo rm -rf /usr/local/share/chromium # 613M + sudo rm -rf /usr/local/share/powershell # 1244M + sudo rm -rf /usr/share/swift # 3207M + sudo df -TBG / + echo "more directories deleted" #docker rmi $(docker image ls -aq) || true sudo swapoff /swapfile || true sudo rm -rf /swapfile - sudo apt-get autoremove -y >/dev/null 2>&1 || true - sudo apt-get autoclean -y >/dev/null 2>&1 || true + echo "cleanup done" - name: Check disk space run: | sudo dpkg-query -Wf '${Installed-Size}\t${Package}\n' | sort -nr | head @@ -90,7 +131,7 @@ jobs: ################## - name: build and test - uses: addnab/docker-run-action@v3 + uses: Baardrw/docker-run-action@v4 with: image: anniesoft/toolanalysis:latest registry: docker.io @@ -100,6 +141,7 @@ jobs: echo `pwd` ls -l cd /TA + git config --global --add safe.directory /TA ls -l ln -s /ToolAnalysis/ToolDAQ $PWD/ToolDAQ ls -l ./ToolDAQ diff --git a/.gitignore b/.gitignore index 4c45d695e..1117cb01c 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,6 @@ DataModel/DataModel_Linkdef.hh # These are imported as part of ToolPack 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.cpp b/DataModel/ADCPulse.cpp index 84a3e3247..03d5a0d21 100755 --- a/DataModel/ADCPulse.cpp +++ b/DataModel/ADCPulse.cpp @@ -7,9 +7,11 @@ ADCPulse::ADCPulse(int TubeId, double start_time, double peak_time, double baseline, double sigma_baseline, unsigned long area, unsigned short raw_amplitude, double calibrated_amplitude, - double charge) : Hit(TubeId, start_time, charge), + double charge, const std::vector& trace_x, const std::vector& trace_y) : + Hit(TubeId, start_time, charge), start_time_(start_time), peak_time_(peak_time), baseline_(baseline), sigma_baseline_(sigma_baseline), raw_area_(area), - raw_amplitude_(raw_amplitude), calibrated_amplitude_(calibrated_amplitude) + raw_amplitude_(raw_amplitude), calibrated_amplitude_(calibrated_amplitude), + trace_x_(trace_x), trace_y_(trace_y) { } diff --git a/DataModel/ADCPulse.h b/DataModel/ADCPulse.h index 891e840d0..422a7cd81 100755 --- a/DataModel/ADCPulse.h +++ b/DataModel/ADCPulse.h @@ -9,6 +9,7 @@ // ToolAnalysis includes #include "ChannelKey.h" #include "Hit.h" +#include class ADCPulse : public Hit { @@ -22,8 +23,9 @@ class ADCPulse : public Hit { // int TubeId member ADCPulse(int TubeId, double start_time, double peak_time, double baseline, double sigma_baseline, unsigned long raw_area, - unsigned short raw_amplitude, double calibrated_amplitude, - double charge); + unsigned short raw_amplitude, double calibrated_amplitude, double charge, + const std::vector& trace_x = std::vector(), + const std::vector& trace_y = std::vector()); // @brief Returns the start time (ns) of the pulse relative to the // start of its minibuffer @@ -59,6 +61,10 @@ class ADCPulse : public Hit { // (baseline-subtracted) pulse inline double amplitude() const { return calibrated_amplitude_; } + // @brief Returns the x [ns] and y [ADC] points of the "found" pulse (baseline-subtracted and relative to pulse start point) + inline const std::vector& GetTraceXPoints() const { return trace_x_; } + inline const std::vector& GetTraceYPoints() const { return trace_y_; } + template void serialize(Archive& ar, const unsigned int version) { @@ -71,6 +77,10 @@ class ADCPulse : public Hit { ar & raw_area_; ar & raw_amplitude_; ar & calibrated_amplitude_; + if (version > 0) { + ar & trace_x_; + ar & trace_y_; + } } protected: @@ -83,4 +93,11 @@ class ADCPulse : public Hit { unsigned short raw_amplitude_; // ADC double calibrated_amplitude_; // V + + std::vector trace_x_ = {}; // x points of the pulse (start at 0, relative to pulse start) [ns] + 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 +// the version number ensures backward compatibility when serializing +BOOST_CLASS_VERSION(ADCPulse, 1) diff --git a/DataModel/ANNIEGeometry.cpp b/DataModel/ANNIEGeometry.cpp index 27e2c66c3..eeeb105ba 100644 --- a/DataModel/ANNIEGeometry.cpp +++ b/DataModel/ANNIEGeometry.cpp @@ -190,8 +190,8 @@ void ANNIEGeometry::SetGeometry(){ //WCSim fCylRadius = 152.0; //cm fCylLength = 396.0; //cm - fCylFiducialRadius = 0.0; - fCylFiducialLength = 0.0; + fCylFiducialRadius = 100.0; //cm + fCylFiducialLength = 200.0; //cm fXoffset = 0.0; fYoffset = 0.0; fZoffset = 0.0; @@ -337,11 +337,11 @@ bool ANNIEGeometry::InsideDetector(double x, double y, double z) bool ANNIEGeometry::InsideFiducialVolume(double x, double y, double z) { if( fGeoType==ANNIEGeometry::kCylinder ){ - if( z>=-0.5*fCylFiducialLength && z<=+0.5*fCylFiducialLength - && x*x+y*y<=fCylFiducialRadius*fCylFiducialRadius ){ + if( y>=-0.5*fCylFiducialLength && y<=+0.5*fCylFiducialLength + && x*x+z*z<=fCylFiducialRadius*fCylFiducialRadius ){ return 1; } - } else std::cout<<"WTF ANNIE Should Be A Cylinder!!!!"<dr ) dr = fCylRadius; if( 0.5*fCylLength>dr ) dr = 0.5*fCylLength; - if( -sqrt(x*x+y*y)+fCylRadius=-0.5*fCylLength && z<=+0.5*fCylLength ){ - return -sqrt(x*x+y*y)+fCylRadius; + if( y>=-0.5*fCylLength && y<=+0.5*fCylLength ){ + return -sqrt(x*x+z*z)+fCylRadius; } - // top region - if( z<=-0.5*fCylLength - && x*x+y*y=+0.5*fCylLength - && x*x+y*y=+0.5*fCylLength + && x*x+z*z=+0.5*fCylLength - && x*x+y*y>=fCylRadius ){ - double dr = sqrt(x*x+y*y)-fCylRadius; - double dz = -z+0.5*fCylLength; - return -sqrt(dr*dr+dz*dz); + if( y>=+0.5*fCylLength + && x*x+z*z>=fCylRadius ){ + double dr = sqrt(x*x+z*z)-fCylRadius; + double dy = -y+0.5*fCylLength; + return -sqrt(dr*dr+dy*dy); } - if( z<=-0.5*fCylLength - && x*x+y*y>=fCylRadius ){ - double dr = sqrt(x*x+y*y)-fCylRadius; - double dz = +z+0.5*fCylLength; - return -sqrt(dr*dr+dz*dz); + if( y<=-0.5*fCylLength + && x*x+z*z>=fCylRadius ){ + double dr = sqrt(x*x+z*z)-fCylRadius; + double dy = y+0.5*fCylLength; + return -sqrt(dr*dr+dy*dy); } } } diff --git a/DataModel/Channel.h b/DataModel/Channel.h index 80f4b2626..90f127f38 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,9 +101,12 @@ class Channel : public SerialisableObject{ ar & hv_card; ar & hv_channel; ar & status; + if(version > 0) ar & channelType; } } }; +BOOST_CLASS_VERSION(Channel, 1) + #endif diff --git a/UserTools/recoANNIE/Constants.h b/DataModel/Constants.h similarity index 100% rename from UserTools/recoANNIE/Constants.h rename to DataModel/Constants.h 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..5ab8253e5 100755 --- a/DataModel/LAPPDPulse.h +++ b/DataModel/LAPPDPulse.h @@ -22,12 +22,24 @@ 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;} + 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 : "< void serialize(Archive & ar, const unsigned int version){ @@ -47,10 +65,19 @@ class LAPPDPulse : public Hit{ ar & Peak; ar & LowRange; ar & HiRange; + ar & halfHeightTime; + ar & halfEndTime; + ar & baseline; + if(version>0){ + ar & pulseFollowTime; + ar & pulseFollowCharge; + } } } }; +BOOST_CLASS_VERSION(LAPPDPulse, 1) + /* Derived classes, if there's a reason to have them. So far...not really class TDCHit : public Hit { diff --git a/UserTools/LAPPDSim/LAPPDresponse.cpp b/DataModel/LAPPDresponse.cpp similarity index 100% rename from UserTools/LAPPDSim/LAPPDresponse.cpp rename to DataModel/LAPPDresponse.cpp diff --git a/UserTools/LAPPDSim/LAPPDresponse.h b/DataModel/LAPPDresponse.h similarity index 100% rename from UserTools/LAPPDSim/LAPPDresponse.h rename to DataModel/LAPPDresponse.h diff --git a/UserTools/recoANNIE/RawAnalyzer.cc b/DataModel/RawAnalyzer.cpp similarity index 100% rename from UserTools/recoANNIE/RawAnalyzer.cc rename to DataModel/RawAnalyzer.cpp diff --git a/UserTools/recoANNIE/RawAnalyzer.h b/DataModel/RawAnalyzer.h similarity index 100% rename from UserTools/recoANNIE/RawAnalyzer.h rename to DataModel/RawAnalyzer.h diff --git a/UserTools/recoANNIE/RawCard.cc b/DataModel/RawCard.cpp similarity index 100% rename from UserTools/recoANNIE/RawCard.cc rename to DataModel/RawCard.cpp diff --git a/UserTools/recoANNIE/RawCard.h b/DataModel/RawCard.h similarity index 100% rename from UserTools/recoANNIE/RawCard.h rename to DataModel/RawCard.h diff --git a/UserTools/recoANNIE/RawChannel.cc b/DataModel/RawChannel.cpp similarity index 100% rename from UserTools/recoANNIE/RawChannel.cc rename to DataModel/RawChannel.cpp diff --git a/UserTools/recoANNIE/RawChannel.h b/DataModel/RawChannel.h similarity index 100% rename from UserTools/recoANNIE/RawChannel.h rename to DataModel/RawChannel.h diff --git a/UserTools/recoANNIE/RawReader.cc b/DataModel/RawReader.cpp similarity index 100% rename from UserTools/recoANNIE/RawReader.cc rename to DataModel/RawReader.cpp diff --git a/UserTools/recoANNIE/RawReader.h b/DataModel/RawReader.h similarity index 100% rename from UserTools/recoANNIE/RawReader.h rename to DataModel/RawReader.h diff --git a/UserTools/recoANNIE/RawReadout.cc b/DataModel/RawReadout.cpp similarity index 100% rename from UserTools/recoANNIE/RawReadout.cc rename to DataModel/RawReadout.cpp diff --git a/UserTools/recoANNIE/RawReadout.h b/DataModel/RawReadout.h similarity index 100% rename from UserTools/recoANNIE/RawReadout.h rename to DataModel/RawReadout.h diff --git a/UserTools/recoANNIE/RawTrigData.cc b/DataModel/RawTrigData.cpp similarity index 100% rename from UserTools/recoANNIE/RawTrigData.cc rename to DataModel/RawTrigData.cpp diff --git a/UserTools/recoANNIE/RawTrigData.h b/DataModel/RawTrigData.h similarity index 100% rename from UserTools/recoANNIE/RawTrigData.h rename to DataModel/RawTrigData.h diff --git a/DataModel/RecoCluster.cpp b/DataModel/RecoCluster.cpp index c63855600..6f49feb0e 100644 --- a/DataModel/RecoCluster.cpp +++ b/DataModel/RecoCluster.cpp @@ -1,4 +1,4 @@ -#include "RecoCluster.h" +#include "RecoCluster.h" #include "ANNIERecoObjectTable.h" #include @@ -17,15 +17,15 @@ RecoCluster::~RecoCluster() void RecoCluster::Reset() { int j=fDigitList.size(); - for(int i=0;iGetCalTime() > rd2->GetCalTime() ); + return ( rd1.GetCalTime() > rd2.GetCalTime() ); } void RecoCluster::SortCluster() @@ -33,14 +33,15 @@ void RecoCluster::SortCluster() sort(fDigitList.begin(), fDigitList.end(), CompareTimes); } -void RecoCluster::AddDigit(RecoDigit* digit) +void RecoCluster::AddDigit(RecoDigit digit) { - fDigitList.push_back(digit); + //digit.AddCluster(fClusterMode); + fDigitList.push_back(digit); } -RecoDigit* RecoCluster::GetDigit(int n) +RecoDigit RecoCluster::GetDigit(int n) { - return (RecoDigit*)(fDigitList.at(n)); + return (RecoDigit)(fDigitList.at(n)); } int RecoCluster::GetNDigits() @@ -48,5 +49,392 @@ int RecoCluster::GetNDigits() return fDigitList.size(); } +void RecoCluster::SetClusterMode(int cmode) +{ + fClusterMode = cmode; +} + +int RecoCluster::GetClusterMode() +{ + return fClusterMode; +} + +bool RecoCluster::CheckFilter() { + map ModeDigitMap; + vector DigitModes; + double baseline; + + fIsFiltered=true; + for (int i=0;i apair : ModeDigitMap) { + if (apair.first>=fClusterMode) continue; + if(apair.second/baseline>0.6) fIsFiltered=false; + } + return fIsFiltered; +} + +void RecoCluster::CalcTime() { + double sum = 0; + for (int i=0; iat(i)->GetDigitType()==RecoDigit::PMT8inch){ + if (fDigitList.at(i).GetFilterStatus()) { + double tube_charge = fDigitList.at(i).GetCalCharge(); + total_Q += tube_charge; + total_QSquared += (tube_charge * tube_charge); + //} + } + } + //FIXME: Need a method to have the 123 be equal to the number of operating detectors + double charge_balance = sqrt((total_QSquared) / (total_Q * total_Q) - (1. / 123.)); + + clusterCB=charge_balance; +} + +//Calculate Angular span +// - AS0 is the maximum angle between any two hit PMTs +// - AS1 is the largest angle between the greatest hit by charge and any of the other hits +// - ASC is a charge-weighted version of AS0 +void RecoCluster::CalcAS() { + + double max_angle = 0; + double angle; + Position i_position, j_position; + double max_charge = 0; + double max_angle2 = 0; + int max_index = 0; + Position max_position; + double max_chargeangle = 0; + double chargeangle; + double iq, jq; + + for (int i = 0; i < fDigitList.size(); i++) { + i_position = fDigitList.at(i).GetPosition(); + for (int j = 0; j < fDigitList.size(); j++) { + if (j == i)continue; + j_position = fDigitList.at(j).GetPosition(); + + angle = j_position.Angle(i_position); + if (angle > max_angle)max_angle = angle; + + } + + if (fDigitList.at(i).GetCalCharge() > max_charge) { + max_charge = fDigitList.at(i).GetCalCharge(); + max_index = i; + max_position = fDigitList.at(i).GetPosition(); + } + + iq = fDigitList.at(i).GetCalCharge(); + for (int j = 0; j < fDigitList.size(); j++) { + if (j == i)continue; + j_position = fDigitList.at(j).GetPosition(); + jq = fDigitList.at(j).GetCalCharge(); + chargeangle = iq * jq * j_position.Angle(i_position); + if (chargeangle > max_chargeangle)max_chargeangle = chargeangle; + } + } + AS0 = max_angle; + + for (int i = 0; i < fDigitList.size(); i++) { + if (i == max_index)continue; + i_position = fDigitList.at(i).GetPosition(); + angle = i_position.Angle(max_position); + if (angle > max_angle2)max_angle2 = angle; + } + AS1 = max_angle2; + + ASC=max_chargeangle; + +} + +//Retrieve Angular Span value +double RecoCluster::GetAS(int mode) { + if(mode==0)return AS0; + else if(mode==1)return AS1; + else return 0; +} + +void RecoCluster::CalcParameters() { + this->CalcTime(); + this->CalcCharge(); + this->CalcCB(); + this->CalcAS(); + this->CalcSA(); + this->CalcAW(); + this->CalcCV(); + this->CalcAMD(); + this->CalcPlanaritySphericity(); + this->CalcTR(); + + //Other needed parameters here +} + +void RecoCluster::SetParticle(int pID, int pPDG, double eff, double pur) { + bestParticleID=pID; + bestParticlePDG=pPDG; + efficiency=eff; + purity=pur; +} + +int RecoCluster::calcBestParent() { + std::map ParticletoClusterCharge; + int parentCandidate; + int maxIndex=0; + double digitCharge; + double maxCharge=0; + int tempPDG = -5; + for (int i = 0; i < fDigitList.size(); i++) { + RecoDigit i_digit=fDigitList.at(i); + for(int j=0; japair : ParticletoClusterCharge) { + if (apair.second > maxCharge) { + maxCharge=apair.second; + maxIndex=apair.first; + + } + } + //cout << "Particle " << maxIndex << " wins with charge " << maxCharge << endl; + + bestParticleID=maxIndex; + purity=maxCharge/clusterCharge; + + return maxIndex; +} + +void RecoCluster::CalcCV() { + Position ud; + ChargeVector.SetX(0); + ChargeVector.SetY(0); + ChargeVector.SetZ(0); + for (int i = 0; i < fDigitList.size(); i++) { + for (int j = i + 1; j < fDigitList.size(); j++) { + ud=(fDigitList.at(i).GetPosition() - fDigitList.at(j).GetPosition()).Unit(); + ChargeVector+=(fDigitList.at(i).GetCalCharge()*fDigitList.at(j).GetCalCharge())*ud; + } + } +} + +void RecoCluster::CalcAMD() { + double min_distance = 9999; + double ave_min_distance=0; + double distance; + for (int i = 0; i < fDigitList.size(); i++) { + Position ipos=fDigitList.at(i).GetPosition(); + for (int j = 0; j < fDigitList.size(); j++) { + if(j == i) continue; + Position jpos=fDigitList.at(j).GetPosition(); + distance = (jpos-ipos).Mag(); + if(distance angle_charge_map; + double angle,charge; + double contained=0; + for (int i = 0; i < fDigitList.size(); i++) { + RecoDigit idigit=fDigitList.at(i); + angle=SpatialAverage.Angle(idigit.GetPosition()); + charge = idigit.GetCalCharge(); + if(angle_charge_map.count(angle)==0) + angle_charge_map.emplace(angle,charge); + else + angle_charge_map.at(angle)+=charge; + } + for (std::pair apair: angle_charge_map) { + AngularWidth=apair.first; + contained+=apair.second/clusterCharge; + if(contained>0.68)break; + } + return; +} + +//Planarity and Sphericity: measure of how planar or spherical cluster is; currently in-process of translating from reference +void RecoCluster::CalcPlanaritySphericity() +{ + double P = 0.0; double S = 0.0; + + // 1) Charge-weighted centroid + Position mean(0, 0, 0); + double wsum = 0.0; + for (int i = 0; i lambda = { evals[0], evals[1], evals[2] }; + std::sort(lambda.begin(), lambda.end(), std::greater()); + + const double lambda1 = lambda[0]; // largest + const double lambda2 = lambda[1]; + const double lambda3 = lambda[2]; // smallest + const double sum = lambda1 + lambda2 + lambda3; + + if (sum <= 0.0) return; + + // 4) Planarity and Sphericity + // P = (lambda2 - lambda3) / (lambda1 + lambda2 + lambda3) + // S = (3/2) * lambda3 / (lambda1 + lambda2 + lambda3) + P = (lambda2 - lambda3) / sum; + S = 1.5 * (lambda3 / sum); + + Planarity=P; + Sphericity=S; +} + +double RecoCluster::CalcBeta(int order) { + double Beta=0; + Position ipos,jpos; + double angle; + int NDigits=fDigitList.size(); + TF1 LegendreFunction("legendrefunction","ROOT::Math::legendre([0],x)",-1,1); + LegendreFunction.SetParameter(0,order); + for (int i = 0; i < fDigitList.size(); i++) { + for (int j = i + 1; j < fDigitList.size(); j++) { + ipos=fDigitList.at(i).GetPosition(); + jpos=fDigitList.at(j).GetPosition(); + angle=ipos.Angle(jpos); + Beta+=2 * LegendreFunction.Eval(cos(angle)) / (NDigits*(NDigits-1)); + } + } + + if(BetaParameters.count(order)) BetaParameters.at(order)=Beta; + else BetaParameters.emplace(order, Beta); + + return Beta; +} + +double RecoCluster::GetBeta(int order) { + if(BetaParameters.count(order))return BetaParameters.at(order); + else return -999; +} + +void RecoCluster::CalcTR() { + double firsttime=fDigitList.at(0).GetCalTime(); + double lasttime=fDigitList.at(fDigitList.size()-1).GetCalTime(); + double maxtime=fDigitList.at(0).GetCalTime(); + double maxcharge=fDigitList.at(0).GetCalCharge(); + + for (int i = 0; i < fDigitList.size(); i++) { + RecoDigit adigit=fDigitList.at(i); + if(adigit.GetCalTime()lasttime)lasttime=adigit.GetCalTime(); + if (adigit.GetCalCharge() > maxcharge) { + maxtime=adigit.GetCalTime(); + maxcharge=adigit.GetCalCharge(); + } + } + + TRTotal=lasttime-firsttime; + if(clusterTime-firsttime>lasttime-clusterTime)TRCluster=clusterTime-firsttime; + else TRCluster=lasttime-clusterTime; + if(maxtime-firsttime>lasttime-maxtime)TRQ=maxtime-firsttime; + else TRQ=lasttime-maxtime; + + TRRatioTQ=TRTotal/TRQ; + TRRatioTC=TRTotal/TRCluster; + TRRatioQC=TRQ/TRCluster; +} +/*void RecoCluster::CleanDigits() { + for (int i = 0; i < fDigitList.size(); i++) { + if (fDigitList.at(i) != nullptr) { + delete fDigitList.at(i); + fDigitList.at(i)=nullptr; + } + } +}*/ \ No newline at end of file diff --git a/DataModel/RecoCluster.h b/DataModel/RecoCluster.h index 4afb14268..4c3681cd0 100644 --- a/DataModel/RecoCluster.h +++ b/DataModel/RecoCluster.h @@ -3,7 +3,15 @@ #ifndef RECOCLUSTER_H #define RECOCLUSTER_H #include "RecoDigit.h" +#include "Position.h" #include +#include "TVector3.h" +#include "TMatrixDSym.h" +#include "TMatrixDSymEigen.h" +#include "TVectorD.h" +#include "TMath.h" +#include "TF1.h" +#include "Math/IFunction.h" class RecoCluster : public SerialisableObject { @@ -16,19 +24,96 @@ class RecoCluster : public SerialisableObject { void Reset(); void SortCluster(); - void AddDigit(RecoDigit* digit); + void AddDigit(RecoDigit digit); + inline void SetDigits(vector indigits){fDigitList=indigits;} - RecoDigit* GetDigit(int n); + RecoDigit GetDigit(int n); + + void SetClusterMode(int cmode); + + int GetClusterMode(); + + std::vector GetDigitList() {return fDigitList;} + int GetNDigits(); bool Print() { cout<<"Number of digits in this cluster : "< BetaParameters; + double TRTotal, TRQ, TRCluster; + double TRRatioTQ, TRRatioTC,TRRatioQC; + int bestParticleID; + int bestParticlePDG; + double efficiency; + double purity; + bool fIsFiltered=0; + + + int fClusterMode = -999; + std::vector fDigitList; + Position TwoDCenter; - std::vector fDigitList; protected: template void serialize(Archive & ar, const unsigned int version){ diff --git a/DataModel/RecoDigit.h b/DataModel/RecoDigit.h index 13d12c4d0..f766d0e45 100644 --- a/DataModel/RecoDigit.h +++ b/DataModel/RecoDigit.h @@ -33,15 +33,32 @@ class RecoDigit : public SerialisableObject{ fIsFiltered = 1; ANNIERecoObjectTable::Instance()->NewDigit(); } + RecoDigit(RecoDigit* origin) { + serialise=true; + fRegion=origin->GetRegion(); + fPosition = origin->GetPosition(); + fCalTime = origin->GetCalTime(); + fCalCharge=origin->GetCalCharge(); + fDigitType=origin->GetDigitType(); + fDetectorID=origin->GetDetectorID(); + fIsFiltered=origin->GetFilterStatus(); + + } ~RecoDigit() {/*ANNIERecoObjectTable::Instance()->DeleteDigit();*/} + bool operator<(const RecoDigit other) const { + return (fPosition.X() == other.GetPosition().X()) ? fPosition.Y() < other.GetPosition().Y() : fPosition.X() < other.GetPosition().X(); + } + inline int GetRegion() const {return fRegion;} inline Position GetPosition() const {return fPosition;} inline double GetCalTime() const {return fCalTime;} inline double GetCalCharge() const {return fCalCharge;} inline bool GetFilterStatus() const {return fIsFiltered;} + inline vector GetClusteredModes() { return fClusterMode; } inline int GetDigitType() const {return fDigitType;} inline int GetDetectorID() const {return fDetectorID;} + inline std::vector GetParents() const {return Parents;} inline void SetRegion(int reg) {fRegion = reg;} inline void SetPosition(Position pos){fPosition = pos;} @@ -52,6 +69,9 @@ class RecoDigit : public SerialisableObject{ inline void SetFilter(bool pass = 1) { fIsFiltered = pass;} inline void ResetFilter() {SetFilter(0);} inline void PassFilter() {SetFilter(1);} + inline void AddCluster(int InClusterMode) {fClusterMode.push_back(InClusterMode); } + inline void UnCluster(){fClusterMode.pop_back(); } + inline void SetParents(std::vector parentsin) { Parents = parentsin; } bool Print() { cout<<"Region : "< fClusterMode; int fDigitType; int fDetectorID; + std::vector Parents; template void serialize(Archive & ar, const unsigned int version){ if(serialise){ diff --git a/UserTools/recoANNIE/RecoPulse.cc b/DataModel/RecoPulse.cpp similarity index 100% rename from UserTools/recoANNIE/RecoPulse.cc rename to DataModel/RecoPulse.cpp diff --git a/UserTools/recoANNIE/RecoPulse.h b/DataModel/RecoPulse.h similarity index 100% rename from UserTools/recoANNIE/RecoPulse.h rename to DataModel/RecoPulse.h diff --git a/UserTools/recoANNIE/RecoReadout.cc b/DataModel/RecoReadout.cpp similarity index 100% rename from UserTools/recoANNIE/RecoReadout.cc rename to DataModel/RecoReadout.cpp diff --git a/UserTools/recoANNIE/RecoReadout.h b/DataModel/RecoReadout.h similarity index 100% rename from UserTools/recoANNIE/RecoReadout.h rename to DataModel/RecoReadout.h diff --git a/UserTools/recoANNIE/Unity_recoANNIE.h b/DataModel/Unity_recoANNIE.h similarity index 100% rename from UserTools/recoANNIE/Unity_recoANNIE.h rename to DataModel/Unity_recoANNIE.h diff --git a/UserTools/recoANNIE/annie_math.cc b/DataModel/annie_math.cpp similarity index 100% rename from UserTools/recoANNIE/annie_math.cc rename to DataModel/annie_math.cpp diff --git a/UserTools/recoANNIE/annie_math.h b/DataModel/annie_math.h similarity index 100% rename from UserTools/recoANNIE/annie_math.h rename to DataModel/annie_math.h diff --git a/FilterLAPPDEvents b/FilterLAPPDEvents deleted file mode 120000 index a369f0f49..000000000 --- a/FilterLAPPDEvents +++ /dev/null @@ -1 +0,0 @@ -configfiles/FilterLAPPDEvents/ToolChainConfig \ No newline at end of file diff --git a/GetToolDAQ.sh b/GetToolDAQ.sh index 543fcff50..7bd2292b3 100644 --- a/GetToolDAQ.sh +++ b/GetToolDAQ.sh @@ -497,6 +497,7 @@ then pip3 install uproot==4.3.7 pip3 install xgboost==1.6.2 pip3 install tensorflow==2.10.0 + pip3 install torch==1.12.1 pip3 install PyQt5 # set tensorflow verbosity to suppress info messages about not having a GPU or maximal acceleration # https://stackoverflow.com/questions/35911252/disable-tensorflow-debugging-information/42121886#42121886 diff --git a/Makefile b/Makefile index f5694a95e..dc65475a8 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,40 @@ ToolDAQPath=${PWD}/ToolDAQ +ifeq ($(TOOLCHAIN),) +TOOLCHAIN:=$(shell find ./configfiles -type d -path ./configfiles/$(MAKECMDGOALS) -exec echo {} \; 2>/dev/null) +TOOLCHAINNAME:=$(subst ./configfiles/,,$(TOOLCHAIN)) +$(info TOOLCHAINNAME: $(TOOLCHAINNAME)) +ifneq ($(MAKECMDGOALS),clean) +TOOLS:=$(shell ./gettools.sh $(TOOLCHAIN)) +#OBJECTS:=$(foreach tool,$(TOOLS),UserTools/$(tool)/$(tool).o) +OBJECTS:=$(shell ./getobjects.sh $(TOOLS)) +endif +$(info TOOLCHAIN: $(TOOLCHAIN)) +$(info TOOLS needed: $(TOOLS)) +$(info OBJECTS: $(OBJECTS)) +NPROCS:=$(shell nproc --all) GIT_VERSION := "$(shell git describe --dirty --always)" +# forward these to variables to internal $(MAKE) calls +export +endif -CPPFLAGS= -DVERSION=\"$(GIT_VERSION)\" -Wno-reorder -Wno-sign-compare -Wno-unused-variable -Wno-unused-but-set-variable -Werror=return-type -Wl,--no-as-needed +ifeq ($(TOOLCHAIN),) +TOOLCHAIN:=./configfiles/Dummy +TOOLCHAINNAME:=Dummy +endif -CC=g++ -std=c++1y -g -fPIC -shared $(CPPFLAGS) -CCC= g++ -std=c++1y -g -fPIC $(CPPFLAGS) +CPPFLAGS= -fmax-errors=1 -DVERSION=\"$(GIT_VERSION)\" -Wno-reorder -Wno-sign-compare -Wno-unused-variable -Wno-unused-but-set-variable -Werror=return-type -Wl,--no-as-needed +CC=g++ -std=c++1y -g -O3 -fPIC -shared $(CPPFLAGS) +CCC= g++ -std=c++1y -g -O3 -fPIC $(CPPFLAGS) -ZMQLib= -L $(ToolDAQPath)/zeromq-4.0.7/lib -lzmq + +ZMQLib= -L $(ToolDAQPath)/zeromq-4.0.7/lib -lzmq ZMQInclude= -isystem$(ToolDAQPath)/zeromq-4.0.7/include/ BoostLib= -L $(ToolDAQPath)/boost_1_66_0/install/lib -lboost_date_time -lboost_serialization -lboost_iostreams -lboost_system -lboost_filesystem -lboost_regex BoostInclude= -isystem$(ToolDAQPath)/boost_1_66_0/install/include - + WCSimLib= -L $(ToolDAQPath)/WCSimLib -lWCSimRoot WCSimInclude= -I $(ToolDAQPath)/WCSimLib/include @@ -58,10 +79,10 @@ MyToolsInclude += `python3-config --cflags` -Wno-sign-compare MyToolsLib = -lcurl $(RootLib) $(MrdTrackLib) $(WCSimLib) $(RATEventLib) $(RawViewerLib) $(CLHEPLib) $(Log4CppLibs) $(GenieLibs) $(PythiaLibs) MyToolsLib += `python3-config --ldflags --embed` +all: Dummy lib/libStore.so lib/libLogging.so lib/libDataModel.so include/Tool.h lib/libServiceDiscovery.so lib/libMyTools.so Analyse +#.PHONY: UserTools/MyFactory/MyFactory.cpp UserTools/MyFactory/Unity.h -all: lib/libStore.so lib/libLogging.so lib/libDataModel.so include/Tool.h lib/libMyTools.so lib/libServiceDiscovery.so lib/libToolChain.so Analyse - -Analyse: src/main.cpp | lib/libMyTools.so lib/libStore.so lib/libLogging.so lib/libToolChain.so lib/libDataModel.so lib/libServiceDiscovery.so +Analyse: UserTools/MyFactory/MyFactory.cpp UserTools/MyFactory/Unity.h src/main.cpp | lib/libStore.so lib/libLogging.so lib/libToolChain.so lib/libServiceDiscovery.so lib/libMyTools.so lib/libDataModel.so @echo -e "\n*************** Making " $@ "****************" g++ -std=c++1y -g -fPIC $(CPPFLAGS) src/main.cpp -o Analyse -I include -L lib -lStore -lMyTools -lToolChain -lDataModel -lLogging -lServiceDiscovery -lpthread $(DataModelInclude) $(DataModelLib) $(MyToolsInclude) $(MyToolsLib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) @@ -70,38 +91,36 @@ lib/libStore.so: $(ToolDAQPath)/ToolDAQFramework/src/Store/* cd $(ToolDAQPath)/ToolDAQFramework && make lib/libStore.so @echo -e "\n*************** Copying " $@ "****************" cp $(ToolDAQPath)/ToolDAQFramework/src/Store/*.h include/ - cp $(ToolDAQPath)/ToolDAQFramework/lib/libStore.so lib/ - #$(CC) -I include $(ToolDAQPath)/ToolDAQFramework/src/Store/*.cpp -o lib/libStore.so $(BoostLib) $(BoostInclude) + cp $(ToolDAQPath)/ToolDAQFramework/lib/libStore.so lib/ include/Tool.h: $(ToolDAQPath)/ToolDAQFramework/src/Tool/Tool.h @echo -e "\n*************** Copying " $@ "****************" cp $(ToolDAQPath)/ToolDAQFramework/src/Tool/Tool.h include/ - cp UserTools/*.h include/ - cp UserTools/*/*.h include/ cp DataModel/*.h include/ - -lib/libToolChain.so: $(ToolDAQPath)/ToolDAQFramework/src/ToolChain/* | lib/libLogging.so lib/libStore.so lib/libServiceDiscovery.so lib/libLogging.so lib/libDataModel.so +lib/libToolChain.so: $(ToolDAQPath)/ToolDAQFramework/src/ToolChain/* UserTools/MyFactory/Unity.h | lib/libLogging.so lib/libStore.so lib/libServiceDiscovery.so lib/libDataModel.so @echo -e "/n*************** Making " $@ "****************" cp $(ToolDAQPath)/ToolDAQFramework/UserTools/Factory/*.h include/ + -if [ ! -z "$(TOOLCHAIN)" ]; then cp -f UserTools/MyFactory/Unity.h include/; else cp -f UserTools/Unity.h include/; fi cp $(ToolDAQPath)/ToolDAQFramework/src/ToolChain/*.h include/ $(CC) $(ToolDAQPath)/ToolDAQFramework/src/ToolChain/ToolChain.cpp -I include -lpthread -L lib -lStore -lDataModel -lServiceDiscovery -lLogging -o lib/libToolChain.so $(DataModelInclude) $(DataModelLib) $(ZMQLib) $(ZMQInclude) $(MyToolsInclude) $(BoostLib) $(BoostInclude) -clean: +clean: @echo -e "\n*************** Cleaning up ****************" rm -f include/*.h rm -f lib/*.so rm -f Analyse - rm -f UserTools/*/*.o + find UserTools/* -type f -name '*.o' -follow -writable -delete rm -f DataModel/*.o rm -f DataModel/DataModel_Linkdef.hh rm -f DataModel/DataModel_RootDict* rm -f lib/*.pcm rm -f DataModel/libDataModel.rootmap + rm -f UserTools/MyFactory/MyFactory.cpp UserTools/MyFactory/Unity.h -lib/libDataModel.so: DataModel/* lib/libLogging.so lib/libStore.so $(patsubst DataModel/%.cpp, DataModel/%.o, $(wildcard DataModel/*.cpp)) DataModel/DataModel_RootDict.cpp +lib/libDataModel.so: DataModel/* lib/libLogging.so lib/libStore.so $(patsubst DataModel/%.cpp, DataModel/%.o, $(wildcard DataModel/*.cpp)) DataModel/DataModel_RootDict.o @echo -e "\n*************** Making " $@ "****************" cp -f DataModel/*.h include/ $(CC) DataModel/*.o -I include -L lib -lStore -lLogging -o lib/libDataModel.so $(DataModelInclude) $(DataModelLib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) @@ -124,12 +143,21 @@ DataModel/DataModel_RootDict.cpp: DataModel/DataModel_Linkdef.hh | include/Tool. cp -f DataModel/libDataModel.rootmap lib/ cp -f DataModel/DataModel_RootDict_rdict.pcm lib/ -lib/libMyTools.so: UserTools/*/* UserTools/* include/Tool.h lib/libLogging.so lib/libStore.so $(patsubst UserTools/%.cpp, UserTools/%.o, $(wildcard UserTools/*/*.cpp)) |lib/libDataModel.so lib/libToolChain.so lib/libRawViewer.so +#lib/libMyTools.so: UserTools/*/* UserTools/* include/Tool.h lib/libLogging.so lib/libStore.so $(patsubst UserTools/%.cpp, UserTools/%.o, $(wildcard UserTools/*/*.cpp)) |lib/libDataModel.so lib/libToolChain.so lib/libRawViewer.so +# @echo -e "\n*************** Making " $@ "****************" +# cp -f UserTools/*/*.h include/ +# cp -f UserTools/*.h include/ +# #$(CC) UserTools/Factory/Factory.cpp -I include -L lib -lStore -lDataModel -lLogging -o lib/libMyTools.so $(MyToolsInclude) $(MyToolsLib) $(DataModelInclude) $(DataModelib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) +# $(CC) UserTools/*/*.o -I include -L lib -lStore -lDataModel -lLogging -o lib/libMyTools.so $(MyToolsInclude) $(DataModelInclude) $(MyToolsLib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) + +lib/libMyTools.so: UserTools/MyFactory/MyFactory.o include/Tool.h lib/libLogging.so lib/libStore.so |lib/libDataModel.so lib/libToolChain.so lib/libRawViewer.so + @echo -e "\n*************** Making " $@ "****************" + $(CC) $< $(OBJECTS) -I include -L lib -lStore -lDataModel -lLogging -o lib/libMyTools.so $(MyToolsInclude) $(DataModelInclude) $(MyToolsLib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) + +UserTools/MyFactory/MyFactory.o: UserTools/MyFactory/MyFactory.cpp UserTools/MyFactory/Unity.h $(OBJECTS) @echo -e "\n*************** Making " $@ "****************" - cp -f UserTools/*/*.h include/ - cp -f UserTools/*.h include/ - #$(CC) UserTools/Factory/Factory.cpp -I include -L lib -lStore -lDataModel -lLogging -o lib/libMyTools.so $(MyToolsInclude) $(MyToolsLib) $(DataModelInclude) $(DataModelib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) - $(CC) UserTools/*/*.o -I include -L lib -lStore -lDataModel -lLogging -o lib/libMyTools.so $(MyToolsInclude) $(DataModelInclude) $(MyToolsLib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) + cp -f $(shell dirname $<)/*.h include + -$(CCC) -c -o $@ $< -I include -L lib -lStore -lDataModel -lLogging $(MyToolsInclude) $(MyToolsLib) $(DataModelInclude) $(DataModelib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) RemoteControl: cd $(ToolDAQPath)/ToolDAQFramework/ && make RemoteControl @@ -155,7 +183,7 @@ lib/libLogging.so: $(ToolDAQPath)/ToolDAQFramework/src/Logging/* | lib/libStore. cp $(ToolDAQPath)/ToolDAQFramework/lib/libLogging.so lib/ #$(CC) -I include $(ToolDAQPath)/ToolDAQFramework/src/Logging/Logging.cpp -o lib/libLogging.so -L lib/ -lStore $(ZMQInclude) $(ZMQLib) $(BoostLib) $(BoostInclude) -lib/libRawViewer.so: UserTools/PlotWaveforms/RawViewer.h UserTools/PlotWaveforms/RawViewer.cc UserTools/PlotWaveforms/viewer_linkdef.hh UserTools/recoANNIE/Constants.h DataModel/ANNIEconstants.h UserTools/recoANNIE/RawReader.h UserTools/recoANNIE/RawReader.cc UserTools/recoANNIE/RawReadout.h UserTools/recoANNIE/RawReadout.cc UserTools/recoANNIE/RawChannel.h UserTools/recoANNIE/RawChannel.cc UserTools/recoANNIE/RawCard.h UserTools/recoANNIE/RawCard.cc UserTools/recoANNIE/RawTrigData.h UserTools/recoANNIE/RawTrigData.cc +lib/libRawViewer.so: UserTools/PlotWaveforms/RawViewer.h UserTools/PlotWaveforms/RawViewer.cc UserTools/PlotWaveforms/viewer_linkdef.hh DataModel/Constants.h DataModel/ANNIEconstants.h DataModel/RawReader.h DataModel/RawReader.cpp DataModel/RawReadout.h DataModel/RawReadout.cpp DataModel/RawChannel.h DataModel/RawChannel.cpp DataModel/RawCard.h DataModel/RawCard.cpp DataModel/RawTrigData.h DataModel/RawTrigData.cpp @echo -e "\n*************** Making " $@ "****************" cd UserTools/PlotWaveforms && . ./setup_builder.sh && make clean && make cp UserTools/PlotWaveforms/libRawViewer.so UserTools/PlotWaveforms/dict_rdict.pcm lib/ @@ -169,9 +197,9 @@ update: cd $(ToolDAQPath)/RATEventLib; git checkout . ; git pull; make git pull -UserTools/%.o: UserTools/%.cpp lib/libStore.so include/Tool.h lib/libLogging.so lib/libDataModel.so lib/libToolChain.so +UserTools/%.o: UserTools/%.cpp | lib/libLogging.so lib/libToolChain.so lib/libDataModel.so @echo -e "\n*************** Making " $@ "****************" - cp $(shell dirname $<)/*.h include + cp -f $(shell dirname $<)/*.h include -$(CCC) -c -o $@ $< -I include -L lib -lStore -lDataModel -lLogging $(MyToolsInclude) $(MyToolsLib) $(DataModelInclude) $(DataModelib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) target: remove $(patsubst %.cpp, %.o, $(wildcard UserTools/$(TOOL)/*.cpp)) @@ -180,7 +208,44 @@ remove: echo "removing" -rm UserTools/$(TOOL)/*.o -DataModel/%.o: DataModel/%.cpp lib/libLogging.so lib/libStore.so +DataModel/%.o: DataModel/%.cpp lib/libLogging.so lib/libStore.so include/Tool.h @echo -e "\n*************** Making " $@ "****************" - cp $(shell dirname $<)/*.h include -$(CCC) -c -o $@ $< -I include -L lib -lStore -lLogging $(DataModelInclude) $(DataModelLib) $(ZMQLib) $(ZMQInclude) $(BoostLib) $(BoostInclude) + +UserTools/MyFactory/Unity.h: $(TOOLCHAIN)/ToolsConfig + @echo "Generating $@ for ToolChain $(TOOLCHAIN)" + @mkdir -p UserTools/MyFactory + @echo "//$(TOOLCHAIN)" > $@ + @for TOOL in $(TOOLS); do\ + echo '#include "'"$${TOOL}.h"'"' >> $@;\ + cp -f UserTools/$${TOOL}/*.h include/ 2>/dev/null || /bin/true;\ + done + + + +UserTools/MyFactory/MyFactory.cpp: UserTools/MyFactory/Unity.h $(TOOLCHAIN)/ToolsConfig + @echo "Generating $@ for ToolChain $(TOOLCHAIN)" + @cp UserTools/Factory/Factory.h UserTools/MyFactory/Factory.h + @echo '#include "Factory.h"' > $@ + @echo 'Tool* Factory(std::string tool) {' >> $@ + @echo 'Tool* ret=0;' >> $@ + @for TOOL in $(TOOLS); do\ + echo 'if (tool=="'"$${TOOL}"'") ret=new '"$${TOOL};" >> $@;\ + done;\ + echo 'return ret;' >> $@;\ + echo '}' >> $@ + +$(TOOLCHAINNAME):: $(TOOLCHAIN)/ToolsConfig + @echo "Target $@" + @if [[ `head -n1 UserTools/MyFactory/Unity.h 2>/dev/null | sed s://::` != "$(TOOLCHAIN)" ]]; then rm -rf UserTools/MyFactory/Unity.h UserTools/MyFactory/MyFactory.cpp UserTools/MyFactory/MyFactory.o; fi + @echo "making NEW" + @if [ ! -z "$(TOOLCHAIN)" ]; then echo "making ToolChain $(TOOLCHAIN)";fi + @# check tools file exists + @ls "./configfiles/$@/ToolsConfig" > /dev/null + + @# make datamodel + $(MAKE) -j $(NPROCS) lib/libDataModel.so + + @# make executable + $(MAKE) -j $(NPROCS) Analyse + diff --git a/README.md b/README.md index b1490a316..df797f33a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,32 @@ ToolAnalysis is a modular analysis program written for the ANNIE collaboration. It is based on ToolDAQ Application[1] which is an open source general DAQ Application template built using the modular ToolDAQ Framework core[2] to give separation between core and implementation code. +In each new shell environment, begin by running: +``` +. Setup.sh +``` + +To compile everything run: +``` +make -j$(nproc) +``` + +To compile only the DataModel objects and those Tools needed for a toolchain 'MyToolChain' (where MyToolChain is the name of the appropriate directory in configfiles)`, run: +``` +make -j$(nproc) MyToolChain +``` + +or for a ToolChain within a hierarchy, e.g. a toolchain described by `./configfiles/EnergyReco/Predict/ToolChainConfig` +``` +make -j$(nproc) EnergyReco/Predict +``` + +Note that compilation can take some time. After the first initial build: +* If only files in the UserTools have been modified, only the modified Tools will be rebuilt, along with libMyTools.so and the Analyse application. +* If anything in the DataModel has been modified, those DataModel objects will need to be rebuilt, along with libDataModel.so, ALL Tools, libMyTool.so and Analyse. This will be considerably slower (building all Tools takes a long time), and is where building a specific toolchain can help speed things up. + +Note that it is known that building and running on windows and mac is slower, due to filesystem differences. For best performance, run under linux. :) + **************************** #Concept **************************** diff --git a/Setup.sh b/Setup.sh index 42bbeacac..8ff308195 100644 --- a/Setup.sh +++ b/Setup.sh @@ -4,6 +4,8 @@ ToolDAQapp=`pwd` +ulimit -n 4096 + export LIBGL_ALWAYS_INDIRECT=1 source ${ToolDAQapp}/ToolDAQ/root-6.24.06/install/bin/thisroot.sh @@ -24,7 +26,7 @@ export PATH=${ToolDAQapp}/ToolDAQ/LHAPDF-6.3.0/install/bin:$GENIE/bin:$GENIE_REW export PATH=/ToolAnalysis/ToolDAQ/fsplit:$PATH export TF_CPP_MIN_LOG_LEVEL=2 -export FW_SEARCH_PATH=${ToolDAQapp}/UserTools/ReweightEventsGenie +export FW_SEARCH_PATH=${ToolDAQapp}/UserTools/ReweightFlux for folder in `ls -d ${PWD}/UserTools/*/ ` do diff --git a/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.cpp b/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.cpp new file mode 100644 index 000000000..65e64a530 --- /dev/null +++ b/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.cpp @@ -0,0 +1,2806 @@ +#include "ANNIEEventTreeMaker.h" + +ANNIEEventTreeMaker::ANNIEEventTreeMaker() : Tool() {} + +bool ANNIEEventTreeMaker::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("ANNIEEventTreeMakerVerbosity", ANNIEEventTreeMakerVerbosity); + m_variables.Get("isData", isData); + m_variables.Get("HasGenie", hasGenie); + + fillAllTriggers = true; + m_variables.Get("fillAllTriggers", fillAllTriggers); + fill_singleTrigger = true; + m_variables.Get("fill_singleTrigger", fill_singleTrigger); + fill_singleTriggerWord = 14; + m_variables.Get("fill_singleTriggerWord", fill_singleTriggerWord); + fill_TriggerWord = {14, 47}; + + m_variables.Get("fillCleanEventsOnly", fillCleanEventsOnly); + m_variables.Get("fillLAPPDEventsOnly", fillLAPPDEventsOnly); + + m_variables.Get("TankHitInfo_fill", TankHitInfo_fill); + m_variables.Get("TankCluster_fill", TankCluster_fill); + m_variables.Get("cluster_TankHitInfo_fill", cluster_TankHitInfo_fill); + m_variables.Get("MRDHitInfo_fill", MRDHitInfo_fill); + m_variables.Get("RWMBRF_fill", RWMBRF_fill); + + m_variables.Get("MCTruth_fill", MCTruth_fill); + m_variables.Get("MRDReco_fill", MRDReco_fill); + m_variables.Get("TankReco_fill", TankReco_fill); + m_variables.Get("RecoDebug_fill", RecoDebug_fill); + m_variables.Get("muonTruthRecoDiff_fill", muonTruthRecoDiff_fill); + m_variables.Get("LAPPDData_fill", LAPPDData_fill); + m_variables.Get("SiPMPulseInfo_fill", SiPMPulseInfo_fill); + m_variables.Get("LAPPDReco_fill", LAPPDReco_fill); + m_variables.Get("LAPPD_PPS_fill", LAPPD_PPS_fill); + m_variables.Get("LAPPD_Waveform_fill", LAPPD_Waveform_fill); + m_variables.Get("LAPPD_MC_fill", LAPPD_MC_fill); + m_variables.Get("RingCounting_fill", RingCounting_fill); + + std::string output_filename = "ANNIEEventTree.root"; + m_variables.Get("OutputFile", output_filename); + fOutput_tfile = new TFile(output_filename.c_str(), "recreate"); + fANNIETree = new TTree("Event", "ANNIE Phase II Event Tree"); + + m_data->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() +{ + if (MCTruth_fill) { + delete fTrueNeutCapVtxX; + delete fTrueNeutCapVtxY; + delete fTrueNeutCapVtxZ; + delete fTrueNeutCapNucleus; + delete fTrueNeutCapTime; + delete fTrueNeutCapGammas; + delete fTrueNeutCapE; + delete fTrueNeutCapGammaE; + delete fTruePrimaryPdgs; + } + + 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(); + fChannelBaseline.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..864ac83dc --- /dev/null +++ b/UserTools/ANNIEEventTreeMaker/ANNIEEventTreeMaker.h @@ -0,0 +1,606 @@ +#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; + std::map fChannelBaseline; + + 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/AssignBunchTimingMC/AssignBunchTimingMC.cpp b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp new file mode 100644 index 000000000..002291ee2 --- /dev/null +++ b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp @@ -0,0 +1,329 @@ +#include "AssignBunchTimingMC.h" + +AssignBunchTimingMC::AssignBunchTimingMC():Tool(){} + +//------------------------------------------------------------------------------ + +bool AssignBunchTimingMC::Initialise(std::string configfile, DataModel &data){ + + // Get configuration variables and set default values if necessary + + if ( !configfile.empty() ) m_variables.Initialise(configfile); + m_data = &data; + + bool got_verbosity = m_variables.Get("verbosity", verbosity); + bool got_width = m_variables.Get("bunchwidth", fbunchwidth); + bool got_interval = m_variables.Get("bunchinterval", fbunchinterval); + bool got_count = m_variables.Get("bunchcount", fbunchcount); + bool got_BRF = m_variables.Get("BRFfituncertainty", fBRF); + bool got_sample = m_variables.Get("sampletype", fsample); + bool got_trigger = m_variables.Get("prompttriggertime", ftriggertime); + bool got_waveform = m_variables.Get("PMTWaveformSim", fPMTWaveformSim); + + if (!got_verbosity) { + verbosity = 0; + logmessage = "Warning (AssignBunchTimingMC): \"verbosity\" not set in the config, defaulting to 0"; + Log(logmessage, v_warning, verbosity); + } + + + // default bunch parameters from MicroBooNE paper: https://doi.org/10.1103/PhysRevD.108.052010 + + if (!got_width) { + fbunchwidth = 1.308; // ns + logmessage = ("Warning (AssignBunchTimingMC): \"bunchwidth\" not " + "set in the config file. Using default: 1.308ns"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_interval) { + fbunchinterval = 18.936; // ns + logmessage = ("Warning (AssignBunchTimingMC): \"bunchinterval\" not " + "set in the config file. Using default: 18.936ns"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_count) { + fbunchwidth = 81; + logmessage = ("Warning (AssignBunchTimingMC): \"bunchcount\" not " + "set in the config file. Using default: 81"); + Log(logmessage, v_warning, verbosity); + } + + // Uncertainty due to beam signals / electronic jitter in our system + // see https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=6489 for more information + if (!got_BRF) { + fBRF = 0; + logmessage = ("Warning (AssignBunchTimingMC): \"BRFfituncertainty\" not " + "set in the config file. Using default: 0ns (no uncertainty will be included for this)"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_sample) { + fsample = 0; // assume they are using the Tank samples + logmessage = ("Warning (AssignBunchTimingMC): \"sampletype\" not " + "set in the config file. Using default: 0 (GENIE tank samples)"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_trigger) { + ftriggertime = 0; // assume they are using the old WCSim prompt trigger time (t = 0, first particle arrival) + logmessage = ("Warning (AssignBunchTimingMC): \"prompttriggertime\" not " + "set in the config file. Using default: 0 (WCSim prompt trigger time = 0)"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_waveform) { + fPMTWaveformSim = false; // assume they are using the standard, parametric MC Hits + logmessage = ("Warning (AssignBunchTimingMC): \"PMTWaveformSim\" not " + "set in the config file. Using default MC Hits instead of waveform hits"); + Log(logmessage, v_warning, verbosity); + } + + + if (verbosity >= v_message) { + std::cout<<"------------------------------------"<<"\n"; + std::cout<<"AssignBunchTimingMC: Config settings"<<"\n"; + std::cout<<"------------------------------------"<<"\n"; + std::cout<<"bunch width = "<; // set up pointer; Store will handle deletion in Finalize + + return true; +} + +//------------------------------------------------------------------------------ + + +bool AssignBunchTimingMC::Execute() +{ + + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Executing tool..." << std::endl; + } + + if (!LoadStores()) // Load info from store + return false; + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Store info loading successful" << std::endl; + } + + fbunchTimes->clear(); // clear map + + BNBtiming(); // grab BNB structure + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: BNB timing successful" << std::endl; + } + + if (fPMTWaveformSim) { // PMTWaveformSim data-like clusters (read from ClusterMap) + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Reading from ClusterMap (PMTWaveformSim)" << std::endl; + } + for (std::pair>&& apair : *fClusterMap) { + double totalHitTime = 0; + int hitCount = 0; + int totalHits = apair.second.size(); + + CalculateClusterAndBunchTimesPMTWaveformSim(apair.second, totalHitTime, hitCount, totalHits); + + // store the cluster time in a map (e.g., keyed by cluster identifier) + fbunchTimes->emplace(apair.first, bunchTime); + } + + } else { // otherwise default to reading the ClusterMapMC + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Reading from ClusterMapMC (default MCHits)" << std::endl; + } + for (std::pair>&& apair : *fClusterMapMC) { + double totalHitTime = 0; + int hitCount = 0; + int totalHits = apair.second.size(); + + CalculateClusterAndBunchTimes(apair.second, totalHitTime, hitCount, totalHits); + + // store the cluster time in a map (e.g., keyed by cluster identifier) + fbunchTimes->emplace(apair.first, bunchTime); + } + } + + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Assigned bunch time successfully. Writing to Store..." << std::endl; + } + + // send to store + m_data->Stores.at("ANNIEEvent")->Set("bunchTimes", fbunchTimes); + + return true; + +} + + +//------------------------------------------------------------------------------ + +bool AssignBunchTimingMC::Finalise() +{ + return true; +} + +//------------------------------------------------------------------------------ + + + + +bool AssignBunchTimingMC::LoadStores() +{ + // grab necessary information from Stores + + if (fPMTWaveformSim) { + bool get_Clusters = m_data->CStore.Get("ClusterMap", fClusterMap); + if (!get_Clusters) { + Log("AssignBunchTimingMC: no ClusterMap in the CStore! Are you sure you ran the ClusterFinder (and the PMTWaveformSim) tool?", v_error, verbosity); + return false; + } + } else { + bool get_MCClusters = m_data->CStore.Get("ClusterMapMC", fClusterMapMC); + if (!get_MCClusters) { + Log("AssignBunchTimingMC: no ClusterMapMC in the CStore! Are you sure you ran the ClusterFinder tool?", v_error, verbosity); + return false; + } + } + + bool get_AnnieEvent = m_data->Stores.count("ANNIEEvent"); + if (!get_AnnieEvent) { + Log("AssignBunchTimingMC: no ANNIEEvent store!", v_error, verbosity); + return false; + } + + bool get_neutrino_vtxt = m_data->Stores["GenieInfo"]->Get("NuIntxVtx_T",TrueNuIntxVtx_T); // grab neutrino interaction time + if (!get_neutrino_vtxt) { + Log("AssignBunchTimingMC: no GENIE neutrino interaction time info in the ANNIEEvent! Are you sure you ran the LoadGENIEEvent tool?", v_error, verbosity); + return false; + } + + return true; +} + + +//------------------------------------------------------------------------------ + + +void AssignBunchTimingMC::BNBtiming() +{ + + // Add instrinsic bunch width and the jitter from our beam signals / fitting + + // Determined from GENIE samples (as of Dec 2024) + const double tank_time = 33.0; // Tank neutrino arrival time: 33ns + const double world_time = 33.0; // WORLD neutrino arrival time: 33ns + + if (ftriggertime == 0) { + new_nu_time = (fsample == 0) ? (TrueNuIntxVtx_T - tank_time) : (TrueNuIntxVtx_T - world_time); + } else if (ftriggertime == 1) { + new_nu_time = (fsample == 0) ? -tank_time : -world_time; + } + + // seed random number generator with the current time + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + generator.seed(seed); + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Random seed selected: " << seed << std::endl; + } + + + // per event, assign BNB structure (random bunch number + jitter based on intrinsic bunch width + new_nu_time) + bunchNumber = rand() % fbunchcount; + std::normal_distribution distribution(0, fbunchwidth); + jitter = distribution(generator); + + // assign beam jitter (BRF uncertainty) + std::normal_distribution BRF_distribution(0, fBRF); + BRF_jitter = BRF_distribution(generator); + + if (verbosity >= v_message) { + std::ostringstream logmessage; + logmessage << "AssignBunchTimingMC: bunchNumber = " << bunchNumber + << " | t0 = " << new_nu_time + << " | sampled intrinsic bunch jitter = " << jitter << " ns" + << " | sampled BRF jitter = " << BRF_jitter << " ns"; + Log(logmessage.str(), v_debug, verbosity); + } + +} + + +//------------------------------------------------------------------------------ + + +void AssignBunchTimingMC::CalculateClusterAndBunchTimes(std::vector const &mchits, double &totalHitTime, int &hitCount, int &totalHits) +{ + + // loop over the hits to get their times + for (auto mchit : mchits) { + double hitTime = mchit.GetTime(); + totalHitTime += hitTime; + hitCount++; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: (" + std::to_string(hitCount) + "/" + std::to_string(totalHits) + ") MCHit time = " + std::to_string(hitTime); + Log(logmessage, v_debug, verbosity); + } + } + + // find nominal cluster time (average hit time) + double clusterTime = (hitCount > 0) ? totalHitTime / hitCount : -9999; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: ClusterTime = " + std::to_string(clusterTime); + Log(logmessage, v_debug, verbosity); + } + + // calculate BunchTime + bunchTime = fbunchinterval * bunchNumber + clusterTime + jitter + new_nu_time ; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: bunchTime = " + std::to_string(bunchTime); + Log(logmessage, v_debug, verbosity); + } + +} + + +void AssignBunchTimingMC::CalculateClusterAndBunchTimesPMTWaveformSim(std::vector const &hits, double &totalHitTime, int &hitCount, int &totalHits) +{ + + // loop over the hits to get their times + for (auto hit : hits) { + double hitTime = hit.GetTime(); + totalHitTime += hitTime; + hitCount++; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: (" + std::to_string(hitCount) + "/" + std::to_string(totalHits) + ") PMTWaveformSim Hit time = " + std::to_string(hitTime); + Log(logmessage, v_debug, verbosity); + } + } + + // find nominal cluster time (average hit time) + double clusterTime = (hitCount > 0) ? totalHitTime / hitCount : -9999; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: ClusterTime = " + std::to_string(clusterTime); + Log(logmessage, v_debug, verbosity); + } + + // calculate BunchTime (add the two gaussian contributions independently) + bunchTime = fbunchinterval * bunchNumber + clusterTime + jitter + BRF_jitter + new_nu_time ; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: bunchTime = " + std::to_string(bunchTime); + Log(logmessage, v_debug, verbosity); + } + +} + + +//------------------------------------------------------------------------------ + +// done diff --git a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h new file mode 100644 index 000000000..3c5b39e07 --- /dev/null +++ b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h @@ -0,0 +1,72 @@ +#ifndef AssignBunchTimingMC_H +#define AssignBunchTimingMC_H + +#include +#include +#include + +#include "Tool.h" +#include "Hit.h" + + +/** + * \class AssignBunchTimingMC + * + * A tool to assign BNB bunch structure to GENIE events +* +* $Author: S.Doran $ +* $Date: 2024/10/09 $ +* Contact: doran@iastate.edu +*/ +class AssignBunchTimingMC: public Tool { + + public: + + AssignBunchTimingMC(); ///< 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 LoadStores(); ///< Loads all relevant information from the store, away from the Execute function + void BNBtiming(); ///< Calculates the appropriate BNB timing to apply to the clusters + void CalculateClusterAndBunchTimes(std::vector const &mchits, double &totalHitTime, int &hitCount, int &totalHits); ///< Loops through the MCHits, finds the cluster times (avg hit time), and calculates the new bunch timing + void CalculateClusterAndBunchTimesPMTWaveformSim(std::vector const &hits, double &totalHitTime, int &hitCount, int &totalHits); ///< Same as above but for the data-like PMTWaveformSim clusters and hits + + private: + + std::map> *fClusterMapMC = nullptr; ///< All MC clusters + std::map> *fClusterMap = nullptr; ///< All MC clusters (data-like hits from the PMTWaveformSim tool) + double TrueNuIntxVtx_T; ///< true neutrino interaction time in ns, from GenieInfo store + + std::map *fbunchTimes = nullptr; ///< Bunch-realistic timing from the cluster times; + /// map linking updated bunch time to normal cluster time + + std::default_random_engine generator; ///< Random number generator for bunch number + + double fbunchwidth; ///< BNB intrinsic bunch width in ns + double fbunchinterval; ///< BNB bunch spacing in ns + int fbunchcount; ///< number of BNB bunches per spill + double fBRF; ///< BRF fit uncertainty extracted from the data (due to any additional electronic jitter unaccounted for) + int fsample; ///< GENIE Tank or WORLD samples + int ftriggertime; ///< whether the samples used the default WCSim prompt trigger = 0 (when particles enter the volume), or the adjusted prompt trigger based on the start of the beam dump + bool fPMTWaveformSim; ///< whether to use the PMTWaveform data-like hits or the defaul MCHits + + + double new_nu_time; ///< offset needed to make the cluster times beam realistic + int bunchNumber; ///< randomly assigned bunch number + double jitter; ///< random jitter based on the intrinsic bunch width + double BRF_jitter; ///< random jitter based on the beam timing + fit uncertainties + double bunchTime; ///< individual bunch time assigned for a specific cluster + + /// \brief verbosity levels: if 'verbosity' < this level, the message type will be logged. + int verbosity; + int v_error=0; // STOP THE SHOW + int v_warning=1; // this and below the show will go on + int v_message=2; + int v_debug=3; + std::string logmessage; + +}; + + +#endif \ No newline at end of file diff --git a/UserTools/AssignBunchTimingMC/README.md b/UserTools/AssignBunchTimingMC/README.md new file mode 100644 index 000000000..951b27023 --- /dev/null +++ b/UserTools/AssignBunchTimingMC/README.md @@ -0,0 +1,34 @@ +# AssignBunchTimingMC + +`AssignBunchTimingMC` applies the spill structure of the BNB to MC clusters. Currently, all MC events are "triggered" at the same time in WCSim; for certain analyses revolving around beam timing it may be necessary to have a beam-realistic simulation. The tool works by taking in a cluster produced by the `ClusterFinder` tool of form std::map> from the CStore ("ClusterMapMC"), and applies a corrective timing factor to each event. The tool also leverages the true neutrino interaction vertex time from GENIE to accurately create a spill structure. For this reason, both the `LoadGenieEvent` and `ClusterFinder` tools must be ran beforehand. This tool is designed for use on Genie Tank and World WCSim samples. + +## Data + +`AssignBunchTimingMC` produces a map of spill-adjusted cluster times and puts them into the ANNIEEvent store (all map keys are the original cluster time): + +**fbunchTimes** `std::map` + + +## Configuration +``` +# AssignBunchTimingMC Config File + +verbosity 0 + +# BNB properties taken from: MicroBooNE https://doi.org/10.1103/PhysRevD.108.052010 +bunchwidth 1.308 # BNB instrinic bunch spread [ns] +bunchinterval 18.936 # BNB bunch spacings [ns] +bunchcount 81 # number of BNB bunches per spill + +# Uncertainty extracted from Data / MC comparisons, see here: https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=6489 +BRFfituncertainty 1.809 # jitter in our beam signals / BRF fitting uncertainty [ns] + +sampletype 0 # Tank (0) or World (1) genie samples you are running over +prompttriggertime 1 # WCSim prompt trigger settings: (0 = default, t0 = 0 when a particle enters the volume) + # (1 = modified, t0 = 0 when the neutrino beam dump begins) +``` + + +## Additional information + +The "bunchTimes" have a spill structure that starts at ~0 ns and extends to M ns (depending on the bunch spacing and number of bunches). The tool is currently configured to the most recent Genie sample production (tank: Dec 2024, world: early 2024) for both the WCSim tank and world events (both of which have different "beam dump" starting times and prompt trigger times). diff --git a/UserTools/BackTracker/BackTracker.cpp b/UserTools/BackTracker/BackTracker.cpp new file mode 100644 index 000000000..ce80ada9b --- /dev/null +++ b/UserTools/BackTracker/BackTracker.cpp @@ -0,0 +1,213 @@ +#include "BackTracker.h" + +BackTracker::BackTracker():Tool(){} + +// To sort +struct sort_by_charge { + bool operator()(const std::pair &left, const std::pair &right) { + return left.second < right.second; + } +}; + + +bool BackTracker::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 + ///////////////////////////////////////////////////////////////// + + // Load my config parameters + bool gotVerbosity = m_variables.Get("verbosity",verbosity); + if (!gotVerbosity) { + verbosity = 0; + logmessage = "BackTracker::Initialize: \"verbosity\" not set in the config, defaulting to 0"; + Log(logmessage, v_error, verbosity); + } + + + // Set up the pointers we're going to save. No need to + // delete them at Finalize, the store will handle it + fClusterToBestParticleID = new std::map; + fClusterToBestParticlePDG = new std::map; + fClusterEfficiency = new std::map; + fClusterPurity = new std::map; + fClusterTotalCharge = new std::map; + + return true; +} + +//------------------------------------------------------------------------------ +bool BackTracker::Execute() +{ + if (!LoadFromStores()) + return false; + + fClusterToBestParticleID ->clear(); + fClusterToBestParticlePDG->clear(); + fClusterEfficiency ->clear(); + fClusterPurity ->clear(); + fClusterTotalCharge ->clear(); + + fParticleToTankTotalCharge.clear(); + SumParticleTankCharge(); + + + // Loop over the clusters and do the things + for (std::pair>&& apair : *fClusterMapMC) { + int prtId = -5; + int prtPdg = -5; + double eff = -5; + double pur = -5; + double totalCharge = 0; + + MatchMCParticle(apair.second, prtId, prtPdg, eff, pur, totalCharge); + + fClusterToBestParticleID ->emplace(apair.first, prtId); + fClusterToBestParticlePDG->emplace(apair.first, prtPdg); + fClusterEfficiency ->emplace(apair.first, eff); + fClusterPurity ->emplace(apair.first, pur); + fClusterTotalCharge ->emplace(apair.first, totalCharge); + } + + m_data->Stores.at("ANNIEEvent")->Set("ClusterToBestParticleID", fClusterToBestParticleID ); + m_data->Stores.at("ANNIEEvent")->Set("ClusterToBestParticlePDG", fClusterToBestParticlePDG); + m_data->Stores.at("ANNIEEvent")->Set("ClusterEfficiency", fClusterEfficiency ); + m_data->Stores.at("ANNIEEvent")->Set("ClusterPurity", fClusterPurity ); + m_data->Stores.at("ANNIEEvent")->Set("ClusterTotalCharge", fClusterTotalCharge ); + + return true; +} + +//------------------------------------------------------------------------------ +bool BackTracker::Finalise() +{ + + return true; +} + +//------------------------------------------------------------------------------ +void BackTracker::SumParticleTankCharge() +{ + for (auto mcHitsIt : *fMCHitsMap) { + std::vector mcHits = mcHitsIt.second; + for (uint mcHitIdx = 0; mcHitIdx < mcHits.size(); ++mcHitIdx) { + + // technically a MCHit could have multiple parents, but they don't appear to in practice + // skip any cases we come across + std::vector parentIdxs = *(mcHits[mcHitIdx].GetParents()); + if (parentIdxs.size() != 1) continue; + + int particleId = -5; + for (auto it : *fMCParticleIndexMap) { + if (it.second == parentIdxs[0]) particleId = it.first; + } + if (particleId == -5) continue; + + double depositedCharge = mcHits[mcHitIdx].GetCharge(); + if (!fParticleToTankTotalCharge.count(particleId)) + fParticleToTankTotalCharge.emplace(particleId, depositedCharge); + else + fParticleToTankTotalCharge.at(particleId) += depositedCharge; + } + } +} + +//------------------------------------------------------------------------------ +void BackTracker::MatchMCParticle(std::vector const &mchits, int &prtId, int &prtPdg, double &eff, double &pur, double &totalCharge) +{ + // Loop over the hits and get all of their parents and the energy that each one contributed + // be sure to bunch up all neutronic contributions + std::map mapParticleToTotalClusterCharge; + totalCharge = 0; + + for (auto mchit : mchits) { + std::vector parentIdxs = *(mchit.GetParents()); + if (parentIdxs.size() != 1) { + logmessage = "BackTracker::MatchMCParticle: this MCHit has "; + logmessage += std::to_string(parentIdxs.size()) + " parents!"; + Log(logmessage, v_debug, verbosity); + continue; + } + + int particleId = -5; + for (auto it : *fMCParticleIndexMap) { + if (it.second == parentIdxs[0]) particleId = it.first; + } + if (particleId == -5) continue; + + double depositedCharge = mchit.GetCharge(); + totalCharge += depositedCharge; + + if (mapParticleToTotalClusterCharge.count(particleId) == 0) + mapParticleToTotalClusterCharge.emplace(particleId, depositedCharge); + else + mapParticleToTotalClusterCharge[particleId] += depositedCharge; + } + + // Loop over the particleIds to find the primary contributer to the cluster + double maxCharge = 0; + for (auto apair : mapParticleToTotalClusterCharge) { + if (apair.second > maxCharge) { + maxCharge = apair.second; + prtId = apair.first; + } + } + + // Check that we have some charge, if not then something is wrong so pass back all -5 + if (totalCharge > 0) { + eff = maxCharge/fParticleToTankTotalCharge.at(prtId); + pur = maxCharge/totalCharge; + prtPdg = (fMCParticles->at(fMCParticleIndexMap->at(prtId))).GetPdgCode(); + } else { + prtId = -5; + eff = -5; + pur = -5; + totalCharge = -5; + } + + logmessage = "BackTracker::MatchMCParticle: best particleId is : "; + logmessage += std::to_string(prtId) + " which has PDG: " + std::to_string(prtPdg); + Log(logmessage, v_message, verbosity); + +} + +//------------------------------------------------------------------------------ +bool BackTracker::LoadFromStores() +{ + // Grab the stuff we need from the stores + bool goodMCClusters = m_data->CStore.Get("ClusterMapMC", fClusterMapMC); + if (!goodMCClusters) { + std::cerr<<"BackTracker: no ClusterMapMC in the CStore!"<Stores.count("ANNIEEvent"); + if (!goodAnnieEvent) { + std::cerr<<"BackTracker: no ANNIEEvent store!"<Stores.at("ANNIEEvent")->Get("MCHits", fMCHitsMap); + if (!goodMCHits) { + std::cerr<<"BackTracker: no MCHits in the ANNIEEvent!"<Stores.at("ANNIEEvent")->Get("MCParticles", fMCParticles); + if (!goodMCParticles) { + std::cerr<<"BackTracker: no MCParticles in the ANNIEEvent!"<Stores.at("ANNIEEvent")->Get("TrackId_to_MCParticleIndex", fMCParticleIndexMap); + if (!goodMCParticleIndexMap) { + std::cerr<<"BackTracker: no TrackId_to_MCParticleIndex in the ANNIEEvent!"< +#include + +#include "Tool.h" +#include "Hit.h" +#include "Particle.h" + + +/** + * \class BackTracker + * + * A tool to link reco info to the paticle(s) that generated the light +* +* $Author: A.Sutton $ +* $Date: 2024/06/16 $ +* Contact: atcsutton@gmail.com +*/ +class BackTracker: public Tool { + + + public: + + BackTracker(); ///< 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 LoadFromStores(); ///< Does all the loading so I can move it away from the Execute function + void SumParticleTankCharge(); + void MatchMCParticle(std::vector const &mchits, int &prtId, int &prtPdg, double &eff, double &pur, double &totalCharge); ///< The meat and potatoes + + private: + + // Things we need to pull out of the store + std::map> *fMCHitsMap = nullptr; ///< All of the MCHits keyed by channel number + std::map> *fClusterMapMC = nullptr; ///< Clusters that we will be linking MCParticles to + std::vector *fMCParticles = nullptr; ///< The true particles from the event + std::map *fMCParticleIndexMap = nullptr; ///< Map between the particle Id and it's position in MCParticles vector + + // We'll calculate this map from MCHit parent particle to the total charge deposited throughout the tank + // technically a MCHit could have multiple parents, but they don't appear to in practice + // the key is particle Id and value is total tank charge + std::map fParticleToTankTotalCharge; + + // We'll save out maps between the local cluster time and + // the ID and PDG of the particle that contributed the most energy + // the efficiency of capturing all light from the best matched particle in that cluster + // the the purity based on the best matched particle + // the total deposited charge in the cluster + // the ammount of cluster charge due to neutrons + std::map *fClusterToBestParticleID = nullptr; + std::map *fClusterToBestParticlePDG = nullptr; + std::map *fClusterEfficiency = nullptr; + std::map *fClusterPurity = nullptr; + std::map *fClusterTotalCharge = nullptr; + + /// \brief verbosity levels: if 'verbosity' < this level, the message type will be logged. + int verbosity; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; + +}; + + +#endif diff --git a/UserTools/BackTracker/README.md b/UserTools/BackTracker/README.md new file mode 100644 index 000000000..0c5a1776d --- /dev/null +++ b/UserTools/BackTracker/README.md @@ -0,0 +1,28 @@ +# BackTracker + +`BackTracker` links reconstructed clusters (vectors of hits) to the MC particle that contributed the most energy to said cluster. Right now, it takes in a cluster of form std::map>, specifically it uses the CStore cluster produced by the ClusterFinder tool, which has the label "ClusterMapMC". That map is indexed by the cluster time and that index is in turn used to ID all of the data products that BackTracker produces. + +## Data + +`BackTracker` produces a number of maps to link MC information to the associated cluster and puts them into the ANNIEEvent store (all map keys are the cluster time): + +**fClusterToBestParticleID** `std::map` +* The MCParticle ID (ie. the ParticleID from the MCParticle class, which is returned via the `MCParticle::GetParticleID()` function) of the best matched particle + +**fClusterToBestParticlePDG** `std::map` +* The PDG value of the best matched particle + +**fClusterEfficiency** `std::map` +* Efficiency of the clustering where the numerator is the number total charge in the cluster contributed by the best matched particle, and the denominator is the total charge that the best matched particle deposited anywhere in the tank + +**fClusterPurity** `std::map` +* Purity of the clustering where the numerator is the number total charge in the cluster contributed by the best matched particle, and the denominator is the total charge of all hits in the cluster + +**fClusterCharge** `std::map` +* Total deposited charge of all hits in the cluster + + +## Configuration +``` +verbosity 1 # Verbosity level of the tool +``` diff --git a/UserTools/BeamFetcherV2/BeamFetcherV2.cpp b/UserTools/BeamFetcherV2/BeamFetcherV2.cpp index 5831fb4ed..5965bd764 100644 --- a/UserTools/BeamFetcherV2/BeamFetcherV2.cpp +++ b/UserTools/BeamFetcherV2/BeamFetcherV2.cpp @@ -24,11 +24,12 @@ bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) m_data = &data; // Get the things - bool got_verbosity = m_variables.Get("verbose", verbosity); - bool got_bundleflag = m_variables.Get("IsBundle", fIsBundle); - bool got_devicesfile = m_variables.Get("DevicesFile", fDevicesFile); - bool got_saveroot = m_variables.Get("SaveROOT", fSaveROOT); - bool got_chunkMSec = m_variables.Get("TimeChunkStepInMilliseconds", fChunkStepMSec); + bool got_verbosity = m_variables.Get("verbose", verbosity); + bool got_bundleflag = m_variables.Get("IsBundle", fIsBundle); + bool got_devicesfile = m_variables.Get("DevicesFile", fDevicesFile); + bool got_saveroot = m_variables.Get("SaveROOT", fSaveROOT); + bool got_chunkMSec = m_variables.Get("TimeChunkStepInMilliseconds", fChunkStepMSec); + bool got_deletectcdata = m_variables.Get("DeleteCTCData", fDeleteCTCData); // Check the config parameters and set default values if necessary @@ -69,7 +70,15 @@ bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) Log(logmessage, v_warning, verbosity); 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_chunkMSec) { logmessage = ("Warning (BeamFetcherV2): TimeChunkStepInMilliseconds was not" @@ -87,6 +96,13 @@ bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) } if (fSaveROOT) this->SetupROOTFile(); + + // initialize the last timestamp + fLastTimestampFetched = 0; + fLastTimestampSaved = 0; + BeamDataMap = new std::map >; + + m_data->CStore.Set("NewBeamDataAvailable", false); return true; } @@ -95,22 +111,35 @@ bool BeamFetcherV2::Initialise(std::string config_filename, DataModel& data) //------------------------------------------------------------------------------ bool BeamFetcherV2::Execute() { + m_data->CStore.Set("NewBeamDataAvailable", false); // Do the things - bool goodFetch = this->FetchFromTrigger(); - - if (goodFetch) { - // Emplace fBeamDataToSave to CStore for other tools to use - m_data->CStore.Set("BeamData",fBeamDataToSave); - goodFetch = true; - } + 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); - if (fSaveROOT) this->WriteTrees(); + goodFetch = this->FetchFromTrigger(); + } else { + logmessage = ("Warning (BeamFetcherV2): No new CTC data found. Nothing to fetch. "); + Log(logmessage, v_message, verbosity); + } - // Clear for the next Fetch - fBeamDataToSave.clear(); - + // Save it out + if (goodFetch) { + logmessage = ("Debug (BeamFetcherV2): Writing out BeamDataMap, which has size: " + std::to_string(BeamDataMap->size())); + Log(logmessage, v_debug, verbosity); + + // put BeamDataMap in CStore for other tools to use + m_data->CStore.Set("NewBeamDataAvailable", true); + m_data->CStore.Set("BeamDataMap", BeamDataMap); + if (fSaveROOT) this->WriteTrees(); + } else if (fNewCTCData) { + logmessage = ("Warning (BeamFetcherV2): Bad fetch. "); + Log(logmessage, v_message, verbosity); + } - return goodFetch; + return true; } //------------------------------------------------------------------------------ @@ -131,30 +160,39 @@ bool BeamFetcherV2::FetchFromTrigger() // Need to get the trigger times std::map>* TimeToTriggerWordMap=nullptr; - bool get_ok = m_data->CStore.Get("TimeToTriggerWordMap",TimeToTriggerWordMap); + bool got_triggers = m_data->CStore.Get("TimeToTriggerWordMap",TimeToTriggerWordMap); // Now loop over the CTC timestamps - if (get_ok && TimeToTriggerWordMap) { - for (auto iterator : *TimeToTriggerWordMap) { - // We only want to get beam info for beam triggers (word 5) - bool hasBeamTrig = false; - for (auto word : iterator.second) - if (word == 5) hasBeamTrig = true; - if (!hasBeamTrig) continue; - - uint64_t trigTimestamp = iterator.first; + // But start at the fLastTimeStampFetched to prevent double counting if the timestamp data wasn't deleted + if (got_triggers && TimeToTriggerWordMap) { + for (auto iterator = TimeToTriggerWordMap->lower_bound(fLastTimestampFetched+1); + iterator != TimeToTriggerWordMap->end(); ++iterator) { + + // We only care about beam triggers here + if (std::find(iterator->second.begin(), iterator->second.end(), 14) == iterator->second.end()) { + continue; + } + + // Grab the timestamp + uint64_t trigTimestamp = iterator->first; + fLastTimestampFetched = trigTimestamp; // Need to drop from ns to ms. This means that some timestamps will // already be recorded. We can skip these cases trigTimestamp = trigTimestamp/1E6; - if (fBeamDataToSave.find(trigTimestamp) != fBeamDataToSave.end()) + if (BeamDataMap->find(trigTimestamp) != BeamDataMap->end()) { + logmessage = ("Debug (BeamFetcherV2): BeamDataMap already has this timstamp: " + + std::to_string(trigTimestamp) + ", skipping."); + Log(logmessage, vv_debug, verbosity); + continue; + } // Check if we already have the info we need bool fetch = false; std::map >::iterator low, prev; - low = fBeamData.lower_bound(trigTimestamp); - if (low == fBeamData.end()) { + low = BeamDataQuery.lower_bound(trigTimestamp); + if (low == BeamDataQuery.end()) { fetch = true; logmessage = ("BeamFetcherV2: I'm going to query the DB"); Log(logmessage, v_message, verbosity); @@ -163,33 +201,32 @@ bool BeamFetcherV2::FetchFromTrigger() // We'll pull fChunkStepMSec worth of data at a time to avoid rapid queries if (fetch) { if (fIsBundle) { - fBeamData = db.QueryBeamDBBundleSpan(fDevices[0], trigTimestamp, trigTimestamp+fChunkStepMSec); + BeamDataQuery = db.QueryBeamDBBundleSpan(fDevices[0], trigTimestamp, trigTimestamp+fChunkStepMSec); } else { - std::map > tempMap; - + std::map > tempMap; for (auto device : fDevices) { auto tempMap = db.QueryBeamDBSingleSpan(device, trigTimestamp, trigTimestamp+fChunkStepMSec); - fBeamData.insert(tempMap.begin(), tempMap.end()); + BeamDataQuery.insert(tempMap.begin(), tempMap.end()); } } } // Now we can match the Beam info to CTC timestamps for saving to the CStore - low = fBeamData.lower_bound(trigTimestamp); - if (low == fBeamData.end()) { + low = BeamDataQuery.lower_bound(trigTimestamp); + if (low == BeamDataQuery.end()) { logmessage = ("Error (BeamFetcherV2): We fetched the data based on the CTC" " but somehow didn't turn anything up!?"); Log(logmessage, v_error, verbosity); return false; - } else if (low == fBeamData.begin()) { - fBeamDataToSave[trigTimestamp] = low->second; + } else if (low == BeamDataQuery.begin()) { + BeamDataMap->emplace(trigTimestamp, low->second); } else { // Check the previous DB timestamp to see if it's closer in time prev = std::prev(low); if ((trigTimestamp - prev->first) < (low->first - trigTimestamp)) - fBeamDataToSave[trigTimestamp] = prev->second; + BeamDataMap->emplace(trigTimestamp, prev->second); else - fBeamDataToSave[trigTimestamp] = low->second; + BeamDataMap->emplace(trigTimestamp, low->second); } }// end loop over trigger times } else { @@ -199,6 +236,14 @@ bool BeamFetcherV2::FetchFromTrigger() return false; } + if (fDeleteCTCData) + { + TimeToTriggerWordMap->clear(); + std::map> *TimeToTriggerWordMapComplete = nullptr; + m_data->CStore.Get("TimeToTriggerWordMapComplete", TimeToTriggerWordMapComplete); + TimeToTriggerWordMapComplete->clear(); + } + return true; } @@ -206,7 +251,7 @@ bool BeamFetcherV2::FetchFromTrigger() bool BeamFetcherV2::SaveToFile() { BoostStore fBeamDBStore(false, BOOST_STORE_MULTIEVENT_FORMAT); - fBeamDBStore.Set("BeamData", fBeamData); + fBeamDBStore.Set("BeamData", BeamDataQuery); fBeamDBStore.Save(fOutFileName); fBeamDBStore.Delete(); @@ -246,12 +291,18 @@ void BeamFetcherV2::SetupROOTFile() void BeamFetcherV2::WriteTrees() { // Loop over timestamps - int devCounter = 0; - for (const auto iterTS : fBeamDataToSave) { - fTimestamp = iterTS.first; + // But start at the fLastTimeStampSaved to prevent double counting if the timestamp data wasn't deleted + int devCounter = 0; + for (auto iterTS = BeamDataMap->lower_bound(fLastTimestampSaved+1); + iterTS != BeamDataMap->end(); ++iterTS) { + + fTimestamp = iterTS->first; + fLastTimestampSaved = fTimestamp; + + std::cout << "Timestamp: " << fTimestamp << std::endl; // Loop over devices - for (const auto iterDev : iterTS.second) { + for (const auto iterDev : iterTS->second) { std::string device = iterDev.first; std::replace( device.begin(), device.end(), ':', '_'); @@ -271,6 +322,9 @@ void BeamFetcherV2::WriteTrees() fOutTree->Fill(); }// end loop over timestamps +// clear BeamDataMap after filling Tree +BeamDataMap->clear(); + } //------------------------------------------------------------------------------ diff --git a/UserTools/BeamFetcherV2/BeamFetcherV2.h b/UserTools/BeamFetcherV2/BeamFetcherV2.h index 94056ea72..6aac55bc2 100644 --- a/UserTools/BeamFetcherV2/BeamFetcherV2.h +++ b/UserTools/BeamFetcherV2/BeamFetcherV2.h @@ -16,6 +16,7 @@ // ToolAnalysis includes #include "Tool.h" +#include "BeamDataPoint.h" // ROOT includes #include "TFile.h" @@ -40,8 +41,8 @@ class BeamFetcherV2: public Tool { // Holder for the retrieved data and the stuff we'll save - std::map > fBeamData; - std::map > fBeamDataToSave; + std::map > BeamDataQuery; + std::map > *BeamDataMap; // For saving out to a file std::map > fBeamDBIdx; @@ -49,6 +50,13 @@ class BeamFetcherV2: public Tool { // Holder for the devices we're going to look up std::vector fDevices; + // Keep the last timestamp around to make sure we don't double count + uint64_t fLastTimestampFetched; + uint64_t fLastTimestampSaved; + + // Is there new data? + bool fNewCTCData; + // For ROOT file TFile *fOutFile; TTree *fOutTree; @@ -61,6 +69,7 @@ class BeamFetcherV2: public Tool { int verbosity; bool fIsBundle; bool fSaveROOT; + bool fDeleteCTCData; std::string fDevicesFile; std::string fOutFileName; uint64_t fChunkStepMSec; diff --git a/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp b/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp index 99e0a5148..e006fc3f6 100644 --- a/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp +++ b/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp @@ -16,6 +16,26 @@ IFBeamDBInterfaceV2::IFBeamDBInterfaceV2() fCurl = curl_easy_init(); 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"}, + {"E:THCURR", "KA"}, + {"E:BTJT2", "DegC"}, + {"E:HP875", "mm"}, + {"E:VP875", "mm"}, + {"E:HPTG1", "mm"}, + {"E:VPTG1", "mm"}, + {"E:HPTG2", "mm"}, + {"E:VPTG2", "mm"}, + {"E:BTH2T2", "DegC"}, + {"B:BRRMPL","unknown"}, + {"B:BRRMPS","unknown"}, + {"B:BRRMPQ","unknown"}, + {"B:BRRMP","volt"}}; } IFBeamDBInterfaceV2::~IFBeamDBInterfaceV2() @@ -237,6 +257,14 @@ IFBeamDBInterfaceV2::ParseDBResponseSingleSpan(const std::string& response) cons unit, timestamp); } + +for (auto &ts : retMap) { + for (auto &dev : requiredDevices) { + if (ts.second.find(dev.first) == ts.second.end()) { + ts.second[dev.first] = BeamDataPoint(-9999, dev.second, ts.first); + } + } + } return retMap; } @@ -280,6 +308,33 @@ IFBeamDBInterfaceV2::ParseDBResponseBundleSpan(const std::string& response) cons unit, timestamp); } + + // 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 + // use value as -9999, unit as doulbe, timestamp = TS + for (auto &ts : retMap) { + for (auto &dev : requiredDevices) { + if (ts.second.find(dev.first) == ts.second.end()) { + //cout<<" not finding device "< requiredDevices; protected: /// @brief Create the singleton IFBeamDBInterfaceV2 object diff --git a/UserTools/BeamFetcherV2/README.md b/UserTools/BeamFetcherV2/README.md index 04df17154..219ec504f 100644 --- a/UserTools/BeamFetcherV2/README.md +++ b/UserTools/BeamFetcherV2/README.md @@ -20,21 +20,22 @@ FetchFromTrigger: The following objects will be put into the CStore ## Configuration -The main configuration variable for the `BeamFetcher` tool is `FetchFromTimes`, which determines whether to use the tigger timestamps or user input timestamps. The `DevicesFile`, `IsBundle`, and `TimeChunkStepInMilliseconds` variables are required regardless of the fetch mode. You can also set the `SaveROOT` bool in order to save out a TTree with the timestamp and device values as the leaves. +The main configuration variable for the `BeamFetcherV2` tool is `FetchFromTimes`, which determines whether to use the tigger timestamps or user input timestamps. The `DevicesFile`, `IsBundle`, and `TimeChunkStepInMilliseconds` variables are required regardless of the fetch mode. You can also set the `SaveROOT` bool in order to save out a TTree with the timestamp and device values as the leaves. If `FetchFromTimes == 1` then you will also need the additional config variables. The preferred timestamp format is chosen with the `TimestampMode` variable (LOCALDATE/MSEC/DB). For LOCALDATE mode you use Start/EndDate files with string formatted times (like 2023-04-11 23:03:19.163505). For MSEC mode you use the Start/EndMillisecondsSinceEpoch variables. For DB mode you must first run `LoadRunInfo` and the run timestamps will be pulled from the CStore. ``` -# BeamFetcher config file -verbose 5 +# BeamFetcherV2 config file +verbose 1 # # These three are always needed # -DevicesFile ./configfiles/BeamFetcher/devices.txt # File containing one device per line or a bundle +DevicesFile ./configfiles/BeamFetcherV2/devices.txt # File containing one device per line or a bundle IsBundle 0 # bool stating whether DevicesFile contains bundles or individual devices FetchFromTimes 0 # bool defining how to grab the data (from input times (1) or trigger(0)) TimeChunkStepInMilliseconds 3600000 # one hour SaveROOT 0 # bool, do you want to write a ROOT file with the timestamps and devices? +DeleteCTCData 0 # bool, delete viewed CTC timestamps? Helps reduce memory overhead when not running ANNIEEventBuilder. # # These parameters are only needed if FetchFromTimes == 1 # diff --git a/UserTools/BeamFetcherV2/devices.txt b/UserTools/BeamFetcherV2/devices.txt new file mode 100644 index 000000000..0bf9117bd --- /dev/null +++ b/UserTools/BeamFetcherV2/devices.txt @@ -0,0 +1 @@ +BoosterNeutrinoBeam_read diff --git a/UserTools/BeamQuality/BeamQuality.cpp b/UserTools/BeamQuality/BeamQuality.cpp new file mode 100644 index 000000000..47ba19d3a --- /dev/null +++ b/UserTools/BeamQuality/BeamQuality.cpp @@ -0,0 +1,256 @@ +#include "BeamQuality.h" + +BeamQuality::BeamQuality():Tool(){} + +//------------------------------------------------------------------------------ +bool BeamQuality::Initialise(std::string configfile, DataModel &data) +{ + // Load configuration file variables + if ( !configfile.empty() ) m_variables.Initialise(configfile); + + // Assign a transient data pointer + m_data = &data; + + // Get the things + bool got_verbosity = m_variables.Get("verbose", verbosity); + bool got_potmin = m_variables.Get("POTMin", fPOTMin); + bool got_potmax = m_variables.Get("POTMax", fPOTMax); + bool got_hornmin = m_variables.Get("HornCurrentMin", fHornCurrMin); + bool got_hornmax = m_variables.Get("HornCurrentMax", fHornCurrMax); + bool got_beamloss = m_variables.Get("BeamLossTolerance", fBeamLoss); + + // Check the config parameters and set default values if necessary + if (!got_verbosity) verbosity = 1; + + if (!got_potmin) { + fPOTMin = 5e11; + + logmessage = ("Warning (BeamQuality): POTMin not " + "set in the config file. Using default: 5e11"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_potmax) { + fPOTMax = 8e12; + + logmessage = ("Warning (BeamQuality): POTMax not " + "set in the config file. Using default: 8e12"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_hornmin) { + fHornCurrMin = 172; + + logmessage = ("Warning (BeamQuality): HornCurrentMin not " + "set in the config file. Using default: 172"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_hornmax) { + fHornCurrMax = 176; + + logmessage = ("Warning (BeamQuality): HornCurrentMax not " + "set in the config file. Using default: 176"); + Log(logmessage, v_warning, verbosity); + } + + if (!got_beamloss) { + fBeamLoss = 0.05; + + logmessage = ("Warning (BeamQuality): BeamLossTolerance not " + "set in the config file. Using default: 0.05"); + Log(logmessage, v_warning, verbosity); + } + + // Necessary initialization + m_data->CStore.Set("NewBeamStatusAvailable", false); + fLastTimestamp = 0; + BeamStatusMap = new std::map; + + return true; +} + +//------------------------------------------------------------------------------ +bool BeamQuality::Execute() +{ + m_data->CStore.Set("NewBeamStatusAvailable", false); + + // Check for CTC timestamps and beam DB info + bool got_ctc = m_data->CStore.Get("NewCTCDataAvailable", fNewCTCData); + bool got_beamdb = m_data->CStore.Get("NewBeamDataAvailable", fNewBeamData); + + // Make sure we have the info we need + if (!got_ctc) { + logmessage = ("Error (BeamQuality): Did not find NewCTCDataAvailable " + "entry in the CStore. Aborting."); + Log(logmessage, v_error, verbosity); + + return false; + } + + if (!got_beamdb) { + logmessage = ("Error (BeamQuality): Did not find NewBeamDataAvailable " + "entry in the CStore. Make sure to run BeamFetcherV2 in " + "your tool chain. Aborting."); + Log(logmessage, v_error, verbosity); + + return false; + } + + + // Start doing the things + if (!fNewCTCData) { + logmessage = ("Message (BeamQuality): No new CTC data is available. " + "Nothing to do for now"); + Log(logmessage, v_message, verbosity); + + return true; + } + + // Need to get the trigger times and loop over them + bool got_triggers = m_data->CStore.Get("TimeToTriggerWordMap", TimeToTriggerWordMap); + bool got_beamdata = m_data->CStore.Get("BeamDataMap", BeamDataMap); + + // Keep track of which timestamps we've seen so we can clear out the BeamDataMap + std::set completed_timestamps; + + // But start from the fLastTimestamp to save time + for (auto iterator = TimeToTriggerWordMap->lower_bound(fLastTimestamp); + iterator != TimeToTriggerWordMap->end(); ++iterator) { + + // Grab the timestamp and check the trigger words + uint64_t timestamp = iterator->first; + uint64_t timestamp_ms = timestamp/1E6; + fLastTimestamp = timestamp; + completed_timestamps.insert(timestamp); + + // 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(), 5) == iterator->second.end()) { + BeamStatus tempStatus(TimeClass(timestamp), 0., BeamCondition::NonBeamMinibuffer); + BeamStatusMap->emplace(timestamp, tempStatus); + continue; + } + + // Have we already saved this timestamp? If so then continue to the next one + if (BeamStatusMap->find(timestamp) != BeamStatusMap->end()) + continue; + + // Check for the existence of beam DB info + if (!fNewBeamData) { + logmessage = ("Warning (BeamQuality): No new Beam DB data is available. " + "Setting it to \"Missing\". "); + Log(logmessage, v_warning, verbosity); + + BeamStatus tempStatus(TimeClass(timestamp), 0., BeamCondition::Missing); + BeamStatusMap->emplace(timestamp, tempStatus); + } + + // Check for beam DB info associated with the timestamp + if (BeamDataMap->find(timestamp_ms) != BeamDataMap->end()) { + // Got the goods, now use it + BeamStatus tempStatus = assess_beam_quality(timestamp); + BeamStatusMap->emplace(timestamp, tempStatus); + + } else { + logmessage = ("Warning (BeamQuality): No Beam DB info found for timestamp: " + + std::to_string(timestamp_ms) + ". Setting it to \"Missing\". "); + Log(logmessage, v_warning, verbosity); + + BeamStatus tempStatus(TimeClass(timestamp), 0., BeamCondition::Missing); + BeamStatusMap->emplace(timestamp, tempStatus); + } // end if found timestamp in BeamDataMap + } // end loop over TimeToTriggerWordMap + + // Clear out the BeamDataMap to free up memory + for (auto ts : completed_timestamps) + BeamDataMap->erase(ts/1E6); + + // Save the status + m_data->CStore.Set("BeamStatusMap", BeamStatusMap); + + logmessage = ("Message (BeamQuality): BeamStatusMap size: " + + std::to_string(BeamStatusMap->size())); + Log(logmessage, v_message, verbosity); + + + return true; +} + +//------------------------------------------------------------------------------ +bool BeamQuality::Finalise() +{ + + return true; +} + +//------------------------------------------------------------------------------ +BeamStatus BeamQuality::assess_beam_quality(uint64_t timestamp) +{ + // initialize the beamstatus that we'll return + BeamStatus retStatus; + retStatus.set_time(TimeClass(timestamp)); + + + // Check for and grab the quatities we want from the BeamDataMap + uint64_t timestamp_ms = timestamp/1E6; + auto BeamDataPointMap = BeamDataMap->at(timestamp_ms); + + std::string device_name = ""; + + // POT downstream toroid + device_name = "E:TOR875"; + double pot_ds_toroid = 0; + if (BeamDataPointMap.find(device_name) != BeamDataPointMap.end()) { + auto bdp = BeamDataPointMap[device_name]; + retStatus.add_measurement(device_name, timestamp_ms, bdp); + retStatus.set_pot(bdp.value); + pot_ds_toroid = bdp.value; + } + + // POT upstream toroid + device_name = "E:TOR860"; + double pot_us_toroid = 0; + if (BeamDataPointMap.find(device_name) != BeamDataPointMap.end()) { + auto bdp = BeamDataPointMap[device_name]; + retStatus.add_measurement(device_name, timestamp_ms, bdp); + pot_us_toroid = bdp.value; + } + + // Horn current + device_name = "E:THCURR"; + double horn_current = 0; + if (BeamDataPointMap.find(device_name) != BeamDataPointMap.end()) { + auto bdp = BeamDataPointMap[device_name]; + retStatus.add_measurement(device_name, timestamp_ms, bdp); + horn_current = bdp.value; + } + + + // Perform the cuts + retStatus.add_cut("POT in range", + (retStatus.pot() >= fPOTMin && retStatus.pot() <= fPOTMax)); + + retStatus.add_cut("Horn current in range", + (horn_current >= fHornCurrMin && horn_current <= fHornCurrMax)); + + double beam_loss_frac = std::abs(pot_ds_toroid - pot_us_toroid) / (pot_ds_toroid + pot_us_toroid); + retStatus.add_cut("Beam loss acceptable", + (beam_loss_frac < fBeamLoss)); + + + // Finish up the beam status + if (retStatus.passed_all_cuts()) { + retStatus.set_condition(BeamCondition::Ok); + } else { + logmessage = ("Message (BeamQuality): Bad beam spill at trigger timestamp " + + std::to_string(timestamp)); + Log(logmessage, v_message, verbosity); + if (verbosity >=v_debug) + retStatus.Print(); + + retStatus.set_condition(BeamCondition::Bad); + } + + return retStatus; +} diff --git a/UserTools/BeamQuality/BeamQuality.h b/UserTools/BeamQuality/BeamQuality.h new file mode 100644 index 000000000..deb37b314 --- /dev/null +++ b/UserTools/BeamQuality/BeamQuality.h @@ -0,0 +1,78 @@ +#ifndef BeamQuality_H +#define BeamQuality_H + +#include +#include +#include +#include +#include +#include + +#include "Tool.h" +#include "BeamStatus.h" +#include "MinibufferLabel.h" +#include "ANNIEconstants.h" +#include "BeamDataPoint.h" +#include "TimeClass.h" + +#include "Tool.h" + + +/** +* \class BeamQuality +* +* Tool to apply quality cuts to the results of BeamFetcherV2 +* +* $Author: A.Sutton $ +* $Date: 2024/04/1 $ +*/ +class BeamQuality: public Tool { + + + public: + + BeamQuality(); ///< 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. + + protected: + BeamStatus assess_beam_quality(uint64_t timestamp); + + + private: + + // Config variables + int verbosity; + + // Cut values from config + // Extend this for additional cuts + double fPOTMin; + double fPOTMax; + double fHornCurrMin; + double fHornCurrMax; + double fBeamLoss; + + + // CStore things + bool fNewCTCData; + bool fNewBeamData; + std::map> *TimeToTriggerWordMap; ///< Trigger information + std::map> *BeamDataMap; ///< BeamDB information + std::map *BeamStatusMap; ///< Map containing the beam status information that will be saved to the CStore + + // Keep the last timestamp around to make sure we don't double process things + uint64_t fLastTimestamp; + + + // Verbosity things + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + int vv_debug = 4; + std::string logmessage; +}; + + +#endif diff --git a/UserTools/BeamQuality/README.md b/UserTools/BeamQuality/README.md new file mode 100644 index 000000000..cd3ed350b --- /dev/null +++ b/UserTools/BeamQuality/README.md @@ -0,0 +1,33 @@ +# BeamQuality + +The `BeamQuality` tool is part of the Event Building chain in ANNIE and forwards information about the Beam Status to the `ANNIEEventBuilder` tool. It uses information that was previously retrieved from the beam database with the `BeamFetcherV2` tool. This mimic the `BeamQuality` tool that is used for the original `BeamFetcher`. + +The information is saved in the form of the `BeamStatus` class. This class contains some basic information like the POT for the timestamp in question and some more detailed information about the horn currents. It is possible to already choose some beam quality cuts for the timestamp tolerance, horn currents, and POT values. However, some beam information will be stored in the object, so it will be possible to use slightly different cuts when analyzing the data later. + +## Data + +The Beam Status information is stored in the `BeamStatusMap` object and put in the CStore. The `ANNIEEventBuilder` tool can access the object in the CStore and write the information to the ANNIEEvent BoostStore. + +The `BeamQuality` tool goes through the decoded trigger timestamps and searches for the beam status at each of these trigger timestamps (in case there was a beam trigger). The properties of the beam are then saved in the BeamStatus object and put into the `BeamStatusMap`. It then deletes the used BeamData to free up memory. + +**BeamStatusMap** `map` +* Beam status for the trigger timestamps + +The `BeamStatusMap` is stored in the form of a pointer, and the `ANNIEEventBuilder` will delete already built entries from the map to free up memory. + +## Configuration + +BeamQuality has the following configuration variables: + +``` +# BeamQuality config file +verbose 1 +# POT window for "good" beam +POTMin 5e11 +POTMax 8e12 +# Horn current window for "good" beam (in kA) +HornCurrentMin 172 +HornCurrentMax 176 +# Fractional difference between the upstream and downstream POT measurements +BeamLossTolerance 0.05 +``` diff --git a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp index 6b8fb705f..939d2dbef 100644 --- a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp +++ b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp @@ -35,7 +35,6 @@ bool ClusterClassifiers::Initialise(std::string configfile, DataModel &data){ bool ClusterClassifiers::Execute(){ - //We're gonna make ourselves a couple cluster classifier maps boyeeee if(verbosity>4) std::cout << "ClusterClassifiers tool: Accessing cluster map in CStore" << std::endl; bool get_clusters = false; m_data->CStore.Get("ClusterMap",m_all_clusters); @@ -222,8 +221,8 @@ double ClusterClassifiers::CalculateChargeBalance(std::vector cluster_hits) total_Q+= tube_charge; total_QSquared += (tube_charge * tube_charge); } - //FIXME: Need a method to have the 123 be equal to the number of operating detectors - double charge_balance = sqrt((total_QSquared)/(total_Q*total_Q) - (1./123.)); + //FIXME: Need a method to have the 1/N be equal to the number of operating detectors + double charge_balance = sqrt((total_QSquared)/(total_Q*total_Q) - (1./121.)); if(verbosity>4) std::cout << "ClusterClassifiers Tool: Calculated charge balance of " << charge_balance << std::endl; return charge_balance; } @@ -249,8 +248,8 @@ double ClusterClassifiers::CalculateChargeBalanceMC(std::vector cluster_h total_Q+= tube_charge; total_QSquared += (tube_charge * tube_charge); } - //FIXME: Need a method to have the 123 be equal to the number of operating detectors - double charge_balance = sqrt((total_QSquared)/(total_Q*total_Q) - (1./123.)); + //FIXME: Need a method to have the 1/N be equal to the number of operating detectors + double charge_balance = sqrt((total_QSquared)/(total_Q*total_Q) - (1./121.)); if(verbosity>4) std::cout << "ClusterClassifiers Tool: Calculated charge balance of " << charge_balance << std::endl; return charge_balance; } diff --git a/UserTools/ClusterFinder/ClusterFinder.cpp b/UserTools/ClusterFinder/ClusterFinder.cpp index f88ca62c6..6d41ff085 100644 --- a/UserTools/ClusterFinder/ClusterFinder.cpp +++ b/UserTools/ClusterFinder/ClusterFinder.cpp @@ -27,6 +27,8 @@ bool ClusterFinder::Initialise(std::string configfile, DataModel &data){ m_variables.Get("Plots2D",draw_2D); m_variables.Get("verbosity",verbose); m_variables.Get("end_of_window_time_cut",end_of_window_time_cut); + m_variables.Get("MC_pulse_width",mc_pulse_width); + m_variables.Get("ApplyDeadMask",ApplyDeadMask); //---------------------------------------------------------------------------- //---------------Get basic geometry properties ------------------------------- @@ -197,12 +199,18 @@ bool ClusterFinder::Execute(){ } if(HitStoreName=="MCHits"){ + if (verbose > 0) std::cout << "ClusterFinder MC pulse_width: " << mc_pulse_width << " [ns]" << endl; int vectsize = MCHits->size(); if (verbose > 3) std::cout <<"ClusterFinder tool: MCHits size: "<>&& apair : *MCHits){ unsigned long chankey = apair.first; Detector* thistube = geom->ChannelToDetector(chankey); int detectorkey = thistube->GetDetectorID(); + + // fetch ON/OFF status of the PMT. If "OFF", do not include that hit in the clustering + if (ApplyDeadMask && thistube->GetStatus() == detectorstatus::OFF) + continue; + if (thistube->GetDetectorElement()=="Tank"){ std::vector& ThisPMTHits = apair.second; PMT_ishit[detectorkey] = 1; @@ -211,39 +219,84 @@ bool ClusterFinder::Execute(){ std::vector datalike_hits; std::vector datalike_hits_charge; for (MCHit &ahit : ThisPMTHits){ - //std::cout <<"Key: "< 2000.) std::cout <<"Found hit later than 2us! Hit time : "< combine multiple photons if they are within a 10ns range - //hit times can only be recorded with 2ns precision --> possible times are 0ns, 2ns, 4ns, ... - hits_2ns_res.push_back(2*(int(ahit.GetTime())/2.)+(int(ahit.GetTime())%2)); + hits_2ns_res.push_back(ahit.GetTime()); hits_2ns_res_charge.push_back(ahit.GetCharge()); } } //Combine multiple MC hits to one pulse std::sort(hits_2ns_res.begin(),hits_2ns_res.end()); - for (int i_hit=0; i_hit < (int) hits_2ns_res.size(); i_hit++){ - double hit1 = hits_2ns_res.at(i_hit); - if (datalike_hits.size()==0) { - datalike_hits.push_back(hit1); - datalike_hits_charge.push_back(hits_2ns_res_charge.at(i_hit)); - } - else { + std::vector temp_times; + double temp_charges = 0.0; + double mid_time; + if (verbose > 0){ + std::cout << " " << std::endl; + std::cout << hits_2ns_res.size() << " total photon hits(s)" << std::endl; + } + + if (hits_2ns_res.size() > 0){ + for (int i_hit=0; i_hit < (int) hits_2ns_res.size(); i_hit++){ + double hit1 = hits_2ns_res.at(i_hit); + if (temp_times.size()==0) { + temp_times.push_back(hit1); + temp_charges += hits_2ns_res_charge.at(i_hit); + } + + else { bool new_pulse = false; - for (int j_hit=0; j_hit < (int) datalike_hits.size(); j_hit++){ - if (fabs(datalike_hits.at(j_hit)-hit1)<10.) { + if (fabs(temp_times[0]-hit1)<10.) { new_pulse=false; - datalike_hits_charge.at(j_hit)+=hits_2ns_res_charge.at(i_hit); - break; + temp_charges+=hits_2ns_res_charge.at(i_hit); + temp_times.push_back(hit1); } else new_pulse=true; - } + if (new_pulse) { - datalike_hits.push_back(hit1); //Only count as a new pulse if it was 10ns away from every other pulse - datalike_hits_charge.push_back(hits_2ns_res_charge.at(i_hit)); + // following the DigitBuilder tool --> take median photon hit time as the hit time of the "pulse" + if (temp_times.size() % 2 == 0){ + mid_time = (temp_times.at(temp_times.size()/2 - 1) + temp_times.at(temp_times.size()/2))/2; + } else{ + mid_time = temp_times.at(temp_times.size()/2); + } + + datalike_hits.push_back(mid_time); + datalike_hits_charge.push_back(temp_charges); + temp_times.clear(); + temp_charges = 0; + temp_times.push_back(hit1); + temp_charges += hits_2ns_res_charge.at(i_hit); + } } } + if (temp_times.size() % 2 == 0){ + mid_time = (temp_times.at(temp_times.size()/2 - 1) + temp_times.at(temp_times.size()/2))/2; + } else{ + mid_time = temp_times.at(temp_times.size()/2); + } + + datalike_hits.push_back(mid_time); + datalike_hits_charge.push_back(temp_charges); + + if (verbose > 0){ + std::cout << " " << std::endl; + std::cout << datalike_hits.size() << " MC pulse(s) identified from the raw photon hit(s)" << std::endl; + std::cout << "Pulse time(s):" << std::endl; + for (int ih=0; ih < (int) datalike_hits.size(); ih++){ + double junk = datalike_hits.at(ih); + std::cout << junk << " "; + } + std::cout << " " << std::endl; + std::cout << "Pulse charge(s):" << std::endl; + for (int ih=0; ih < (int) datalike_hits_charge.size(); ih++){ + double junk2 = datalike_hits_charge.at(ih); + std::cout << junk2 << " "; + } + std::cout << " " << std::endl; + } + } + for (int i_hit = 0; i_hit < (int) datalike_hits.size(); i_hit++){ //v_hittimes.push_back(ahit.GetTime()); // fill a vector with all hit times (unsorted) v_hittimes.push_back(datalike_hits.at(i_hit)); @@ -267,6 +320,11 @@ bool ClusterFinder::Execute(){ unsigned long chankey = apair.first; Detector* thistube = geom->ChannelToDetector(chankey); int detectorkey = thistube->GetDetectorID(); + + // fetch ON/OFF status of the PMT. If "OFF", do not include that hit in the clustering + if (ApplyDeadMask && thistube->GetStatus() == detectorstatus::OFF) + continue; + if (thistube->GetDetectorElement()=="Tank"){ std::vector& ThisPMTHits = apair.second; PMT_ishit[detectorkey] = 1; @@ -295,7 +353,7 @@ bool ClusterFinder::Execute(){ // Now sort the hit time array, fill the highest time in a new array until the old array is empty do { - double max_time = 0; + double max_time = -9999; int i_max_time = 0; for (std::vector::iterator it = v_hittimes.begin(); it != v_hittimes.end(); ++it) { if (*it > max_time) { @@ -321,12 +379,21 @@ bool ClusterFinder::Execute(){ } thiswindow_Nhits = 0; v_mini_hits.clear(); - for (double j_time = *it; j_time < *it + ClusterFindingWindow; j_time+=2){ // loops through times in the window and check if there's a hit at this time + for (double j_time = *it; j_time < *it + ClusterFindingWindow; j_time+=1){ // loops through times in the window and check if there's a hit at this time for(std::vector::iterator it2 = v_hittimes_sorted.begin(); it2 != v_hittimes_sorted.end(); ++it2) { - if (*it2 == j_time) { - thiswindow_Nhits++; - v_mini_hits.push_back(*it2); + if(HitStoreName=="MCHits"){ + if (static_cast(j_time) == static_cast(*it2)) { // accept all hit times (some may be smeared to negative values) + thiswindow_Nhits++; + v_mini_hits.push_back(*it2); + } + } + if(HitStoreName=="Hits"){ + if (*it2 > 0 && static_cast(j_time) == static_cast(*it2)) { // reject hit times in the data that are 0 + thiswindow_Nhits++; + v_mini_hits.push_back(*it2); + } } + } } if (!v_mini_hits.empty()) { diff --git a/UserTools/ClusterFinder/ClusterFinder.h b/UserTools/ClusterFinder/ClusterFinder.h index 5da5e5478..d7e9b06ee 100644 --- a/UserTools/ClusterFinder/ClusterFinder.h +++ b/UserTools/ClusterFinder/ClusterFinder.h @@ -67,6 +67,8 @@ class ClusterFinder: public Tool { int MinHitsPerCluster; bool draw_2D = false; double end_of_window_time_cut; + double mc_pulse_width; + bool ApplyDeadMask; // define ANNIEEvent variables int evnum; diff --git a/UserTools/ClusterFinder/README.md b/UserTools/ClusterFinder/README.md index eb3b04a47..67e3006a4 100644 --- a/UserTools/ClusterFinder/README.md +++ b/UserTools/ClusterFinder/README.md @@ -18,11 +18,13 @@ The following variables can be configured for the ClusterFinder tool: # ClusterFinder Config File HitStore Hits #Either MCHits or Hits (accessed in ANNIEEvent store) +ApplyDeadMask 1 #Do not include faulty/dead PMTs that may be in the ProcessedData OutputFile LEDRun1415S0Beam_AllPMTs_TestClusterFinder #Output root prefix name for the current run ClusterFindingWindow 50 # in ns, size of the window used to "clusterize" AcqTimeWindow 4000 # in ns, size of the acquisition window ClusterIntegrationWindow 50 # 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 +MC_pulse_width 10 # 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 verbose 1 #verbosity of the application diff --git a/UserTools/ClusterSearcher/ClusterSearcher.cpp b/UserTools/ClusterSearcher/ClusterSearcher.cpp new file mode 100644 index 000000000..e4c766a7e --- /dev/null +++ b/UserTools/ClusterSearcher/ClusterSearcher.cpp @@ -0,0 +1,699 @@ +#include "ClusterSearcher.h" + +static ClusterSearcher* fgClusterSearcher = 0; + +ClusterSearcher* ClusterSearcher::Instance() +{ + if( !fgClusterSearcher ){ + fgClusterSearcher = new ClusterSearcher(); + } + + return fgClusterSearcher; +} + +ClusterSearcher::ClusterSearcher():Tool(){} + +ClusterSearcher::~ClusterSearcher() { + +} + +bool ClusterSearcher::Initialise(std::string configfile, DataModel &data){ + if(verbosity)cout<<"Initializing ClusterSearcher"<; + fClusteringParam->emplace("ClusterMode",fClusterMode); + fClusteringParam->emplace("PmtMinPulseHeight",fPmtMinPulseHeight); + fClusteringParam->emplace("PmtNeighbourRadius",fPmtNeighbourRadius); + fClusteringParam->emplace("PmtMinNeighbourDigits",fPmtMinNeighbourDigits); + fClusteringParam->emplace("PmtClusterRadius",fPmtClusterRadius); + fClusteringParam->emplace("PmtTimeWindowN",fPmtTimeWindowN); + fClusteringParam->emplace("PmtTimeWindowC",fPmtTimeWindowC); + fClusteringParam->emplace("LappdMinPulseHeight",fLappdMinPulseHeight); + fClusteringParam->emplace("LappdNeighbourRadius",fLappdNeighbourRadius); + fClusteringParam->emplace("LappdMinNeighbourDigits",fLappdMinNeighbourDigits); + fClusteringParam->emplace("LappdClusterRadius",fLappdClusterRadius); + fClusteringParam->emplace("LappdTimeWindowN",fLappdTimeWindowN); + fClusteringParam->emplace("LappdTimeWindowC",fLappdTimeWindowC); + fClusteringParam->emplace("MinClusterDigits",fMinClusterDigits); + + Log("ClusterSearcher " + to_string(fClusterMode) + " configs Initialized", v_debug, verbosity); + if (!fisMC){ + ifstream file_singlepe(singlePEgains.c_str()); + unsigned long temp_chankey; + double temp_gain; + while (!file_singlepe.eof()){ + file_singlepe >> temp_chankey >> temp_gain; + pmt_gains.emplace(temp_chankey,temp_gain); + } + file_singlepe.close(); + m_data->CStore.Get("pmt_tubeid_to_channelkey",pmt_tubeid_to_channelkey); + Log("ClusterSearcher " + to_string(fClusterMode) + " !MC Initialized", v_debug, verbosity); + } + + // vector of selected digits + fSelectAll = new std::vector; + fSelectByPulseHeight = new std::vector; + fSelectByNeighbours = new std::vector; + fSelectByClusters = new std::vector; + // only for test + fSelectByTruthInfo = new std::vector; + // vector of clusters + //fClusterList = new std::vector; + fRecoClusters = new std::vector; + + //Set clustering parameters in the RecoEvent store + std::map* pre_ClusteringParam = nullptr; // read existing container for parameters + bool cluster_parameter_status = m_data->Stores.at("RecoEvent")->Get("ClusteringParameters", pre_ClusteringParam); + if(!cluster_parameter_status) m_data->Stores.at("RecoEvent")->Set("ClusteringParameters", fClusteringParam); + else { + pre_ClusteringParam->insert(fClusteringParam->begin(), fClusteringParam->end()); + //m_data->Stores.at("RecoEvent")->Set("ClusteringParameters", pre_ClusteringParam); + } + Log("ClusterSearcher "+to_string(fClusterMode)+" Initialized",v_debug,verbosity); + return true; +} + + +bool ClusterSearcher::Execute(){ + + if(fFirstRun && pre_RecoClusters) pre_RecoClusters->clear(); + + std::string name = "ClusterSearcher::Execute()"; + Log(name + ": Executing",v_error,verbosity); + + // print Selecting parameters + if(verbosity>v_message) this->PrintParameters(); + + // see if "ANNIEEvent" exists + auto get_annieevent = m_data->Stores.count("ANNIEEvent"); + if(!get_annieevent){ + Log(name + ": No ANNIEEvent store!",v_error,verbosity); + return false; + } + + /// see if "RecoEvent" exists + auto get_recoevent = m_data->Stores.count("RecoEvent"); + if(!get_recoevent){ + Log(name + ": No RecoEvent store!",v_error,verbosity); + return false; + } + + if (fisMC) { + // get true vertex + auto get_truevtx = m_data->Stores.at("RecoEvent")->Get("TrueVertex", fTrueVertex); + if(!get_truevtx){ + Log(name + ": Error retrieving TrueVertex from RecoEvent!",v_error,verbosity); + return false; + } + } + + // get digit list + auto get_recodigit = m_data->Stores.at("RecoEvent")->Get("RecoDigit",fDigitList); ///> Get digits from "RecoEvent" + if(!get_recodigit){ + Log("VtxSeedGenerator Tool: Error retrieving RecoDigits,no digit from the RecoEvent store!",v_error,verbosity); + return false; + } + // copy to a new digit list + std::vector* digits = new std::vector; + for(int i=0;isize());i++) { + RecoDigit* recodigitptr = &(fDigitList->at(i)); + digits->push_back((RecoDigit*)recodigitptr); + } + + // Reset Digit Filter + // ============ + for(int n=0; nsize()); n++ ) { + digits->at(n)->ResetFilter(); + } + + // Set Digit Filter + // ========== + SelectDigits(digits); + + this->RecoClusters(digits); + // Digit clustering done! + // ===== + + pre_RecoClusters = nullptr; // to read existing clusters + bool cluster_status = m_data->Stores.at("RecoEvent")->Get("RecoClusters", pre_RecoClusters); + + Log("ClusterSearcher Tool: Final count of clusters: "+to_string(fRecoClusters->size()),v_debug,verbosity); + if(!cluster_status) { + pre_RecoClusters=new std::vector; + for (int i = 0; i < fRecoClusters->size(); i++) { + pre_RecoClusters->push_back(fRecoClusters->at(i)); + } + fIsHitClusteringDone = true; + Log("Hit Clustering done",v_debug,verbosity); + m_data->Stores.at("RecoEvent")->Set("HitClusteringDone", fIsHitClusteringDone); + m_data->Stores.at("RecoEvent")->Set("RecoClusters", pre_RecoClusters); + } + else { + pre_RecoClusters->insert(pre_RecoClusters->end(), fRecoClusters->cbegin(), fRecoClusters->cend()); // append new clusters to the existing cluster list + //m_data->Stores.at("RecoEvent")->Set("RecoClusters", pre_RecoClusters); // save updated clusters + //fRecoClusters->clear(); + } + + if (!fFirstRun && pre_RecoClusters->size() == 0) { + Log("ClusterSearcher: NO CLUSTERS FOUND IN EVENT!",v_debug,verbosity); + Log("Digit list size: "+to_string(fDigitList->size()),v_debug,verbosity); + } + + delete digits; digits = 0; + return true; +} + +bool ClusterSearcher::Finalise(){ + //delete fClusteringParam; fClusteringParam = 0; //Will be deleted by the store, don't manually delete + delete fSelectAll; fSelectAll = 0; + delete fSelectByPulseHeight; fSelectByPulseHeight = 0; + delete fSelectByNeighbours; fSelectByNeighbours = 0; + delete fSelectByClusters; fSelectByClusters = 0; + //delete fRecoClusters; fRecoClusters = 0; //Will be deleted by the store, don't manually delete + delete fRecoClusters; fRecoClusters = 0; + // for test + delete fSelectByTruthInfo; fSelectByTruthInfo = 0; + return true; +} + +/*void ClusterSearcher::Config(int config) +{ + ClusterSearcher::Instance()->SetConfig(config); +}*/ + +void ClusterSearcher::PmtMinPulseHeight(double min) +{ + ClusterSearcher::Instance()->SetPmtMinPulseHeight(min); +} + +void ClusterSearcher::PmtNeighbourRadius(double radius) +{ + ClusterSearcher::Instance()->SetPmtNeighbourRadius(radius); +} + +void ClusterSearcher::PmtNeighbourDigits(int digits) +{ + ClusterSearcher::Instance()->SetPmtNeighbourDigits(digits); +} + +void ClusterSearcher::PmtClusterRadius(double radius) +{ + ClusterSearcher::Instance()->SetPmtClusterRadius(radius); +} + +void ClusterSearcher::MinClusterDigits(int digits) +{ + ClusterSearcher::Instance()->SetMinClusterDigits(digits); +} + +void ClusterSearcher::PmtTimeWindowN(double windowN) +{ + ClusterSearcher::Instance()->SetPmtTimeWindowNeighbours(windowN); +} + +void ClusterSearcher::PmtTimeWindowC(double windowC) +{ + ClusterSearcher::Instance()->SetPmtTimeWindowClusters(windowC); +} + +void ClusterSearcher::PrintParameters() +{ + std::cout << " *** ClusterSearcher::PrintParameters() *** " << std::endl; + + std::cout << " Clustering Parameters: " << std::endl + << " ClusterMode = " << fClusterMode<< std::endl + << " PmtMinPulseHeight = " << fPmtMinPulseHeight << std::endl + << " PmtNeighbourRadius = " << fPmtNeighbourRadius << std::endl + << " PmtMinNeighbourDigits = " << fPmtMinNeighbourDigits << std::endl + << " PmtClusterRadius = " << fPmtClusterRadius << std::endl + << " PmtTimeWindowN = " << fPmtTimeWindowN << std::endl + << " PmtTimeWindowC = " << fPmtTimeWindowC << std::endl + << " LappdMinPulseHeight = " << fLappdMinPulseHeight << std::endl + << " LappdNeighbourRadius = " << fLappdNeighbourRadius << std::endl + << " LappdMinNeighbourDigits = " << fLappdMinNeighbourDigits << std::endl + << " LappdClusterRadius = " << fLappdClusterRadius << std::endl + << " LappdTimeWindowN = " << fLappdTimeWindowN << std::endl + << " LappdTimeWindowC = " << fLappdTimeWindowC << std::endl + << " MinClusterDigits = " << fMinClusterDigits << std::endl; +} + +void ClusterSearcher::Reset() +{ + + return; +} + +// Set all filter status to 0 (default is 1) +std::vector* ClusterSearcher::ResetDigits(std::vector* DigitList) +{ + for(int idigit=0; idigitsize()); idigit++ ){ + RecoDigit* recoDigit = (RecoDigit*)(DigitList->at(idigit)); + recoDigit->ResetFilter(); + } + + return DigitList; +} + +std::vector* ClusterSearcher::SelectDigits(std::vector* DigitList) +{ + for(int idigit=0; idigitsize()); idigit++ ){ + RecoDigit* recoDigit = (RecoDigit*)(DigitList->at(idigit)); + recoDigit->PassFilter(); + } + + return DigitList; +} + +void ClusterSearcher::SelectDigits(std::vector* DigitList) +{ + for (int idigit = 0; idigitsize()); idigit++) { + RecoDigit recoDigit = (RecoDigit)(DigitList->at(idigit)); + recoDigit.PassFilter(); + } + + return; +} + +std::vector* ClusterSearcher::SelectAll(std::vector* DigitList) +{ + std::string name = "ClusterSearcher::SelectAll() "; + // clear vector of selected digits + // ============================== + fSelectAll->clear(); + // select all digits + // ================= + for(int idigit=0; idigitsize()); idigit++ ){ + RecoDigit* recoDigit = (RecoDigit*)(DigitList->at(idigit)); + fSelectAll->push_back(recoDigit); + } + + // return vector of selected digits + // ================================ + if(verbosity>v_message) std::cout << name << " select all: " << fSelectAll->size() << std::endl; + + return fSelectAll; +} + +std::vector* ClusterSearcher::SelectByPulseHeight(std::vector* DigitList) +{ + std::string name = "ClusterSearcher::SelectByPulseHeight() "; + // clear vector of selected digits + // =============================== + fSelectByPulseHeight->clear(); + + // Select by pulse height + // ====================== + for(int idigit=0; idigitsize()); idigit++ ){ + RecoDigit* recoDigit = (RecoDigit*)(DigitList->at(idigit)); + double qep = recoDigit->GetCalCharge(); + if (!fisMC){ + int pmtid = recoDigit->GetDetectorID(); + unsigned long chankey = pmt_tubeid_to_channelkey[pmtid]; + if (pmt_gains[chankey]>0) qep/=pmt_gains[chankey]; + } + int detType = recoDigit->GetDigitType(); + if(detType == RecoDigit::lappd_v0) { + if( qep>fLappdMinPulseHeight ){ + fSelectByPulseHeight->push_back(recoDigit); + } + } + else if(detType == RecoDigit::PMT8inch) { + if( qep>fPmtMinPulseHeight ){ + fSelectByPulseHeight->push_back(recoDigit); + } + } + else Log(name + " detector type doesn't exist!",v_error,verbosity); + } + + + // return vector of selected digits + // ================================ + if(verbosity>v_message) std::cout <size() << std::endl; + + return fSelectByPulseHeight; +} + +std::vector* ClusterSearcher::SelectByNeighbours(std::vector* DigitList) +{ + std::string name = "ClusterSearcher::SelectByNeighbours() "; + // clear vector of Selected digits + // =============================== + fSelectByNeighbours->clear(); + + // create array of neighbours + // ========================== + int Ndigits = DigitList->size(); + + if( Ndigits<=0 ){ + return fSelectByNeighbours; + } + + int* numNeighbours = new int[Ndigits]; + + for( int idigit=0; idigitsize()); idigit1++ ){ + RecoDigit* fdigit1 = (RecoDigit*)(DigitList->at(idigit1)); + TString digit1Type = fdigit1->GetDigitType(); + for(int idigit2=idigit1+1; idigit2size()); idigit2++ ){ + RecoDigit* fdigit2 = (RecoDigit*)(DigitList->at(idigit2)); + TString digit2Type = fdigit2->GetDigitType(); + + double dx = fdigit1->GetPosition().X() - fdigit2->GetPosition().X(); + double dy = fdigit1->GetPosition().Y() - fdigit2->GetPosition().Y(); + double dz = fdigit1->GetPosition().Z() - fdigit2->GetPosition().Z(); + double dt = fdigit1->GetCalTime() - fdigit2->GetCalTime(); + double drsq = dx*dx + dy*dy + dz*dz; + + if(digit1Type == RecoDigit::PMT8inch && digit2Type == RecoDigit::PMT8inch) { + if( drsq>0.0 + && drsq0.0 + && drsq0.0 + && drsq0.0 + && drsq0.0 + && drsq0.0 + && drsqsize()); idigit++){ + RecoDigit* fdigit = (RecoDigit*)(DigitList->at(idigit)); + //std::cout << "numNeighbours[" << idigit << "] = " << numNeighbours[idigit] << std::endl; + if( numNeighbours[idigit]>=fPmtMinNeighbourDigits ){ + fSelectByNeighbours->push_back(fdigit); + } + } + + // delete array of neighbours + // ========================== + delete [] numNeighbours; + + // return vector of Selected digits + // ================================ + if(verbosity>v_message) std::cout << name << " Select by neighbours: " << fSelectByNeighbours->size() << std::endl; + + + return fSelectByNeighbours; +} + +void ClusterSearcher::RecoClusters(std::vector* DigitList) +{ + + // delete cluster digits + // ===================== + for(int i=0; iclear(); + + //Digit Selection + SelectByPulseHeight(DigitList); + SelectByNeighbours(fSelectByPulseHeight); + + // make cluster digits + // =================== + for(int idigit=0; idigitsize()); idigit++ ){ + RecoDigit* recoDigit = (RecoDigit*)(fSelectByNeighbours->at(idigit)); + Log("Check RC: Does the digit have a parent? "+to_string(recoDigit->GetParents().size()), v_debug, verbosity); + RecoClusterDigit* clusterDigit = new RecoClusterDigit(recoDigit); + vClusterDigitList.push_back(clusterDigit); + } + + // run clustering algorithm + // ======================== + for(int idigit1=0; idigit1GetDigitType(); + for(int idigit2=idigit1+1; idigit2GetDigitType(); + + double dx = fdigit1->GetX() - fdigit2->GetX(); + double dy = fdigit1->GetY() - fdigit2->GetY(); + double dz = fdigit1->GetZ() - fdigit2->GetZ(); + double dt = fdigit1->GetTime() - fdigit2->GetTime(); + double drsq = dx*dx + dy*dy + dz*dz; + if(digit1Type == RecoDigit::PMT8inch && digit2Type == RecoDigit::PMT8inch) { + if( drsq>0.0 + && drsqAddClusterDigit(fdigit2); + fdigit2->AddClusterDigit(fdigit1); + } + if (drsq == 0 && fabs(dt) < fPmtTimeWindowC) { + fdigit2->SetClustered(); + } + } + + if(digit1Type == RecoDigit::lappd_v0 && digit2Type == RecoDigit::lappd_v0) { + if( drsq>0.0 + && drsqAddClusterDigit(fdigit2); + fdigit2->AddClusterDigit(fdigit1); + } + } + + if(digit1Type == RecoDigit::PMT8inch && digit2Type == RecoDigit::lappd_v0) { + if( drsq>0.0 + && drsqAddClusterDigit(fdigit2); + } + if( drsq>0.0 + && drsqAddClusterDigit(fdigit1); + } + } + + if(digit1Type == RecoDigit::lappd_v0 && digit2Type == RecoDigit::PMT8inch) { + if( drsq>0.0 + && drsqAddClusterDigit(fdigit2); + } + if( drsq>0.0 + && drsqAddClusterDigit(fdigit1); + } + } + + } + } + + // collect up clusters + // =================== + Bool_t carryon = 0; + for(int idigit=0; idigitIsClustered()==0 && fdigit->GetNClusterDigits()>0 ){ + Log("ClusterSearcher: valid fdigit index: "+to_string(idigit),v_debug,verbosity); + Log("with time: "+to_string(fdigit->GetTime()),v_debug,verbosity); + Log("And location: "+to_string(fdigit->GetX())+", "+to_string(fdigit->GetY())+", "+to_string(fdigit->GetZ()),v_debug,verbosity); + vClusterDigitCollection.clear(); + vClusterDigitCollection.push_back(fdigit); + fdigit->SetClustered(); + + carryon = 1; + while( carryon ){ + carryon = 0; + for(int jdigit=0; jdigit=fMinClusterDigits ){ + RecoCluster cluster; + cluster.SetClusterMode(fClusterMode); + + Log("Adding Digits",v_debug,verbosity); + vector ClusteredDigits; + + for(int jdigit=0; jdigitGetRecoDigit(); + arecodigit->AddCluster(fClusterMode); + RecoDigit brecodigit(arecodigit); + ClusteredDigits.push_back(brecodigit); + + //cluster.AddDigit(*arecodigit); + } + cluster.SetDigits(ClusteredDigits); + //ClusteredDigits = nullptr; + Log("Cluster has " + to_string(cluster.GetNDigits()) + " digits", v_debug, verbosity); + Log("ready to caluclate parameters.",v_debug,verbosity); + cluster.CalcParameters(); + int parent = cluster.calcBestParent(); + Log("Cluster Parent: "+ to_string(parent),v_debug,verbosity); + fRecoClusters->push_back(cluster); + Log("ClusterSearcher: Clusters made: "+to_string(fRecoClusters->size()),v_debug,verbosity); + + + } + } + } + + + Log("Number of clusters = "+to_string(fRecoClusters->size()),v_message,verbosity); + // return vector of clusters + // ========================= + return; +} + +std::vector* ClusterSearcher::SelectByTruthInfo(std::vector* DigitList) +{ + std::string name = " ClusterSearcher::SelectByTruthInfo(() "; + // clear vector of Selected digits + // =============================== + fSelectByTruthInfo->clear(); + + //===================== true info. + double x0 = fTrueVertex->GetPosition().X(); + double y0 = fTrueVertex->GetPosition().Y(); + double z0 = fTrueVertex->GetPosition().Z(); + double dirx = fTrueVertex->GetDirection().X(); + double diry = fTrueVertex->GetDirection().Y(); + double dirz = fTrueVertex->GetDirection().Z(); + double t0 = 0.0; + + // Select by truth + // ====================== + for(int idigit=0; idigitsize()); idigit++ ){ + RecoDigit* recoDigit = (RecoDigit*)DigitList->at(idigit); + double x = recoDigit->GetPosition().X(); + double y = recoDigit->GetPosition().Y(); + double z = recoDigit->GetPosition().Z(); + double dx = x-x0; + double dy = y-y0; + double dz = z-z0; + double ds = sqrt(dx*dx + dy*dy + dz*dz); + double px = dx/ds; + double py = dy/ds; + double pz = dz/ds; + double cosphi = px*dirx + py*diry + pz*dirz; + double phideg = acos(cosphi)/3.14*180; + if(phideg>38) fSelectByTruthInfo->push_back(recoDigit); + } + + // return vector of Selected digits + // ================================ + if(verbosity>v_message) std::cout << name << " Select by opening angle: " << fSelectByTruthInfo->size() << std::endl; + + return fSelectByTruthInfo; +} + diff --git a/UserTools/ClusterSearcher/ClusterSearcher.h b/UserTools/ClusterSearcher/ClusterSearcher.h new file mode 100644 index 000000000..4341d39eb --- /dev/null +++ b/UserTools/ClusterSearcher/ClusterSearcher.h @@ -0,0 +1,149 @@ +#ifndef CLUSTERSEARCHER_H +#define CLUSTERSEARCHER_H + +#include +#include +#include + +#include "Tool.h" +#include "RecoCluster.h" +#include "RecoClusterDigit.h" +#include "TString.h" + +class ClusterSearcher: public Tool { + + public: + + ClusterSearcher(); + ~ClusterSearcher(); + bool Initialise(std::string configfile,DataModel &data); + bool Execute(); + bool Finalise(); + + typedef enum EFilterConfig { + kNone = 0, + kPulseHeight = 1, + kPulseHeightAndNeighbours = 2, + kPulseHeightAndClusters = 3, + kPulseHeightAndTruthInfo = 4 + } FilterConfig_t; + + static ClusterSearcher* Instance(); + + //static void Config(int config); + //static void ClusterType(int ctype); + static void PmtMinPulseHeight(double min); + static void PmtNeighbourRadius(double radius); + static void PmtNeighbourDigits(int digits); + static void PmtClusterRadius(double radius); + static void MinClusterDigits(int digits); + static void PmtTimeWindowN(double windowN); + static void PmtTimeWindowC(double windowC); + + void PrintParameters(); + + void SetClusterMode(int cmode) {fClusterMode = cmode;} + void SetPmtMinPulseHeight(double min) { fPmtMinPulseHeight = min; } + void SetPmtNeighbourRadius(double radius) { fPmtNeighbourRadius = radius; } + void SetPmtNeighbourDigits(int digits) { fPmtMinNeighbourDigits = digits; } + void SetPmtClusterRadius(double radius) { fPmtClusterRadius = radius; } + void SetPmtTimeWindowNeighbours(double windowN) { fPmtTimeWindowN = windowN; } + void SetPmtTimeWindowClusters(double windowC) { fPmtTimeWindowC = windowC; } + + void SetLappdMinPulseHeight(double min) { fLappdMinPulseHeight = min; } + void SetLappdNeighbourRadius(double radius) { fLappdNeighbourRadius = radius; } + void SetLappdNeighbourDigits(int digits) { fLappdMinNeighbourDigits = digits; } + void SetLappdClusterRadius(double radius) { fLappdClusterRadius = radius; } + void SetLappdTimeWindowNeighbours(double windowN) { fLappdTimeWindowN = windowN; } + void SetLappdTimeWindowClusters(double windowC) { fLappdTimeWindowC = windowC; } + //void LoadConfigFile(string configfilename); + void SetMinClusterDigits(int digits) { fMinClusterDigits = digits; } + + + std::vector* ResetDigits(std::vector* digitlist); + std::vector* SelectDigits(std::vector* digitlist); + void SelectDigits(std::vector* digitlist); + std::vector* SelectAll(std::vector* digitlist); + std::vector* SelectByPulseHeight(std::vector* digitlist); + std::vector* SelectByNeighbours(std::vector* digitlist); + std::vector* SelectByTruthInfo(std::vector* digitlist); //use truth information. Only for testing the code + void RecoClusters(std::vector* digitlist); + + + + private: + void Reset(); + + + // clustering mode + int fClusterMode; + + // cleaning parameters + double fPmtMinPulseHeight; + double fPmtNeighbourRadius; + int fPmtMinNeighbourDigits; + double fPmtClusterRadius; + double fPmtTimeWindowN; + double fPmtTimeWindowC; + double fPmtMinHitsPerCluster; + + double fLappdMinPulseHeight; + double fLappdNeighbourRadius; + int fLappdMinNeighbourDigits; + double fLappdClusterRadius; + + double fLappdTimeWindowN; + double fLappdTimeWindowC; + double fLappdMinHitsPerCluster; + + int fMinClusterDigits; + bool fisMC; + bool fFirstRun; //Likely temp; would be nice to have it automatically set. + + // p.e. conversion parameters + std::map pmt_tubeid_to_channelkey; + std::map pmt_gains; + std::string singlePEgains; + + // Container for parameters + std::map* fClusteringParam = nullptr; + + // internal containers + std::vector vNdigitsCluster; + std::vector vClusterDigitList; + std::vector vClusterDigitCollection; + + // vectors of selected digitss + std::vector* fSelectAll; + std::vector* fSelectByPulseHeight; + std::vector* fSelectByNeighbours; + std::vector* fSelectByClusters; + + // for test only + std::vector* fSelectByTruthInfo; + + // vector of clusters (accessible to the CStore) + std::vector* fRecoClusters = nullptr; + std::vector* pre_RecoClusters = nullptr; + + // true vertex + RecoVertex* fTrueVertex = 0; + + // digit list + std::vector* fDigitList = 0; + + // hit clustering status; + bool fIsHitClusteringDone = false; + + /// \brief verbosity levels: if 'verbosity' < this level, the message type will be logged. + int verbosity=1; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; + +}; + + +#endif diff --git a/UserTools/ClusterSearcher/README.md b/UserTools/ClusterSearcher/README.md new file mode 100644 index 000000000..7444b12d7 --- /dev/null +++ b/UserTools/ClusterSearcher/README.md @@ -0,0 +1,51 @@ +# ClusterSearcher + +ClusterSearcher +Creates list of RecoClusters according to provided time- and neighboring- parameters. Clusters are tagged with an int ClusterMode variable for use to differentiate different forms of clusters, created from multiple iterations of the tool within the ToolChain, using separate configfiles (e.g. ClusterSearcherConfig, ClusterSearcherConfig2, etc., using Clustermode 1, 2, etc. respectively) + +## Data + +Describe any data formats ClusterSearch creates, destroys, changes, or analyzes. E.G. + +**pmt_tubeid_to_chanelkey** from CStore +* Identifies individual PMTs in order to find effective charge in p.e. + +**ClusteringParameters** from RecoEvent +* Compares execution parameters to other iterations of this tool within the toolchain + +**TrueVertex** from RecoEvent +* True vertex position, used for + +**RecoClusters** Into and from RecoEvent +* List of RecoClusters found based on the configuration parameters provided +* Any RecoClusters created by previous iteration(s) of ClusterSearcher in the toolchain, so that new clusters can be added to the singular list + + + + +## Configuration + + +verbosity 5 +ClusterMode 1 #searching track-like clusters +Config 3 #config type: 1 = pulse height cut, 2 = +neighbour cut, 3 = +cluster cut +PmtMinPulseHeight 20 #minimum pulse height +PmtNeighbourRadius 60 #digit neighbouring distance [cm] +PmtMinNeighbourDigits 2 #minimum neighbour digits +PmtClusterRadius 60 #digit clustering distance [cm] +PmtTimeWindowN 10 #neighbouring time window [ns] +PmtTimeWindowC 100 #clustering time window [ns] +PmtMinHitsPerCluster 4 #number of hits per cluster +LappdMinPulseHeight 0 #minimum pulse height +LappdNeighbourRadius 25 #digit neighbouring distance [cm] +LappdMinNeighbourDigits 20 #minimum neighbour digits +LappdClusterRadius 25 #digit clustering distance [cm] +LappdTimeWindowN 1 #neighbouring time window [ns] +LappdTimeWindowC 1 #clustering time window [ns] +LappdMinHitsPerCluster 5 #number of digits per cluster +MinClusterDigits 50 #minimum clustered digits (LAPPD+PMT) +MinClusterDigits 4 #minimum clustered digits (PMT-only) +SinglePEGains /path/to/gains/file #file in which SPE information can be found for PMT charge conversions; only needed on Data +FirstRun 1 #Debug input for differentiating first iteration from later iterations + +``` diff --git a/UserTools/DigitBuilder/DigitBuilder.cpp b/UserTools/DigitBuilder/DigitBuilder.cpp index b3a5a3e4e..62f591f66 100644 --- a/UserTools/DigitBuilder/DigitBuilder.cpp +++ b/UserTools/DigitBuilder/DigitBuilder.cpp @@ -18,7 +18,6 @@ DigitBuilder::~DigitBuilder() { bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ /////////////////// Usefull header /////////////////////// - if(verbosity) cout<<"Initializing Tool DigitBuilder"<; + fHitLAPPDs = new std::vector; // Make the RecoDigit Store if it doesn't exist int recoeventexists = m_data->Stores.count("RecoEvent"); @@ -57,6 +62,7 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ Log("DigitBuilder Tool: Error retrieving Geometry from ANNIEEvent!",v_error,verbosity); return false; } + Log("Strip Hit Mode:" + to_string(striphit),v_debug,verbosity); // Some hard-coded values of old WCSim LAPPDIDs are in this Tool // I would recommend moving away from the use of WCSim IDs if possible as they are liable to change @@ -66,6 +72,10 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ m_data->CStore.Get("channelkey_to_pmtid",channelkey_to_pmtid); } else { ifstream file_pmtid(path_chankeymap.c_str()); + if (!file_pmtid) { + Log("DigitBuilder Tool: Did not find chankeymap file",v_error,verbosity); + return false; + } while (!file_pmtid.eof()){ unsigned long chankey; int pmtid; @@ -73,19 +83,39 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ channelkey_to_pmtid.emplace(chankey,pmtid); pmtid_to_channelkey.emplace(pmtid,chankey); if (file_pmtid.eof()) break; + Log("DigitBuilder Tool: still gathering chankeys",v_debug,verbosity); } - + Log("DigitBuilder Tool: chankeys done",v_debug,verbosity); file_pmtid.close(); m_data->CStore.Set("pmt_tubeid_to_channelkey",pmtid_to_channelkey); ifstream file_singlepe(singlePEgains.c_str()); + if (!file_singlepe) { + Log("DigitBuilder Tool: Did not find SinglePEgains file",v_error,verbosity); + return false; + } unsigned long temp_chankey; double temp_gain; - while (!file_singlepe.eof()){ - file_singlepe >> temp_chankey >> temp_gain; - if (file_singlepe.eof()) break; - pmt_gains.emplace(temp_chankey,temp_gain); + + std::string line; + if (file_singlepe.is_open()) { + //Loop over lines, collect all detector data (should only be one line here) + while (getline(file_singlepe, line)) { + if (verbosity > 3) std::cout << line << std::endl; //has our stuff; + if (line.empty() || line[0] == '#') continue; + std::vector DataEntries; + boost::split(DataEntries, line, boost::is_any_of(","), boost::token_compress_on); + int channelkey = -9999; + double SPECharge = -9999.; + channelkey = std::stoi(DataEntries.at(0)); + SPECharge = std::stod(DataEntries.at(1)); + pmt_gains.emplace(channelkey, SPECharge); + } } + + + + Log("DigitBuilder Tool: SPE gains done",v_debug,verbosity); file_singlepe.close(); } @@ -93,10 +123,10 @@ bool DigitBuilder::Initialise(std::string configfile, DataModel &data){ //Read the LAPPDID file, if given if(fLAPPDIDFile!="none"){ - if(verbosity>2) std::cout << "Loading digits from LAPPD IDs in file " << fLAPPDIDFile << std::endl; + Log("Loading digits from LAPPD IDs in file " + fLAPPDIDFile,v_debug,verbosity); this->ReadLAPPDIDFile(); } else { - if(verbosity>2) std::cout << "Loading digits from all LAPPDs" << std::endl; + Log("Loading digits from all LAPPDs",v_debug,verbosity); } return true; } @@ -135,16 +165,11 @@ bool DigitBuilder::Execute(){ return false; } } else { - auto get_clusters = m_data->CStore.Get("ClusterMap",m_all_clusters); - if (!get_clusters){ - Log("DigitBuilder Tool: ERROR retrieving clustered hits (ClusterMap) in Data mode!",v_error,verbosity); - return false; - } - auto get_clusters_chankey = m_data->CStore.Get("ClusterMapDetkey",m_all_clusters_detkey); - if (!get_clusters_chankey){ - Log("DigitBuilder Tool: ERROR retrieving clustered chankeys (ClusterMapDetkey) in Data mode!",v_error,verbosity); - return false; - } + auto get_dhits = m_data->Stores.at("ANNIEEvent")->Get("Hits",Hits); + if (!get_dhits) { + Log("DigitBuilder Tool: ERROR retrieving hits in Data mode!",v_error,verbosity); + return false; + } } /// Build RecoDigit @@ -160,8 +185,7 @@ bool DigitBuilder::Execute(){ } bool DigitBuilder::Finalise(){ - //delete fDigitList; fDigitList = 0; //Don't delete pointer to fDigitList, will be deleted by the BoostStore! - if(verbosity>0) cout<<"DigitBuilder exitting"<> + + if(fMCPMTHits){ + if (fCollectHits) { + Log("DigitBuilder Tool: Collecting Hits to make Digits",v_message,verbosity); + CollectMCPMTHits(); + Log("DigitBuilder Tool: # of digits in this event: "+to_string(fDigitList->size()),v_debug,verbosity); + } + else { Log("DigitBuilder Tool: Num PMT Digits = "+to_string(fMCPMTHits->size()),v_message, verbosity); /// iterate over the map of sensors with a measurement for(std::pair>&& apair : *fMCPMTHits){ @@ -243,69 +276,86 @@ bool DigitBuilder::BuildMCPMTRecoDigit() { if(det->GetDetectorElement()=="Tank"){ std::vector& hits = apair.second; if(fParametricModel){ - if(verbosity>2) std::cout << "Using parametric model to build PMT hits" << std::endl; + Log("Using parametric model to build PMT hits",v_debug,verbosity); //We'll get all hit info and then define a time/charge for each digit std::vector hitTimes; std::vector hitCharges; + //std::vector hitIDs; for(MCHit& ahit : hits){ - if(verbosity>3){ - std::cout << "This HIT'S TIME AND CHARGE: " << ahit.GetTime() << - "," << ahit.GetCharge() << std::endl; - } + Log("This HIT'S TIME AND CHARGE: " + to_string(ahit.GetTime()) + ", " + to_string(ahit.GetCharge()),v_debug,verbosity); double hitTime = ahit.GetTime()*1.0; - if(hitTime>-10 && hitTime<40) { + if(hitTime>-10 && hitTime 0)calT = calT / ((int)(timesize / 5)); + } + else if (fParametricModel == 4) { //Average hit time + for (int i = 0; i < timesize; i++) { + calT += hitTimes.at(i); + } + calT = calT / timesize; + } + else if (fParametricModel == 5) { + for (int i = 0; i < timesize; i++) { + if (hitCharges.at(i) > maxT) maxT = hitTimes.at(i); + } + calT = maxT; + } + if (MCPMTResolution > 0) calT = frand.Gaus(calT, MCPMTResolution); calQ = 0.; for(std::vector::iterator it = hitCharges.begin(); it != hitCharges.end(); ++it){ calQ += *it; } - if (verbosity>4) { - std::cout << "PMT position (XfDigitChargeThr) { //changed to 0 for cross-checks with other tools, change back later! digitType = RecoDigit::PMT8inch; RecoDigit recoDigit(region, pos_reco, calT, calQ, digitType, PMTId); + //recoDigit.SetHitIDs(hitIDs); fDigitList->push_back(recoDigit); } - } else { + }else{ for(MCHit& ahit : hits){ - //if(v_message4) { - std::cout << "PMT position (Xpush_back(recoDigit); } - } + } } } // end loop over MCHits - } else { - cout<<"No MCHits"<size() > 0) { + fHitLAPPDs->clear(); + } + // repeat for LAPPD hits // MCLAPPDHits is a std::map> - if(fMCLAPPDHits){ + if(fMCLAPPDHits && fMCLAPPDHits->size() > 0){ Log("DigitBuilder Tool: Num LAPPD Digits = "+to_string(fMCLAPPDHits->size()),v_message,verbosity); // iterate over the map of sensors with a measurement for(std::pair>&& apair : *fMCLAPPDHits){ @@ -341,46 +396,122 @@ bool DigitBuilder::BuildMCLAPPDRecoDigit() { } if(!isSelectedLAPPD && fLAPPDId.size()>0) continue; if(verbosity>2){ - std::cout << "Loading in digits for LAPPDID " << LAPPDId << std::endl; + Log("Loading in digits for LAPPDID " + to_string(LAPPDId), v_message,verbosity); + Log("located: ",v_message,verbosity); + det->GetPositionInTank().Print(); + Log("directed: ",v_message,verbosity); + det->GetDetectorDirection().Print(); } - if(det->GetDetectorElement()=="LAPPD"){ // redundant, MCLAPPDHits are LAPPD hitss - std::vector& hits = apair.second; - for(MCLAPPDHit& ahit : hits){ - //if(v_message4) { - std::cout << "LAPPD position (XGetDetectorElement() == "LAPPD") { // redundant, MCLAPPDHits are LAPPD hitss + std::vector& hits = apair.second; + + std::vector sumposX; + std::vector sumposY; + std::vector sumposZ; + std::vector sumT; + double posX; + std::vector nHitsOnStrip; + int a; + for (int i = 0; i < 28; i++) { + sumposX.push_back(0); + sumposY.push_back(0); + sumposZ.push_back(0); + sumT.push_back(0); + nHitsOnStrip.push_back(0); } - // I found the charge is 0 for all the hits. In order to test the code, - // here I just set the charge to 1. We should come back to this later. (Jingbo Wang) - calQ = 1.; - digitType = RecoDigit::lappd_v0; - RecoDigit recoDigit(region, pos_reco, calT, calQ, digitType,LAPPDId); - //if(v_message40 || calT<-10) continue; // cut off delayed hits - fDigitList->push_back(recoDigit); + for(MCLAPPDHit& ahit : hits){ + if (LAPPDId != currentLAPPD && hits.size() > 3) { + Log("THERE ARE HITS ON LAPPD " + to_string(LAPPDId),v_message,verbosity); + currentLAPPD = LAPPDId; + fHitLAPPDs->push_back(currentLAPPD); + Log("fHitLAPPDs size: " + to_string(fHitLAPPDs->size()),v_message,verbosity); + } + if (striphit == 0) { + //if(v_message 40 || calT < -10) continue; // cut off delayed hits + //recoDigit.SetHitIDs(hitIDs); + fDigitList->push_back(recoDigit); + + } + else { + posX = (ahit.GetPosition().at(0) * 100 + xshift) - (det->GetPositionInTank().X() * 100 + xshift); + double dirX = det->GetDetectorDirection().X(); + double AngX = std::asin(dirX); + int strip = (int)((posX / (20.* std::sin(AngX) / 28.)) + 14 - 1); + if (strip > 27 || strip < 0) { + Log("warning: LAPPD hit found off LAPPD: ", v_warning, verbosity); + Log("hit found on strip " + to_string(strip),v_warning,verbosity); + Log("LAPPD truehit X,Y,Z: " + to_string(ahit.GetPosition().at(0)) + ", " + to_string(ahit.GetPosition().at(1)) + ", " + to_string(ahit.GetPosition().at(2)),v_warning,verbosity); + Log("continuing loop without this hit.",v_warning,verbosity); + continue; + } + Log("hit found on strip " + to_string(strip),v_debug,verbosity); + sumposX.at(strip) += ahit.GetPosition().at(0) * 100 + xshift; + sumposY.at(strip) += ahit.GetPosition().at(1) * 100 + yshift; + sumposZ.at(strip) += ahit.GetPosition().at(2) * 100 + zshift; + Log("LAPPD truehit X,Y,Z: " + to_string(ahit.GetPosition().at(0)) + ", " + to_string(ahit.GetPosition().at(1)) + ", " + to_string(ahit.GetPosition().at(2)),v_debug,verbosity); + + if ((striphit == 3 && nHitsOnStrip.at(strip) < 3) || (striphit==2 && nHitsOnStrip.at(strip) == 0) || striphit == 1) + sumT.at(strip) += frand.Gaus(calT, 0.1); // time is smeared with 100 ps time resolution. Harded-coded for now. + nHitsOnStrip.at(strip) += 1; + + } } + if (striphit != 0) { + for (int strip = 0; strip < 28; strip++) { + if (nHitsOnStrip.at(strip) != 0) { + pos_reco.SetX(sumposX.at(strip) / nHitsOnStrip.at(strip)); + pos_reco.SetY(sumposY.at(strip) / nHitsOnStrip.at(strip)); + pos_reco.SetZ(sumposZ.at(strip) / nHitsOnStrip.at(strip)); + if(striphit == 1) calT = sumT.at(strip) / nHitsOnStrip.at(strip); + if (striphit == 3) calT = sumT.at(strip) / 3; + calQ = nHitsOnStrip.at(strip); //set to the number of hits for now. + digitType = RecoDigit::lappd_v0; + + Log("LAPPD ID: " + to_string(LAPPDId),v_message,verbosity); + Log("LAPPD strip-hit position (Xpush_back(recoDigit); + } + } + } + sumposX.clear(); + sumposY.clear(); + sumposZ.clear(); + sumT.clear(); + nHitsOnStrip.clear(); } } // end loop over MCLAPPDHits } else { - cout<<"No MCLAPPDHits"<> - - if (m_all_clusters && m_all_clusters_detkey){ - int clustersize = m_all_clusters->size(); - std::cout <<"Clustersize of m_all_clusters: "<>&& apair : *m_all_clusters){ - std::vector&Hits = apair.second; - double time = 0; - int hits=0; - double charge = 0; - for (unsigned int i_hit = 0; i_hit < Hits.size(); i_hit++){ - hits++; - time+=Hits.at(i_hit).GetTime(); - charge+=Hits.at(i_hit).GetCharge(); - } - if (hits>0) { - time/=hits; - } - if (time > 2000.) continue; //not a beam muon if not in primary window - if (charge > max_charge) { - muon_available = true; - max_charge = charge; - max_cluster = apair.first; - } - } - if (muon_available){ - std::vector& Hits = m_all_clusters->at(max_cluster); - std::vector detkeys = m_all_clusters_detkey->at(max_cluster); - int hits_pmt = 0; - - std::map> hitTimes; - std::map> hitCharges; - - Log("DigitBuilder Tool: Num PMT Clustered Digits = "+to_string(Hits.size()),v_message, verbosity); - for (unsigned int i_hit = 0; i_hit < Hits.size(); i_hit++){ - Hit ahit = Hits.at(i_hit); - unsigned long chankey = detkeys.at(i_hit); - - - if (hitTimes.find(chankey)!=hitTimes.end()){ - hitTimes.at(chankey).push_back(ahit.GetTime()); - hitCharges.at(chankey).push_back(ahit.GetCharge()); - } - else { - std::vector temp_hittimes{ahit.GetTime()}; - std::vector temp_hitcharges{ahit.GetCharge()}; - hitTimes.emplace(chankey,temp_hittimes); - hitCharges.emplace(chankey,temp_hitcharges); - } - } - if(fParametricModel){ - Log("DigitBuilder tool: Use Parametric Model to create digits",v_message,verbosity); - // Do median and sum - std::map>::iterator it, it2; - for (it=hitTimes.begin(),it2 = hitCharges.begin(); it != hitTimes.end(), it2 != hitCharges.end(); it++, it2++){ - unsigned long chankey = it->first; - std::vector hittimes = it->second; - std::vector hitcharges = it2->second; - det = fGeometry->ChannelToDetector(chankey); - int PMTId = channelkey_to_pmtid.at(chankey); //PMTID In WCSim - if(det==nullptr){ - Log("DigitBuilder Tool: Detector not found! ",v_message,verbosity); - continue; - } - // convert the WCSim coordinates to the ANNIEreco coordinates - // convert the unit from m to cm - pos_sim = det->GetDetectorPosition(); - pos_sim.UnitToCentimeter(); - pos_reco.SetX(pos_sim.X()+xshift); - pos_reco.SetY(pos_sim.Y()+yshift); - pos_reco.SetZ(pos_sim.Z()+zshift); - - std::sort(hittimes.begin(), hittimes.end()); - size_t timesize = hittimes.size(); - if (timesize == 0) continue; - if (timesize % 2 == 0){ - calT = (hittimes.at(timesize/2 - 1) + hittimes.at(timesize/2))/2; - } else { - calT = hittimes.at(timesize/2); - } - calQ = 0.; - for(std::vector::iterator it3 = hitcharges.begin(); it3 != hitcharges.end(); ++it3){ - calQ += *it3; - } - if (verbosity>4) { - std::cout << "PMT position (X 0.0){ - calQ_temp = calQ / pmt_gains.at(chankey); - } - if(calQ_temp>fDigitChargeThr) { - digitType = RecoDigit::PMT8inch; - RecoDigit recoDigit(region, pos_reco, calT, calQ_temp, digitType, PMTId); - fDigitList->push_back(recoDigit); - } - } - } else { - std::map>::iterator it, it2; - for (it=hitTimes.begin(), it2 = hitCharges.begin(); it != hitTimes.end(), it2 != hitCharges.end(); it++, it2++){ - unsigned long chankey = it->first; - std::vector hittimes = it->second; - std::vector hitcharges = it2->second; - det = fGeometry->ChannelToDetector(chankey); - int PMTId = channelkey_to_pmtid.at(chankey); //PMTID In WCSim - if(det==nullptr){ - Log("DigitBuilder Tool: Detector not found! ",v_message,verbosity); - continue; - } - pos_sim = det->GetDetectorPosition(); - pos_sim.UnitToCentimeter(); - pos_reco.SetX(pos_sim.X()+xshift); - pos_reco.SetY(pos_sim.Y()+yshift); - pos_reco.SetZ(pos_sim.Z()+zshift); - - for (int i=0; i< int(hitcharges.size()); i++){ - calT = hittimes.at(i); - calQ = hitcharges.at(i); - if (verbosity>4) { - std::cout << "PMT position (X>&& apair : *Hits) { + unsigned long chankey = apair.first; + Detector* thistube = fGeometry->ChannelToDetector(chankey); + det = fGeometry->ChannelToDetector(chankey); + int detectorkey = thistube->GetDetectorID(); + int PMTId = channelkey_to_pmtid.at(chankey); + if (thistube->GetDetectorElement() == "Tank") { + std::vector& ThisPMTHits = apair.second; + for (Hit& ahit : ThisPMTHits) { + pos_reco=det->GetDetectorPosition(); + calT = ahit.GetTime(); + + calQ = ahit.GetCharge(); + + if (pmt_gains.find(chankey) != pmt_gains.end() && pmt_gains.at(chankey) > 0.0) { + calQ_temp = calQ / pmt_gains.at(chankey); } - digitType = RecoDigit::PMT8inch; - RecoDigit recoDigit(region, pos_reco, calT, calQ, digitType, PMTId); - fDigitList->push_back(recoDigit); - } - } - } - } - } - } else { - cout<<"No Clustered Hits found."< fDigitChargeThr) { + digitType = RecoDigit::PMT8inch; + RecoDigit recoDigit(region, pos_reco, calT, calQ_temp, digitType, PMTId); + + //recoDigit.SetHitIDs(hitIDs); + fDigitList->push_back(recoDigit); + } + + } + + } + } return true; @@ -551,11 +565,13 @@ bool DigitBuilder::BuildDataPMTRecoDigit(){ void DigitBuilder::PushRecoDigits(bool savetodisk) { Log("DigitBuilder Tool: Push reconstructed digits to the RecoEvent store",v_message,verbosity); m_data->Stores.at("RecoEvent")->Set("RecoDigit", fDigitList, savetodisk); ///> Add digits to RecoEvent + m_data->Stores.at("RecoEvent")->Set("HitLAPPDs", fHitLAPPDs, savetodisk); } void DigitBuilder::Reset() { // Reset fDigitList->clear(); + fHitLAPPDs->clear(); } void DigitBuilder::ReadLAPPDIDFile() { @@ -564,7 +580,7 @@ void DigitBuilder::ReadLAPPDIDFile() { if (myfile.is_open()){ while(getline(myfile,line)){ if(verbosity>0){ - std::cout << "DigitBuilder tool: Loading hits from LAPPD ID " << line << std::endl; + Log("DigitBuilder tool: Loading hits from LAPPD ID " + line,v_message,verbosity); } int thisID = std::atoi(line.c_str()); fLAPPDId.push_back(thisID); @@ -573,3 +589,145 @@ void DigitBuilder::ReadLAPPDIDFile() { Log("Unable to open given LAPPD ID File. Using all LAPPDs",v_error,verbosity); } } + +void DigitBuilder::CollectMCPMTHits() { + double calT = 0; + double calQ = 0; + Position pos_reco, pos_sim; + std::map PMT_ishit; + + + for (std::pair>&& apair : *fMCPMTHits) { + unsigned long chankey = apair.first; + Detector* thistube = fGeometry->ChannelToDetector(chankey); + int detectorkey = thistube->GetDetectorID(); + int PMTId = channelkey_to_pmtid.at(chankey); + Log("DigitBuilder Tool: collecting hits for PMT "+to_string(detectorkey)+", which corresponds to PMTId "+to_string(PMTId),v_debug,verbosity); + if (thistube->GetDetectorElement() == "Tank") { + std::vector& hits = apair.second; + PMT_ishit[detectorkey] = 1; + std::vector hit_times; + std::vector temp_times; + double first_time=0; + double mid_time=0; + std::vector datalike_hits; + std::vector datalike_hits_charge; + std::vector Parents_by_hit; + std::vector temp_parents; + double max_charge=-999; + pos_sim = thistube->GetDetectorPosition(); + pos_sim.UnitToCentimeter(); + pos_reco.SetX(pos_sim.X() + xshift); + pos_reco.SetY(pos_sim.Y() + yshift); + pos_reco.SetZ(pos_sim.Z() + zshift); + + + for (MCHit& ahit : hits) { + + hit_times.push_back(ahit.GetTime()); + + } + + + if (hit_times.size() == 0) { + Log("DigitBuilder tool: no hits in window.",v_message,verbosity); + return; + } + + //Combine multiple MC hits to one pulse + std::sort(hit_times.begin(), hit_times.end()); + for (int i_hit = 0; i_hit < (int)hit_times.size(); i_hit++) { + Log("Hits, hit_times, datalike_hits, parents size: "+to_string(hits.size())+" "+to_string(hit_times.size())+" "+to_string(datalike_hits.size())+" " + to_string(hits.at(i_hit).GetParents()->size()), v_debug, verbosity); + double hit1 = hit_times.at(i_hit); + if(hit1>end_of_window_time_cut * AcqTimeWindow) continue; + int j_hit=0; + if (datalike_hits.size() == 0) { + + + datalike_hits.push_back(hit1); + first_time=hit1; + + datalike_hits_charge.push_back(hits.at(i_hit).GetCharge()); + if (hits.at(i_hit).GetParents()->size() == 0) { + Parents_by_hit.push_back(-5); + Log("found hit with no parent at time "+to_string(hits.at(i_hit).GetTime()),v_debug,verbosity); + } + else { + Parents_by_hit.push_back(hits.at(i_hit).GetParents()->at(0)); + } + + temp_times.push_back(hit1); + } + else { + bool new_pulse = false; + + for (int j_hit = 0; j_hit < (int)datalike_hits.size(); j_hit++) { + + if (fabs(first_time - hit1) < 10.) { + new_pulse = false; + datalike_hits_charge.at(j_hit) += hits.at(i_hit).GetCharge(); + temp_times.push_back(hit1); + + } + else { + new_pulse = true; + temp_times.push_back(hit1); + + } + + } + + if (new_pulse) { + first_time=hit1; + + // following the DigitBuilder tool --> take median photon hit time as the hit time of the "pulse" + sort(temp_times.begin(),temp_times.end()); + if (temp_times.size() % 2 == 0) { + mid_time = (temp_times.at(temp_times.size() / 2 - 1) + temp_times.at(temp_times.size() / 2)) / 2; + } + else { + mid_time = temp_times.at(temp_times.size() / 2); + } + + datalike_hits.at(j_hit)=mid_time; //datalike_hits.push_back(mid_time); //Only count as a new pulse if it was 10ns away from every other pulse + datalike_hits_charge.push_back(hits.at(i_hit).GetCharge()); + j_hit++; + + datalike_hits.push_back(hit1); + + if (hits.at(i_hit).GetParents()->size() == 0) Parents_by_hit.push_back(-5); + else { + Parents_by_hit.push_back(hits.at(i_hit).GetParents()->at(0)); + Log("Hit parent " + to_string(hits.at(i_hit).GetParents()->at(0)) + " and time: " + to_string(hits.at(i_hit).GetTime()), v_debug, verbosity); + } + temp_times.clear(); + + } + } + } + + + //hits.clear(); + + for (int i_hit = 0; i_hit < (int)datalike_hits.size(); i_hit++) { + + calT = datalike_hits.at(i_hit); + + if (MCPMTResolution > 0) calT= frand.Gaus(calT, MCPMTResolution); + calQ = datalike_hits_charge.at(i_hit); + + RecoDigit recoDigit(-999 /*region*/, pos_reco, calT, calQ, RecoDigit::PMT8inch, PMTId); + temp_parents.push_back(Parents_by_hit.at(i_hit)); + + recoDigit.SetParents(temp_parents); + fDigitList->push_back(recoDigit); + temp_parents.clear(); + + Log("PMT position (X class DigitBuilder: public Tool { @@ -43,6 +44,7 @@ class DigitBuilder: public Tool { /// It adds PMT hits to the RecoDigit list bool BuildMCPMTRecoDigit(); bool BuildDataPMTRecoDigit(); ///> Same as BuildMCPMTRecoDigit, but applicable for data. + void CollectMCPMTHits(); /// \brief Build LAPPD digits /// @@ -72,15 +74,21 @@ class DigitBuilder: public Tool { int verbosity=1; std::string fInputfile; unsigned long fNumEvents; - + std::vector* fHitLAPPDs; std::vector fLAPPDId; ///< selected LAPPDs std::string fPhotodetectorConfiguration; ///< "PMTs_Only", "LAPPDs_Only", "All_Detectors" - bool fParametricModel; ///< configures if PMTs hits for each event are accumulated into one hit per PMT + int fParametricModel; ///< configures how PMTs hits for each event are accumulated into one hit per PMT 0: they are not, 1: median hit time, 2: first hit time, 3: average first 20% of hits, 4: average all hits, 5: highest charge hit time bool fIsMC; ///< Configure whether to load from MCHits or Hits in boost store std::string fLAPPDIDFile="none"; double fDigitChargeThr; std::string path_chankeymap; std::string singlePEgains; + int striphit; //0 all LAPPD Hits as true; 1 average all times per strip; 2 use first time for each strip + double MCPMTResolution = 0; + + bool fCollectHits; + int AcqTimeWindow; + double end_of_window_time_cut; Geometry* fGeometry=nullptr; ///< ANNIE Geometry TRandom3 frand; ///< Random number generator @@ -104,10 +112,11 @@ class DigitBuilder: public Tool { /// Reconstructed information std::vector* fDigitList; ///< Reconstructed Hits including both LAPPD hits and PMT hits std::map>* fMCPMTHits=nullptr; ///< PMT hits + std::map>* Hits = nullptr; std::map>* fMCLAPPDHits=nullptr; ///< LAPPD hits std::map>* fTDCData=nullptr; ///< MRD & veto hits - std::map>* m_all_clusters=nullptr; ///< Clusters, from ClusterFinder tool - std::map>* m_all_clusters_detkey=nullptr; ///< Chankeys corresponding to clusters, from ClusterFinder tool + std::map>* m_all_clusters=nullptr; ///< Clusters, from ClusterFinder tool - deprecated and to be removed + std::map>* m_all_clusters_detkey=nullptr; ///< Chankeys corresponding to clusters, from ClusterFinder tool - deprecated and to be removed std::map pmt_gains; diff --git a/UserTools/Examples/DummyTool.cpp b/UserTools/DummyTool/DummyTool.cpp similarity index 100% rename from UserTools/Examples/DummyTool.cpp rename to UserTools/DummyTool/DummyTool.cpp diff --git a/UserTools/Examples/DummyTool.h b/UserTools/DummyTool/DummyTool.h similarity index 100% rename from UserTools/Examples/DummyTool.h rename to UserTools/DummyTool/DummyTool.h diff --git a/UserTools/EBLAPPD/EBLAPPD.cpp b/UserTools/EBLAPPD/EBLAPPD.cpp new file mode 100644 index 000000000..e78ca5a18 --- /dev/null +++ b/UserTools/EBLAPPD/EBLAPPD.cpp @@ -0,0 +1,382 @@ +#include "EBLAPPD.h" + +EBLAPPD::EBLAPPD() : Tool() {} + +bool EBLAPPD::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("verbosityEBLAPPD", verbosityEBLAPPD); + matchTargetTrigger = 14; + m_variables.Get("matchTargetTrigger", matchTargetTrigger); + matchTolerance_ns = 400000; // default 400us + m_variables.Get("matchTolerance_ns", matchTolerance_ns); + matchToAllTriggers = false; + m_variables.Get("matchToAllTriggers", matchToAllTriggers); + exePerMatch = 500; + m_variables.Get("exePerMatch", exePerMatch); + + return true; +} + +bool EBLAPPD::Execute() +{ + m_data->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) +{ + Log("\033[1;34m******* EBLAPPD : Matching *******\033[0m", v_message, verbosityEBLAPPD); + 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 (const 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; + } + const vector>& GroupedTriggers = pair.second; + + for (int j = 0; j < GroupedTriggers.size(); j++) + { + const map& groupedTrigger = GroupedTriggers.at(j); + // itearte over all the grouped triggers, if the value is target trigger, then calculate the time difference + for (const 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; +} 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..68ae0deae --- /dev/null +++ b/UserTools/EBLoadRaw/EBLoadRaw.cpp @@ -0,0 +1,713 @@ +#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); + } + } + else + { + std::cerr << "EBLoadRaw::OrganizeRunParts: Failed to open file list " << FileList << std::endl; + } + // 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..fbbaa483b --- /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 (const std::pair>>& p : MRDEvents) + { + const uint64_t MTCtime = p.first; + const std::vector>& WaveMap = p.second; + // if find the MTCtime in the PairedMRDTimeStamps, then skip + if (PairedMRDTimeStamps.size() > 0) + { + bool skip = false; + for (const std::pair>& pair : PairedMRDTimeStamps) + { + for (const 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) +{ + Log("\033[1;34m******* EBMRD : Matching *******\033[0m", v_message, verbosityEBMRD); + 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 (const std::pair>>& mrdpair : MRDEventsBuffer) + { + if (verbosityEBMRD > 11) + cout << "******************EBMRD: new MRD event: " << loopNum << endl; + const uint64_t MTCtime = mrdpair.first; + const 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 (const 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); + + const vector>& groupedTriggers = pair.second; + + for (int i = 0; i < groupedTriggers.size(); i++) + { + const map& groupedTrigger = groupedTriggers.at(i); + // itearte over all the grouped triggers, if the value is target trigger, then calculate the time difference + for (const 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; +} 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/EBPMT/EBPMT.cpp b/UserTools/EBPMT/EBPMT.cpp new file mode 100644 index 000000000..cc160819f --- /dev/null +++ b/UserTools/EBPMT/EBPMT.cpp @@ -0,0 +1,513 @@ +#include "EBPMT.h" + +EBPMT::EBPMT() : Tool() {} + +bool EBPMT::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("verbosityEBPMT", verbosityEBPMT); + matchTargetTrigger = 5; + m_variables.Get("matchTargetTrigger", matchTargetTrigger); + matchTolerance_ns = 200; // default 200ns + m_variables.Get("matchTolerance_ns", matchTolerance_ns); + exePerMatch = 500; + m_variables.Get("exePerMatch", exePerMatch); + matchToAllTriggers = false; + m_variables.Get("matchToAllTriggers", matchToAllTriggers); + + NumWavesInCompleteSet = 140; + + FinishedHits = new std::map> *>(); + //RWMRawWaveforms = new std::map>(); + //BRFRawWaveforms = new std::map>(); + + saveRWMWaveforms = true; + saveBRFWaveforms = true; + m_variables.Get("saveRWMWaveforms", saveRWMWaveforms); + m_variables.Get("saveBRFWaveforms", saveBRFWaveforms); + + return true; +} + +bool EBPMT::Execute() +{ + m_data->CStore.Get("RunCode", currentRunCode); + bool gotHits = m_data->CStore.Get("InProgressHits", InProgressHits); + bool gotChkey = m_data->CStore.Get("InProgressChkey", InProgressChkey); + + if (!gotHits || !gotChkey) + { + Log("EBPMT: No InProgressHits or InProgressChkey found", v_message, verbosityEBPMT); + return true; + } + Log("EBPMT: got inprogress hits and chkey with size " + std::to_string(InProgressHits->size()) + " and " + std::to_string(InProgressChkey->size()), v_message, verbosityEBPMT); + + + + if (exeNum % 80 == 0 && exeNum != 0) + { + // 80 is arbitrary, because 6*80 = 480 around, close, and smaller than the pairing exe number, exePerMatch default 500 + Log("EBPMT: exeNum: " + std::to_string(exeNum) + " Before loading, apply a VMEOffset correction", v_message, verbosityEBPMT); + Log("EBPMT: before apply the VME offset correction, the size of FinishedHits is " + std::to_string(FinishedHits->size()), v_message, verbosityEBPMT); + m_data->CStore.Get("InProgressHitsAux", InProgressHitsAux); + m_data->CStore.Get("InProgressRecoADCHits", InProgressRecoADCHits); + m_data->CStore.Get("InProgressRecoADCHitsAux", InProgressRecoADCHitsAux); + + CorrectVMEOffset(); + m_data->CStore.Set("InProgressHits", InProgressHits); + m_data->CStore.Set("InProgressChkey", InProgressChkey); + m_data->CStore.Set("InProgressHitsAux", InProgressHitsAux); + m_data->CStore.Set("InProgressRecoADCHits", InProgressRecoADCHits); + m_data->CStore.Set("InProgressRecoADCHitsAux", InProgressRecoADCHitsAux); + m_data->CStore.Set("RWMRawWaveforms", RWMRawWaveforms); + m_data->CStore.Set("BRFRawWaveforms", BRFRawWaveforms); + } + + m_data->CStore.Get("PairedPMTTriggerTimestamp", PairedCTCTimeStamps); + m_data->CStore.Get("PairedPMTTimeStamps", PairedPMTTimeStamps); + Log("EBPMT: Got PairedPMTTimeStamps size: " + std::to_string(PairedPMTTimeStamps.size()), v_message, verbosityEBPMT); + Log("EBPMT: Got PairedPMTTriggerTimestamp size: " + std::to_string(PairedCTCTimeStamps.size()), v_message, verbosityEBPMT); + + + + bool gotRWM = m_data->CStore.Get("RWMRawWaveforms", RWMRawWaveforms); + bool gotBRF = m_data->CStore.Get("BRFRawWaveforms", BRFRawWaveforms); + if (gotRWM && gotBRF && RWMRawWaveforms != NULL && BRFRawWaveforms != NULL) + { + Log("EBPMT: Got RWMRawWaveforms size: " + std::to_string(RWMRawWaveforms->size()), v_message, verbosityEBPMT); + Log("EBPMT: Got BRFRawWaveforms size: " + std::to_string(BRFRawWaveforms->size()), v_message, verbosityEBPMT); + } + else + { + Log("EBPMT: No RWMRawWaveforms or BRFRawWaveforms found", v_message, verbosityEBPMT); + } + + vector PMTEmplacedHitTimes; + vector RWMEmplacedTimes; + vector BRFEmplacedTimes; + + for (std::pair> *> p : *InProgressHits) + { + uint64_t PMTCounterTimeNs = p.first; + std::map> *hitMap = p.second; + vector ChannelKey = InProgressChkey->at(PMTCounterTimeNs); + + Log("EBPMT: PMTCounterTimeNs: " + std::to_string(PMTCounterTimeNs), v_debug, verbosityEBPMT); + Log("EBPMT: hitMap size: " + std::to_string(hitMap->size()), v_debug, verbosityEBPMT); + Log("EBPMT: ChannelKey vector size: " + std::to_string(ChannelKey.size()), v_debug, verbosityEBPMT); + Log("EBPMT: Current unfinished InProgressHits size: " + std::to_string(InProgressHits->size()), v_debug, verbosityEBPMT); + + if (static_cast(ChannelKey.size()) > MaxObservedNumWaves) + MaxObservedNumWaves = ChannelKey.size(); + if (InProgressHits->size() > 500 && MaxObservedNumWaves < NumWavesInCompleteSet && !max_waves_adapted && MaxObservedNumWaves >= 130) + { + NumWavesInCompleteSet = MaxObservedNumWaves; + max_waves_adapted = true; + Log("EBPMT: MaxObservedNumWaves = " + std::to_string(MaxObservedNumWaves), v_message, verbosityEBPMT); + Log("EBPMT: NumWavesInCompleteSet = " + std::to_string(NumWavesInCompleteSet), v_message, verbosityEBPMT); + } + + if (MaxObservedNumWaves > NumWavesInCompleteSet) + NumWavesInCompleteSet = MaxObservedNumWaves; + + if (ChannelKey.size() >= (NumWavesInCompleteSet - 10)) + { + Log("EBPMT: ChannelKey.size() == (NumWavesInCompleteSet - 1), ChannelKey.size() = " + std::to_string(ChannelKey.size()) + " == NumWavesInCompleteSet - 1 = " + std::to_string(NumWavesInCompleteSet - 1), v_debug, verbosityEBPMT); + if (AlmostCompleteWaveforms.find(PMTCounterTimeNs) != AlmostCompleteWaveforms.end()) + { + Log("EBPMT: AlmostCompleteWaveforms size = " + std::to_string(AlmostCompleteWaveforms.size()), v_debug, verbosityEBPMT); + AlmostCompleteWaveforms[PMTCounterTimeNs]++; + } + else + AlmostCompleteWaveforms.emplace(PMTCounterTimeNs, 0); + Log("EBPMT: AlmostCompleteWaveforms adding PMTCounterTimeNs = " + std::to_string(PMTCounterTimeNs) + " to " + std::to_string(AlmostCompleteWaveforms[PMTCounterTimeNs]), v_debug, verbosityEBPMT); + } + + //Log("EBPMT: ChannelKey.size() = " + std::to_string(ChannelKey.size()) + " >= NumWavesInCompleteSet = " + std::to_string(NumWavesInCompleteSet) + " or AlmostCompleteWaveforms.at(PMTCounterTimeNs) = " + std::to_string(AlmostCompleteWaveforms[PMTCounterTimeNs] >= 5), v_debug, verbosityEBPMT); + + + // print all elements in vector ChannelKey +// cout<<"EBPMT: ChannelKey: "; +// for (unsigned long ch : ChannelKey) +// { +// cout<second; + } + + + if (ChannelKey.size() >= NumWavesInCompleteSet || ((ChannelKey.size() == NumWavesInCompleteSet - 1) && (AlmostCompleteWaveforms_CountHere >= 5))) + { + Log("EBPMT: Emplace hit map to FinishedHits, ChannelKey.size() = " + std::to_string(ChannelKey.size()) + " >= NumWavesInCompleteSet = " + std::to_string(NumWavesInCompleteSet) + " or AlmostCompleteWaveforms.at(PMTCounterTimeNs) = " + std::to_string(AlmostCompleteWaveforms.at(PMTCounterTimeNs) >= 5), v_debug, verbosityEBPMT); + + // check if the PMTCounterTimeNs is already in the FinishedHits, if not then add it + + if (FinishedHits->find(PMTCounterTimeNs) != FinishedHits->end()) + { + Log("EBPMT: PMTCounterTimeNs: " + std::to_string(PMTCounterTimeNs) + " already in FinishedHits", v_debug, verbosityEBPMT); + continue; + } + // if find PMTCounterTimeNs in PairedPMTTimeStamps, then skip this hit + if (PairedPMTTimeStamps.size() > 0) + { + bool skip = false; + for (std::pair> p : PairedPMTTimeStamps) + { + vector PMTTimeStamps = p.second; + for (uint64_t PMTTimeStamp : PMTTimeStamps) + { + if (PMTCounterTimeNs == PMTTimeStamp) + { + skip = true; + break; + } + } + if (skip) + break; + } + if (skip) + continue; + } + FinishedHits->emplace(PMTCounterTimeNs, hitMap); + + PMTEmplacedHitTimes.push_back(PMTCounterTimeNs); + + std::map, int> aWaveMapSampleSize; + + // Put PMT timestamp into the timestamp set for this run. + Log("EBPMT: waveset has clock counter: " + std::to_string(PMTCounterTimeNs), v_debug, verbosityEBPMT); + } + + if ((ChannelKey.size() == NumWavesInCompleteSet - 1)) + { + if (AlmostCompleteWaveforms.at(PMTCounterTimeNs) >= 5) + AlmostCompleteWaveforms.erase(PMTCounterTimeNs); + } + } + + Log("EBPMT: InProgressHits size: " + std::to_string(InProgressHits->size()) + " InProgressChkey size: " + std::to_string(InProgressChkey->size()), v_message, verbosityEBPMT); + Log("EBPMT: PMTEmplacedHitTimes size: " + std::to_string(PMTEmplacedHitTimes.size()), v_message, verbosityEBPMT); + /*for (uint64_t PMTCounterTimeNs : PMTEmplacedHitTimes) + { + InProgressHits->erase(PMTCounterTimeNs); + InProgressChkey->erase(PMTCounterTimeNs); + }*/ + Log("EBPMT: InProgressHits size: " + std::to_string(InProgressHits->size()) + " InProgressChkey size: " + std::to_string(InProgressChkey->size()), v_message, verbosityEBPMT); + + // If this InProgressTankEvent is too old, clear it + Log("EBPMT: Current number of unfinished hitmaps in InProgressHits: " + std::to_string(InProgressHits->size()), v_debug, verbosityEBPMT); + + Log("EBPMT: All finished, left size are, matchedHitNumber: " + std::to_string(matchedHitNumber) + " InProgressHits: " + std::to_string(InProgressHits->size()) + " FinishedHits: " + std::to_string(FinishedHits->size()), v_message, verbosityEBPMT); + + if (exeNum % 80 == 0) + { + Log("EBPMT: after apply the VME offset correction and loading, the size of FinishedHits is " + std::to_string(FinishedHits->size()), v_message, verbosityEBPMT); + } + + exeNum++; + + if (exeNum % 50 == 0) + { + Log("EBPMT: exeNum: " + std::to_string(exeNum), v_message, verbosityEBPMT); + } + + bool stopLoop = false; + m_data->vars.Get("StopLoop", stopLoop); + int runNum = thisRunNum; // run number saved in buffer as the previous run number + // m_data->vars.Get("RunNumber", thisRunNum); + m_data->CStore.Get("runNumber", thisRunNum); + + bool ForcePMTMatching = false; + m_data->CStore.Get("ForcePMTMatching", ForcePMTMatching); + + if (exeNum % exePerMatch == 0 || runNum != thisRunNum || stopLoop || ForcePMTMatching) + { + Log("EBPMT: exeNum: " + std::to_string(exeNum) + " Doing Matching", v_message, verbosityEBPMT); + if (matchToAllTriggers) + { + Matching(0, 0); + } + else + { + bool BeamTriggerGroupped = false; + m_data->CStore.Get("BeamTriggerGroupped", BeamTriggerGroupped); + if (BeamTriggerGroupped) + Matching(5, 14); + else + Log("EBPMT: BeamTriggerGroupped is false, no beam trigger groupped in the grouper, stop matching", v_message, verbosityEBPMT); + } + } + + m_data->CStore.Set("PairedPMTTriggerTimestamp", PairedCTCTimeStamps); + m_data->CStore.Set("PairedPMTTimeStamps", PairedPMTTimeStamps); + m_data->CStore.Set("PairedPMT_TriggerIndex", PairedPMT_TriggerIndex); + m_data->CStore.Set("PMTHitmapRunCode", PMTHitmapRunCode); + // everytime change the trigger group, also update the trigger index. + Log("EBPMT: Set PairedPMTTimeStamps size: " + std::to_string(PairedPMTTimeStamps.size()), v_message, verbosityEBPMT); + Log("EBPMT: Set PairedPMTTriggerTimestamp size: " + std::to_string(PairedCTCTimeStamps.size()), v_message, verbosityEBPMT); + + return true; +} + +bool EBPMT::Finalise() +{ + + Log("\033[1;34mEBPMT: Finalising\033[0m", v_message, verbosityEBPMT); + Log("EBPMT: Matched Hit Map Entry Number: " + std::to_string(matchedHitNumber), v_message, verbosityEBPMT); + Log("EBPMT: Unmatched Hit Map Entry Number left: " + std::to_string(FinishedHits->size()), v_message, verbosityEBPMT); + + return true; +} + +bool EBPMT::Matching(int targetTrigger, int matchToTrack) +{ + cout << "\033[1;34m******* EBPMT : 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); + + vector matchedHitTimes; + // loop over all the Hits, for each FinishedHits, loop all grouped triggers, if the time differencs<100 for trigger 5, + // matchedHitNumber ++, then remove the hit from the map + int loopNum = 0; + for (std::pair> *> pmtpair : *FinishedHits) + { + if (verbosityEBPMT > 11) + cout << "******************EBPMT: new hit" << endl; + uint64_t PMTCounterTimeNs = pmtpair.first; + std::map> *hitMap = pmtpair.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; + // loop all tracks of GroupedTriggersInTotal + for (std::pair>> pair : GroupedTriggersInTotal) + { + int TrackTriggerWord = pair.first; + if (TrackTriggerWord != matchToTrack && !matchToAllTriggers) + continue; + + vector> groupedTriggers = pair.second; + + // loop all the grouped triggers, if the value is target trigger, then calculate the time difference + 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 (PMTCounterTimeNs > p.first) + { + dt = PMTCounterTimeNs - p.first; + } + else + { + dt = p.first - PMTCounterTimeNs; + } + if (dt < minDT) + { + minDT = dt; + minDTTrigger = p.first; + matchedTrigWord = p.second; + matchedTrack = TrackTriggerWord; + matchedIndex = i; + } + } + } + } + } + + Log("EBPMT: looping hit " + std::to_string(loopNum) + ", minDT: " + std::to_string(minDT) + ", minDTTrigger time: " + std::to_string(minDTTrigger) + " with word " + std::to_string(matchedTrigWord) + ", in trigger track " + std::to_string(matchedTrack), v_warning, verbosityEBPMT); + if (minDT < matchTolerance_ns) + { + //PairedCTCTimeStamps[matchedTrack].push_back(minDTTrigger); + //PairedPMTTimeStamps[matchedTrack].push_back(PMTCounterTimeNs); + //PairedPMT_TriggerIndex[matchedTrack].push_back(matchedIndex); + + PairedCTCTimeStamps.emplace(matchedTrack, std::vector{}).first->second.push_back(minDTTrigger); + PairedPMTTimeStamps.emplace(matchedTrack, std::vector{}).first->second.push_back(PMTCounterTimeNs); + PairedPMT_TriggerIndex.emplace(matchedTrack, std::vector{}).first->second.push_back(matchedIndex); + + // the pmt hit map with timestmap PMTCounterTimeNs, match to trigger with timestamp minDTTrigger + // the matched trigger is at matchedIndex of that trigger track + + matchedHitNumber++; + matchedHitTimes.push_back(PMTCounterTimeNs); + // FinishedHits->erase(PMTCounterTimeNs); + Log("EBPMT: Matched Hit to trigger " + std::to_string(matchedTrigWord) + " at PMTCounterTimeNs: " + std::to_string(PMTCounterTimeNs) + " to TriggerTime: " + std::to_string(minDTTrigger) + " with minDT: " + std::to_string(minDT) + ", in trigger track " + std::to_string(matchedTrack) + ", in trigger index " + std::to_string(matchedIndex), v_message, verbosityEBPMT); + } + else + { + Log("EBPMT: Match failed, found min diff Hit to trigger " + std::to_string(matchedTrigWord) + " at PMTCounterTimeNs: " + std::to_string(PMTCounterTimeNs) + " to TriggerTime: " + std::to_string(minDTTrigger) + " with minDT: " + std::to_string(minDT) + ", in trigger track " + std::to_string(matchedTrack) + ", in trigger index " + std::to_string(matchedIndex), v_message, verbosityEBPMT); + } + loopNum++; + } + Log("EBPMT: total matchedHitNumber: " + std::to_string(matchedHitNumber), v_message, verbosityEBPMT); + Log("EBPMT: Current number of unfinished hitmaps after match in InProgressHits: " + std::to_string(InProgressHits->size()), v_message, verbosityEBPMT); + + Log("EBPMT: Found matched hits: " + std::to_string(matchedHitTimes.size()), v_message, verbosityEBPMT); + Log("EBPMT: before erase, left number of unfinished hitmaps in FinishedHits: " + std::to_string(FinishedHits->size()), v_message, verbosityEBPMT); + for (uint64_t PMTCounterTimeNs : matchedHitTimes) + { + FinishedHits->erase(PMTCounterTimeNs); + + if (saveRWMWaveforms) + { + // check does RWMRawWaveforms have key PMTCounterTimeNs, if not, print a log waring and skip + if (RWMRawWaveforms->find(PMTCounterTimeNs) == RWMRawWaveforms->end()) + { + Log("EBPMT: After matching, RWMRawWaveforms does not have key PMTCounterTimeNs: " + std::to_string(PMTCounterTimeNs), v_warning, verbosityEBPMT); + } + } + + if (saveBRFWaveforms) + { + // check does BRFRawWaveforms have key PMTCounterTimeNs, if not, print a log waring and skip + if (BRFRawWaveforms->find(PMTCounterTimeNs) == BRFRawWaveforms->end()) + { + Log("EBPMT: After matching, BRFRawWaveforms does not have key PMTCounterTimeNs: " + std::to_string(PMTCounterTimeNs), v_warning, verbosityEBPMT); + } + } + } + Log("EBPMT: after erase, left number of unfinished hitmaps in FinishedHits: " + std::to_string(FinishedHits->size()), v_message, verbosityEBPMT); + + return true; +} + +void EBPMT::CorrectVMEOffset() +{ + Log("EBPMT: Correcting VME Offset", v_message, verbosityEBPMT); + vector timestamps; // all current timestamps + std::map timestamps_to_shift; // timestamps need to be shifted + + // if InProgressHits size is 0, return + if (InProgressHits->size() == 0) + { + Log("EBPMT: InProgressHits size is 0, return", v_message, verbosityEBPMT); + return; + } + + // insert the key of std::map> *> *InProgressHits; to timestamps + for (std::pair> *> p : *InProgressHits) + { + timestamps.push_back(p.first); + } + + Log("EBPMT: Found " + std::to_string(timestamps.size()) + " timestamps", v_message, verbosityEBPMT); + + // loop timestamps,对于每一个时间戳,检查它与它之前的时间戳的差值是否是8或者16 + // 如果是,获得InProgressHits在这两个时间戳上的map的size + // 在timestamps_to_shift中记录pair,第一个时间戳是size较小的那个,第二个是较大的那个 + for (int i = 1; i < timestamps.size(); i++) + { + uint64_t dt = (timestamps[i] > timestamps[i - 1]) ? (timestamps[i] - timestamps[i - 1]) : (timestamps[i - 1] - timestamps[i]); + Log("EBPMT: Found two timestamps with difference = " + std::to_string(dt) + "ns", v_message, verbosityEBPMT); + Log("EBPMT: timestamps[i - 1] = " + std::to_string(timestamps[i - 1]) + " timestamps[i] = " + std::to_string(timestamps[i]), v_message, verbosityEBPMT); + if (dt == 8 || dt == 16) + { + uint64_t FirstMapSize = InProgressHits->at(timestamps[i - 1])->size(); + uint64_t SecondMapSize = InProgressHits->at(timestamps[i])->size(); + Log("EBPMT: Found two timestamps with 8 or 16ns difference, FirstMapSize: " + std::to_string(FirstMapSize) + " SecondMapSize: " + std::to_string(SecondMapSize), v_message, verbosityEBPMT); + if (FirstMapSize < SecondMapSize) + { + timestamps_to_shift.emplace(timestamps[i - 1], timestamps[i]); + } + else + { + timestamps_to_shift.emplace(timestamps[i], timestamps[i - 1]); + } + } + else if (dt < 1600) + { + Log("EBPMT: Found two timestamps with difference = " + std::to_string(dt) + "ns", v_message, verbosityEBPMT); + continue; + } + } + + int correctionApplied = 0; + Log("EBPMT: Found " + std::to_string(timestamps_to_shift.size()) + " timestamps to shift", v_message, verbosityEBPMT); + // go through timestamps_to_shift, for each pair, shift the hit map in the first smaller timestamp to the second larger timestamp + // apply on InProgressHits, InProgressHitsAux, InProgressChkey, InProgressRecoADCHits, InProgressRecoADCHitsAux + // also need to apply on RWMRawWaveforms and BRFRawWaveforms + if (InProgressHitsAux != NULL && InProgressRecoADCHitsAux != NULL) + { // InProgressHitsAux,InProgressRecoADCHitsAux may not exist yet + for (std::map::iterator it = timestamps_to_shift.begin(); it != timestamps_to_shift.end(); it++) + { + uint64_t SmallerMapTS = it->first; + uint64_t LargerMapTS = it->second; + Log("EBPMT::CorrectVMEOffset: Map Timestamp " + std::to_string(SmallerMapTS) + " to timestamp " + std::to_string(LargerMapTS), v_debug, verbosityEBPMT); + if (InProgressHits->count(SmallerMapTS) == 0 || InProgressHits->count(LargerMapTS) == 0) + { // map object at FirstTS, SecondTS may not exist yet + Log("EBPMT::CorrectVMEOffset: InProgressHits->count(FirstTS) == " + std::to_string(InProgressHits->count(SmallerMapTS)) + ", InProgressHits->count(SecondTS) == " + std::to_string(InProgressHits->count(LargerMapTS)), v_debug, verbosityEBPMT); + break; + } + // Get InProgress* {Hits, Chkey, and RecoADCHits} objects + std::map> *FirstTankHits = InProgressHits->at(SmallerMapTS); + std::map> *SecondTankHits = InProgressHits->at(LargerMapTS); + std::vector FirstChankey = InProgressChkey->at(SmallerMapTS); + std::vector SecondChankey = InProgressChkey->at(LargerMapTS); + std::map> *FirstTankHitsAux = InProgressHitsAux->at(SmallerMapTS); + std::map> *SecondTankHitsAux = InProgressHitsAux->at(LargerMapTS); + std::map>> FirstRecoADCHits = InProgressRecoADCHits->at(SmallerMapTS); + std::map>> SecondRecoADCHits = InProgressRecoADCHits->at(LargerMapTS); + std::map>> FirstRecoADCHitsAux = InProgressRecoADCHitsAux->at(SmallerMapTS); + std::map>> SecondRecoADCHitsAux = InProgressRecoADCHitsAux->at(LargerMapTS); + + SecondTankHits->insert(FirstTankHits->begin(), FirstTankHits->end()); + SecondChankey.insert(SecondChankey.end(), FirstChankey.begin(), FirstChankey.end()); + SecondTankHitsAux->insert(FirstTankHitsAux->begin(), FirstTankHitsAux->end()); + SecondRecoADCHits.insert(FirstRecoADCHits.begin(), FirstRecoADCHits.end()); + SecondRecoADCHitsAux.insert(FirstRecoADCHitsAux.begin(), FirstRecoADCHitsAux.end()); + + (*InProgressHits)[LargerMapTS] = SecondTankHits; + InProgressHits->erase(SmallerMapTS); + (*InProgressChkey)[LargerMapTS] = SecondChankey; + InProgressChkey->erase(SmallerMapTS); + (*InProgressHitsAux)[LargerMapTS] = SecondTankHitsAux; + InProgressHitsAux->erase(SmallerMapTS); + (*InProgressRecoADCHits)[LargerMapTS] = SecondRecoADCHits; + InProgressRecoADCHits->erase(SmallerMapTS); + (*InProgressRecoADCHitsAux)[LargerMapTS] = SecondRecoADCHitsAux; + InProgressRecoADCHitsAux->erase(SmallerMapTS); + + if (saveRWMWaveforms) + { + // if found SmallerMapTS in RWMRawWaveforms, then change it to LargerMapTS + if (RWMRawWaveforms->find(SmallerMapTS) != RWMRawWaveforms->end()) + { + (*RWMRawWaveforms)[LargerMapTS] = (*RWMRawWaveforms)[SmallerMapTS]; + RWMRawWaveforms->erase(SmallerMapTS); + } + } + if (saveBRFWaveforms) + { + // if found SmallerMapTS in BRFRawWaveforms, then change it to LargerMapTS + if (BRFRawWaveforms->find(SmallerMapTS) != BRFRawWaveforms->end()) + { + (*BRFRawWaveforms)[LargerMapTS] = (*BRFRawWaveforms)[SmallerMapTS]; + BRFRawWaveforms->erase(SmallerMapTS); + } + + correctionApplied++; + } + } + } + Log("EBPMT: Corrected VME Offset for " + std::to_string(correctionApplied) + " timestamps", v_message, verbosityEBPMT); +} diff --git a/UserTools/EBPMT/EBPMT.h b/UserTools/EBPMT/EBPMT.h new file mode 100644 index 000000000..9065ef439 --- /dev/null +++ b/UserTools/EBPMT/EBPMT.h @@ -0,0 +1,78 @@ +#ifndef EBPMT_H +#define EBPMT_H + +#include +#include + +#include "Tool.h" +#include "Hit.h" +#include "ADCPulse.h" + +/** + * \class EBPMT + * + * $Author: Yue Feng $ + * $Date: 2024/04 $ + * Contact: yuef@iaistate.edu + * + */ + +class EBPMT : public Tool +{ + +public: + EBPMT(); ///< 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); + void CorrectVMEOffset(); + +private: + int verbosityEBPMT; + int matchTargetTrigger; + uint64_t matchTolerance_ns; + + int currentRunCode; + + std::map> *> *FinishedHits; // Key: {MTCTime}, value: map of Hit distributions + std::map> *FinishedRWMWaveforms; // Key: {MTCTime}, value: RWM waveform + std::map> *FinishedBRFWaveforms; // Key: {MTCTime}, value: BRF waveform + + std::map AlmostCompleteWaveforms; + + std::map> *> *InProgressHits; // Key: {MTCTime}, value: map of Hit distributions + std::map> *InProgressChkey; // Key: {MTCTime}, value: vector of in progress chankeys + + // only used for VME offset correction + std::map> *> *InProgressHitsAux; // Key: {MTCTime}, value: map of Hit distributions + std::map>>> *InProgressRecoADCHits; // Key: {MTCTime}, value: map of found pulses + std::map>>> *InProgressRecoADCHitsAux; // Key: {MTCTime}, value: map of found pulses + std::map> *RWMRawWaveforms; // Key: MTCTime, Value: RWM waveform + std::map> *BRFRawWaveforms; // Key: MTCTime, Value: BRF waveform + + std::map> PairedCTCTimeStamps; + std::map> PairedPMT_TriggerIndex; + std::map> PairedPMTTimeStamps; + std::map PMTHitmapRunCode; // Key: {MTCTime}, value: RunCode + + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; + + int MaxObservedNumWaves = 0; + int NumWavesInCompleteSet = 140; + bool max_waves_adapted = false; + + int matchedHitNumber = 0; + int exeNum = 0; + int thisRunNum; + int exePerMatch = 500; + bool matchToAllTriggers; + + bool saveRWMWaveforms; + bool saveBRFWaveforms; +}; + +#endif diff --git a/UserTools/EBPMT/README.md b/UserTools/EBPMT/README.md new file mode 100644 index 000000000..cfb62496a --- /dev/null +++ b/UserTools/EBPMT/README.md @@ -0,0 +1,43 @@ +# EBPMT + +EBPMT 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 +EBPMT match the ADC timestamps to grouped trigger, and save the matching results to CStore for EBSaver. + + +## Data + +**FinishedHits** +The PMT hits on each PMT are decoded from the PMTDataDecoder. While there are enough number of PMT loaded for a (ADC) PMT timestamp, the timestamp will be pushed to FinishedHits. The name was taken from ANNIEEventBuilder. + + +**RWMRawWaveforms** +**BRFRawWaveforms** +These two behaves like FinishedHits, but for raw RWM and BRF waveforms. +The slides for BRF and RWM waveforms: https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=5756 + + +**PairedCTCTimeStamps** +After matching, the matched trigger timestamp will be saved here. The key is the main trigger word for each run type. + +**PairedPMTTimeStamps** +After matching, the matched PMT 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. + + + +## Configuration + +**matchTargetTrigger** +This gives which trigger word that the PMT timestamps should be matched to. + +**matchTolerance_ns** +This gives the maximum allowed time tolerance between the PMT timestmap and the target trigger timestamp. + +**exePerMatch** +This gives how many loops need to be past for one matching between PMT timestmaps and target trigger timestamps. +500 is generally fine with beam runs + +**matchToAllTriggers** +1 or 0. 1 means match PMT 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..8621243ac --- /dev/null +++ b/UserTools/EBSaver/EBSaver.cpp @@ -0,0 +1,1536 @@ +#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); + + if (saveBeamInfo) + { + Log("EBSaver: saveBeamInfo is true, loading Beam Info", v_message, verbosityEBSaver); + return 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; + + // delete LAPPD related timestamps + 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); + } + } + } + + // delete PMT related timestamps + + 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); + } + } + } + + // delete MRD related timestamps + 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); +} + +bool EBSaver::LoadBeamInfo() +{ + TFile *file = new TFile(beamInfoFileName.c_str(), "READ"); + + if (file->IsZombie()) { + delete file; + Log("EBSaver: Failed to load beam info from file with name: " + beamInfoFileName, v_error, verbosityEBSaver); + return false; + } + + TTree *tree; + file->GetObject("BeamTree", tree); + + if (!tree) + { + file->Close(); + delete file; + Log("EBSaver: Failed to load beam info from file with name: " + beamInfoFileName, v_error, verbosityEBSaver); + return false; + } + + // 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); + + file->Close(); + delete file; + return true; +} + +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..70dc6a96d --- /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(); + + bool 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/EBTriggerGrouper/EBTriggerGrouper.cpp b/UserTools/EBTriggerGrouper/EBTriggerGrouper.cpp new file mode 100644 index 000000000..1bf900702 --- /dev/null +++ b/UserTools/EBTriggerGrouper/EBTriggerGrouper.cpp @@ -0,0 +1,745 @@ +#include "EBTriggerGrouper.h" + +EBTriggerGrouper::EBTriggerGrouper() : Tool() {} + +bool EBTriggerGrouper::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("verbosityEBTG", verbosityEBTG); + savePath = ""; + m_variables.Get("savePath", savePath); + m_variables.Get("GroupMode", GroupMode); + m_variables.Get("GroupTolerance", GroupTolerance); + m_variables.Get("GroupTrigWord", GroupTrigWord); + + TimeToTriggerWordMap = new std::map>; + TimeToTriggerWordMapComplete = new std::map>; + + groupBeam = true; + m_variables.Get("groupBeam", groupBeam); + groupCosmic = false; + m_variables.Get("groupCosmic", groupCosmic); + groupLaser = true; + m_variables.Get("groupLaser", groupLaser); + groupLED = false; + m_variables.Get("groupLED", groupLED); + groupAmBe = false; + m_variables.Get("groupAmBe", groupAmBe); + groupPPS = false; + m_variables.Get("groupPPS", groupPPS); + groupNuMI = true; + m_variables.Get("groupNuMI", groupNuMI); + + BeamTriggerMain = 14; + BeamTolerance = 3000000; // use 3 ms here, the spill time difference is 66ms + m_variables.Get("BeamTolerance", BeamTolerance); + BeamTriggers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 14, 37, 38, 40, 41, 46}; + m_data->CStore.Set("BeamTriggersUsedForGroupping", BeamTriggers); + m_data->CStore.Set("BeamTriggerMain", BeamTriggerMain); + + LaserTriggerMain = 47; + m_variables.Get("LaserTriggerMain", LaserTriggerMain); + LaserTolerance = 1000; // 1us + m_variables.Get("LaserTolerance", LaserTolerance); + LaserTriggers = {47, 46}; // 47 first, then 46, (~232ns in run 4692 data) + m_data->CStore.Set("LaserTriggersUsedForGroupping", LaserTriggers); + + PPSTriggerMain = 32; + PPSTolerance = 30000; // 30 us + m_variables.Get("PPSTolerance", PPSTolerance); + PPSTriggers = {32, 34}; // 32 first, then 34, (~20us in run 4802 data) + m_data->CStore.Set("PPSTriggersUsedForGroupping", PPSTriggers); + + CosmicTriggerMain = 45; // TODO need to check + m_variables.Get("CosmicTriggerMain", CosmicTriggerMain); + CosmicTolerance = 100; // 330000ns, TODO + m_variables.Get("CosmicTolerance", CosmicTolerance); + CosmicTriggers = {44, 45, 36, 27, 28, 29, 30, 46}; // TODO: check the trigger words in cosmic run + m_data->CStore.Set("CosmicTriggersUsedForGroupping", CosmicTriggers); + + LEDTriggerMain = 31; // need to check + m_variables.Get("LEDTriggerMain", LEDTriggerMain); + LEDTolerance = 1000; // 1ms 440ns in LED run 4792 + m_variables.Get("LEDTolerance", LEDTolerance); + LEDTriggers = {33, 22, 31, 43, 46}; // in run 4792 [[22, 33], [4160001224, 4160001664]] + m_data->CStore.Set("LEDTriggersUsedForGroupping", LEDTriggers); + + AmBeTriggerMain = 11; // TODO: need to check + m_variables.Get("AmBeTriggerMain", AmBeTriggerMain); + AmBeTolerance = 5000; // 2336 in Ambe run 4707 + m_variables.Get("AmBeTolerance", AmBeTolerance); + AmBeTriggers = {11, 12, 15, 19, 46}; // in run 4707 [[19, 12, 15, 11], [21275647928, 21275647936, 21275647952, 21275650264]] + m_data->CStore.Set("AmBeTriggersUsedForGroupping", AmBeTriggers); + + NuMITriggerMain = 42; + m_variables.Get("NuMITriggerMain", NuMITriggerMain); + NuMITolerance = 100; // 100ns + m_variables.Get("NuMITolerance", NuMITolerance); + NuMITriggers = {42, 46}; // + m_data->CStore.Set("NuMITriggersUsedForGroupping", NuMITriggers); + + StoreTotalEntry = 0; + + maxNumAllowedInBuffer = 10000; + m_variables.Get("maxNumAllowedInBuffer", maxNumAllowedInBuffer); + Log("EBTG: maxNumAllowedInBuffer = " + std::to_string(maxNumAllowedInBuffer), v_message, verbosityEBTG); + + return true; +} + +bool EBTriggerGrouper::Execute() +{ + bool NewCTCDataAvailable = false; + m_data->CStore.Get("NewCTCDataAvailable", NewCTCDataAvailable); + Log("EBTG: NewCTCDataAvailable = " + std::to_string(NewCTCDataAvailable), v_message, verbosityEBTG); + bool FileProcessingComplete = false; + m_data->CStore.Get("FileProcessingComplete", FileProcessingComplete); + if (FileProcessingComplete) + { + Log("EBTG: FileProcessingComplete = " + std::to_string(FileProcessingComplete), v_message, verbosityEBTG); + return true; + } + if (!NewCTCDataAvailable) + { + Log("EBTG: No new CTC data avaliable", v_message, verbosityEBTG); + return true; + } + Log("EBTG: Get Run information", v_message, verbosityEBTG); + m_data->CStore.Get("RunNumber", CurrentRunNum); + m_data->CStore.Get("SubRunNumber", CurrentSubrunNum); + int CurrentUsingPartNum = CurrentPartNum; + m_data->CStore.Get("PartFileNumber", CurrentPartNum); + m_data->CStore.Get("RunCode", currentRunCode); + + m_data->CStore.Get("usingTriggerOverlap", usingTriggerOverlap); + if (usingTriggerOverlap) + { + CurrentPartNum -= 1; + Log("EBTG: usingTriggerOverlap, CurrentPartNum was minused 1 to be " + std::to_string(CurrentPartNum), v_message, verbosityEBTG); + } + + /* + if (CurrentPartNum != CurrentUsingPartNum) + { + Log("EBTG: PartFileNumber changed from " + std::to_string(CurrentUsingPartNum) + " to " + std::to_string(CurrentPartNum) + " Clear buffer with size " + std::to_string(TrigTimeForGroup.size()), v_message, verbosityEBTG); + TrigTimeForGroup.clear(); + TrigWordForGroup.clear(); + }*/ + + Log("EBTG: Accessing new Trigger data in CStore", v_message, verbosityEBTG); + m_data->CStore.Get("TimeToTriggerWordMap", TimeToTriggerWordMap); + m_data->CStore.Get("TimeToTriggerWordMapComplete", TimeToTriggerWordMapComplete); + + // do grouping in the TimeToTriggerWordMap, remove the groupped triggers from both of them + // 1. load the trigger from TimeToTriggerWordMap to local buffer TrigTimeForGroup and TrigWordForGroup, clean it + // 2. group the triggers in buffer, save to GroupedTriggers, and remove grouped trigger from buffer + // 2.1 group trigger based on trigger word selection or time Tolerance relative to the target trigger + // 2.2 for left triggers, pair them with the grouped trigger using the same Tolerance fo cover triggers before the target trigger + // 2.3 run for different trigger tracks. like pps + + // Finally we should have: + // 1. GroupedTriggers: mutiple grouped trigger tracks + // 2. buffer: left triggers in buffer, not grouped + + vector TriggerToRemove; + for (auto it = TimeToTriggerWordMap->begin(); it != TimeToTriggerWordMap->end(); ++it) + { + uint64_t timestamp = it->first; + std::vector triggers = it->second; + bool stopLoading = false; + + // if found the target trigger in the trigger vector, stop loading to buffer. + if (usingTriggerOverlap) + { + for (auto trig = triggers.begin(); trig != triggers.end(); ++trig) + { + if (*trig == GroupTrigWord) + stopLoading = true; + Log("EBTG: when using TriggerOverlap, met the new target trigger " + std::to_string(GroupTrigWord) + ", stop loading to buffer", v_message, verbosityEBTG); + } + } + if (stopLoading) + break; + + for (auto trig = triggers.begin(); trig != triggers.end(); ++trig) + { + TrigTimeForGroup.push_back(timestamp); + TrigWordForGroup.push_back(*trig); + TriggerToRemove.push_back(timestamp); + StoreTotalEntry++; + if (verbosityEBTG > 11) + cout << "EBTG: TrigTimeForGroup: " << timestamp << " TrigWordForGroup: " << *trig << endl; + } + } + Log("EBTG: finish loading trigger from TimeToTriggerWordMap, buffer TrigTimeForGroup size = " + std::to_string(TrigTimeForGroup.size()) + ", loaded TimeToTriggerWordMap size = " + std::to_string(TimeToTriggerWordMap->size()), v_message, verbosityEBTG); + Log("EBTG: Start erase triggers from TimeToTriggerWordMap and TimeToTriggerWordMapComplete, TimeToTriggerWordMap and TimeToTriggerWordMapComplete size = " + std::to_string(TimeToTriggerWordMap->size()) + ", " + std::to_string(TimeToTriggerWordMapComplete->size()), v_message, verbosityEBTG); + for (int i = 0; i < TriggerToRemove.size(); i++) + { + TimeToTriggerWordMap->erase(TriggerToRemove[i]); + TimeToTriggerWordMapComplete->erase(TriggerToRemove[i]); + } + Log("EBTG: Finish erase triggers from TimeToTriggerWordMap and TimeToTriggerWordMapComplete, TimeToTriggerWordMap and TimeToTriggerWordMapComplete size = " + std::to_string(TimeToTriggerWordMap->size()) + ", " + std::to_string(TimeToTriggerWordMapComplete->size()), v_message, verbosityEBTG); + + /*{ + //TODO: this should be removed after later changes was made + Log("EBTG: Start grouping based on trigger word " + std::to_string(GroupTrigWord), v_message, verbosityEBTG); + + GroupByTolerance(); // remove grouped trigger in the function + FillByTolerance(); + //CleanBuffer(); + + Log("EBTG: grouping and filling finishes, buffer size is " + std::to_string(TrigTimeForGroup.size()) + ", now save to CStore", v_message, verbosityEBTG); + + m_data->CStore.Set("GroupedTriggers", GroupedTriggers); + }*/ + + m_data->CStore.Set("TrigTimeForGroup", TrigTimeForGroup); + m_data->CStore.Set("TrigWordForGroup", TrigWordForGroup); + + Log("EBTG: Start grouping for different trigger tracks", v_message, verbosityEBTG); + if (groupBeam) + { + Log("EBTG: Grouping Beam Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(BeamTriggerMain, BeamTriggers, BeamTolerance); + int fillNum = FillByTrigWord(BeamTriggerMain, BeamTriggers, BeamTolerance); + Log("EBTG: Found Beam Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("BeamTriggerGroupped", true); + } + else + { + m_data->CStore.Set("BeamTriggerGroupped", false); + } + + if (groupCosmic) + { + Log("EBTG: Grouping Cosmic Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(CosmicTriggerMain, CosmicTriggers, CosmicTolerance); + int fillNum = FillByTrigWord(CosmicTriggerMain, CosmicTriggers, CosmicTolerance); + Log("EBTG: Found Cosmic Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("CosmicTriggerGroupped", true); + } + else + { + m_data->CStore.Set("CosmicTriggerGroupped", false); + } + + if (groupLaser) + { + Log("EBTG: Grouping Laser Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(LaserTriggerMain, LaserTriggers, LaserTolerance); + int fillNum = FillByTrigWord(LaserTriggerMain, LaserTriggers, LaserTolerance); + Log("EBTG: Found Laser Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("LaserTriggerGroupped", true); + } + else + { + m_data->CStore.Set("LaserTriggerGroupped", false); + } + + if (groupLED) + { + Log("EBTG: Grouping LED Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(LEDTriggerMain, LEDTriggers, LEDTolerance); + int fillNum = FillByTrigWord(LEDTriggerMain, LEDTriggers, LEDTolerance); + Log("EBTG: Found LED Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("LEDTriggerGroupped", true); + } + else + { + m_data->CStore.Set("LEDTriggerGroupped", false); + } + + if (groupAmBe) + { + Log("EBTG: Grouping AmBe Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(AmBeTriggerMain, AmBeTriggers, AmBeTolerance); + int fillNum = FillByTrigWord(AmBeTriggerMain, AmBeTriggers, AmBeTolerance); + Log("EBTG: Found AmBe Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("AmBeTriggerGroupped", true); + } + else + { + m_data->CStore.Set("AmBeTriggerGroupped", false); + } + + if (groupPPS) + { + Log("EBTG: Grouping PPS Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(PPSTriggerMain, PPSTriggers, PPSTolerance); + int fillNum = FillByTrigWord(PPSTriggerMain, PPSTriggers, PPSTolerance); + Log("EBTG: Found PPS Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("PPSTriggerGroupped", true); + } + else + { + m_data->CStore.Set("PPSTriggerGroupped", false); + } + + if (groupNuMI) + { + Log("EBTG: Grouping NuMI Triggers", v_message, verbosityEBTG); + int groupNum = GroupByTrigWord(NuMITriggerMain, NuMITriggers, NuMITolerance); + int fillNum = FillByTrigWord(NuMITriggerMain, NuMITriggers, NuMITolerance); + Log("EBTG: Found NuMI Trigger group: " + std::to_string(groupNum) + ". Fill additional triggers to group: " + std::to_string(fillNum), v_message, verbosityEBTG); + m_data->CStore.Set("NuMITriggerGroupped", true); + } + else + { + m_data->CStore.Set("NuMITriggerGroupped", false); + } + + Log("EBTG: Grouping for different trigger tracks finishes, save to CStore", v_message, verbosityEBTG); + m_data->CStore.Set("GroupedTriggersInTotal", GroupedTriggersInTotal); + m_data->CStore.Set("RunCodeInTotal", RunCodeInTotal); + + int removedTriggerNumber = CleanTriggerBuffer(); + Log("EBTG: CleanTriggerBuffer finishes, removed " + std::to_string(removedTriggerNumber) + " triggers from buffer, buffer size = " + std::to_string(TrigTimeForGroup.size()), v_message, verbosityEBTG); + + return true; +} + +bool EBTriggerGrouper::Finalise() +{ + Log("\033[1;34mEBTG: Finalising\033[0m", v_message, verbosityEBTG); + Log("EBTG: GroupedTriggersInTotal track number = " + std::to_string(GroupedTriggersInTotal.size()), v_message, verbosityEBTG); + for (auto it = GroupedTriggersInTotal.begin(); it != GroupedTriggersInTotal.end(); ++it) + { + Log("EBTG: GroupedTriggersInTotal track " + std::to_string(it->first) + " size = " + std::to_string(it->second.size()), v_message, verbosityEBTG); + } + Log("EBTG: In configfile, set left trigger number = " + std::to_string(maxNumAllowedInBuffer), v_message, verbosityEBTG); + Log("EBTG: Left Total loaded trigger number to buffer = " + std::to_string(StoreTotalEntry), v_message, verbosityEBTG); + Log("EBTG: Ungrouped triggers in buffer size = " + std::to_string(TrigTimeForGroup.size()), v_message, verbosityEBTG); + // calculate which trigger word left in TrigWordForGroup, and print them + std::map triggerWordCount; + for (int i = 0; i < TrigWordForGroup.size(); i++) + { + triggerWordCount[TrigWordForGroup[i]]++; + } + for (auto it = triggerWordCount.begin(); it != triggerWordCount.end(); ++it) + { + Log("EBTG: Trigger word " + std::to_string(it->first) + " left in buffer " + std::to_string(it->second) + " times", v_message, verbosityEBTG); + } + Log("EBTG: Ungrouped triggers in TimeToTriggerWordMap size = " + std::to_string(TimeToTriggerWordMap->size()), v_message, verbosityEBTG); + Log("EBTG: Ungrouped triggers in TimeToTriggerWordMapComplete size = " + std::to_string(TimeToTriggerWordMapComplete->size()), v_message, verbosityEBTG); + + // print first 10000 triggers to a txt for debug + Log("EBTG: Save first 2000 triggers in each track of GroupedTriggersInTotal to TrigDebugGrouped.txt", v_message, verbosityEBTG); + ofstream trigDebugGrouped; + trigDebugGrouped.open("TrigDebugGrouped.txt"); + trigDebugGrouped << "trackTargetTrigger groupIndex triggerTime triggerWord" << endl; + for (auto it = GroupedTriggersInTotal.begin(); it != GroupedTriggersInTotal.end(); ++it) + { + int i = 0; + for (int j = 0; j < it->second.size(); j++) + { + for (auto trig = it->second[j].begin(); trig != it->second[j].end(); ++trig) + { + if (i > 2000) + break; + trigDebugGrouped << it->first << " " << j << " " << trig->first << " " << trig->second << endl; + i++; + } + if (i > 2000) + break; + } + } + trigDebugGrouped.close(); + Log("EBTG: Save first 10000 triggers in TrigTimeForGroup to TrigDebugBufferLeft.txt", v_message, verbosityEBTG); + ofstream trigDebugBufferLeft; + trigDebugBufferLeft.open("TrigDebugBufferLeft.txt"); + for (int i = 0; i < TrigTimeForGroup.size(); i++) + { + if (i > 10000) + break; + trigDebugBufferLeft << i << " " << TrigTimeForGroup[i] << " " << TrigWordForGroup[i] << endl; + } + Log("EBTG: Save first 2000 triggers in TimeToTriggerWordMap to TrigDebug.txt", v_message, verbosityEBTG); + ofstream trigDebug; + trigDebug.open("TrigDebug.txt"); + int i = 0; + for (auto it = TimeToTriggerWordMap->begin(); it != TimeToTriggerWordMap->end(); ++it) + { + if (i > 2000) + break; + trigDebug << it->first << " "; + for (auto trig = it->second.begin(); trig != it->second.end(); ++trig) + { + trigDebug << *trig << " "; + } + trigDebug << endl; + i++; + } + trigDebug.close(); + + Log("EBTG: Printing SkippedDuplicateTriggers", v_message, verbosityEBTG); + int totalSkipped = 0; + for (auto it = SkippedDuplicateTriggers.begin(); it != SkippedDuplicateTriggers.end(); ++it) + { + Log("EBTG: Skipped " + std::to_string(it->second) + " groups of triggers for trigger track " + std::to_string(it->first), v_message, verbosityEBTG); + totalSkipped += it->second; + } + Log("EBTG: Total skipped groups of triggers = " + std::to_string(totalSkipped), v_message, verbosityEBTG); + + return true; +} + +bool EBTriggerGrouper::GroupByTolerance() +{ + Log("EBTG: GroupByTolerance()", v_warning, verbosityEBTG); + Log("EBTG: Grouping by Tolerance: " + std::to_string(GroupTolerance), v_warning, verbosityEBTG); + Log("EBTG: size of time buffer before grouping is " + std::to_string(TrigTimeForGroup.size()) + ", size of word buffer is " + std::to_string(TrigWordForGroup.size()), v_warning, verbosityEBTG); + bool found = false; + uint64_t prev_target_time = 0; + std::map ThisGroup; + vector toRemove; + int totalGroupedTriggerNumber = 0; + for (int i = 0; i < TrigTimeForGroup.size(); i++) + { + uint64_t dt = 0; + if (TrigTimeForGroup[i] > prev_target_time) + dt = TrigTimeForGroup[i] - prev_target_time; + else if (TrigTimeForGroup[i] < prev_target_time) + dt = prev_target_time - TrigTimeForGroup[i]; + else if (TrigTimeForGroup[i] == prev_target_time) + dt = 0; + + if (!found && TrigWordForGroup[i] == GroupTrigWord) + { + found = true; + ThisGroup.clear(); + prev_target_time = TrigTimeForGroup[i]; + ThisGroup.insert(std::pair(TrigTimeForGroup[i], TrigWordForGroup[i])); + toRemove.push_back(i); + } + else if (found && dt < GroupTolerance) + { + + ThisGroup.insert(std::pair(TrigTimeForGroup[i], TrigWordForGroup[i])); + toRemove.push_back(i); + if (TrigWordForGroup[i] == 10 || TrigWordForGroup[i] == 40 || TrigWordForGroup[i] == 41) + { + ThisGroup.insert(std::pair(TrigTimeForGroup[i] + 1, TrigWordForGroup[i])); + } + ///!!! attention, the trigger word 10 always come with 8 with the same time, so it won't be inserted to the map + // Therefore we add another 1ns to it, but it's not real + } + else if (found && dt > GroupTolerance) + { + if (verbosityEBTG > 9) + { + // print all triggers in this group + cout << "EBTG: GroupByTolerance: ThisGroup size = " << ThisGroup.size() << endl; + for (auto it = ThisGroup.begin(); it != ThisGroup.end(); ++it) + { + cout << it->first << " - " << it->second << ", "; + } + cout << endl; + } + GroupedTriggers.push_back(ThisGroup); + totalGroupedTriggerNumber += ThisGroup.size(); + ThisGroup.clear(); + found = false; + } + } + int totalToRemoveTriggerNumber = toRemove.size(); + // from end to beginning, remove the triggers in buffer based on toRemove index + for (int i = toRemove.size() - 1; i >= 0; i--) + { + TrigTimeForGroup.erase(TrigTimeForGroup.begin() + toRemove[i]); + TrigWordForGroup.erase(TrigWordForGroup.begin() + toRemove[i]); + } + Log("EBTG: GroupByTolerance Finished, accumulated saved " + std::to_string(GroupedTriggers.size()) + " group of triggers", v_warning, verbosityEBTG); + Log("EBTG: buffer TriggersForGroup after grouping size = " + std::to_string(TrigTimeForGroup.size()), v_warning, verbosityEBTG); + Log("EBTG: totalGroupedTriggerNumber in this grouping step is: " + std::to_string(totalGroupedTriggerNumber) + ", totalToRemoveTriggerNumber = " + std::to_string(totalToRemoveTriggerNumber), v_warning, verbosityEBTG); + + return true; +} + +bool EBTriggerGrouper::FillByTolerance() +{ + Log("EBTG: FillByTolerance()", v_warning, verbosityEBTG); + Log("EBTG: Fill by Tolerance: " + std::to_string(GroupTolerance), v_warning, verbosityEBTG); + Log("EBTG: size of time buffer before refilling is " + std::to_string(TrigTimeForGroup.size()) + ", size of word buffer is " + std::to_string(TrigWordForGroup.size()), v_warning, verbosityEBTG); + + int addedTriggerNumber = 0; + + for (int i = TrigTimeForGroup.size() - 1; i >= 0; i--) + { + for (int j = 0; j < GroupedTriggers.size(); j++) + { + + for (auto it = GroupedTriggers[j].begin(); it != GroupedTriggers[j].end(); ++it) + { + if (it->second == GroupTrigWord) + { + uint64_t dt = (TrigTimeForGroup[i] > it->first) ? (TrigTimeForGroup[i] - it->first) : (it->first - TrigTimeForGroup[i]); + if (dt < GroupTolerance) + { + GroupedTriggers[j].insert(std::make_pair(TrigTimeForGroup[i], TrigWordForGroup[i])); + TrigTimeForGroup.erase(TrigTimeForGroup.begin() + i); + TrigWordForGroup.erase(TrigWordForGroup.begin() + i); + addedTriggerNumber++; + break; + } + } + } + } + } + + Log("EBTG: FillByTolerance Finished, addedTriggerNumber = " + std::to_string(addedTriggerNumber), v_warning, verbosityEBTG); + Log("EBTG: buffer TriggersForGroup after refilling size = " + std::to_string(TrigTimeForGroup.size()), v_warning, verbosityEBTG); + + return true; +} + +bool EBTriggerGrouper::CleanBuffer() +{ + Log("EBTG: CleanBuffer()", v_warning, verbosityEBTG); + Log("EBTG: size of time buffer before cleaning is " + std::to_string(TrigTimeForGroup.size()) + ", size of word buffer is " + std::to_string(TrigWordForGroup.size()), v_warning, verbosityEBTG); + // check is there any target trigger word in the buffer + // if yes, print a warning message + // only leave the last 100 triggers in the buffer + int numberOfTargetTriggers = 0; + for (int i = 0; i < TrigWordForGroup.size(); i++) + { + if (TrigWordForGroup[i] == GroupTrigWord) + { + numberOfTargetTriggers++; + } + } + if (numberOfTargetTriggers > 0) + { + Log("EBTG: CleanBuffer: Warning: there are " + std::to_string(numberOfTargetTriggers) + " target trigger words in the buffer", v_warning, verbosityEBTG); + } + else + { + Log("EBTG: CleanBuffer: no target trigger words left in the buffer.", v_warning, verbosityEBTG); + } + if (TrigTimeForGroup.size() > 100) + { + TrigTimeForGroup.erase(TrigTimeForGroup.begin(), TrigTimeForGroup.end() - 100); + TrigWordForGroup.erase(TrigWordForGroup.begin(), TrigWordForGroup.end() - 100); + } + Log("EBTG: CleanBuffer Finished, buffer size = " + std::to_string(TrigTimeForGroup.size()), v_warning, verbosityEBTG); + return true; +} + +int EBTriggerGrouper::GroupByTrigWord(uint32_t mainTrigWord, vector TrigWords, int tolerance) +{ + Log("EBTG: GroupByTrigWord()", v_warning, verbosityEBTG); + Log("EBTG: Grouping by TrigWord: " + std::to_string(mainTrigWord), v_warning, verbosityEBTG); + Log("EBTG: size of time buffer before grouping is " + std::to_string(TrigTimeForGroup.size()) + ", size of word buffer is " + std::to_string(TrigWordForGroup.size()), v_warning, verbosityEBTG); + bool found = false; + uint64_t prev_target_time = 0; + std::map ThisGroup; + vector toRemove; + int totalGroupedTriggerNumber = 0; + uint64_t trackTriggerTime = 0; + uint32_t trackTriggerWord = 0; + + for (int i = 0; i < TrigTimeForGroup.size(); i++) + { + uint64_t dt = 0; + if (TrigTimeForGroup[i] > prev_target_time) + dt = TrigTimeForGroup[i] - prev_target_time; + else if (TrigTimeForGroup[i] < prev_target_time) + dt = prev_target_time - TrigTimeForGroup[i]; + else if (TrigTimeForGroup[i] == prev_target_time) + dt = 0; + + if (!found && TrigWordForGroup[i] == mainTrigWord) + { + found = true; + ThisGroup.clear(); + prev_target_time = TrigTimeForGroup[i]; + ThisGroup.insert(std::pair(TrigTimeForGroup[i], TrigWordForGroup[i])); + trackTriggerTime = TrigTimeForGroup[i]; + trackTriggerWord = TrigWordForGroup[i]; + toRemove.push_back(i); + } + else if (found && dt < tolerance) + { + // if found TrigWordForGroup in TrigWords, insert to ThisGroup + if (std::find(TrigWords.begin(), TrigWords.end(), TrigWordForGroup[i]) != TrigWords.end()) + { + ThisGroup.insert(std::pair(TrigTimeForGroup[i], TrigWordForGroup[i])); + toRemove.push_back(i); + if (mainTrigWord == 14 && (TrigWordForGroup[i] == 10 || TrigWordForGroup[i] == 40 || TrigWordForGroup[i] == 41)) + { + ThisGroup.insert(std::pair(TrigTimeForGroup[i] + 1, TrigWordForGroup[i])); + } + ///!!! attention, the trigger word 10 always come with 8 with the same time, so it won't be inserted to the map + // Therefore we add another 1ns to it, but it's not real + } + } + else if (found && dt > tolerance) + { + if (verbosityEBTG > 9) + { + // print all triggers in this group + cout << "EBTG: GroupByTrigWord: ThisGroup size = " << ThisGroup.size() << endl; + for (auto it = ThisGroup.begin(); it != ThisGroup.end(); ++it) + { + cout << it->first << " - " << it->second << ", "; + } + cout << endl; + } + // check is the current track trigger already exist in GroupedTriggersInTotal, if so, don't add it + // find trackTriggerTime in each element in GroupedTriggersInTotal[mainTrigWord] + bool trackTriggerExist = false; + for (int j = 0; j < GroupedTriggersInTotal[mainTrigWord].size(); j++) + { + for (auto it = GroupedTriggersInTotal[mainTrigWord][j].begin(); it != GroupedTriggersInTotal[mainTrigWord][j].end(); ++it) + { + if (it->first == trackTriggerTime && it->second == trackTriggerWord) + { + trackTriggerExist = true; + break; + } + } + } + if (!trackTriggerExist) + { + GroupedTriggersInTotal[mainTrigWord].push_back(ThisGroup); + } + else + { + // in it's track of SkippedDuplicateTriggers, plus one. if found it, ++, if not, emplace 1 + if (SkippedDuplicateTriggers.find(mainTrigWord) != SkippedDuplicateTriggers.end()) + { + SkippedDuplicateTriggers[mainTrigWord]++; + } + else + { + SkippedDuplicateTriggers.emplace(mainTrigWord, 1); + } + + Log("EBTG: Found a duplicated main trigger with word " + std::to_string(mainTrigWord) + " and time " + std::to_string(trackTriggerTime), v_message, verbosityEBTG); + } + + if (verbosityEBTG > 9) + cout << "EBTG: saving grouped trigger with currentRunCode = " << currentRunCode << endl; + if (!trackTriggerExist) + RunCodeInTotal[mainTrigWord].push_back(currentRunCode); + else + Log("EBTG: Found a duplicated main trigger with word " + std::to_string(mainTrigWord) + " and time " + std::to_string(trackTriggerTime) + ", so skip adding run code vector", v_message, verbosityEBTG); + totalGroupedTriggerNumber += ThisGroup.size(); + ThisGroup.clear(); + found = false; + } + } + int totalToRemoveTriggerNumber = toRemove.size(); + // from end to beginning, remove the triggers in buffer based on toRemove index + for (int i = toRemove.size() - 1; i >= 0; i--) + { + TrigTimeForGroup.erase(TrigTimeForGroup.begin() + toRemove[i]); + TrigWordForGroup.erase(TrigWordForGroup.begin() + toRemove[i]); + } + Log("EBTG: GroupByTrigWord Finished, accumulated saved " + std::to_string(GroupedTriggers.size()) + " group of triggers", v_warning, verbosityEBTG); + Log("EBTG: buffer TriggersForGroup after grouping size = " + std::to_string(TrigTimeForGroup.size()), v_warning, verbosityEBTG); + Log("EBTG: totalGroupedTriggerNumber in this grouping step is: " + std::to_string(totalGroupedTriggerNumber) + ", totalToRemoveTriggerNumber = " + std::to_string(totalToRemoveTriggerNumber), v_warning, verbosityEBTG); + + return totalToRemoveTriggerNumber; +} + +int EBTriggerGrouper::FillByTrigWord(uint32_t mainTrigWord, vector TrigWords, int tolerance) +{ + // Fill the trigger maps at GroupedTriggersInTotal[mainTrigWord] + // for all triggers in the buffer, if the trigger word is in the vector, and in the range of main TrigWord - the tolerance + // push the trigger into the map + + Log("EBTG: FillByTrigWord()", v_warning, verbosityEBTG); + Log("EBTG: Fill by TrigWord: " + std::to_string(mainTrigWord), v_warning, verbosityEBTG); + Log("EBTG: size of time buffer before refilling is " + std::to_string(TrigTimeForGroup.size()) + ", size of word buffer is " + std::to_string(TrigWordForGroup.size()), v_warning, verbosityEBTG); + + int addedTriggerNumber = 0; + vector indexToRemove; + + for (int i = TrigTimeForGroup.size() - 1; i >= 0; i--) + { + if (verbosityEBTG > 11) + cout << "EBTG: FillByTrigWord: mainTrigWord = " << mainTrigWord << ", TrigWordForGroup[i] = " << TrigWordForGroup[i] << ", TrigTimeForGroup[i] = " << TrigTimeForGroup[i] << ", tolerance = " << tolerance << endl; + // check is current trigger word in TrigWords + if (std::find(TrigWords.begin(), TrigWords.end(), TrigWordForGroup[i]) == TrigWords.end()) + continue; + bool triggerToAdd = false; + int insertTrack = 0; + int insertGroupIndex = 0; + uint64_t insertedDT = tolerance; + for (int j = 0; j < GroupedTriggersInTotal[mainTrigWord].size(); j++) + { + for (auto it = GroupedTriggersInTotal[mainTrigWord][j].begin(); it != GroupedTriggersInTotal[mainTrigWord][j].end(); ++it) + { + if (it->second == mainTrigWord) + { + uint64_t dt = (TrigTimeForGroup[i] > it->first) ? (TrigTimeForGroup[i] - it->first) : (it->first - TrigTimeForGroup[i]); + if (dt < tolerance && dt < insertedDT) + { + insertedDT = dt; + insertTrack = mainTrigWord; + insertGroupIndex = j; + triggerToAdd = true; + Log("EBTG: FillByTrigWord: Found trigger to add, insertTrack = " + std::to_string(insertTrack) + ", insertGroupIndex = " + std::to_string(insertGroupIndex) + ", insert DT = " + std::to_string(insertedDT), 9, verbosityEBTG); + break; + } + } + } + } + if (triggerToAdd) + { + GroupedTriggersInTotal[mainTrigWord][insertGroupIndex].insert(std::make_pair(TrigTimeForGroup[i], TrigWordForGroup[i])); + indexToRemove.push_back(i); + if (verbosityEBTG > 11) + cout << "EBTG: FillByTrigWord: add this trigger: " << TrigTimeForGroup[i] << " - " << TrigWordForGroup[i] << endl; + addedTriggerNumber++; + } + } + Log("EBTG: FillByTrigWord Finished, addedTriggerNumber = " + std::to_string(addedTriggerNumber), v_warning, verbosityEBTG); + Log("EBTG: indexToRemove size = " + std::to_string(indexToRemove.size()) + ", buffer size before remove is " + std::to_string(TrigTimeForGroup.size()), v_warning, verbosityEBTG); + + // sort indexToRemove from large to small, then remove the triggers in buffer based on toRemove index + std::sort(indexToRemove.begin(), indexToRemove.end(), std::greater()); + + if (verbosityEBTG > 11) + { + // print all index to remove + cout << "EBTG: FillByTrigWord: indexToRemove: "; + for (int i = 0; i < indexToRemove.size(); i++) + { + cout << indexToRemove[i] << ", "; + } + } + + for (int i = 0; i < indexToRemove.size(); i++) + { + TrigTimeForGroup.erase(TrigTimeForGroup.begin() + indexToRemove[i]); + TrigWordForGroup.erase(TrigWordForGroup.begin() + indexToRemove[i]); + } + Log("EBTG: buffer TriggersForGroup after refilling and removing size = " + std::to_string(TrigTimeForGroup.size()), v_warning, verbosityEBTG); + + return addedTriggerNumber; +} + +int EBTriggerGrouper::CleanTriggerBuffer() +{ + // remove very early trigger in TrigTimeForGroup and TrigWordForGroup + // only leave the latest maxNumAllowedInBuffer elements + int removedNumber = 0; + if (TrigTimeForGroup.size() > maxNumAllowedInBuffer) + { + removedNumber = TrigTimeForGroup.size() - maxNumAllowedInBuffer; + removedTriggerInBuffer += removedNumber; + Log("EBTG: CleanTriggerBuffer, will remove the earliest " + std::to_string(TrigTimeForGroup.size() - maxNumAllowedInBuffer) + " triggers in buffer", v_message, verbosityEBTG); + TrigTimeForGroup.erase(TrigTimeForGroup.begin(), TrigTimeForGroup.end() - maxNumAllowedInBuffer); + TrigWordForGroup.erase(TrigWordForGroup.begin(), TrigWordForGroup.end() - maxNumAllowedInBuffer); + } + return removedNumber; +} diff --git a/UserTools/EBTriggerGrouper/EBTriggerGrouper.h b/UserTools/EBTriggerGrouper/EBTriggerGrouper.h new file mode 100644 index 000000000..3d573259b --- /dev/null +++ b/UserTools/EBTriggerGrouper/EBTriggerGrouper.h @@ -0,0 +1,124 @@ +#ifndef EBTriggerGrouper_H +#define EBTriggerGrouper_H + +#include +#include + +#include "Tool.h" + +/** + * \class EBPMT + * + * $Author: Yue Feng $ + * $Date: 2024/04 $ + * Contact: yuef@iaistate.edu + * + */ + +class EBTriggerGrouper : public Tool +{ + +public: + EBTriggerGrouper(); ///< 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 GroupByTolerance(); + bool FillByTolerance(); + bool SaveGroupedTriggers(); + bool CleanBuffer(); + + int GroupByTrigWord(uint32_t mainTrigWord, vector TrigWords, int tolerance); + // group and save triggers to GroupedTriggersInTotal and RunCodeInTotal + // input a vector of trigger words in that combination, and a tolerance + // during grouping, select based on the main TrigWord + the tolerance + // in that range, if the trigger word is in the vector, group them together + // push the grouped trigger map into the vector at GroupedTriggersInTotal[mainTrigWord] + + int FillByTrigWord(uint32_t mainTrigWord, vector TrigWords, int tolerance); + // Fill the trigger maps at GroupedTriggersInTotal[mainTrigWord] + // for all triggers in the buffer, if the trigger word is in the vector, and in the range of main TrigWord - the tolerance + // push the trigger into the map + + int CleanTriggerBuffer(); // remove very early trigger in TrigTimeForGroup and TrigWordForGroup + // only leave the latest maxNumAllowedInBuffer elements + +private: + string savePath; + string GroupMode; // beam, Tolerance + double GroupTolerance; + int GroupTrigWord; + + std::map> *TimeToTriggerWordMap; + std::map> *TimeToTriggerWordMapComplete; // Info about all triggerwords + + vector TrigTimeForGroup; + vector TrigWordForGroup; + vector RunCodeBuffer; + + std::vector> GroupedTriggers; // each map is a group of triggers, for the main target trigger + vector RunCode; //!! RunCode goes with each group, always modify them together + + std::map>> GroupedTriggersInTotal; // each map is a group of triggers, with the key is the target trigger word + std::map> RunCodeInTotal; //!! RunCode goes with each group, always modify them together + + std::map SkippedDuplicateTriggers; // if the trigger was duplicated in multiple entries, skip it. this record the skipped number of groups + + int verbosityEBTG; + + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; + + int ANNIEEventNum; + int CurrentRunNum; + int CurrentSubrunNum; + int CurrentPartNum; + int currentRunCode; + bool usingTriggerOverlap; + + int StoreTotalEntry; + + int maxNumAllowedInBuffer; + int removedTriggerInBuffer; + + bool groupBeam; + bool groupCosmic; + bool groupLaser; + bool groupLED; + bool groupAmBe; + bool groupPPS; + bool groupNuMI; + + int BeamTriggerMain; + double BeamTolerance; + vector BeamTriggers; + + int CosmicTriggerMain; + double CosmicTolerance; + vector CosmicTriggers; + + int LaserTriggerMain; + double LaserTolerance; + vector LaserTriggers; + + int LEDTriggerMain; + double LEDTolerance; + vector LEDTriggers; + + int AmBeTriggerMain; + double AmBeTolerance; + vector AmBeTriggers; + + int PPSTriggerMain; + double PPSTolerance; + vector PPSTriggers; + + int NuMITriggerMain; + double NuMITolerance; + vector NuMITriggers; +}; + +#endif diff --git a/UserTools/EBTriggerGrouper/README.md b/UserTools/EBTriggerGrouper/README.md new file mode 100644 index 000000000..3f84b6468 --- /dev/null +++ b/UserTools/EBTriggerGrouper/README.md @@ -0,0 +1,32 @@ +# EBTriggerGrouper + +EBTriggerGrouper is a part of the Event Builder V2 tool chain. +For reference slides, see: +https://annie-docdb.fnal.gov/cgi-bin/sso/ShowDocument?docid=5633 + + +This tool take TimeToTriggerWordMap from the trigger data decoder as input, push the triggers and trigger words into TrigTimeForGroup and TrigWordForGroup, then use the pre defined trigger groups like BeamTriggers to group the triggers based on time tolorance. Finally save the grouped triggers to GroupedTriggersInTotal in CStore. + +## Data + +**TimeToTriggerWordMap** `std::map>` +**TimeToTriggerWordMapComplete** `std::map>` +Take from TriggerDataDecoder. This tool will push the info to + +**TrigTimeForGroup** `vector` +**TrigWordForGroup** `vector` +Buffer for timestamps. Only be used in this tool. + + +**GroupedTriggersInTotal** `std::map>>` +Groupped triggers, will be passed to other tools for matching. + +## Configuration +For one group type, you need one option, and two configs from the config file, one config hard coded in the cpp file. +groupBeam: tell the tool group this run type or not +BeamTriggerMain: the main trigger of a run type. For instance, main beam trigger is 14 +BeamTolerance: the time tolerance that you allow other triggers in this run type to be paired with a main trigger. +BeamTriggers: hard coded in the cpp file for safety. This vector contains all trigger word that allowed to be grouped as beam. +They are sent to GroupByTrigWord function for each run type. In case there will be more run types in the future. + + diff --git a/UserTools/EventSelector/EventSelector.cpp b/UserTools/EventSelector/EventSelector.cpp index 4563381a5..e06fb99c5 100644 --- a/UserTools/EventSelector/EventSelector.cpp +++ b/UserTools/EventSelector/EventSelector.cpp @@ -14,7 +14,8 @@ bool EventSelector::Initialise(std::string configfile, DataModel &data){ fPMTMRDOffset = false; fIsMC = true; - fPMTMRDOffset = 745; + fMCWaveform = false; + fPMTMRDOffset = 755; fRecoPDG = -1; //Get the tool configuration variables @@ -42,9 +43,15 @@ bool EventSelector::Initialise(std::string configfile, DataModel &data){ m_variables.Get("NoVeto",fNoVetoCut); m_variables.Get("Veto",fVetoCut); m_variables.Get("ThroughGoing",fThroughGoing); - m_variables.Get("TriggerWord",fTriggerWord); + bool got_trigger_word = m_variables.Get("TriggerWord",fTriggerWord); + if (!got_trigger_word) { + Log("EventSelector Tool: Woah there, buddy! We set TriggerWord around these parts. Come back when you've done that. \n If you're not sure what they might need to be, check out Table 3.6 in Michael Nieslony's thesis."); + m_data->vars.Set("StopLoop",1); + return false; + } m_variables.Get("SaveStatusToStore", fSaveStatusToStore); m_variables.Get("IsMC",fIsMC); + m_variables.Get("PMTWaveformSim",fMCWaveform); m_variables.Get("RecoPDG",fRecoPDG); m_variables.Get("TriggerExtendedWindow",fTriggerExtended); m_variables.Get("BeamOK",fBeamOK); @@ -89,7 +96,7 @@ bool EventSelector::Execute(){ Log("EventSelector Tool: No ANNIEEvent store!",v_error,verbosity); return false; }; - + // ANNIE Event number m_data->Stores.at("ANNIEEvent")->Get("EventNumber",fEventNumber); @@ -626,12 +633,12 @@ bool EventSelector::EventSelectionByMCProjectedMRDHit() { bool EventSelector::EventSelectionByPMTMRDCoinc() { - if (fIsMC){ - bool has_clustered_pmt = m_data->CStore.Get("ClusterMapMC",m_all_clusters_MC); - if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMapMC from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } + if (!fIsMC || fMCWaveform) { + bool has_clustered_pmt = m_data->CStore.Get("ClusterMap",m_all_clusters); + if (not has_clustered_pmt) { Log("EventSelector Tool: MCWaveform - Error retrieving ClusterMap from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } } else { - bool has_clustered_pmt = m_data->CStore.Get("ClusterMap",m_all_clusters); - if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMap from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } + bool has_clustered_pmt = m_data->CStore.Get("ClusterMapMC",m_all_clusters_MC); + if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMapMC from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } } bool has_clustered_mrd = m_data->CStore.Get("MrdTimeClusters",MrdTimeClusters); @@ -644,8 +651,12 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { } int pmt_cluster_size; - if (fIsMC) pmt_cluster_size = (int) m_all_clusters_MC->size(); - else pmt_cluster_size = (int) m_all_clusters->size(); + if (!fIsMC || fMCWaveform) { + pmt_cluster_size = (int) m_all_clusters->size(); + } else { + pmt_cluster_size = (int) m_all_clusters_MC->size(); + } + m_data->Stores["RecoEvent"]->Set("NumPMTClusters",pmt_cluster_size); vec_pmtclusters_charge->clear(); vec_pmtclusters_time->clear(); @@ -662,7 +673,42 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { pmt_time = -1; - if (fIsMC){ + // MC Waveform or Data + if (!fIsMC || fMCWaveform) { + if (m_all_clusters->size()){ + double cluster_time; + for(std::pair>&& apair : *m_all_clusters){ + std::vector&Hits = apair.second; + double time_temp = 0; + double charge_temp = 0; + for (unsigned int i_hit = 0; i_hit < Hits.size(); i_hit++){ + time_temp+=Hits.at(i_hit).GetTime(); + int tube = Hits.at(i_hit).GetTubeId(); + // check if PMT is present in the map before accessing it + auto it = ChannelNumToTankPMTSPEChargeMap->find(tube); + if (it != ChannelNumToTankPMTSPEChargeMap->end()) { + double charge_pe = Hits.at(i_hit).GetCharge() / it->second; + charge_temp += charge_pe; + } else { + std::cerr << "PMT channel with hit not found in ChannelNumToTankPMTSPEChargeMap. Skipping this hit." << std::endl; + continue; + } + } + if (Hits.size()>0) time_temp/=Hits.size(); + vec_pmtclusters_charge->push_back(charge_temp); + vec_pmtclusters_time->push_back(time_temp); + if (time_temp > 2000.) continue; //not a prompt event + if (charge_temp > max_charge){ + max_charge = charge_temp; + prompt_cluster = true; + pmt_time = time_temp; + n_hits = int(Hits.size()); + } + } + } + + // MC (parametric) + } else { if (m_all_clusters_MC->size()){ double cluster_time; for(std::pair>&& apair : *m_all_clusters_MC){ @@ -685,31 +731,6 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { } } } - } else { - if (m_all_clusters->size()){ - double cluster_time; - for(std::pair>&& apair : *m_all_clusters){ - std::vector&Hits = apair.second; - double time_temp = 0; - double charge_temp = 0; - for (unsigned int i_hit = 0; i_hit < Hits.size(); i_hit++){ - time_temp+=Hits.at(i_hit).GetTime(); - int tube = Hits.at(i_hit).GetTubeId(); - double charge_pe = Hits.at(i_hit).GetCharge()/ChannelNumToTankPMTSPEChargeMap->at(tube); - charge_temp+=charge_pe; - } - if (Hits.size()>0) time_temp/=Hits.size(); - vec_pmtclusters_charge->push_back(charge_temp); - vec_pmtclusters_time->push_back(time_temp); - if (time_temp > 2000.) continue; //not a prompt event - if (charge_temp > max_charge){ - max_charge = charge_temp; - prompt_cluster = true; - pmt_time = time_temp; - n_hits = int(Hits.size()); - } - } - } } if (verbosity > 1) { @@ -750,10 +771,14 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { } m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time, true); - if (fIsMC){ - if (MrdTimeClusters.size() == 0 || m_all_clusters_MC->size() == 0) return false; + if (fIsMC) { + if (MrdTimeClusters.size() == 0 || (fMCWaveform ? m_all_clusters->size() == 0 : m_all_clusters_MC->size() == 0)) { + return false; + } } else { - if (MrdTimeClusters.size() == 0 || m_all_clusters->size() == 0) return false; + if (MrdTimeClusters.size() == 0 || m_all_clusters->size() == 0) { + return false; + } } pmtmrd_coinc_min = fPMTMRDOffset - 50; @@ -769,7 +794,7 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { if (verbosity > 1) std::cout <<"max_charge: "< pmtmrd_coinc_min && time_diff < pmtmrd_coinc_max && max_charge > 200 && n_hits >= 20){ + if (time_diff > pmtmrd_coinc_min && time_diff < pmtmrd_coinc_max){ coincidence = true; vector_mrd_coincidence.push_back(i_mrd); } @@ -1014,12 +1039,12 @@ bool EventSelector::FindPaddleChankey(double x, double y, int layer, unsigned lo bool EventSelector::EventSelectionByRecoPDG(int recoPDG, std::vector & cluster_reco_pdg){ - if (fIsMC){ - bool has_clustered_pmt = m_data->CStore.Get("ClusterMapMC",m_all_clusters_MC); - if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMapMC from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } + if (!fIsMC || fMCWaveform) { + bool has_clustered_pmt = m_data->CStore.Get("ClusterMap",m_all_clusters); + if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMap from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } } else { - bool has_clustered_pmt = m_data->CStore.Get("ClusterMap",m_all_clusters); - if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMap from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } + bool has_clustered_pmt = m_data->CStore.Get("ClusterMapMC",m_all_clusters_MC); + if (not has_clustered_pmt) { Log("EventSelector Tool: Error retrieving ClusterMapMC from CStore, did you run ClusterFinder beforehand?",v_error,verbosity); return false; } } std::map ClusterMaxPEs; @@ -1033,52 +1058,51 @@ bool EventSelector::EventSelectionByRecoPDG(int recoPDG, std::vector & c bool found_pdg = false; if (fabs(recoPDG)==2112){ - if (fIsMC){ - if (m_all_clusters_MC->size()){ - for(std::pair>&& apair : *m_all_clusters_MC){ - double cluster_time = apair.first; - double charge_balance = ClusterChargeBalances.at(cluster_time); - std::vector&MCHits = apair.second; - double time_temp = 0; - double charge_temp = 0; - for (unsigned int i_hit = 0; i_hit < MCHits.size(); i_hit++){ - time_temp+=MCHits.at(i_hit).GetTime(); - charge_temp+=MCHits.at(i_hit).GetCharge(); - } - if (cluster_time > 10000 && charge_balance < 0.4 && charge_temp < 120) { - cluster_reco_pdg.push_back(cluster_time); - found_pdg = true; - std::cout <<"Found neutron candidate for cluster at time = "<size()){ - double cluster_time; - for(std::pair>&& apair : *m_all_clusters){ - double cluster_time = apair.first; - double charge_balance = ClusterChargeBalances.at(cluster_time); - std::vector&Hits = apair.second; - double time_temp = 0; - double charge_temp = 0; - for (unsigned int i_hit = 0; i_hit < Hits.size(); i_hit++){ - time_temp+=Hits.at(i_hit).GetTime(); - int tube = Hits.at(i_hit).GetTubeId(); - double charge_pe = Hits.at(i_hit).GetCharge()/ChannelNumToTankPMTSPEChargeMap->at(tube); - charge_temp+=charge_pe; - } - if (cluster_time > 10000 && charge_balance < 0.4 && charge_temp < 120) { - cluster_reco_pdg.push_back(cluster_time); - found_pdg = true; - std::cout <<"Found neutron candidate for cluster at time = "<size()){ + for(std::pair>&& apair : *m_all_clusters){ + double cluster_time = apair.first; + double charge_balance = ClusterChargeBalances.at(cluster_time); + std::vector&Hits = apair.second; + double time_temp = 0; + double charge_temp = 0; + for (unsigned int i_hit = 0; i_hit < Hits.size(); i_hit++){ + time_temp+=Hits.at(i_hit).GetTime(); + int tube = Hits.at(i_hit).GetTubeId(); + double charge_pe = Hits.at(i_hit).GetCharge()/ChannelNumToTankPMTSPEChargeMap->at(tube); + charge_temp+=charge_pe; + } + if (cluster_time > 10000 && charge_balance < 0.4 && charge_temp < 120) { + cluster_reco_pdg.push_back(cluster_time); + found_pdg = true; + std::cout <<"Found neutron candidate for cluster at time = "<size()){ + for(std::pair>&& apair : *m_all_clusters_MC){ + double cluster_time = apair.first; + double charge_balance = ClusterChargeBalances.at(cluster_time); + std::vector&MCHits = apair.second; + double time_temp = 0; + double charge_temp = 0; + for (unsigned int i_hit = 0; i_hit < MCHits.size(); i_hit++){ + time_temp+=MCHits.at(i_hit).GetTime(); + charge_temp+=MCHits.at(i_hit).GetCharge(); + } + if (cluster_time > 10000 && charge_balance < 0.4 && charge_temp < 120) { + cluster_reco_pdg.push_back(cluster_time); + found_pdg = true; + std::cout <<"Found neutron candidate for cluster at time = "<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 new file mode 100644 index 000000000..45035356e --- /dev/null +++ b/UserTools/FitRWMWaveform/FitRWMWaveform.cpp @@ -0,0 +1,395 @@ +#include "FitRWMWaveform.h" + +FitRWMWaveform::FitRWMWaveform() : Tool() {} + +bool FitRWMWaveform::Initialise(std::string configfile, DataModel &data) +{ + + if (configfile != "") + m_variables.Initialise(configfile); + + m_data = &data; + + m_variables.Get("verbosityFitRWMWaveform", verbosityFitRWMWaveform); + m_variables.Get("printToRootFile", printToRootFile); + + maxPrintNumber = 100; + m_variables.Get("maxPrintNumber", maxPrintNumber); + + output_filename = "RWMBRFWaveforms.root"; + m_variables.Get("output_filename", output_filename); + + return true; +} + +bool FitRWMWaveform::Execute() +{ + + Log("FitRWMWaveform: Execute()", v_debug, verbosityFitRWMWaveform); + m_data->Stores["ANNIEEvent"]->Get("RWMRawWaveform", RWMRawWaveform); + m_data->Stores["ANNIEEvent"]->Get("BRFRawWaveform", BRFRawWaveform); + + uint64_t WaveformTime = 0; + m_data->Stores["ANNIEEvent"]->Get("EventTimeTank", WaveformTime); + + if (printToRootFile && ToBePrintedRWMWaveforms.size() < maxPrintNumber) + { + + ToBePrintedRWMWaveforms.emplace(WaveformTime, RWMRawWaveform); + ToBePrintedBRFWaveforms.emplace(WaveformTime, BRFRawWaveform); + Log("FitRWMWaveform: Execute(): Added RWM and BRF waveforms to be printed to root file", v_debug, verbosityFitRWMWaveform); + } + + RWMRisingStart = 0; + RWMRisingEnd = 0; + RWMHalfRising = 0; + RWMFHWM = 0; + RWMFirstPeak = 0; + + BRFFirstPeak = 0; + BRFAveragePeak = 0; + BRFFirstPeakFit = 0; + + // Fit the RWM waveform, find the rising start, rising end and half rising time + FitRWM(); + + FitBRF(); + + m_data->Stores["ANNIEEvent"]->Set("RWMRisingStart", RWMRisingStart); + m_data->Stores["ANNIEEvent"]->Set("RWMRisingEnd", RWMRisingEnd); + m_data->Stores["ANNIEEvent"]->Set("RWMHalfRising", RWMHalfRising); + m_data->Stores["ANNIEEvent"]->Set("RWMFHWM", RWMFHWM); + m_data->Stores["ANNIEEvent"]->Set("RWMFirstPeak", RWMFirstPeak); + + m_data->Stores["ANNIEEvent"]->Set("BRFFirstPeak", BRFFirstPeak); + m_data->Stores["ANNIEEvent"]->Set("BRFAveragePeak", BRFAveragePeak); + m_data->Stores["ANNIEEvent"]->Set("BRFFirstPeakFit", BRFFirstPeakFit); + + return true; +} +bool FitRWMWaveform::Finalise() +{ + if (printToRootFile) + { + TFile *fOutput_tfile = new TFile(output_filename.c_str(), "recreate"); + + // Loop ToBePrintedRWMWaveforms and ToBePrintedBRFWaveforms, fill each waveform to a histogram and save it to the root file + // Use the RWM+event number + key as the name of the histogram + int RWMCount = 0; + for (const auto &kv : ToBePrintedRWMWaveforms) + { + const auto &key = kv.first; + const auto &val = kv.second; + TH1D *hRWM = new TH1D(Form("RWM_%d_%lu", RWMCount, key), Form("RWM_%d_%lu", RWMCount, key), val.size(), 0, val.size()); + for (int i = 0; i < val.size(); i++) + { + hRWM->SetBinContent(i + 1, val[i]); // Note the 1-based index + } + hRWM->Write(); + delete hRWM; + RWMCount++; + } + + int BRFCount = 0; + for (const auto &kv : ToBePrintedBRFWaveforms) + { + const auto &key = kv.first; + const auto &val = kv.second; + TH1D *hBRF = new TH1D(Form("BRF_%d_%lu", BRFCount, key), Form("BRF_%d_%lu", BRFCount, key), val.size(), 0, val.size()); + for (int i = 0; i < val.size(); i++) + { + hBRF->SetBinContent(i + 1, val[i]); // Note the 1-based index + } + hBRF->Write(); + delete hBRF; + BRFCount++; + } + + fOutput_tfile->Close(); + delete fOutput_tfile; + } + + return true; +} + +void FitRWMWaveform::FitRWM() +{ + Log("FitRWMWaveform: FitRWM()", v_debug, verbosityFitRWMWaveform); + if (RWMRawWaveform.size() == 0) + { + Log("FitRWMWaveform: FitRWM(): RWMRawWaveform is empty", v_message, verbosityFitRWMWaveform); + return; + } + int threshold = 50; + int bin_size = 2; // 2ns per bin + int max_bin_RWM = RWMRawWaveform.size(); + + // RWM + RWMRisingStart = 300; + for (int i = 300; i < max_bin_RWM; ++i) + { + if (RWMRawWaveform[i] > 400 && RWMRawWaveform[i] - RWMRawWaveform[i - 1] > threshold) + { + RWMRisingStart = i - 1; + break; + } + } + + RWMRisingEnd = RWMRisingStart; + for (int i = RWMRisingStart; i < RWMRisingStart + 60 && i < max_bin_RWM; ++i) + { + if (RWMRawWaveform[i] > RWMRawWaveform[RWMRisingEnd]) + { + RWMRisingEnd = i; + } + } + if (!(RWMRisingStart > 200 && RWMRisingStart < 600) || !(RWMRisingEnd > 200 && RWMRisingEnd < 600)) + { + Log("FitRWMWaveform: FitRWM(): RWMRisingStart or RWMRisingEnd out of range, found at " + std::to_string(RWMRisingStart) + " and " + std::to_string(RWMRisingEnd), v_message, verbosityFitRWMWaveform); + return; + } + + Log("FitRWMWaveform: FitRWM(): Found rising start and end at " + std::to_string(RWMRisingStart) + " and " + std::to_string(RWMRisingEnd) + " with rising start value " + std::to_string(RWMRawWaveform[RWMRisingStart]), v_debug, verbosityFitRWMWaveform); + double RWMBottom = std::accumulate(RWMRawWaveform.begin(), RWMRawWaveform.begin() + RWMRisingStart, 0.0) / RWMRisingStart; + double RWMTop = std::accumulate(RWMRawWaveform.begin() + RWMRisingEnd + 50, RWMRawWaveform.begin() + RWMRisingEnd + 400, 0.0) / 350; + double RWMHalf = (RWMBottom + RWMTop) / 2; + + int best_bin_RWM = RWMRisingStart; + double best_diff_RWM = std::abs(RWMRawWaveform[RWMRisingStart] - RWMHalf); + + for (int i = RWMRisingStart; i <= RWMRisingEnd; ++i) + { + double diff = std::abs(RWMRawWaveform[i] - RWMHalf); + if (diff < best_diff_RWM) + { + best_bin_RWM = i; + best_diff_RWM = diff; + } + } + + int best_interval_RWM = 0; + double interval_size = 1.0 / 400; + double min_diff_RWM = std::numeric_limits::max(); + Log("FitRWMWaveform: FitRWM(): Found best bin at " + std::to_string(best_bin_RWM), v_debug, verbosityFitRWMWaveform); + + for (int i = -200; i < 200; ++i) + { + // Log("FitRWMWaveform: FitRWM(): Interpolating value at " + std::to_string(i),v_debug, verbosityFitRWMWaveform); + double interpolated_value = RWMRawWaveform[best_bin_RWM] + (RWMRawWaveform[best_bin_RWM + (i < 0 ? -1 : 1)] - RWMRawWaveform[best_bin_RWM]) * (std::abs(i) * interval_size); + double diff = std::abs(interpolated_value - RWMHalf); + if (diff < min_diff_RWM) + { + min_diff_RWM = diff; + best_interval_RWM = i; + } + } + + double RWMHalfTimeInPs = (best_bin_RWM + best_interval_RWM * interval_size) * 10 + RWMRisingStart * 2000; + + RWMHalfRising = RWMHalfTimeInPs; + Log("FitRWMWaveform: FitRWM(): Found RWMHalfRising = " + std::to_string(RWMHalfRising), v_debug, verbosityFitRWMWaveform); + // finding the falling half + // Finding the falling end + int RWMFallingStart = RWMRisingEnd; + for (int i = RWMRisingEnd; i < max_bin_RWM; ++i) + { + if (RWMRawWaveform[i] < 1000) + { + RWMFallingStart = i; + break; + } + } + Log("FitRWMWaveform: FitRWM(): Found falling start", v_debug, verbosityFitRWMWaveform); + int bin_close = RWMFallingStart; + double best_diff_fall = std::abs(RWMRawWaveform[RWMFallingStart] - RWMHalf); + + for (int i = RWMFallingStart - 20; i <= RWMFallingStart + 20 && i < max_bin_RWM; ++i) + { + double diff = std::abs(RWMRawWaveform[i] - RWMHalf); + if (diff < best_diff_fall) + { + bin_close = i; + best_diff_fall = diff; + } + } + if (!(bin_close < 950)) + { + Log("FitRWMWaveform: FitRWM(): falling bin out of range, found at " + std::to_string(bin_close), v_message, verbosityFitRWMWaveform); + return; + } + Log("FitRWMWaveform: FitRWM(): Found falling close", v_debug, verbosityFitRWMWaveform); + + best_interval_RWM = 0; + min_diff_RWM = std::numeric_limits::max(); + + for (int i = -200; i < 200; ++i) + { + double interpolated_value = RWMRawWaveform[bin_close] + (RWMRawWaveform[bin_close + (i < 0 ? -1 : 1)] - RWMRawWaveform[bin_close]) * (std::abs(i) * interval_size); + double diff = std::abs(interpolated_value - RWMHalf); + if (diff < min_diff_RWM) + { + min_diff_RWM = diff; + best_interval_RWM = i; + } + } + Log("FitRWMWaveform: FitRWM(): Found falling end", v_debug, verbosityFitRWMWaveform); + double RWMHalfEnd = (bin_close * 2000) + (best_interval_RWM * 10); + RWMFHWM = RWMHalfEnd - RWMHalfRising; + + int RWMFirstPeakBin = -1; + for (int i = 0; i < RWMRawWaveform.size(); ++i) + { + if (RWMRawWaveform[i] > 1600) + { + RWMFirstPeakBin = i; + break; + } + } + + // change the unit from bin number to ns or ps + RWMRisingStart = RWMRisingStart * 2; + RWMRisingEnd = RWMRisingEnd * 2; + RWMFirstPeak = RWMFirstPeakBin * 2; +} + +void FitRWMWaveform::FitBRF() +{ + // fit the first peak, and the average of peaks of std::vector BRFRawWaveform. + // find the size of the vector, in the first 10 bin interval, find the bin with highest value, as the first peak + // for each 10 bin interval, find the highest value bin position in each interval, and minus the beginning of the interval, and average them. + double maximum = 0; + double first_peak = 0; + double average = 0; + int bin_size = 2; // 2ns per bin + + if (BRFRawWaveform.size() == 0) + { + Log("FitRWMWaveform: FitBRF(): BRFRawWaveform is empty", v_message, verbosityFitRWMWaveform); + return; + } + + int max_bin_BRF = BRFRawWaveform.size(); + + // Find the first peak in the first 10 bin interval + for (int i = 0; i < 10 && i < max_bin_BRF; ++i) + { + if (BRFRawWaveform[i] > maximum) + { + maximum = BRFRawWaveform[i]; + first_peak = i; + } + } + + // Find the highest value bin position in each 10 bin interval and calculate the average + int interval_count = 0; + for (int i = 0; i <= max_bin_BRF - 10; i += 10) + { + double max = 0; + int max_bin = 0; + for (int j = i; j < i + 10; ++j) + { + if (BRFRawWaveform[j] > max) + { + max = BRFRawWaveform[j]; + max_bin = j; + } + } + average += (max_bin - i); + ++interval_count; + } + + if (interval_count > 0) + { + average /= interval_count; + } + + // Logging results + Log("FitRWMWaveform: FitBRF(): First peak at bin = " + std::to_string(first_peak), v_debug, verbosityFitRWMWaveform); + Log("FitRWMWaveform: FitBRF(): Average peak position = " + std::to_string(average), v_debug, verbosityFitRWMWaveform); + + BRFFirstPeak = first_peak * bin_size; + BRFAveragePeak = average * bin_size; + + BRFFirstPeakFit = 0; + // now, we use a simple Gaussian fit to find the first peak in the first 10 bins (before understanding the Booster RF properties) + // first, in the first 10 bins, find the maximum value and its position, if the maximum value is smaller than 3050, return + // then check the side bins. check from the max bin to zero, find the first bin with value less than 2920, or until the first bin, save this bin as fitting start bin + // then check from the max bin to the 10th bin, find the first bin with value less than 3020. check if the next bin has value less than this bin, if yes, set next bin as the fitting end, if not, set this bin as fitting end. + // in the fitting range, fit the waveform with a Gaussian function, and find the peak position. + // save the peak position as BRFFirstPeakFit + + if (maximum < 3050) + return; + + int fit_start_bin = 0; + for (int i = first_peak; i >= 0; --i) + { + if (BRFRawWaveform[i] < 2920) + { + fit_start_bin = i; + break; + } + } + + int fit_end_bin = first_peak; + for (int i = first_peak; i < 10 && i < max_bin_BRF; ++i) + { + if (BRFRawWaveform[i] < 3020) + { + if (BRFRawWaveform[i + 1] < BRFRawWaveform[i]) + { + fit_end_bin = i + 1; + } + else + { + fit_end_bin = i; + } + break; + } + } + + if (fit_end_bin <= fit_start_bin) + return; + + std::vector x_vals, y_vals; + for (int i = fit_start_bin; i <= fit_end_bin; ++i) + { + x_vals.push_back(i * bin_size); + y_vals.push_back(BRFRawWaveform[i]); + } + + // 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); + + // Find the bin with the maximum value between bin_minimum + 2 and bin_minimum + 4 + auto max_it = std::max_element(BRFRawWaveform.begin() + bin_minimum + 2, BRFRawWaveform.begin() + bin_minimum + 5); + int bin_maximum = std::distance(BRFRawWaveform.begin(), max_it); + + // Calculate the half height + double half_height = (BRFRawWaveform[bin_minimum] + BRFRawWaveform[bin_maximum]) / 2.0; + + // Perform linear interpolation + const int intervals_per_bin = 2000; + double min_difference = std::numeric_limits::max(); + int min_difference_bin = -1; + + for (int bin = bin_minimum; bin < bin_maximum; ++bin) + { + for (int interval = 0; interval < intervals_per_bin; ++interval) + { + double fraction = interval / static_cast(intervals_per_bin); + double interpolated_value = BRFRawWaveform[bin] + fraction * (BRFRawWaveform[bin + 1] - BRFRawWaveform[bin]); + double difference = std::abs(interpolated_value - half_height); + + if (difference < min_difference) + { + min_difference = difference; + min_difference_bin = bin * intervals_per_bin + interval; + } + } + } + + double BRFRisingHalfLinearFit = min_difference_bin; // in ps + BRFFirstPeakFit = BRFRisingHalfLinearFit; +} diff --git a/UserTools/FitRWMWaveform/FitRWMWaveform.h b/UserTools/FitRWMWaveform/FitRWMWaveform.h new file mode 100644 index 000000000..629b81883 --- /dev/null +++ b/UserTools/FitRWMWaveform/FitRWMWaveform.h @@ -0,0 +1,63 @@ +#ifndef FitRWMWaveform_H +#define FitRWMWaveform_H + +#include +#include + +#include "Tool.h" +#include "TFile.h" +#include "TH1D.h" +#include // for std::accumulate +#include +#include + +/** + * \class FitRWMWaveform + * + * 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 FitRWMWaveform : public Tool +{ + +public: + FitRWMWaveform(); ///< 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 FitRWM(); + void FitBRF(); + +private: + int verbosityFitRWMWaveform; + int v_message = 1; + int v_warning = 2; + int v_error = 3; + int v_debug = 4; + + bool printToRootFile; + int maxPrintNumber; + std::string output_filename; + + std::vector RWMRawWaveform; + std::vector BRFRawWaveform; + + std::map> ToBePrintedRWMWaveforms; + std::map> ToBePrintedBRFWaveforms; + + double RWMRisingStart; + double RWMRisingEnd; + double RWMHalfRising; + double RWMFHWM; + double RWMFirstPeak; + + double BRFFirstPeak; + double BRFAveragePeak; + double BRFFirstPeakFit; +}; + +#endif diff --git a/UserTools/FitRWMWaveform/README.md b/UserTools/FitRWMWaveform/README.md new file mode 100644 index 000000000..798057458 --- /dev/null +++ b/UserTools/FitRWMWaveform/README.md @@ -0,0 +1,35 @@ +# 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 +``` diff --git a/UserTools/HitCleaner/HitCleaner.cpp b/UserTools/HitCleaner/HitCleaner.cpp index 3475b4ce2..77ea6fb52 100644 --- a/UserTools/HitCleaner/HitCleaner.cpp +++ b/UserTools/HitCleaner/HitCleaner.cpp @@ -118,8 +118,8 @@ bool HitCleaner::Initialise(std::string configfile, DataModel &data){ // only for test fFilterByTruthInfo = new std::vector; // vector of clusters - fClusterList = new std::vector; - fHitCleaningClusters = new std::vector; + fClusterList = new std::vector; + fHitCleaningClusters = new std::vector; //Set hit cleaner parameters in the RecoEvent store m_data->Stores.at("RecoEvent")->Set("HitCleaningParameters", fHitCleaningParam); @@ -194,6 +194,7 @@ bool HitCleaner::Execute(){ fIsHitCleaningDone = true; m_data->Stores.at("RecoEvent")->Set("HitCleaningDone", fIsHitCleaningDone); m_data->Stores.at("RecoEvent")->Set("HitCleaningClusters", fHitCleaningClusters); + CBCheck(digits,FilterDigitList); delete digits; digits = 0; return true; @@ -309,11 +310,11 @@ std::vector* HitCleaner::Run(std::vector* myDigitList) myOutputList = FilterDigits(myOutputList); if( fConfig==HitCleaner::kPulseHeightAndNeighbours ) return myOutputList; - // filter using clustered digits + // filter using clustered digits Not functional with current cluster architecture. Removed for the time being. // ============================= - myInputList = ResetDigits(myOutputList); - myOutputList = (std::vector*)(this->FilterByClusters(myInputList)); - myOutputList = FilterDigits(myOutputList); + //myInputList = ResetDigits(myOutputList); + //myOutputList = (std::vector*)(this->FilterByClusters(myInputList)); + //myOutputList = FilterDigits(myOutputList); if( fConfig==HitCleaner::kPulseHeightAndClusters ) return myOutputList; if (fisMC){ @@ -513,7 +514,8 @@ std::vector* HitCleaner::FilterByNeighbours(std::vector* return fFilterByNeighbours; } -std::vector* HitCleaner::FilterByClusters(std::vector* myDigitList) +//FilterByClusters is not functioning with current RecoCluster architecture. +/*std::vector* HitCleaner::FilterByClusters(std::vector* myDigitList) { std::string name = "HitCleaner::FilterByClusters() "; // clear vector of filtered digits @@ -523,14 +525,15 @@ std::vector* HitCleaner::FilterByClusters(std::vector* m // run clustering algorithm // ======================== - std::vector* myClusterList = (std::vector*)(this->RecoClusters(myDigitList)); + std::vector* myClusterList = (std::vector*)(this->RecoClusters(myDigitList)); for(int icluster=0; iclustersize()); icluster++ ){ - RecoCluster* myCluster = (RecoCluster*)(myClusterList->at(icluster)); + RecoCluster myCluster = (myClusterList->at(icluster)); fHitCleaningClusters->push_back(myCluster); - for(int idigit=0; idigitGetNDigits(); idigit++ ){ - RecoDigit* myDigit = (RecoDigit*)(myCluster->GetDigit(idigit)); + for(int idigit=0; idigitpush_back(myDigit); } } @@ -541,9 +544,9 @@ std::vector* HitCleaner::FilterByClusters(std::vector* m return fFilterByClusters; -} +}*/ -std::vector* HitCleaner::RecoClusters(std::vector* myDigitList) +std::vector* HitCleaner::RecoClusters(std::vector* myDigitList) { // delete cluster digits @@ -679,13 +682,13 @@ std::vector* HitCleaner::RecoClusters(std::vector* myD } //std::cout <<"vClusterDigitCollection.size() == "<=fMinClusterDigits ){ - RecoCluster* cluster = new RecoCluster(); + RecoCluster cluster; fClusterList->push_back(cluster); for(int jdigit=0; jdigitGetRecoDigit()); - cluster->AddDigit(recodigit); + cluster.AddDigit(recodigit); } } } @@ -738,3 +741,32 @@ std::vector* HitCleaner::FilterByTruthInfo(std::vector* return fFilterByTruthInfo; } + +void HitCleaner::CBCheck(std::vector* unfilteredDigits, std::vector* filteredDigits) { + //calculate unfiltered CB + double total_Q = 0; + double total_QSquared = 0; + for (int i=0;isize();i++) { + //if(unfilteredDigits->at(i)->GetDigitType()==RecoDigit::PMT8inch){ + double tube_charge = unfilteredDigits->at(i)->GetCalCharge(); + total_Q += tube_charge; + total_QSquared += (tube_charge * tube_charge); + //} + } + //FIXME: Need a method to have the 123 be equal to the number of operating detectors + double ucharge_balance = sqrt((total_QSquared) / (total_Q * total_Q) - (1. / 123.)); + if (verbosity > 4) std::cout << "HitCleaner Tool: Unfiltered CB: " << ucharge_balance << std::endl; + + total_Q = 0; + total_QSquared = 0; + for (int i = 0; i < filteredDigits->size(); i++) { + //if (filteredDigits->at(i)->GetDigitType() == RecoDigit::PMT8inch) { + double tube_charge = filteredDigits->at(i)->GetCalCharge(); + total_Q += tube_charge; + total_QSquared += (tube_charge * tube_charge); + //} + } + double fcharge_balance = sqrt((total_QSquared) / (total_Q * total_Q) - (1. / 123.)); + if (verbosity > 4) std::cout << "HitCleaner Tool: filtered CB: " << fcharge_balance << std::endl; + +} diff --git a/UserTools/HitCleaner/HitCleaner.h b/UserTools/HitCleaner/HitCleaner.h index e20cef7a0..85e558485 100644 --- a/UserTools/HitCleaner/HitCleaner.h +++ b/UserTools/HitCleaner/HitCleaner.h @@ -65,13 +65,14 @@ class HitCleaner: public Tool { std::vector* FilterAll(std::vector* digitlist); std::vector* FilterByPulseHeight(std::vector* digitlist); std::vector* FilterByNeighbours(std::vector* digitlist); - std::vector* FilterByClusters(std::vector* digitlist); + //std::vector* FilterByClusters(std::vector* digitlist); std::vector* FilterByTruthInfo(std::vector* digitlist); //use truth information. Only for testing the code - std::vector* RecoClusters(std::vector* digitlist); + std::vector* RecoClusters(std::vector* digitlist); private: void Reset(); + void CBCheck(std::vector* unfilteredDigits, std::vector* filteredDigits); // running mode int fConfig; @@ -120,10 +121,10 @@ class HitCleaner: public Tool { std::vector* fFilterByTruthInfo; // vectors of clusters - std::vector* fClusterList; + std::vector* fClusterList; // vector of clusters (accessible to the CStore) - std::vector* fHitCleaningClusters = nullptr; + std::vector* fHitCleaningClusters = nullptr; // true vertex RecoVertex* fTrueVertex = 0; 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/LAPPDClusterTree/LAPPDClusterTree.cpp b/UserTools/LAPPDClusterTree/LAPPDClusterTree.cpp index aaa36826f..b7a2bc0b7 100644 --- a/UserTools/LAPPDClusterTree/LAPPDClusterTree.cpp +++ b/UserTools/LAPPDClusterTree/LAPPDClusterTree.cpp @@ -30,6 +30,7 @@ bool LAPPDClusterTree::Initialise(std::string configfile, DataModel &data) WraparoundBin=0; QualityVar=0; TrigDeltaT1=0.; TrigDeltaT2=0.; PulseHeight=0.; MaxAmp0=0.; MaxAmp1=0.; BeamTime=0.; EventTime=0.; TotalCharge=0.; Npulses_cfd=0; Npulses_simp=0; T0Bin=0; NHits=0; NHits_simp=0; Npulses_cfd=0; Npulses_simp=0; Nchannels=60; + timestamps_meta=0; for(int i=0; i<60; i++){ hQ[i]=0; hxpar[i]=0; hxperp[i]=0; htime[i]=0; hdeltime[i]=0; hvpeak[i]=0; @@ -42,7 +43,7 @@ bool LAPPDClusterTree::Initialise(std::string configfile, DataModel &data) SelectedAmp0[i]=0; SelectedAmp1[i]=0; SelectedTime0[i]=0; SelectedTime1[i]=0; - StripPeak[i]=0; StripPeak_Sm[i]=0; StripPeakT[i]=0; StripPeakT_Sm[i] =0; + StripPeak[i]=0; StripPeak_Sm[i]=0; StripPeakT[i]=0; StripPeakT_Sm[i] =0; StripMaxAmp[i]=0.; StripMinAmp[i]=0.; StripRMSAmp[i]=0.; StripStandDevAmp[i]=0.; StripVarianceAmp[i]=0.; StripInt[i]=0.; StripQ[i]=0; StripQ_Sm[i]=0; } @@ -66,6 +67,7 @@ bool LAPPDClusterTree::Initialise(std::string configfile, DataModel &data) fMyTree->Branch("EventTime", &EventTime, "EventTime/D" ); fMyTree->Branch("TotalCharge", &TotalCharge, "TotalCharge/D" ); + fMyTree->Branch("timestamps_meta", ×tamps_meta, "timestamps_meta/I" ); //Hit parameters (from CFD) fMyTree->Branch("NHits", &NHits, "NHits/I" ); @@ -86,6 +88,14 @@ bool LAPPDClusterTree::Initialise(std::string configfile, DataModel &data) fMyTree->Branch("StripQ", StripQ, "StripQ[Nchannels]/D" ); fMyTree->Branch("StripQ_Sm", StripQ_Sm, "StripQ_Sm[Nchannels]/D" ); + // Information of the waveforms + fMyTree->Branch("StripMaxAmp", StripMaxAmp, "StripMaxAmp[Nchannels]/D" ); + fMyTree->Branch("StripMinAmp", StripMinAmp, "StripMinAmp[Nchannels]/D" ); + fMyTree->Branch("StripRMSAmp", StripRMSAmp, "StripRMSAmp[Nchannels]/D" ); + fMyTree->Branch("StripStandDevAmp", StripStandDevAmp, "StripStandDevAmp[Nchannels]/D" ); + fMyTree->Branch("StripVarianceAmp", StripVarianceAmp, "StripVarianceAmp[Nchannels]/D" ); + fMyTree->Branch("StripInt", StripInt, "StripInt[Nchannels]/D" ); + //Hit parameters (from simple FindPeak) fMyTree->Branch("NHits_simp", &NHits_simp, "NHits_simp/I" ); @@ -185,7 +195,31 @@ bool LAPPDClusterTree::Execute() m_data->Stores["ANNIEEvent"]->Get("TML",TML); m_data->Stores["ANNIEEvent"]->Get("TMR",TMR); + vector acdcmetadata; + bool okACDCmetadata = m_data->Stores["ANNIEEvent"]->Get("ACDCmetadata", acdcmetadata); + if (!okACDCmetadata) { + std::cerr << "ERROR: Could not retrieve ACDCmetadata from ANNIEEvent store." << std::endl; + return false; + } + // Adding the TIMESTAMP In tree + // Timestamp indices inside ACDC metadata + // These four entries store the timestamp bytes (or string fragments) + static const std::array TS_INDICES = {204, 206, 208, 210}; + int meta_timestamp_int; + std::string meta_timestamp; + + for (size_t idx : TS_INDICES) { + meta_timestamp += acdcmetadata.at(idx); + } + + std::istringstream iss(meta_timestamp); + iss >> std::hex >> meta_timestamp_int; + timestamps_meta = meta_timestamp_int; + //std::cout << meta_timestamp_int << std::endl; + //std::cout << acdcmetadata[204] << acdcmetadata[206] << acdcmetadata[208] << acdcmetadata[210] << std::endl; + //std::cout << acdcmetadata[205] << acdcmetadata[207] << acdcmetadata[209] << acdcmetadata[211] << std::endl; + //std::cout<<"----------------------------------------------"<>> :: iterator TMitr; for (TMitr = TML.begin(); TMitr != TML.end(); ++TMitr){ @@ -198,6 +232,12 @@ bool LAPPDClusterTree::Execute() StripPeakT_Sm[stripno] = aTML.at(3); StripQ[stripno] = aTML.at(4); StripQ_Sm[stripno] = aTML.at(5); + StripMaxAmp[stripno] = aTML.at(6); + StripMinAmp[stripno] = aTML.at(7); + StripRMSAmp[stripno] = aTML.at(8); + StripStandDevAmp[stripno] = aTML.at(9); + StripVarianceAmp[stripno] = aTML.at(10); + StripInt[stripno] = aTML.at(11); //cout<<"Trace on Strip in ClusterTree "<<(int) stripno<<" amplitude:"<GetStripNum(); int mystripside = mychannel->GetStripSide(); - if(LAPPDClusterTreeVerbosity>2) cout<<"vPsize: "<2) cout<<"vPsize: "<=59) { cout<<"MORE THAN 60 SIMPLE PULSES!!!!!!"<1) cout<<"DONE WITH SIMP Npulses: "<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/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/LAPPDStoreReadIn/LAPPDStoreReadIn.cpp b/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.cpp index 8b57492b0..6f93e77c4 100644 --- a/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.cpp +++ b/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.cpp @@ -3,6 +3,11 @@ LAPPDStoreReadIn::LAPPDStoreReadIn():Tool(){} +namespace { +const unsigned int NUM_CH = 30; +const unsigned int NUM_PSEC = 5; +const unsigned int NUM_SAMP = 256; +} bool LAPPDStoreReadIn::Initialise(std::string configfile, DataModel &data){ /////////////////// Useful header /////////////////////// diff --git a/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.h b/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.h index 86aeea97b..5d343d518 100644 --- a/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.h +++ b/UserTools/LAPPDStoreReadIn/LAPPDStoreReadIn.h @@ -8,10 +8,6 @@ #include #include "Tool.h" -#define NUM_CH 30 -#define NUM_PSEC 5 -#define NUM_SAMP 256 - using namespace std; /** * \class LAPPDStoreReadIn 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..95b0f8a32 --- /dev/null +++ b/UserTools/LAPPDTimeAlignment/LAPPDTimeAlignment.cpp @@ -0,0 +1,377 @@ +#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; + delete edge; + } + } + 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; + delete edge; + } + } + } + + 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/LAPPDTraceMax/LAPPDTraceMax.cpp b/UserTools/LAPPDTraceMax/LAPPDTraceMax.cpp index 9f63db90b..4a2aa1e6e 100644 --- a/UserTools/LAPPDTraceMax/LAPPDTraceMax.cpp +++ b/UserTools/LAPPDTraceMax/LAPPDTraceMax.cpp @@ -84,6 +84,9 @@ bool LAPPDTraceMax::Execute(){ vector ampvect = CalcAmp(bwav,lowR,hiR); vector ampvect_sm = CalcAmpSmoothed(bwav,lowR,hiR); + // find min max amplitude + vector ampminmaxvect = CalcMinMaxAmp(bwav); + // integrate the pulse from the low range to high range in units of mV*psec double Qmvpsec = CalcIntegral(bwav,lowR,hiR); // convert to coulomb @@ -112,6 +115,13 @@ bool LAPPDTraceMax::Execute(){ astripsumL.push_back(ampvect_sm.at(1)); astripsumL.push_back(Qelectrons); astripsumL.push_back(sQelectrons); + + astripsumL.push_back(ampminmaxvect.at(0)); + astripsumL.push_back(ampminmaxvect.at(1)); + astripsumL.push_back(ampminmaxvect.at(2)); + astripsumL.push_back(ampminmaxvect.at(3)); + astripsumL.push_back(ampminmaxvect.at(4)); + astripsumL.push_back(ampminmaxvect.at(5)); } if(stripside==1){ @@ -121,6 +131,13 @@ bool LAPPDTraceMax::Execute(){ astripsumR.push_back(ampvect_sm.at(1)); astripsumR.push_back(Qelectrons); astripsumR.push_back(sQelectrons); + + astripsumR.push_back(ampminmaxvect.at(0)); + astripsumR.push_back(ampminmaxvect.at(1)); + astripsumR.push_back(ampminmaxvect.at(2)); + astripsumR.push_back(ampminmaxvect.at(3)); + astripsumR.push_back(ampminmaxvect.at(4)); + astripsumR.push_back(ampminmaxvect.at(5)); } vastripsumL.push_back(astripsumL); @@ -175,12 +192,52 @@ double LAPPDTraceMax::CalcIntegral(Waveform hwav, double lowR, double hi for(int i=lowb; i LAPPDTraceMax::CalcMinMaxAmp(Waveform hwav){ + + // Get the Samples from Waveform + std::vector *theWav = hwav.GetSamples(); + int nbins = theWav->size(); + + // Find the minimum and maximum values + auto minmax = std::minmax_element(theWav->begin(), theWav->end()); + + // Get the minimum and maximum values + double minAmp = *minmax.first; + double maxAmp = *minmax.second; + + // Get RMS + double sumOfSquares = 0.0; + for (int i=0; iat(i),2); + double rms = sqrt(sumOfSquares / nbins); + + // Get Mean + double sum = 0.0; + for (int i=0; iat(i); + double mean = sum / nbins; + + // Get Variance + double variance = 0.0; + for (int i=0; iat(i) - mean,2); + variance = variance / nbins; + + // Get Standard deviation + double StandDev = sqrt(variance); + + vector minmaxVect; + minmaxVect.push_back(minAmp); + minmaxVect.push_back(maxAmp); + minmaxVect.push_back(rms); + minmaxVect.push_back(StandDev); + minmaxVect.push_back(variance); + minmaxVect.push_back(mean); + + return minmaxVect; +} std::vector LAPPDTraceMax::CalcAmp(Waveform hwav, double lowR, double hiR){ @@ -202,7 +259,7 @@ std::vector LAPPDTraceMax::CalcAmp(Waveform hwav, double lowR, d tTime=(double)i; } } - } else std::cout<<"OUT OF RANGE!!!!"< tAmpVect; tAmpVect.push_back(tAmp); @@ -240,7 +297,7 @@ std::vector LAPPDTraceMax::CalcAmpSmoothed(Waveform hwav, double tTime=(double)i - (Nsmooth/2.) ; } } - } else std::cout<<"OUT OF RANGE!!!!"< tAmpVect; tAmpVect.push_back(tAmp); @@ -265,7 +322,7 @@ double LAPPDTraceMax::CalcIntegralSmoothed(Waveform hwav, double lowR, d for(int i=lowb; i #include "Tool.h" +#include class LAPPDTraceMax: public Tool { @@ -22,6 +23,7 @@ class LAPPDTraceMax: public Tool { double CalcIntegral(Waveform hwav, double lowR, double hiR); double CalcIntegralSmoothed(Waveform hwav, double lowR, double hiR); std::vector CalcAmp(Waveform hwav, double lowR, double hiR); + std::vector CalcMinMaxAmp(Waveform hwav); std::vector CalcAmpSmoothed(Waveform hwav, double lowR, double hiR); int DimSize; double Deltat; diff --git a/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.cpp b/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.cpp new file mode 100644 index 000000000..f4e5cec6b --- /dev/null +++ b/UserTools/LAPPDTreeMaker/LAPPDTreeMaker.cpp @@ -0,0 +1,1095 @@ +#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"); + + 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(); + delete file; + + 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; + } +} 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/LAPPDWaveformDisplay/LAPPDWaveformDisplay.cpp b/UserTools/LAPPDWaveformDisplay/LAPPDWaveformDisplay.cpp new file mode 100644 index 000000000..d4f45790c --- /dev/null +++ b/UserTools/LAPPDWaveformDisplay/LAPPDWaveformDisplay.cpp @@ -0,0 +1,439 @@ +#include "LAPPDWaveformDisplay.h" + +LAPPDWaveformDisplay::LAPPDWaveformDisplay(): +Tool(), +mGeo(nullptr), +mFirstEventNumber(0), +mLastEventNumber(100), +mChannelOffset(0), +mTriggerChannel1(1005), +mTriggerChannel2(1035), +mVerbosity(0), +mIsT0SignalRequired(false), +mIsTriggerChannelDisplayed(false), +mIsRunInfoPrinted(false), +mCanvas(nullptr), +mEventID(0), +mIsEventRangeDefined(false) +{ +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +bool LAPPDWaveformDisplay::Initialise(std::string configfile, DataModel &data){ + + if(configfile!="") m_variables.Initialise(configfile); + + m_data= &data; + + { //Get from ANNIEEvent BoostStore + mBoostStoreErrMsg = "Error: Data retrieval from 'ANNIEEvent' store failed."; + if ( !m_data->Stores["ANNIEEvent"]->Header->Get("AnnieGeometry", mGeo) ) + ThrowRuntimeError(mBoostStoreErrMsg, __LINE__); + } + + { //Get variables from config file + if (m_variables.Get("FirstEventNumber", mFirstEventNumber) && + m_variables.Get("LastEventNumber", mLastEventNumber)) { + mIsEventRangeDefined = true; + } + + std::string storeErrMsg = "Error: Data retrieval from 'Store' failed."; + + if ( !m_variables.Get("InputWaveformLabel", mInputWaveformLabel) ) + ThrowRuntimeError(storeErrMsg, __LINE__); + + if ( !m_variables.Get("ChannelOffset", mChannelOffset) ) + ThrowRuntimeError(storeErrMsg, __LINE__); + + if ( !m_variables.Get("TrigerChannel1", mTriggerChannel1) ) + ThrowRuntimeError(storeErrMsg, __LINE__); + + if ( !m_variables.Get("TrigerChannel2", mTriggerChannel2) ) + ThrowRuntimeError(storeErrMsg, __LINE__); + + if (!m_variables.Get("WaveformDisplayVerbosity", mVerbosity)) + mVerbosity = 0; //default + + if (!m_variables.Get("RequireT0Signal", mIsT0SignalRequired)) + mIsT0SignalRequired = false; + + if (!m_variables.Get("DisplayTriggerChannelInPlot", mIsTriggerChannelDisplayed)) + mIsTriggerChannelDisplayed = true; + + if (!m_variables.Get("OutputFileName", mOutputFileName)) + mOutputFileName = "LAPPDWaveformDisplay.pdf"; + + if (!m_variables.Get("PrintRunInfo", mIsRunInfoPrinted)) + mIsRunInfoPrinted = 1; + + if (!m_variables.Get("Date", mDate)) + mDate = "N/A"; + + if (!m_variables.Get("LAPPDModel", mLAPPDModel)) + mLAPPDModel = "N/A"; + + if (!m_variables.Get("Path", mPath)) + mPath = "N/A"; + + if (!m_variables.Get("LaserStatus", mLaserStatus)) + mLaserStatus = "N/A"; + + if (!m_variables.Get("TriggerMode", mTriggerMode)) + mTriggerMode = "N/A"; + + if (!m_variables.Get("NDFilter", mNDFilter)) + mNDFilter = "N/A"; + + if (!m_variables.Get("RunInfo", mRunInfo)) + mRunInfo = "N/A"; + + } + + { // Create a canvas for event display, apply canvas style, + // and open the output file in append mode to start saving plots + mCanvas = new TCanvas("Event Display Canvas", "Event Display", 1200, 800); + SetCanvasStyle(); + mCanvas->Print( (mOutputFileName + "[").c_str() ); + } + + return true; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +bool LAPPDWaveformDisplay::Execute(){ + // This function is organized into 8 steps for readability and clarity. + + // 1. Skip events that are outside the defined event range + if (mIsEventRangeDefined){ + if (mEventID < mFirstEventNumber || mEventID > mLastEventNumber) { + mEventID++; + return true; + } + } + + // 2. Skip events if T0 signal is required but not found in the time window + bool T0SignalInWindow{false}; + if ( m_data->Stores["ANNIEEvent"]->Get("T0signalInWindow", T0SignalInWindow) ) + T0SignalInWindow = true; + if (mIsT0SignalRequired && !T0SignalInWindow){ + mEventID++; + return true; + } + + // 3. Get lappd waveforms fromv ANNIEEvent BoostStore + std::map< unsigned long, vector>> lappddata; + if ( !m_data->Stores["ANNIEEvent"]->Get( mInputWaveformLabel, lappddata) ) + ThrowRuntimeError(mBoostStoreErrMsg, __LINE__); + + // 4. Create 2D histogram and multi-graph for each strip side + int numSamples{0}; + { + Waveform fwav = (lappddata.begin()->second).at(0); + numSamples = fwav.GetSamples()->size(); + if (numSamples != 256) + ThrowRuntimeError("Unexpected waveform size! ", __LINE__); + } + TString side0HistoName = "Side 0 Event "; + side0HistoName += mEventID; + TH2D* hSideO = new TH2D(side0HistoName, side0HistoName, numSamples, + -0.5, 255.5, 30, -0.5, 29.5); + TString side1HistoName = "Side 1 Event "; + side1HistoName += mEventID; + TH2D* hSide1 = new TH2D(side1HistoName, side1HistoName, numSamples, + -0.5, 255.5, 30, -0.5, 29.5); + TMultiGraph *side0MultiGraph = new TMultiGraph(); + TMultiGraph *side1MultiGraph = new TMultiGraph(); + + // 5. Fill histograms and graphs + std::map>> :: iterator itr; + for (itr = lappddata.begin(); itr != lappddata.end(); ++itr){ + + unsigned long channelNo = itr->first; + channelNo = channelNo + mChannelOffset; + + if (channelNo == mTriggerChannel1 || channelNo == mTriggerChannel2) + if (!mIsTriggerChannelDisplayed) continue; + + Channel* mychannel = mGeo->GetChannel(channelNo); + + if (!mychannel) + ThrowRuntimeError("mGeo->GetChannel(channelNo) returns null!!", __LINE__); + + int stripNo = mychannel->GetStripNum(); + int stripSide = mychannel->GetStripSide(); + + if (mVerbosity > 1){ + cout<<"ChannelNo: "< > Vwavs = itr->second; + + if (stripSide == 0){ + TGraph *graphSide0 = new TGraph(); + + for (int i = 0; i < Vwavs.size(); i++){ + Waveform bwav = Vwavs.at(i); + + for (int j = 0; j < bwav.GetSamples()->size(); j++){ + hSideO->Fill(j, stripNo, -bwav.GetSamples()->at(j)); + graphSide0->SetPoint(j, j, -bwav.GetSamples()->at(j)); + } + } + + graphSide0->SetLineColor(GetColorForStrip(stripNo)); + side0MultiGraph->Add(graphSide0); + + }else if( stripSide == 1){ + + TGraph *graphSide1 = new TGraph(); + + for (int i = 0; i < Vwavs.size(); i++){ + Waveform bwav = Vwavs.at(i); + + for (int j = 0; j < bwav.GetSamples()->size(); j++){ + hSide1->Fill(j, stripNo, -bwav.GetSamples()->at(j)); + graphSide1->SetPoint(j, j, -bwav.GetSamples()->at(j)); + } + + } + + graphSide1->SetLineColor(GetColorForStrip(stripNo)); + side1MultiGraph->Add(graphSide1); + + } + + } + + // 6. Print run info only on the first page if enabled + if (mIsRunInfoPrinted && (mEventID == 0 || mEventID == mFirstEventNumber)) + PrintRunInfo(); + + // 7. Clear the canvas and divide it into 2x2 grid for displaying 4 plots + mCanvas->Clear(); + mCanvas->Divide(2, 2); + mCanvas->cd(1); + hSideO->Draw("COLZ"); + //hSideO->SetTitle(""); + hSideO->GetXaxis()->SetTitle("Sample number or Time (x ~0.1 ns)"); + hSideO->GetXaxis()->CenterTitle(); + hSideO->GetYaxis()->SetTitle("Strip number"); + hSideO->GetYaxis()->CenterTitle(); + hSideO->GetZaxis()->SetTitle("Amplitute (mV)"); + hSideO->GetZaxis()->CenterTitle(); + mCanvas->cd(2); + hSide1->Draw("COLZ"); + //hSide1->SetTitle(""); + hSide1->GetXaxis()->SetTitle("Sample number or Time (x ~0.1 ns)"); + hSide1->GetXaxis()->CenterTitle(); + hSide1->GetYaxis()->SetTitle("Strip number"); + hSide1->GetYaxis()->CenterTitle(); + hSide1->GetZaxis()->SetTitle("Amplitute (mV)"); + hSide1->GetZaxis()->CenterTitle(); + mCanvas->cd(3); + side0MultiGraph->Draw("AL"); + //side0MultiGraph->SetTitle(mOutputWavLabel.c_str()); + //side0MultiGraph->GetYaxis()->SetRangeUser(-200, 200); + side0MultiGraph->GetXaxis()->SetTitle("Sample number or Time (x ~0.1 ns)"); + side0MultiGraph->GetXaxis()->CenterTitle(); + side0MultiGraph->GetYaxis()->SetTitle("Amplitude (mV)"); + side0MultiGraph->GetYaxis()->CenterTitle(); + side0MultiGraph->GetXaxis()->SetNdivisions(10); + mCanvas->cd(4); + side1MultiGraph->Draw("AL"); + //side1MultiGraph->SetTitle(mOutputWavLabel.c_str()); + //side1MultiGraph->GetYaxis()->SetRangeUser(-400, 400); + side1MultiGraph->GetXaxis()->SetTitle("Sample number or Time (x ~0.1 ns)"); + side1MultiGraph->GetXaxis()->CenterTitle(); + side1MultiGraph->GetYaxis()->SetTitle("Amplitude (mV)"); + side1MultiGraph->GetYaxis()->CenterTitle(); + side1MultiGraph->GetXaxis()->SetNdivisions(10); + mCanvas->cd(); + mCanvas->Print( mOutputFileName.c_str() ); + + //8. Cleanup memory + delete hSideO; + delete hSide1; + // The TMultiGraph owns the graphs added to it, so deleting the multi-graph + // will automatically delete all the graphs contained within it. + delete side0MultiGraph; + delete side1MultiGraph; + + mEventID++; + + return true; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +bool LAPPDWaveformDisplay::Finalise(){ + mCanvas->Print( (mOutputFileName + "]").c_str() ); + + delete mCanvas; + + return true; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +int LAPPDWaveformDisplay::GetColorForStrip(int stripNo) { + + static std::map stripColors; + + if ( stripColors.find(stripNo) != stripColors.end() ) { + return stripColors[stripNo]; + } + + static const int numColors = 30; //strip number + + int colorPalette[numColors] = { + TColor::GetColor(255, 0, 0), // Red + TColor::GetColor(0, 0, 255), // Blue + TColor::GetColor(0, 255, 0), // Green + TColor::GetColor(255, 165, 0), // Orange + TColor::GetColor(128, 0, 128), // Purple + TColor::GetColor(255, 20, 147), // Deep Pink + TColor::GetColor(0, 255, 255), // Cyan (Light Blue) + TColor::GetColor(75, 0, 130), // Indigo + TColor::GetColor(210, 105, 30), // Chocolate Brown + TColor::GetColor(255, 255, 0), // Yellow + TColor::GetColor(0, 128, 128), // Dark Turquoise + TColor::GetColor(128, 128, 0), // Olive Green + TColor::GetColor(139, 0, 0), // Dark Red + TColor::GetColor(0, 139, 139), // Dark Cyan + TColor::GetColor(144, 238, 144), // Light Green + TColor::GetColor(70, 130, 180), // Steel Blue + TColor::GetColor(255, 140, 0), // Dark Orange + TColor::GetColor(186, 85, 211), // Orchid + TColor::GetColor(147, 112, 219), // Medium Purple + TColor::GetColor(60, 179, 113), // Medium Sea Green + TColor::GetColor(205, 92, 92), // Dark Salmon + TColor::GetColor(255, 105, 180), // Hot Pink + TColor::GetColor(72, 61, 139), // Dark Slate Blue + TColor::GetColor(0, 191, 255), // Deep Sky Blue + TColor::GetColor(255, 228, 196), // Wheat + TColor::GetColor(85, 107, 47), // Dark Olive Green + TColor::GetColor(255, 99, 71), // Tomato Red + TColor::GetColor(123, 104, 238), // Medium Slate Blue + TColor::GetColor(34, 139, 34), // Forest Green + TColor::GetColor(250, 128, 114) // Salmon + }; + + int colorIndex = stripNo % numColors; + int assignedColor = colorPalette[colorIndex]; + + stripColors[stripNo] = assignedColor; + + if (mVerbosity > 2) + cout<<"StripNo: "<SetCanvasColor(kWhite); + gStyle->SetPadColor(kWhite); + gStyle->SetFrameFillColor(kWhite); + + gStyle->SetFrameLineWidth(2); + gStyle->SetFrameLineColor(kBlack); + + // gStyle->SetGridColor(kGray+1); + // gStyle->SetGridStyle(3); + // gStyle->SetGridWidth(1); + // gStyle->SetPadGridX(true); + // gStyle->SetPadGridY(true); + + // Axis style + gStyle->SetLabelSize(0.045, "XYZ"); + gStyle->SetLabelFont(42, "XYZ"); + gStyle->SetLabelColor(kBlack, "XYZ"); + + gStyle->SetTitleSize(0.05, "XYZ"); + gStyle->SetTitleFont(42, "XYZ"); + gStyle->SetTitleColor(kBlack, "XYZ"); + + gStyle->SetTitleOffset(1.2, "X"); + gStyle->SetTitleOffset(1.2, "Y"); + + // Margins + gStyle->SetPadLeftMargin(0.16); + gStyle->SetPadRightMargin(0.15); + gStyle->SetPadBottomMargin(0.13); + gStyle->SetPadTopMargin(0.1); + + gStyle->SetPalette(112); // kViridis + // gStyle->SetPalette(55); // Alternative: kBird + + // Thicken the frame for better readability + gStyle->SetHistLineWidth(2); + + // Align axis titles for better clarity + gStyle->SetTitleAlign(23); // Center align + + gStyle->SetOptStat(0); + gStyle->SetPalette(kBird); + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +void LAPPDWaveformDisplay::PrintRunInfo() +{ + //Header + TPaveText *headerBox = new TPaveText(0.05, 0.92, 0.95, 1.0, "NDC"); + headerBox->SetTextAlign(22); + headerBox->SetTextSize(0.04); + headerBox->SetFillColor(kGray); + headerBox->SetTextColor(kWhite); + headerBox->AddText("LAPPD Event Waveform Display"); + headerBox->Draw(); + + TPaveText *infoBox = new TPaveText(0.05, 0.2, 0.95, 0.9, "NDC"); + infoBox->SetTextAlign(12); + infoBox->SetTextSize(0.03); + + std::string date = "Date : " + mDate; + infoBox->AddText(date.c_str()); + + std::string lappdModel = "LAPPD model : " + mLAPPDModel; + infoBox->AddText(lappdModel.c_str()); + + std::string path = "Path : " + mPath; + infoBox->AddText(path.c_str()); + + std::string laserStatus = "Laser status: " + mLaserStatus; + infoBox->AddText(laserStatus.c_str()); + + std::string triggerMode = "Trigger mode: " + mTriggerMode; + infoBox->AddText(triggerMode.c_str()); + + std::string ndFilter = "ND filter: " + mNDFilter; + infoBox->AddText(ndFilter.c_str()); + + std::string runInfo = "Run info: " + mRunInfo; + infoBox->AddText(runInfo.c_str()); + + //infoBox->AddText(""); //Empty line + infoBox->Draw(); + + mCanvas->Print( mOutputFileName.c_str() ); + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +void LAPPDWaveformDisplay::ThrowRuntimeError +( + const std::string& errorMessage, + int line +) +{ + throw std::runtime_error(errorMessage + " at " + __FILE__ + + ":" + std::to_string(line)); +} diff --git a/UserTools/LAPPDWaveformDisplay/LAPPDWaveformDisplay.h b/UserTools/LAPPDWaveformDisplay/LAPPDWaveformDisplay.h new file mode 100644 index 000000000..493220ee5 --- /dev/null +++ b/UserTools/LAPPDWaveformDisplay/LAPPDWaveformDisplay.h @@ -0,0 +1,72 @@ +#ifndef LAPPDWaveformDisplay_H +#define LAPPDWaveformDisplay_H + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +#include +#include +#include "Tool.h" + +#include "TCanvas.h" +#include "TH2D.h" +#include "TGraph.h" +#include "TMultiGraph.h" +#include +#include "TPaletteAxis.h" +#include "TPaveText.h" + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +class LAPPDWaveformDisplay: public Tool { + + public: + + LAPPDWaveformDisplay(); + bool Initialise(std::string configfile,DataModel &data); + bool Execute(); + bool Finalise(); + + private: + int GetColorForStrip(int stripNo); + void ThrowRuntimeError(const std::string& errorMessage, int line); + void SetCanvasStyle(); + void PrintRunInfo(); + + private: + //From ANNIEEvent store + Geometry* mGeo; + + //From config file + int mFirstEventNumber; + int mLastEventNumber; + + std::string mInputWaveformLabel; + int mChannelOffset; + int mTriggerChannel1; + int mTriggerChannel2; + + int mVerbosity; + bool mIsT0SignalRequired; + bool mIsTriggerChannelDisplayed; + std::string mOutputFileName; + + bool mIsRunInfoPrinted; + std::string mDate; + std::string mLAPPDModel; + std::string mPath; + std::string mLaserStatus; + std::string mTriggerMode; + std::string mNDFilter; + std::string mRunInfo; + + // Class-specific variables + TCanvas *mCanvas; + int mEventID; + bool mIsEventRangeDefined; + std::string mBoostStoreErrMsg; + +}; + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +#endif diff --git a/UserTools/LAPPDWaveformDisplay/README.md b/UserTools/LAPPDWaveformDisplay/README.md new file mode 100644 index 000000000..fe0bf35f5 --- /dev/null +++ b/UserTools/LAPPDWaveformDisplay/README.md @@ -0,0 +1,51 @@ +# LAPPDWaveformDisplay + +The `LAPPDWaveformDisplay` tool visualizes LAPPD waveforms for each event and generates a PDF file. Each page of the PDF contains four plots: the two plots on the left correspond to one end of the striplines, labeled side 0, and the two plots on the right correspond to the other end, labeled side 1. The bottom plots show the time-amplitude relationship for each channel, while the top plots are 2D histograms with time on the x-axis, strip number on the y-axis, and amplitude represented by color. + +Each side consists of 30 channels, allowing a clear visualization of the waveform data on both sides of the stripline. + +This tool can be used in several LAPPD-related toolchains to visualize and track waveform modifications. Many tools within these toolchains typically modify the waveform (e.g., time shifting, baseline subtraction) and save it under a new label in the `ANNIEEvent BoostStore`. The next tool uses this modified waveform, applies further changes, and saves it again with a new label. This tool is useful for visualizing the waveform at any stage of this process to track changes. It simply takes a labeled waveform as input and generates a PDF file on an event-by-event basis. + +## Requirements + +Before running the LAPPDWaveformDisplay, at least two tools must be executed. The first required tool is `LoadGeometry`, which is essential for LAPPD channel mapping. The second required tool is responsible for reading waveforms from a data file. These tools ensure that the necessary geometry and waveform data are available before visualization. + +## Configuration + +`LAPPDWaveformDisplay` has the following configuration parameters/variables: + +Most parameters are self-explanatory by their names. However, special attention should be given to the ChannelOffset parameter. This offset is used to adjust the channel numbering in the waveform labels to match the convention defined in the Channel class. In ToolAnalysis, the data model Channel class assigns channel numbers starting from 1000 for LAPPDs. Therefore, the offset should typically be set to 1000 to ensure consistency. However, if the waveform label already uses channel numbers starting from 1000, then the offset should be set to 0. + +``` +# To display specific events, uncomment and set the range. +#FirstEventNumber 53 +#LastEventNumber 85 + +InputWaveformLabel ABLSLAPPDData +ChannelOffset 0 +TrigerChannel1 1005 +TrigerChannel2 1035 +WaveformDisplayVerbosity 0 +RequireT0Signal 0 +DisplayTriggerChannelInPlot 1 +OutputFileName LAPPDWaveformDisplay.pdf +``` + +## LAPPD-Laser Setup Parameters + +The following parameters are related to the LAPPD-laser setup in the dark room at Fermilab Lab 6. If this is not relevant to you, feel free to skip this part. It is a common practice among researchers working in the dark room to frequently visualize waveforms after data taking. If you want to provide the following information, set PrintRunInfo to 1. + +The provided information will appear on the first page of the generated PDF file. + +``` +# If PrintRunInfo is set to 0, the other settings below it are ignored, and the run information is not printed. +PrintRunInfo 0 + +Date 2025-03-05 +LAPPDModel 151 +Path /pnfs/annie/persistent/LAPPDData/LAPPD151/2025-03-12/all.txt +LaserStatus On +TriggerMode Forced +NDFilter 2.0 +RunInfo "Cross-talk-data" +``` 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/LoadGenieEvent/LoadGenieEvent.cpp b/UserTools/LoadGenieEvent/LoadGenieEvent.cpp index 7995901fc..40279c0ab 100644 --- a/UserTools/LoadGenieEvent/LoadGenieEvent.cpp +++ b/UserTools/LoadGenieEvent/LoadGenieEvent.cpp @@ -308,6 +308,10 @@ bool LoadGenieEvent::Execute(){ neutcode=thegenieinfo.neutinteractioncode; // currently disabled to prevent excessive verbosity eventq2=thegenieinfo.Q2; //MeV + eventw2=thegenieinfo.W2; //MeV + eventbj_x = thegenieinfo.x; + eventelastic_y = thegenieinfo.y; + TrueTargetZ = thegenieinfo.targetnucleusZ; eventEnu=thegenieinfo.probeenergy; //MeV eventPnu=thegenieinfo.probethreemomentum; //MeV neutrinopdg=thegenieinfo.probepdg; @@ -426,6 +430,14 @@ bool LoadGenieEvent::Execute(){ geniestore->Set("NuVtxInTank",isintank); geniestore->Set("NuVtxInFidVol",isinfiducialvol); geniestore->Set("EventQ2",eventq2); + geniestore->Set("EventW2",eventw2); + geniestore->Set("EventBjx",eventbj_x); + geniestore->Set("Eventy",eventelastic_y); + geniestore->Set("TargetZ",TrueTargetZ); + geniestore->Set("Eventq0",eventq0); + geniestore->Set("Eventq3",eventq3); + geniestore->Set("pdg_vector", pdgs); + geniestore->Set("Pmag_vector",Pmag); geniestore->Set("NeutrinoEnergy",eventEnu); geniestore->Set("NeutrinoMomentum",eventPnu); geniestore->Set("NeutrinoPDG",neutrinopdg); @@ -458,6 +470,8 @@ bool LoadGenieEvent::Execute(){ Log("Tool LoadGenieEvent: Clearing genieintx",v_debug,verbosity); genieintx->Clear(); // REQUIRED TO PREVENT MEMORY LEAK + pdgs.clear(); + Pmag.clear(); Log("Tool LoadGenieEvent: done",v_debug,verbosity); return true; @@ -645,44 +659,66 @@ void LoadGenieEvent::GetGenieEntryInfo(genie::EventRecord* gevtRec, genie::Inter genie::GHepParticle * p = 0; //Loop over event particles + /// Kolanoski, Hermann, and Norbert Wermes, Particle Detectors: Fundamentals and Applications + // (Oxford, 2020; online edn, Oxford Academic, 17 Sept. 2020), + /// https://doi.org/10.1093/oso/9780198858362.001.0001, accessed 15 Aug. 2024. + // Using the equation P_th = Mass[GeV/C] / sqrt(n^2-1), where "n" is the index for refraction + /// rounding to 2 SigFigs + double wclimit_pion = 0.16; //water Cherenkov momentum threshold GeV + double wclimit_proton = 1.1; //water Cherenkov momentum threshold GeV + double wclimit_kaon = .56; //water Cherenkov momentum threshold GeV **THe the charged and neutral kaons thresholds are the same to 2 sigfigs while ((p = dynamic_cast(iter.Next()))) { int pdgc = p->Pdg(); + double pipx = p->Px(); + double pipy = p->Py(); + double pipz = p->Pz(); + double P_mag = std::sqrt(pipx*pipx + pipy*pipy + pipz*pipz); int status = p->Status(); double wclimit = 0.160; //water Cherenkov momentum threshold GeV if (status != genie::kIStStableFinalState) continue; if (pdgc == genie::kPdgNeutron) thegenieinfo.numfsneutrons++; - else if (pdgc == genie::kPdgProton) thegenieinfo.numfsprotons++; + else if (pdgc == genie::kPdgProton) { + thegenieinfo.numfsprotons++; + if (P_mag > wclimit_proton) { + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + } + } else if (pdgc == genie::kPdgPiP) { thegenieinfo.numfspiplus++; - double pipx = p->Px(); - double pipy = p->Py(); - double pipz = p->Pz(); - if (std::sqrt(pipx*pipx + pipy*pipy + pipz*pipz) > wclimit) thegenieinfo.numfspipluscher++; + if (P_mag > wclimit_pion){ + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfspipluscher++; + } } else if (pdgc == genie::kPdgPiM) { thegenieinfo.numfspiminus++; - double pipx = p->Px(); - double pipy = p->Py(); - double pipz = p->Pz(); - if (std::sqrt(pipx*pipx + pipy*pipy + pipz*pipz) > wclimit) thegenieinfo.numfspiminuscher++; + if (P_mag > wclimit_pion) { + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfspiminuscher++; + } } else if (pdgc == genie::kPdgPi0) thegenieinfo.numfspi0++; else if (pdgc == genie::kPdgKP) { thegenieinfo.numfskplus++; - double pipx = p->Px(); - double pipy = p->Py(); - double pipz = p->Pz(); - if (std::sqrt(pipx*pipx + pipy*pipy + pipz*pipz) > wclimit) thegenieinfo.numfskpluscher++; + if (P_mag > wclimit_kaon) { + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfskpluscher++; + } } else if (pdgc == genie::kPdgKM) { thegenieinfo.numfskminus++; - double pipx = p->Px(); - double pipy = p->Py(); - double pipz = p->Pz(); - if (std::sqrt(pipx*pipx + pipy*pipy + pipz*pipz) > wclimit) thegenieinfo.numfskminuscher++; + if (P_mag > wclimit_kaon){ + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfskminuscher++; + } } } @@ -703,6 +739,14 @@ void LoadGenieEvent::GetGenieEntryInfo(genie::EventRecord* gevtRec, genie::Inter // q=k1-k2, 4-p transfer /*TLorentzVector*/ thegenieinfo.q = TLorentzVectorToFourVector((*k1)-(*k2)); // /*Double_t*/ thegenieinfo.Q2 = genieint->Kine().Q2(); // not set in our GENIE files! + double q0 = (gevtRec->Probe()->P4()->E()*1000.) - (gevtRec->FinalStatePrimaryLepton()->P4()->E()*1000.); + double px1 = (gevtRec->FinalStatePrimaryLepton()->P4()->Px()*1000.) - (gevtRec->Probe()->P4()->Px()*1000.); + double py1 = (gevtRec->FinalStatePrimaryLepton()->P4()->Py()*1000.) - (gevtRec->Probe()->P4()->Py()*1000.); + double pz1 = (gevtRec->FinalStatePrimaryLepton()->P4()->Pz()*1000.) - (gevtRec->Probe()->P4()->Pz()*1000.); + double q3 = sqrt(px1*px1+py1*py1+pz1*pz1); + thegenieinfo.Q2 = q3*q3 - q0*q0; // MeV + eventq0 = q0; + eventq3 = q3; // momemtum transfer /*Double_t*/ thegenieinfo.Q2 = -1 * thegenieinfo.q.M2(); // E transfer to the nucleus diff --git a/UserTools/LoadGenieEvent/LoadGenieEvent.h b/UserTools/LoadGenieEvent/LoadGenieEvent.h index 1a0582570..304984eae 100644 --- a/UserTools/LoadGenieEvent/LoadGenieEvent.h +++ b/UserTools/LoadGenieEvent/LoadGenieEvent.h @@ -159,6 +159,14 @@ class LoadGenieEvent: public Tool { bool isintank=false; bool isinfiducialvol=false; double eventq2=-1; + double eventw2=-1; + int TrueTargetZ = -1; + double eventbj_x=-1; + double eventelastic_y=-1; + double eventq0=-1; + double eventq3=-1; + std::vectorpdgs; + std::vectorPmag; double eventEnu=-1; Direction eventPnu; int neutrinopdg=-1; diff --git a/UserTools/LoadGeometry/LoadGeometry.cpp b/UserTools/LoadGeometry/LoadGeometry.cpp index b93355c1b..8974e989c 100644 --- a/UserTools/LoadGeometry/LoadGeometry.cpp +++ b/UserTools/LoadGeometry/LoadGeometry.cpp @@ -20,6 +20,7 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ m_variables.Get("FACCMRDGeoFile", fFACCMRDGeoFile); m_variables.Get("TankPMTGeoFile", fTankPMTGeoFile); m_variables.Get("TankPMTGainFile", fTankPMTGainFile); + m_variables.Get("TankPMTTimingOffsetFile", fTankPMTTimingOffsetFile); m_variables.Get("AuxiliaryChannelFile", fAuxChannelFile); m_variables.Get("LAPPDGeoFile", fLAPPDGeoFile); m_variables.Get("DetectorGeoFile", fDetectorGeoFile); @@ -58,6 +59,12 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ return false; } + if(!this->FileExists(fTankPMTTimingOffsetFile)){ + Log("LoadGeometry Tool: File for Tank PMT Timing offsets does not exist!",v_error,verbosity); + if (verbosity > 0) std::cout << "Filepath was... " << fTankPMTTimingOffsetFile << std::endl; + return false; + } + if(!this->FileExists(fAuxChannelFile)){ Log("LoadGeometry Tool: File for Auxiliary Channels does not exist!",v_error,verbosity); if (verbosity > 0) std::cout << "Filepath was... " << fAuxChannelFile << std::endl; @@ -69,6 +76,8 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ MRDChannelNumToCrateSpaceMap = new std::map>; 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; @@ -87,6 +96,9 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ //Load TankPMT charge to PE conversion this->LoadTankPMTGains(); + //Load TankPMT timing offsets + this->LoadTankPMTTimingOffsets(); + //Load auxiliary and spare channels this->LoadAuxiliaryChannels(); @@ -100,6 +112,8 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ m_data->CStore.Set("TankPMTCrateSpaceToChannelNumMap",TankPMTCrateSpaceToChannelNumMap); 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); @@ -618,6 +632,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 @@ -631,7 +661,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}; @@ -906,3 +937,27 @@ 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 + 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; + 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 9f666ed10..8841ad510 100644 --- a/UserTools/LoadGeometry/LoadGeometry.h +++ b/UserTools/LoadGeometry/LoadGeometry.h @@ -36,6 +36,7 @@ class LoadGeometry: public Tool { bool ParseAuxChannelDataEntry(std::vector SpecLine, std::vector AuxChannelLegendEntries); void LoadTankPMTGains(); + void LoadTankPMTTimingOffsets(); Geometry* AnnieGeometry; @@ -49,6 +50,7 @@ class LoadGeometry: public Tool { std::string fFACCMRDGeoFile; std::string fTankPMTGeoFile; std::string fTankPMTGainFile; + std::string fTankPMTTimingOffsetFile; std::string fAuxChannelFile; std::string fLAPPDGeoFile; std::string fDetectorGeoFile; @@ -66,6 +68,8 @@ class LoadGeometry: public Tool { std::map>* ChannelNumToTankPMTCrateSpaceMap; 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 bbddfcde9..d99d04225 100644 --- a/UserTools/LoadRawData/LoadRawData.cpp +++ b/UserTools/LoadRawData/LoadRawData.cpp @@ -63,7 +63,7 @@ bool LoadRawData::Initialise(std::string configfile, DataModel &data){ MRDEntriesCompleted = false; TrigEntriesCompleted = false; LAPPDEntriesCompleted = false; - + JumpBecauseLAPPD = false; LAPPDPaused = 0; m_data->CStore.Set("FileProcessingComplete",false); @@ -78,7 +78,7 @@ bool LoadRawData::Execute(){ //Check if we've reached the end of our file list or single file bool ProcessingComplete = false; if(FileCompleted) ProcessingComplete = this->InitializeNewFile(); - if(ProcessingComplete) { + if(BuildType != "LAPPDMerging" && ProcessingComplete) { Log("LoadRawData Tool: All files have been processed.",v_message,verbosity); m_data->CStore.Set("FileProcessingComplete",true); return true; @@ -113,6 +113,9 @@ bool LoadRawData::Execute(){ std::cout << "LoadRawData tool ERROR: no files in file list to parse! Stopping toolchain" << std::endl; m_data->vars.Set("StopLoop",1); return false; + if(BuildType == "LAPPDMerging" && FileCompleted){ + return true; + } } if(FileCompleted || CurrentFile=="NONE"){ Log("LoadRawData tool: Moving to next file.",v_message,verbosity); @@ -127,10 +130,63 @@ bool LoadRawData::Execute(){ this->LoadPMTMRDData(); this->LoadTriggerData(); this->LoadLAPPDData(); + + { + // 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; + if (std::regex_search(CurrentFile, match, runNumber_regex) && match.size() > 1) + { + int runNumber = std::stoi(match.str(1)); + if(verbosity > 0) std::cout << "runNumber: " << runNumber << std::endl; + m_data->CStore.Set("runNumber", runNumber); + } + else + { + std::cout << "runNumber not found" << std::endl; + m_data->CStore.Set("rawFileNumber", -9999); + } + + if (std::regex_search(CurrentFile, match, subrunNUmber_regex) && match.size() > 1) + { + int subrunNumber = std::stoi(match.str(1)); + if(verbosity > 0) std::cout << "subrunNumber: " << subrunNumber << std::endl; + m_data->CStore.Set("subrunNumber", subrunNumber); + } + else + { + std::cout << "subrunNumber not found" << std::endl; + m_data->CStore.Set("subrunNumber", -9999); + } + + if (std::regex_search(CurrentFile, match, rawFileNumber_regex) && match.size() > 1) + { + int rawFileNumber = std::stoi(match.str(1)); + if(verbosity > 0) std::cout << "rawFileNumber: " << rawFileNumber << std::endl; + m_data->CStore.Set("rawFileNumber", rawFileNumber); + } + else + { + std::cout << "rawFileNumber not found" << std::endl; + m_data->CStore.Set("runNumber", -9999); + } + } + } else { if(verbosity>v_message) std::cout << "LoadRawDataTool: continuing file " << OrganizedFileList.at(FileNum) << std::endl; } FileCompleted = false; + if (JumpBecauseLAPPD){ + //sometimes the LAPPD data in raw data file may have a very large entry number due to 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; + JumpBecauseLAPPD = false; + cout<<"LoadRawData: Jumping to next file because there is something wrong about LAPPD data"< tanktotalentries && BuildType != "MRD"){ + if (mrdtotalentries > tanktotalentries && BuildType != "MRD" && BuildType != "MRDAndCTC"){ std::cout << "LoadRawData tool ERROR: More MRD entries than VME entries! Stopping toolchain" << std::endl; m_data->vars.Set("StopLoop",1); } @@ -258,16 +314,15 @@ bool LoadRawData::Execute(){ Log("LoadRawData Tool: ALL LAPPD ENTRIES COLLECTED.",v_debug, verbosity); LAPPDEntriesCompleted = true; LAPPDPaused = true; - if(TrigEntryNum < trigtotalentries) CTCPaused = false; + //if(TrigEntryNum < trigtotalentries) CTCPaused = false; + //when using 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 (LAPPDEntryNum == lappdtotalentries){ - Log("LoadRawData Tool: ALL LAPPD ENTRIES COLLECTED.",v_debug, verbosity); + if (lappdtotalentries < 0){ //some times the lappd broken data can give negative value LAPPDEntriesCompleted = true; - LAPPDPaused = true; - if(TankEntryNum < tanktotalentries) TankPaused = false; - if(MRDEntryNum < mrdtotalentries) MRDPaused = false; } m_data->CStore.Set("PauseTankDecoding",TankPaused); @@ -281,6 +336,10 @@ bool LoadRawData::Execute(){ //Set if the raw data file has been completed if (TankEntriesCompleted && BuildType == "Tank") FileCompleted = true; if (MRDEntriesCompleted && BuildType == "MRD") FileCompleted = true; + if (LAPPDEntriesCompleted && BuildType == "LAPPD") FileCompleted = true; + if ((LAPPDEntriesCompleted && TrigEntriesCompleted) && (BuildType == "LAPPDAndCTC" || BuildType == "CTCAndLAPPD")) FileCompleted = true; + if (lappdtotalentries == 0 && (BuildType == "LAPPD" || BuildType == "LAPPDMerging" || BuildType == "LAPPDAndCTC" || BuildType == "CTCAndLAPPD")) FileCompleted = true; + if (LAPPDEntriesCompleted && BuildType == "LAPPDMerging") FileCompleted = true; if ((TankEntriesCompleted && MRDEntriesCompleted) && (BuildType == "TankAndMRD")) FileCompleted = true; if ((TrigEntriesCompleted && TankEntriesCompleted) && (BuildType == "TankAndCTC")) FileCompleted = true; if ((TrigEntriesCompleted && MRDEntriesCompleted) && (BuildType == "MRDAndCTC")) FileCompleted = true; @@ -396,12 +455,28 @@ void LoadRawData::LoadTriggerData(){ void LoadRawData::LoadLAPPDData(){ Log("LoadRawData Tool: Accessing LAPPD Data in raw data",v_message,verbosity); - if((BuildType == "TankAndMRDAndCTCAndLAPPD")){ + if(BuildType == "TankAndMRDAndCTCAndLAPPD" || BuildType == "LAPPD" || BuildType == "LAPPDMerging" || BuildType == "LAPPDAndCTC" || BuildType == "CTCAndLAPPD"){ Log("LoadRawData Tool: Accessing LAPPD Data in raw data",v_message,verbosity); try{ RawData->Get("LAPPDData",*LAPPDData); LAPPDData->Header->Get("TotalEntries",lappdtotalentries); - if(verbosity>3) LAPPDData->Print(false); + if(verbosity>3) { + Log("LoadRawData Tool: LAPPDData printing",v_message,verbosity); + LAPPDData->Print(false); + Log("LoadRawData Tool: LAPPDData Header printing",v_message,verbosity); + LAPPDData->Header->Print(false); + } + if(lappdtotalentries < 0){ //some time the lappd broken data can give negative value + lappdtotalentries = 0; + LAPPDEntriesCompleted = true; + }else{ + Log("LoadRawData Tool: in loading, LAPPDData has "+std::to_string(lappdtotalentries)+" entries",v_message,verbosity); + if(lappdtotalentries > 100000){ + Log("LoadRawData Tool: LAPPDData has "+std::to_string(lappdtotalentries)+" entries. This is a large wrong number of entries. May be a corrupted file.",v_warning,verbosity); + JumpBecauseLAPPD = true; //if loading LAPPD data and the LAPPD data in this file was broken, jump to next file + return; + } + } } catch (...) { Log("LoadRawData: Did not find LAPPDData in raw data file! (Maybe corrupted!!!) Don't process LAPPDData",0,0); lappdtotalentries=0; @@ -516,8 +591,16 @@ TrigData->Close(); TrigData->Delete(); delete TrigData; TrigData = new BoostStor EndOfProcessing = true; } if(Mode == "FileList" && FileNum == int(OrganizedFileList.size())){ + //In Merging LAPPD with event building data, loading LAPPD from raw data will be finished before finishing merging + //so set the FileNum == to >=, and minus 1 to not disturb other code relate to FileNum Log("LoadRawData Tool: Full file list parsed. Ending toolchain after this loop.",v_message, verbosity); - m_data->vars.Set("StopLoop",1); + m_data->CStore.Set("LAPPDanaData",false); //while use loading raw data to merge LAPPD data with other data, after reading all LAPPD data, set later LAPPDReadIn to stop. + if(BuildType != "LAPPDMerging"){ + m_data->vars.Set("StopLoop",1); + }else{ + Log("LoadRawData Tool: in LAPPD Merging mode, do not stop tool chain",v_message, verbosity); + FileNum -= 1; + } EndOfProcessing = true; } //No need to stop the loop in continous mode @@ -529,7 +612,7 @@ TrigData->Close(); TrigData->Delete(); delete TrigData; TrigData = new BoostStor } void LoadRawData::GetNextDataEntries(){ - std::cout <<"BuildType: "<0) std::cout <<"BuildType: "<GetEntry(LAPPDEntryNum); - LAPPDData->Get("LAPPDData",*Ldata); - m_data->CStore.Set("LAPPDData",Ldata,true); - LAPPDEntryNum+=1; - } - } - //Get next TrigData Entry - if((BuildType == "TankAndMRDAndCTC" || BuildType == "TankAndCTC" || BuildType == "MRDAndCTC" || BuildType == "CTC" || BuildType == "TankAndMRDAndCTCAndLAPPD") && !TrigEntriesCompleted && !CTCPaused){ + if((BuildType == "TankAndMRDAndCTC" || BuildType == "TankAndCTC" || BuildType == "MRDAndCTC" || BuildType == "CTC" || BuildType == "TankAndMRDAndCTCAndLAPPD" || BuildType == "CTCAndLAPPD" || BuildType == "LAPPDAndCTC") && !TrigEntriesCompleted && !CTCPaused){ Log("LoadRawData Tool: Procesing TrigData Entry "+to_string(TrigEntryNum)+"/"+to_string(trigtotalentries),v_debug, verbosity); if (storetrigoverlap && TrigEntryNum == 0 && extract_part != 0){ TrigData->GetEntry(TrigEntryNum); @@ -613,12 +685,15 @@ void LoadRawData::GetNextDataEntries(){ } //Get next LAPPDData Entry - if(BuildType == "LAPPD" || BuildType == "TankAndLAPPD" || BuildType == "MRDAndLAPPD" || BuildType == "TankAndMRDAndLAPPD" || BuildType == "TankAndMRDAndLAPPDAndCTC"){ - Log("LoadRawData Tool: Processing LAPPDData Entry "+to_string(LAPPDEntryNum)+"/"+to_string(lappdtotalentries),v_debug,verbosity); - LAPPDData->GetEntry(LAPPDEntryNum); - LAPPDData->Get("LAPPDData", *Ldata); - m_data->CStore.Set("LAPPDData", Ldata); - LAPPDEntryNum+=1; + if(BuildType == "LAPPD" || BuildType == "TankAndLAPPD" || BuildType == "MRDAndLAPPD" || BuildType == "TankAndMRDAndLAPPD" || BuildType == "TankAndMRDAndCTCAndLAPPD" || BuildType == "CTCAndLAPPD" || BuildType == "LAPPDMerging" || BuildType == "LAPPDAndCTC" ){ + if(!LAPPDPaused && !LAPPDEntriesCompleted){ + Log("LoadRawData Tool: Processing LAPPDData Entry "+to_string(LAPPDEntryNum)+"/"+to_string(lappdtotalentries),v_debug,verbosity); + LAPPDData->GetEntry(LAPPDEntryNum); + LAPPDData->Get("LAPPDData", *Ldata); + m_data->CStore.Set("LAPPDData", Ldata); + m_data->CStore.Set("LAPPDanaData",true); + LAPPDEntryNum+=1; + } } return; } diff --git a/UserTools/LoadRawData/LoadRawData.h b/UserTools/LoadRawData/LoadRawData.h index 95204fed2..54308c5e0 100644 --- a/UserTools/LoadRawData/LoadRawData.h +++ b/UserTools/LoadRawData/LoadRawData.h @@ -63,6 +63,7 @@ class LoadRawData: public Tool { bool TrigEntriesCompleted; bool LAPPDEntriesCompleted; bool FileCompleted; + bool JumpBecauseLAPPD; int TankEntryNum = 0; int MRDEntryNum = 0; int TrigEntryNum = 0; diff --git a/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.cpp b/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.cpp new file mode 100644 index 000000000..5af826f50 --- /dev/null +++ b/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.cpp @@ -0,0 +1,1522 @@ +/* vim:set noexpandtab tabstop=2 wrap */ +#include "LoadReweightGenieEvent.h" + +#include "TChain.h" +#include "TFile.h" +#include "TVector3.h" +#include "TLorentzVector.h" + +#include "MRDspecs.hh" +//using namespace genie; +//using namespace genie::constants; +//using namespace genie::flux; + +// *********************** +// GENIE ERROR HANDLING +#include +#include +// global jump buffer for signal recovery +static jmp_buf genie_jump_buffer; + +// signal handler function +void handle_genie_abort(int sig) { + if (sig == SIGABRT) { + longjmp(genie_jump_buffer, 1); + } +} +// *********************** + +/* +GENIE INPUTS +============ + +Robert's Files +-------------- +1) gnumi files: /pnfs/annie/persistent/flux/bnb/bnb_annie_0000.root +- these are on parallel with the gsimple files but store less information +- they feed into genie and are used to generate neutrino rays + +Zarko's Files +------------- +There are 2 stages of files: +1) ReDecay files: /annie/data/flux/redecay_bnb/beammc_annie_0000.root +- these are the topmost BNB flux files, containing all BNB simulation errors +- these files are used to generate gsimple ntuples +- events in this ntuple have weighting according to systematic errors on generation parameters +- there are 1000 weights for 7 systematics: +K+, K-, K0, pi+, pi-, beamunisims, and total (product of other 6) +beamunisims contains systematics due to horn current miscal, skin depth, variations in total, qe and inelastic cross section of pi on Be and Al +- you can use these to do systematic studies + +2) gsimple files: /pnfs/annie/persistent/flux/gsimple_bnb/gsimple_beammc_annie_0000.root +- the flux rom the re-decay files is propagated to a detector window +- weights are stripped as genie cannot propagate them +- the resulting gsimple files describe neutrino rays that feed into genie +- zarko's above files have a window of 20x20m, 20m upstream of detector origin at (0,0,100.35m) + (the origin of detector coordinate system in beam coordinate system) + +GENIE OUTPUTS +============= + +Robert's Files +-------------- +Genie 2.8.6 GNTP files: /pnfs/annie/persistent/users/vfischer/genie/BNB_Water_10k_22-05-17/gntp.1000.ghep.root +- these files contain genie::NtpMCEventRecord objects that contain details of the neutrino event +- input event information is passed into a genie::flux::GNuMIFluxPassThroughInfo object + +James's Files +------------- +Genie 3.0.4.ub3 GNTP files: /pnfs/annie/persistent/simulation/genie3/G1810a0211a/standard/tank/gntp.1000.ghep.root +- these files contain genie::NtpMCEventRecord objects to describe details of the neutrino event +- input event information is passed to a genie::flux::GSimpleNtpEntry and genie::flux::GSimpleNtpNuMI object +*/ + +LoadReweightGenieEvent::LoadReweightGenieEvent():Tool(){} + +Position TVector3ToPositionRW(TVector3 tvecin); +Direction TVector3ToDirectionRW(TVector3 tvecin); +FourVector TLorentzVectorToFourVectorRW(TLorentzVector tlvecin); + +bool LoadReweightGenieEvent::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 + ///////////////////////////////////////////////////////////////// + + + int evoffset; + + m_variables.Get("verbosity",verbosity); + m_variables.Get("FluxVersion",fluxver); // flux version: 0=rhatcher files, 1=zarko files + m_variables.Get("FileDir",filedir); + m_variables.Get("FilePattern",filepattern); + m_variables.Get("ManualFileMatching",manualmatch); + m_variables.Get("EventOffset",evoffset); + m_variables.Get("FileEvents",fileevents); + m_variables.Get("OnGrid",on_grid); + m_variables.Get("genie_module_label",fGenieModuleWeight); + + + // create a store for holding Genie information to pass to downstream Tools + // will be a single entry BoostStore containing a vector of single entry BoostStores + geniestore = new BoostStore(true,0); // enable type-checking, BoostStore type binary + m_data->Stores.emplace("GenieInfo",geniestore); + + // Open the flux files + /////////////////////// + Log("Tool LoadReweightGenieEvent: Opening TChain",v_debug,verbosity); + loadwcsimsource = (filepattern=="LoadWCSimTool"); + if(not loadwcsimsource && not manualmatch){ + // construct a new TChain and add all the files at once + // this is for use of looking at stand alone Genie file, with no WCSim + std::string inputfiles = filedir+"/"+filepattern; + tchainentrynum=0; + flux = new TChain("gtree"); + int numbytes = flux->Add(inputfiles.c_str()); + Log("Tool LoadReweightGenieEvent: Read "+to_string(numbytes)+" bytes loading TChain "+inputfiles,v_debug,verbosity); + Log("Tool LoadReweightGenieEvent: Genie TChain has "+to_string(flux->GetEntries())+" entries",v_message,verbosity); + SetBranchAddresses(); + tchainentrynum = evoffset; + Log("LoadReweightGenieEvent tool: # of flux entries: "+std::to_string(flux->GetEntries()),v_message,verbosity); + } + + if(manualmatch){ + // Manually create path to matching GENIE File for WCSim file + std::string wcsimfile; + m_data->Stores.at("ANNIEEvent")->Get("MCFile",wcsimfile); + //Strip WCSim file name of its prefix path + std::string wcsim_prefix = "wcsim_0."; + wcsimfile.erase(0,wcsimfile.find(wcsim_prefix)+wcsim_prefix.length()); + wcsimfile.erase(wcsimfile.find(".root"),wcsimfile.find(".root")+5); + std::string wcsimev = wcsimfile; + wcsimfile.erase(wcsimfile.find("."),wcsimfile.length()); + wcsimev.erase(0,wcsimev.find(".")+1); + + std::cout <<"wcsimfile: "<Get("gtree"); + SetBranchAddresses(); + tchainentrynum = wcsimevnumber*fileevents; + } + + m_variables.Get("weight_functions_xsec",weight_options); + std::string central_values; + m_variables.Get("genie_central_values",central_values); + + //parse and tokenize array of strings that list weights + std::stringstream weights_in(weight_options); + std::string temp; + while (weights_in.good()){ + std::getline(weights_in, temp, ','); + weight_names.push_back(temp); + } + + //Parse Genie central values configuration + std::stringstream CV_in(central_values); + std::string temp_token; + float val; + vector CV_knob_names; + vector CV_knob_value; + while (CV_in.good()){ + std::getline(CV_in, temp, '|'); + std::stringstream token_in(temp); + while (token_in.good()){ + std::getline(token_in, temp_token, ':'); + CV_knob_names.push_back(temp_token); + std::getline(token_in, temp_token, ':'); + std::stringstream to_val(temp_token); + to_val >> val; + CV_knob_value.push_back(val); + } + } + // Map to store the CV knob settings + std::map< genie::rew::GSyst_t, float > gsyst_to_cv_map; + genie::rew::GSyst_t temp_knob; + for (unsigned int i = 0; i < CV_knob_names.size(); i++ ) { + if ( valid_knob_name(CV_knob_names[i], temp_knob) ) { + if ( gsyst_to_cv_map.count( temp_knob ) ) { + std::cout << "ERROR: Duplicate central values were configured for the " << CV_knob_names[i] << " GENIE knob."; + } + gsyst_to_cv_map[ temp_knob ] = CV_knob_value[i]; + } + } + + reweightVector.resize(weight_names.size()); + + //intitalize variables for Genie weight configurations + std::string parameter, tokens, keys, values; + std::string temp_pars, temp_sigs, temp_mins, temp_maxs; + float sig; + vector str_par; + vector str_sig; + vector str_min; + vector str_max; + //Get each parameter + for(unsigned int i = 0; i < weight_names.size(); i++){ + xsecevwgh::xsecconfig xs_configs; + m_variables.Get(weight_names[i],parameter); + //Separate key-value pairs from each other + std::stringstream param_in(parameter); + while (param_in.good()){ + std::getline(param_in, tokens, '|'); + //Separate and save values from keys + std::stringstream pair_in(tokens); + while (pair_in.good()){ + std::getline(pair_in, keys, ':'); + std::getline(pair_in, values, ':'); + if(keys == "parameter_list"){ + values.erase(0,1);//strip out brackets + values.erase(values.size()-1); + std::stringstream pars_in(values); + while(pars_in.good()){ + std::getline(pars_in, temp_pars, ',');//separate tokens + temp_pars.erase(0,1);//strip out quotations + temp_pars.erase(temp_pars.size()-1); + xs_configs.parameter_list.push_back(temp_pars); + } + } + else if(keys == "parameter_sigma"){ + values.erase(0,1);//strip out brackets + values.erase(values.size()-1); + std::stringstream sigs_in(values); + while(sigs_in.good()){ + std::getline(sigs_in, temp_sigs, ',');//separate tokens + std::stringstream to_float(temp_sigs); + to_float >> sig; + xs_configs.parameter_sigma.push_back(sig); + } + } + else if(keys == "parameter_min"){ + values.erase(0,1);//strip out brackets + values.erase(values.size()-1); + std::stringstream mins_in(values); + while(mins_in.good()){ + std::getline(mins_in, temp_mins, ',');//separate tokens + std::stringstream to_float(temp_mins); + to_float >> sig; + xs_configs.parameter_min.push_back(sig); + } + } + else if(keys == "parameter_max"){ + values.erase(0,1);//strip out brackets + values.erase(values.size()-1); + std::stringstream maxs_in(values); + while(maxs_in.good()){ + std::getline(maxs_in, temp_maxs, ',');//separate tokens + std::stringstream to_float(temp_maxs); + to_float >> sig; + xs_configs.parameter_max.push_back(sig); + } + } + else if(keys == "type") xs_configs.type = values; + else if(keys == "mode") xs_configs.mode = values; + else if(keys == "random_seed"){ + std::stringstream to_int(values); + int rand; + to_int >> rand; + xs_configs.random_seed = rand; + } + else if(keys == "number_of_multisims"){ + std::stringstream to_int(values); + int nom; + to_int >> nom; + xs_configs.number_of_multisims = nom; + } + } + } + + vector< genie::rew::GSyst_t > knobs_to_use; + for ( const auto& knob_name : xs_configs.parameter_list ) { + if ( valid_knob_name(knob_name, temp_knob) ) knobs_to_use.push_back( temp_knob ); + } + + // We need to add all of the tuned CV knobs to the list when configuring + // the weight calculators and checking for incompatibilities. Maybe all of + // the systematic variation knobs are fine to use together, but they also + // need to be compatible with the tuned CV. To perform the check, copy the + // list of systematic variation knobs to use and add all the CV knobs that + // aren't already present. + std::vector< genie::rew::GSyst_t > all_knobs_vec = knobs_to_use; + for ( const auto& pair : gsyst_to_cv_map ) { + genie::rew::GSyst_t cv_knob = pair.first; + auto begin = all_knobs_vec.cbegin(); + auto end = all_knobs_vec.cend(); + if ( !std::count(begin, end, cv_knob) ) all_knobs_vec.push_back( cv_knob ); + } + + // Check that the enabled knobs (both systematic variations and knobs used + // for the CV tune) are all compatible with each other. The std::map + // returned by this function call provides information needed to fine-tune + // the configuration of the GENIE weight calculators. + std::map< std::string, int > modes_to_use = this->CheckForIncompatibleSystematics( all_knobs_vec ); + + //check for same number of parameters as sigmas ========================= + + if(xs_configs.mode == "pm1sigma" || xs_configs.mode == "minmax") xs_configs.number_of_multisims = 2; + else if(xs_configs.mode == "central_value") xs_configs.number_of_multisims = 1; + + CLHEP::HepJamesRandom engine(xs_configs.random_seed); + + reweightVector[i].resize(xs_configs.number_of_multisims); + + // Set up the weight calculators for each universe + for ( auto& rwght : reweightVector[i] ) { + this->SetupWeightCalculators( rwght, modes_to_use ); + } + + //prepare sigmas + size_t num_usable_knobs = knobs_to_use.size(); + std::vector< std::vector > reweightingSigmas( num_usable_knobs ); + + for ( size_t k = 0; k < num_usable_knobs; ++k ) { + reweightingSigmas[k].resize( xs_configs.number_of_multisims ); + genie::rew::GSyst_t current_knob = knobs_to_use.at( k ); + for ( size_t u = 0; u < xs_configs.number_of_multisims; ++u ) { + if (xs_configs.mode == "multisim") { + reweightingSigmas[k][u] = xs_configs.parameter_sigma[k] * CLHEP::RandGaussQ::shoot(&engine, 0., 1.); + } + else if (xs_configs.mode == "pm1sigma") { + reweightingSigmas[k][u] = ( u == 0 ? 1. : -1. ); // u == 0 => 1; u == 1 => -1 if pm1sigma is specified + } + else if (xs_configs.mode == "minmax") { + reweightingSigmas[k][u] = ( u == 0 ? xs_configs.parameter_max.at(k) : xs_configs.parameter_min.at(k) ); // u == 0 => max; u == 1 => min if minmax is specified + } + else if (xs_configs.mode == "central_value") { + reweightingSigmas[k][u] = 0.; // we'll correct for a modified CV below if needed + } + else { + reweightingSigmas[k][u] = xs_configs.parameter_sigma[k]; + } + std::cout << "Set sigma for the " << genie::rew::GSyst::AsString( current_knob ) << " knob in universe #" << u << ". sigma = " << reweightingSigmas[k][u] << std::endl; + // Add an offset if the central value for the current knob has been + // configured (and is thus probably nonzero). Ignore this for minmax mode + // (the limits should be chosen to respect a modified central value) + if (xs_configs.mode != "minmax") { + auto iter = gsyst_to_cv_map.find( current_knob ); + if ( iter != gsyst_to_cv_map.end() ) { + reweightingSigmas[k][u] += iter->second; + std::cout << "CV offset added to the " << genie::rew::GSyst::AsString( current_knob ) << " knob. New sigma for universe #" << u << " is " << reweightingSigmas[k][u] << std::endl; + } + } + } + } + + // Set of FHiCL weight calculator labels for which the tuned CV will be + // ignored. If the name of the weight calculator doesn't appear in this set, + // then variation weights will be thrown around the tuned CV. + std::set< std::string > CALC_NAMES_THAT_IGNORE_TUNED_CV = { "RootinoFix" }; + + // Don't adjust knobs to reflect the tuned CV if this weight calculator + // should ignore those (as determined by whether it has one of the special + // FHiCL names) + if ( !CALC_NAMES_THAT_IGNORE_TUNED_CV.count(weight_names[i]) ) { + // Add tuned CV knobs which have not been tweaked, and set them to their + // modified central values. This ensures that weights are always thrown + // around the modified CV. + for ( const auto& pair : gsyst_to_cv_map ) { + genie::rew::GSyst_t cv_knob = pair.first; + float cv_value = pair.second; + // If the current tuned CV knob is not present in the list of tweaked + // knobs, then add it to the list with its tuned central value + if ( !std::count(knobs_to_use.cbegin(), knobs_to_use.cend(), cv_knob) ) { + ++num_usable_knobs; + knobs_to_use.push_back( cv_knob ); + // The tuned CV knob will take the same value in every universe + reweightingSigmas.emplace_back(std::vector(xs_configs.number_of_multisims, cv_value) ); + } + } + } + + // TODO: deal with parameters that have a priori bounds (e.g., FFCCQEVec, + // which can vary on the interval [0,1]) + // Set up the knob values for each universe + for ( size_t u = 0; u < reweightVector[i].size(); ++u ) { + auto& rwght = reweightVector[i].at( u ); + genie::rew::GSystSet& syst = rwght.Systematics(); + for ( unsigned int k = 0; k < knobs_to_use.size(); ++k ) { + genie::rew::GSyst_t knob = knobs_to_use.at( k ); + float twk_dial_value = reweightingSigmas.at( k ).at( u ); + syst.Set( knob, twk_dial_value ); + } // loop over tweaked knobs + rwght.Reconfigure(); + rwght.Print(); + } // loop over universes + } + + return true; + +} + +bool LoadReweightGenieEvent::Execute(){ + + if(loadwcsimsource && !manualmatch){ + // retrieve the genie file and entry number from the LoadWCSim tool + std::string inputfiles; + get_ok = m_data->CStore.Get("GenieFile",inputfiles); + if(!get_ok){ + if(verbosity) std::cout << "Tool LoadReweightGenieEvent: Failed to find GenieFile in CStore" << std::endl; + return false; + } + if(filedir!="NA"){ + std::string genie_prefix = "gntp."; + inputfiles.erase(0, inputfiles.find(genie_prefix)); + inputfiles = filedir+"/"+inputfiles; + if(verbosity) std::cout << "Tool LoadReweightGenieEvent: Loading Genie file: " << inputfiles << std::endl; + } + get_ok = m_data->CStore.Get("GenieEntry",tchainentrynum); + if(!get_ok){ + Log("Tool LoadReweightGenieEvent: Failed to find GenieEntry in CStore",v_error,verbosity); + return false; + } + std::string curfname = ((curf) ? curf->GetName() : ""); + // check if this is a new file + if(inputfiles!=curfname){ + // we need to load the new file + if(flux) flux->ResetBranchAddresses(); + if(curf) curf->Close(); + Log("Tool LoadReweightGenieEvent: Loading new file "+inputfiles,v_debug,verbosity); + curf=TFile::Open(inputfiles.c_str()); + flux=(TChain*)curf->Get("gtree"); + SetBranchAddresses(); + } + } + + Log("Tool LoadReweightGenieEvent: Loading tchain entry "+to_string(tchainentrynum),v_message,verbosity); + local_entry = flux->LoadTree(tchainentrynum); + Log("Tool LoadReweightGenieEvent: localentry is "+to_string(local_entry),v_debug,verbosity); + if(local_entry<0||local_entry!=tchainentrynum){ + Log("Tool LoadReweightGenieEvent: Reached end of file, returning",v_message,verbosity); + m_data->vars.Set("StopLoop",1); + return true; + } + flux->GetEntry(local_entry); + curf = flux->GetCurrentFile(); + if(curf!=curflast || curflast==nullptr){ + TString curftstring = curf->GetName(); + currentfilestring = std::string(curftstring.Data()); + curflast=curf; + Log("Tool LoadReweightGenieEvent: Opening new file \""+currentfilestring+"\"",v_debug,verbosity); + } + if (manualmatch){ + uint16_t MCTriggernum; + m_data->Stores["ANNIEEvent"]->Get("MCTriggernum",MCTriggernum); + if (MCTriggernum != 0){ + m_data->CStore.Set("NewGENIEEntry",false); + return true; //Don't evaluate new GENIE event for dealyed WCSim triggers + } else { + m_data->CStore.Set("NewGENIEEntry",true); + } + } + + // Expand out the neutrino event info + // ======================================================= + + // header only contains the event number + genie::NtpMCRecHeader hdr = genieintx->hdr; + unsigned int genie_event_num = hdr.ievent; + + // all neutrino intx details are in the event record + genie::EventRecord* gevtRec = genieintx->event; + + if(fluxver==0){ + // FLUXVER 0 - genie::flux::GNuMIFluxPassThroughInfo + // ================================================= + // extract the target intx details from the GNuMIFluxPassThroughInfo object + parentpdg = gnumipassthruentry->ptype; + parentdecaymode = gnumipassthruentry->ndecay; + parentdecayvtx_x = gnumipassthruentry->vx; + parentdecayvtx_y = gnumipassthruentry->vy; + parentdecayvtx_z = gnumipassthruentry->vz; + parentdecaymom_x = gnumipassthruentry->pdpx; + parentdecaymom_y = gnumipassthruentry->pdpy; + parentdecaymom_z = gnumipassthruentry->pdpz; + parentprodmom_x = gnumipassthruentry->ppdxdz; + parentprodmom_y = gnumipassthruentry->ppdydz; + parentprodmom_z = gnumipassthruentry->pppz; + parentprodmedium = gnumipassthruentry->ppmedium; //Seems to be 0 all the time? Not registered in the materials table, numbers start at 5... + parentpdgattgtexit = gnumipassthruentry->tptype; + parenttgtexitmom_x = gnumipassthruentry->tpx; + parenttgtexitmom_y = gnumipassthruentry->tpy; + parenttgtexitmom_z = gnumipassthruentry->tpz; + pcodes = gnumipassthruentry->pcodes; //pcodes = 0--> GEANT particle codes, 1--> converted PDG particle codes + + // convenience type conversions + parentdecayvtx = Position(parentdecayvtx_x,parentdecayvtx_y,parentdecayvtx_z); + parentdecaymom = Direction(parentdecaymom_x,parentdecaymom_y,parentdecaymom_z); + parentprodmom = Direction(parentprodmom_x,parentprodmom_y,parentprodmom_z); + parenttgtexitmom = Direction(parenttgtexitmom_x,parenttgtexitmom_y,parenttgtexitmom_z); + //parenttypestring = (fluxstage==0) ? GnumiToString(parentpdg) : PdgToString(parentpdg); + //parenttypestringattgtexit = (fluxstage==0) ? + parenttypestring = (pcodes==0) ? GnumiToString(parentpdg) : PdgToString(parentpdg); + parenttypestringattgtexit = (pcodes==0) ? + GnumiToString(parentpdgattgtexit) : PdgToString(parentpdgattgtexit); + parentdecaystring = DecayTypeToString(parentdecaymode); + parentprodmediumstring = MediumToString(parentprodmedium); + + } else { + // FLUXVER 1 - genie::flux::GSimpleNtpEntry + // ======================================== + // extract the target intx details from the GSimpleNtpNuMI object + Log("Tool LoadReweightGenieEvent: Retrieving interaction info from GSimpleNtpNuMI object",v_debug,verbosity); + parentpdg = gsimplenumientry->ptype; + parentdecaymode = gsimplenumientry->ndecay; + parentdecayvtx_x = gsimplenumientry->vx; + parentdecayvtx_y = gsimplenumientry->vy; + parentdecayvtx_z = gsimplenumientry->vz; + parentdecaymom_x = gsimplenumientry->pdpx; + parentdecaymom_y = gsimplenumientry->pdpy; + parentdecaymom_z = gsimplenumientry->pdpz; + parentprodmom_x = gsimplenumientry->pppx/gsimplenumientry->pppz; // ??? is this ppdxdz? + parentprodmom_y = gsimplenumientry->pppy/gsimplenumientry->pppz; + parentprodmom_z = gsimplenumientry->pppz; + parentprodmedium = gsimplenumientry->ppmedium; + parentpdgattgtexit = gsimplenumientry->tptype; + parenttgtexitmom_x = gsimplenumientry->tpx; + parenttgtexitmom_y = gsimplenumientry->tpy; + parenttgtexitmom_z = gsimplenumientry->tpz; + + fluxentryno = gsimplenumientry->entryno; + fluxrun = gsimplenumientry->run; + double flux_energy = gsimpleentry->E; + fluxnenergyn = flux_energy; + fluxnenergyf = flux_energy; + fluxevtno = gsimplenumientry->evtno; + fluxntype = gsimpleentry->pdg; + fluxnimpwt = gsimpleentry->wgt; + + // convenience type conversions + parentdecayvtx = Position(parentdecayvtx_x,parentdecayvtx_y,parentdecayvtx_z); + parentdecaymom = Direction(parentdecaymom_x,parentdecaymom_y,parentdecaymom_z); + parentprodmom = Direction(parentprodmom_x,parentprodmom_y,parentprodmom_z); + parenttgtexitmom = Direction(parenttgtexitmom_x,parenttgtexitmom_y,parenttgtexitmom_z); + parenttypestring = PdgToString(parentpdg); + parenttypestringattgtexit = PdgToString(parentpdgattgtexit); + parentdecaystring = DecayTypeToString(parentdecaymode); + parentprodmediumstring = MediumToString(parentprodmedium); + + } + + // neutrino interaction info + genie::Interaction* genieint = gevtRec->Summary(); + //cout<<"scraping interaction info"<v_debug)); + + // retrieve info from the struct + IsQuasiElastic=thegenieinfo.eventtypes.at("IsQuasiElastic"); + IsResonant=thegenieinfo.eventtypes.at("IsResonant"); + IsDeepInelastic=thegenieinfo.eventtypes.at("IsDeepInelastic"); + IsCoherent=thegenieinfo.eventtypes.at("IsCoherent"); + IsDiffractive=thegenieinfo.eventtypes.at("IsDiffractive"); + IsInverseMuDecay=thegenieinfo.eventtypes.at("IsInverseMuDecay"); + IsIMDAnnihilation=thegenieinfo.eventtypes.at("IsIMDAnnihilation"); + IsSingleKaon=thegenieinfo.eventtypes.at("IsSingleKaon"); + IsNuElectronElastic=thegenieinfo.eventtypes.at("IsNuElectronElastic"); + IsEM=thegenieinfo.eventtypes.at("IsEM"); + IsWeakCC=thegenieinfo.eventtypes.at("IsWeakCC"); + IsWeakNC=thegenieinfo.eventtypes.at("IsWeakNC"); + IsMEC=thegenieinfo.eventtypes.at("IsMEC"); + interactiontypestring=thegenieinfo.interactiontypestring; + neutcode=thegenieinfo.neutinteractioncode; // currently disabled to prevent excessive verbosity + + eventq2=thegenieinfo.Q2; //MeV + eventw2=thegenieinfo.W2; //MeV + eventbj_x = thegenieinfo.x; + eventelastic_y = thegenieinfo.y; + TrueTargetZ = thegenieinfo.targetnucleusZ; + eventEnu=thegenieinfo.probeenergy; //MeV + eventPnu=thegenieinfo.probethreemomentum; //MeV + neutrinopdg=thegenieinfo.probepdg; + muonenergy=thegenieinfo.fsleptonenergy; //MeV + muonangle=thegenieinfo.fslangle; + + nuIntxVtx_X=thegenieinfo.Intx_x; // cm + nuIntxVtx_Y=thegenieinfo.Intx_y; // cm + nuIntxVtx_Z=thegenieinfo.Intx_z; // cm + nuIntxVtx_T=thegenieinfo.Intx_t; // ns + // check in tank + if( ( sqrt( pow(nuIntxVtx_X, 2) + pow(nuIntxVtx_Z-MRDSpecs::tank_start-MRDSpecs::tank_radius,2) ) + < MRDSpecs::tank_radius ) && + ( abs(nuIntxVtx_Y-MRDSpecs::tank_yoffset) < MRDSpecs::tank_halfheight) ){ + isintank=true; + } else { isintank=false; } + // check in fiducial volume + if( isintank && + ( sqrt (pow(nuIntxVtx_X, 2) + pow(nuIntxVtx_Z-MRDSpecs::tank_start-MRDSpecs::tank_radius,2)) + < MRDSpecs::fidcutradius ) && + ( abs(nuIntxVtx_Y-MRDSpecs::tank_yoffset) < MRDSpecs::fidcuty ) && + ( (nuIntxVtx_Z-MRDSpecs::tank_start-MRDSpecs::tank_radius) < MRDSpecs::fidcutz) ){ + isinfiducialvol=true; + } else { isinfiducialvol = false; } + + fsleptonname = std::string(thegenieinfo.fsleptonname); + fsleptonenergy = thegenieinfo.fsleptonenergy; //MeV + fsleptonpdg = thegenieinfo.fsleptonpdg; + fsleptonm = thegenieinfo.fsleptonm; //MeV + fsleptonmomentum = thegenieinfo.fsleptonmomentum; //MeV +// fsleptonmomentumdir = thegenieinfo.fsleptonmomentumdir; + fsleptonvtx = thegenieinfo.fsleptonvtx; // cm + fsleptont = thegenieinfo.fsleptont; // ns + + // this data does not appear to be populated... + // Edit: Maybe due to the numbers for the exclusive tag being evaluated before Final State Interactions + // Compare e.g. documentation here: https://internal.dunescience.org/doxygen/classgenie_1_1XclsTag.html + /* + numfsprotons = thegenieinfo.numfsprotons = genieint->ExclTag().NProtons(); + numfsneutrons = thegenieinfo.numfsneutrons = genieint->ExclTag().NNeutrons(); + numfspi0 = thegenieinfo.numfspi0 = genieint->ExclTag().NPi0(); + numfspiplus = thegenieinfo.numfspiplus = genieint->ExclTag().NPiPlus(); + numfspiminus = thegenieinfo.numfspiminus = genieint->ExclTag().NPiMinus(); + */ + //The following is more cumbersome, but seems to work (we count the number of final state particles by hand) + numfsprotons = thegenieinfo.numfsprotons; + numfsneutrons = thegenieinfo.numfsneutrons; + numfspi0 = thegenieinfo.numfspi0; + numfspiplus= thegenieinfo.numfspiplus; + numfspipluscher = thegenieinfo.numfspipluscher; + numfspiminus = thegenieinfo.numfspiminus; + numfspiminuscher = thegenieinfo.numfspiminuscher; + numfskplus = thegenieinfo.numfskplus; + numfskpluscher = thegenieinfo.numfskpluscher; + numfskminus = thegenieinfo.numfskminus; + numfskminuscher = thegenieinfo.numfskminuscher; + + // Expand out the neutrino event and flux info + // ======================================================= + // header only contains the event number + + //assume 1 neutrino per event, no pile-up + std::vector> weights(weight_names.size()); + std::map> reweights; + + for(unsigned int i = 0; i < weight_names.size(); i++){ + unsigned int num_knobs = reweightVector[i].size(); + + genie::Kinematics* kine_ptr = genieint->KinePtr(); + // Final lepton mass + double ml = genieint->FSPrimLepton()->Mass(); + // Final lepton 4-momentum + const TLorentzVector& p4l = kine_ptr->FSLeptonP4(); + // Final lepton kinetic energy + double Tl = p4l.E() - ml; + // Final lepton scattering cosine + double ctl = p4l.CosTheta(); + + kine_ptr->SetKV( kKVTl, Tl ); + kine_ptr->SetKV( kKVctl, ctl ); + + // All right, the event record is fully ready. Now ask the GReWeight + // objects to compute the weights. + weights[i].resize( num_knobs ); + for (unsigned int k = 0; k < num_knobs; ++k ) { + + // ERROR HANDLING FROM GENIE + // ************************************ + // register the signal handler + void (*prev_handler)(int) = std::signal(SIGABRT, handle_genie_abort); + + // set the jump point + if (setjmp(genie_jump_buffer) == 0) { + // default (if no error is present) + weights[i][k] = reweightVector[i].at(k).CalcWeight( *gevtRec ); + } else { + // recovery path: if GENIE calls abort(), we land here + std::cerr << "!!! GENIE Aborted on event " << tchainentrynum + << " (Knob: " << k << "). Skipping and using weight 1.0." << std::endl; + weights[i][k] = 1.0; + } + + // restore the original handler + std::signal(SIGABRT, prev_handler); + // ************************************ + + } + + reweights.insert(std::pair>(weight_names[i],weights[i])); + } + + Log("Tool LoadReweightGenieEvent: Passing information to the GenieEvent store",v_debug,verbosity); + // Update the Store with all the current event information + // ======================================================= + geniestore->Set("file",currentfilestring); + geniestore->Set("fluxver",fluxver); + geniestore->Set("evtnum",tchainentrynum); + geniestore->Set("ParentPdg",parentpdg); + geniestore->Set("ParentTypeString",parenttypestring); + geniestore->Set("ParentDecayMode",parentdecaymode); + geniestore->Set("ParentDecayString",parentdecaystring); + geniestore->Set("ParentDecayVtx",parentdecayvtx); + geniestore->Set("ParentDecayVtx_X",parentdecayvtx_x); + geniestore->Set("ParentDecayVtx_Y",parentdecayvtx_y); + geniestore->Set("ParentDecayVtx_Z",parentdecayvtx_z); + geniestore->Set("ParentDecayMom",parentdecaymom); + geniestore->Set("ParentDecayMom_X",parentdecaymom_x); + geniestore->Set("ParentDecayMom_Y",parentdecaymom_y); + geniestore->Set("ParentDecayMom_Z",parentdecaymom_z); + geniestore->Set("ParentProdMom",parentprodmom); + geniestore->Set("ParentProdMom_X",parentprodmom_x); + geniestore->Set("ParentProdMom_Y",parentprodmom_y); + geniestore->Set("ParentProdMom_Z",parentprodmom_z); + geniestore->Set("ParentProdMedium",parentprodmedium); + geniestore->Set("ParentProdMediumString",parentprodmediumstring); + geniestore->Set("ParentPdgAtTgtExit",parentpdgattgtexit); + geniestore->Set("ParentTypeAtTgtExitString",parenttypestringattgtexit); + geniestore->Set("ParentTgtExitMom",parenttgtexitmom); + geniestore->Set("ParentTgtExitMom_X",parenttgtexitmom_x); + geniestore->Set("ParentTgtExitMom_Y",parenttgtexitmom_y); + geniestore->Set("ParentTgtExitMom_Z",parenttgtexitmom_z); + geniestore->Set("ParentEntryNo",fluxentryno); + geniestore->Set("ParentRunNo",fluxrun); + geniestore->Set("ParentNEnergyN",fluxnenergyn); + geniestore->Set("ParentNEnergyF",fluxnenergyf); + geniestore->Set("ParentEventNo",fluxevtno); + geniestore->Set("ParentNType",fluxntype); + geniestore->Set("ParentWgt",fluxnimpwt); + + geniestore->Set("IsQuasiElastic",IsQuasiElastic); + geniestore->Set("IsResonant",IsResonant); + geniestore->Set("IsDeepInelastic",IsDeepInelastic); + geniestore->Set("IsCoherent",IsCoherent); + geniestore->Set("IsDiffractive",IsDiffractive); + geniestore->Set("IsInverseMuDecay",IsInverseMuDecay); + geniestore->Set("IsIMDAnnihilation",IsIMDAnnihilation); + geniestore->Set("IsSingleKaon",IsSingleKaon); + geniestore->Set("IsNuElectronElastic",IsNuElectronElastic); + geniestore->Set("IsEM",IsEM); + geniestore->Set("IsWeakCC",IsWeakCC); + geniestore->Set("IsWeakNC",IsWeakNC); + geniestore->Set("IsMEC",IsMEC); + geniestore->Set("InteractionTypeString",interactiontypestring); + geniestore->Set("NeutCode",neutcode); + geniestore->Set("NuIntxVtx_X",nuIntxVtx_X); + geniestore->Set("NuIntxVtx_Y",nuIntxVtx_Y); + geniestore->Set("NuIntxVtx_Z",nuIntxVtx_Z); + geniestore->Set("NuIntxVtx_T",nuIntxVtx_T); + geniestore->Set("NuVtxInTank",isintank); + geniestore->Set("NuVtxInFidVol",isinfiducialvol); + geniestore->Set("EventQ2",eventq2); + geniestore->Set("EventW2",eventw2); + geniestore->Set("EventBjx",eventbj_x); + geniestore->Set("Eventy",eventelastic_y); + geniestore->Set("TargetZ",TrueTargetZ); + geniestore->Set("Eventq0",eventq0); + geniestore->Set("Eventq3",eventq3); + geniestore->Set("pdg_vector", pdgs); + geniestore->Set("Pmag_vector",Pmag); + geniestore->Set("NeutrinoEnergy",eventEnu); + geniestore->Set("NeutrinoMomentum",eventPnu); + geniestore->Set("NeutrinoPDG",neutrinopdg); + geniestore->Set("MuonEnergy",muonenergy); + geniestore->Set("MuonAngle",muonangle); + geniestore->Set("FSLeptonName",fsleptonname); + geniestore->Set("FSLeptonPdg",fsleptonpdg); + geniestore->Set("FSLeptonMass",fsleptonm); + geniestore->Set("FSLeptonEnergy",fsleptonenergy); + geniestore->Set("FSLeptonMomentum",fsleptonmomentum); +// geniestore->Set("FSLeptonMomentumDir",fsleptonmomentumdir); + geniestore->Set("FSLeptonVertex",fsleptonvtx); + geniestore->Set("FSLeptonTime",fsleptont); + geniestore->Set("NumFSProtons",numfsprotons); + geniestore->Set("NumFSNeutrons",numfsneutrons); + geniestore->Set("NumFSPi0",numfspi0); + geniestore->Set("NumFSPiPlus",numfspiplus); + geniestore->Set("NumFSPiPlusCher",numfspipluscher); + geniestore->Set("NumFSPiMinus",numfspiminus); + geniestore->Set("NumFSPiMinusCher",numfspiminuscher); + geniestore->Set("NumFSKPlus",numfskplus); + geniestore->Set("NumFSKPlusCher",numfskpluscher); + geniestore->Set("NumFSKMinus",numfskminus); + geniestore->Set("NumFSKMinusCher",numfskminuscher); + geniestore->Set("GenieInfo",thegenieinfo); + m_data->Stores.at("ANNIEEvent")->Set("xsec_weights",reweights); + //geniestore->Set("TheGenieInfoPtr",&thegenieinfo,false); + //intptr_t thegenieinfoptr = reinterpret_cast(&thegenieinfo); + //m_data->CStore.Set("TheGenieInfoPtr2",thegenieinfoptr); + tchainentrynum++; + + Log("Tool LoadReweightGenieEvent: Clearing genieintx",v_debug,verbosity); + genieintx->Clear(); // REQUIRED TO PREVENT MEMORY LEAK + pdgs.clear(); + Pmag.clear(); + + Log("Tool LoadReweightGenieEvent: done",v_debug,verbosity); + return true; +} + +bool LoadReweightGenieEvent::Finalise(){ + + if(flux){ + flux->ResetBranchAddresses(); + if (not loadwcsimsource) delete flux; //only need to delete in case it was created with "new" --> only in not-loadwcsimource case. Otherwise double-free corruption + flux=nullptr; + } + Log("Tool LoadReweightGenieEvent: exiting",v_debug,verbosity); + return true; +} + + +void LoadReweightGenieEvent::SetBranchAddresses(){ + Log("Tool LoadReweightGenieEvent: Setting branch addresses",v_debug,verbosity); + // neutrino event information + flux->SetBranchAddress("gmcrec",&genieintx); + flux->GetBranch("gmcrec")->SetAutoDelete(kTRUE); + // input (BNB intx) event information + if(fluxver==0){ // rhatcher files + flux->SetBranchAddress("flux",&gnumipassthruentry); + flux->GetBranch("flux")->SetAutoDelete(kTRUE); + } else { // zarko files + // flux->Print(); + flux->SetBranchAddress("numi",&gsimplenumientry); + flux->GetBranch("numi")->SetAutoDelete(kTRUE); + flux->SetBranchAddress("simple",&gsimpleentry); + flux->GetBranch("simple")->SetAutoDelete(kTRUE); + flux->SetBranchAddress("aux",&gsimpleauxinfo); + flux->GetBranch("aux")->SetAutoDelete(kTRUE); + } +} + +void LoadReweightGenieEvent::GetGenieEntryInfo(genie::EventRecord* gevtRec, genie::Interaction* genieint, GenieInfo &thegenieinfo, bool printneutrinoevent){ + // process information: + /*TString*/ thegenieinfo.procinfostring = genieint->ProcInfo().AsString(); + /*TString*/ thegenieinfo.scatteringtypestring = genieint->ProcInfo().ScatteringTypeAsString(); + /*TString*/ thegenieinfo.interactiontypestring = genieint->ProcInfo().InteractionTypeAsString(); + thegenieinfo.eventtypes.at("IsQuasiElastic") = genieint->ProcInfo().IsQuasiElastic(); + thegenieinfo.eventtypes.at("IsResonant") = genieint->ProcInfo().IsResonant(); + thegenieinfo.eventtypes.at("IsDeepInelastic") = genieint->ProcInfo().IsDeepInelastic(); + thegenieinfo.eventtypes.at("IsCoherent") = genieint->ProcInfo().IsCoherent(); + thegenieinfo.eventtypes.at("IsDiffractive") = genieint->ProcInfo().IsDiffractive(); + thegenieinfo.eventtypes.at("IsInverseMuDecay") = genieint->ProcInfo().IsInverseMuDecay(); + thegenieinfo.eventtypes.at("IsIMDAnnihilation") = genieint->ProcInfo().IsIMDAnnihilation(); + thegenieinfo.eventtypes.at("IsSingleKaon") = genieint->ProcInfo().IsSingleKaon(); + thegenieinfo.eventtypes.at("IsNuElectronElastic") = genieint->ProcInfo().IsNuElectronElastic(); + thegenieinfo.eventtypes.at("IsEM") = genieint->ProcInfo().IsEM(); + thegenieinfo.eventtypes.at("IsWeakCC") = genieint->ProcInfo().IsWeakCC(); + thegenieinfo.eventtypes.at("IsWeakNC") = genieint->ProcInfo().IsWeakNC(); + thegenieinfo.eventtypes.at("IsMEC") = genieint->ProcInfo().IsMEC(); + /* + getting the neut reaction code results in the printing of a bunch of surplus info, e.g: +1501283211 NOTICE GHepUtils : [n] : Current event is RES or DIS with W<2 +1501283211 NOTICE GHepUtils : [n] : Num of primary particles: + p = 1, n = 0, pi+ = 0, pi- = 1, pi0 = 0, eta = 0, K+ = 0, K- = 0, K0 = 0, Lambda's = 0, gamma's = 0 + if we could redirect and capture this (rather than printing it to stdout) it might actually be useful, + as extracting number of other hadrons doesn't work! but for now, just turn it off to reduce verbosity. + */ + /*Int_t*/ //thegenieinfo.neutinteractioncode = genie::utils::ghep::NeutReactionCode(gevtRec); + /*Int_t*/ thegenieinfo.nuanceinteractioncode = genie::utils::ghep::NuanceReactionCode(gevtRec); + TLorentzVector* IntxVtx = gevtRec->Vertex(); + /*Double_t*/ thegenieinfo.Intx_x = IntxVtx->X() * 100.; // same info as nuvtx in g4dirt file + /*Double_t*/ thegenieinfo.Intx_y = IntxVtx->Y() * 100.; // GENIE uses meters + /*Double_t*/ thegenieinfo.Intx_z = IntxVtx->Z() * 100.; // GENIE uses meters + /*Double_t*/ thegenieinfo.Intx_t = IntxVtx->T() * 1000000000.; // GENIE uses seconds + + // neutrino information: + /*Double_t*/ thegenieinfo.probeenergy = genieint->InitState().ProbeE(genie::kRfLab)*1000.; //GeV->MeV + /*Int_t*/ thegenieinfo.probepdg = genieint->InitState().Probe()->PdgCode(); + /*TString*/ thegenieinfo.probepartname = genieint->InitState().Probe()->GetName(); + TLorentzVector* probemomentum = new TLorentzVector(gevtRec->Probe()->P4()->Px()*1000., + gevtRec->Probe()->P4()->Py()*1000., + gevtRec->Probe()->P4()->Pz()*1000., + gevtRec->Probe()->P4()->E()*1000.); //GeV->MeV + if(probemomentum->E()!=thegenieinfo.probeenergy){ + logmessage = "LoadReweightGenieEvent Tool: WARNING, Probe energy from probemomentum.E and ProbeE differ!"; + logmessage+= "ProbeE = "+to_string(thegenieinfo.probeenergy); + logmessage+= ", ProbeMomentum[0] = "+to_string(probemomentum->E()); + Log(logmessage,v_warning,verbosity); + } + /*Direction*/ thegenieinfo.probethreemomentum = TVector3ToDirectionRW(probemomentum->Vect()); + /*TVector3*/ thegenieinfo.probemomentumdir = thegenieinfo.probethreemomentum.Unit(); + /*Double_t*/ thegenieinfo.probeanglex = + TMath::ATan(thegenieinfo.probethreemomentum.X()/thegenieinfo.probethreemomentum.Z()); + /*Double_t*/ thegenieinfo.probeangley = + TMath::ATan(thegenieinfo.probethreemomentum.Y()/thegenieinfo.probethreemomentum.Z()); + /*Double_t*/ thegenieinfo.probeangle = TMath::Max(thegenieinfo.probeanglex,thegenieinfo.probeangley); + // n.b. genieint->InitState().Probe != gevtRec->Probe() + + // target nucleon: + genie::GHepParticle* targetnucleon = gevtRec->HitNucleon(); + /*int*/ thegenieinfo.targetnucleonpdg = genieint->InitState().Tgt().HitNucPdg(); + /*TString*/ thegenieinfo.targetnucleonname=""; + if ( genie::pdg::IsNeutronOrProton(thegenieinfo.targetnucleonpdg) ) { + TParticlePDG * p = genie::PDGLibrary::Instance()->Find(thegenieinfo.targetnucleonpdg); + thegenieinfo.targetnucleonname = p->GetName(); + } else { + thegenieinfo.targetnucleonname = std::to_string(thegenieinfo.targetnucleonpdg); + } + /*TVector3*/ thegenieinfo.targetnucleonthreemomentum=Direction(0.,0.,0.); + /*Double_t*/ thegenieinfo.targetnucleonenergy=0.; + if(targetnucleon){ + TLorentzVector* targetnucleonmomentum = new TLorentzVector(targetnucleon->P4()->Px()*1000., + targetnucleon->P4()->Py()*1000., + targetnucleon->P4()->Pz()*1000., + targetnucleon->P4()->E()*1000.); //GeV->MeV + thegenieinfo.targetnucleonthreemomentum = TVector3ToDirectionRW(targetnucleonmomentum->Vect()); + thegenieinfo.targetnucleonenergy = targetnucleonmomentum->Energy(); + } + + // target nucleus: + /*Int_t*/ thegenieinfo.targetnucleuspdg = genieint->InitState().Tgt().Pdg(); + TParticlePDG* targetnucleus = + genie::PDGLibrary::Instance()->Find(thegenieinfo.targetnucleuspdg); + /*TString*/ thegenieinfo.targetnucleusname = "unknown"; + if(targetnucleus){ thegenieinfo.targetnucleusname = targetnucleus->GetName(); } + /*Int_t*/ thegenieinfo.targetnucleusZ = genieint->InitState().Tgt().Z(); + /*Int_t*/ thegenieinfo.targetnucleusA = genieint->InitState().Tgt().A(); + + // remnant nucleus: + int remnucpos = gevtRec->RemnantNucleusPosition(); + /*TString*/ thegenieinfo.remnantnucleusname="n/a"; + /*Double_t*/ thegenieinfo.remnantnucleusenergy=-1.; + if(remnucpos>-1){ + thegenieinfo.remnantnucleusname = gevtRec->Particle(remnucpos)->Name(); + thegenieinfo.remnantnucleusenergy = gevtRec->Particle(remnucpos)->Energy()*1000.; //GeV->MeV + } + + // final state lepton: + int fsleppos = gevtRec->FinalStatePrimaryLeptonPosition(); + /*TString*/ thegenieinfo.fsleptonname="n/a"; + /*Double_t*/ thegenieinfo.fsleptonenergy=-1.; + /*Int_t*/ thegenieinfo.fsleptonpdg=-1; + /*Double_t*/ thegenieinfo.fsleptonm=-1.; + /*Double_t*/ thegenieinfo.fsleptont=-1.; + /*TVector3*/ thegenieinfo.fsleptonmomentum=Direction(0.,0.,0.); + /*TVector3*/ thegenieinfo.fsleptonmomentumdir=Direction(0.,0.,0.); + /*TVector3*/ thegenieinfo.fsleptonvtx=Position(0.,0.,0.); + if(fsleppos>-1){ + thegenieinfo.fsleptonname = gevtRec->Particle(fsleppos)->Name(); + thegenieinfo.fsleptonenergy = gevtRec->Particle(fsleppos)->Energy()*1000.; //GeV->MeV + thegenieinfo.fsleptonpdg = gevtRec->Particle(fsleppos)->Pdg(); + thegenieinfo.fsleptonm = gevtRec->Particle(fsleppos)->Mass()*1000.; //GeV->MeV + TLorentzVector* fsleptonmom = new TLorentzVector(gevtRec->Particle(fsleppos)->Px()*1000., + gevtRec->Particle(fsleppos)->Py()*1000., + gevtRec->Particle(fsleppos)->Pz()*1000., + gevtRec->Particle(fsleppos)->E()*1000.); //GeV->MeV + thegenieinfo.fsleptonmomentum = TVector3ToDirectionRW(fsleptonmom->Vect()); + thegenieinfo.fsleptonmomentumdir = thegenieinfo.fsleptonmomentum.Unit(); + thegenieinfo.fsleptonvtx = Position(gevtRec->Particle(fsleppos)->Vx()*100., + gevtRec->Particle(fsleppos)->Vy()*100., + gevtRec->Particle(fsleppos)->Vz()*100.); //meters -> cm + thegenieinfo.fsleptont = gevtRec->Particle(fsleppos)->Vt()*1000000000.; //sec -> ns + } + + // other remnants: TEMP FIX: this information is NOT being correctly read in + // Edit: Maybe due to the numbers for the exclusive tag being evaluated before Final State Interactions + // Compare e.g. documentation here: https://internal.dunescience.org/doxygen/classgenie_1_1XclsTag.html + /*Int_t*/ //thegenieinfo.numfsprotons = genieint->ExclTag().NProtons(); + /*Int_t*/ //thegenieinfo.numfsneutrons = genieint->ExclTag().NNeutrons(); + /*Int_t*/ //thegenieinfo.numfspi0 = genieint->ExclTag().NPi0(); + /*Int_t*/ //thegenieinfo.numfspiplus = genieint->ExclTag().NPiPlus(); + /*Int_t*/ //thegenieinfo.numfspiminus = genieint->ExclTag().NPiMinus(); + + //The following is more cumbersome, but seems to work (we count the number of final state particles by hand) + thegenieinfo.numfsprotons = 0; + thegenieinfo.numfsneutrons = 0; + thegenieinfo.numfspi0 = 0; + thegenieinfo.numfspiplus= 0; + thegenieinfo.numfspipluscher = 0; + thegenieinfo.numfspiminus = 0; + thegenieinfo.numfspiminuscher = 0; + thegenieinfo.numfskplus = 0; + thegenieinfo.numfskpluscher = 0; + thegenieinfo.numfskminus = 0; + thegenieinfo.numfskminuscher = 0; + + TObjArrayIter iter(gevtRec); + genie::GHepParticle * p = 0; + + //Loop over event particles + /// Kolanoski, Hermann, and Norbert Wermes, Particle Detectors: Fundamentals and Applications + // (Oxford, 2020; online edn, Oxford Academic, 17 Sept. 2020), + /// https://doi.org/10.1093/oso/9780198858362.001.0001, accessed 15 Aug. 2024. + // Using the equation P_th = Mass[GeV/C] / sqrt(n^2-1), where "n" is the index for refraction + /// rounding to 2 SigFigs + double wclimit_pion = 0.16; //water Cherenkov momentum threshold GeV + double wclimit_proton = 1.1; //water Cherenkov momentum threshold GeV + double wclimit_kaon = .56; //water Cherenkov momentum threshold GeV **THe the charged and neutral kaons thresholds are the same to 2 sigfigs + while ((p = dynamic_cast(iter.Next()))) { + + int pdgc = p->Pdg(); + double pipx = p->Px(); + double pipy = p->Py(); + double pipz = p->Pz(); + double P_mag = std::sqrt(pipx*pipx + pipy*pipy + pipz*pipz); + int status = p->Status(); + double wclimit = 0.160; //water Cherenkov momentum threshold GeV + + if (status != genie::kIStStableFinalState) continue; + + if (pdgc == genie::kPdgNeutron) thegenieinfo.numfsneutrons++; + else if (pdgc == genie::kPdgProton) { + thegenieinfo.numfsprotons++; + if (P_mag > wclimit_proton) { + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + } + } + else if (pdgc == genie::kPdgPiP) { + thegenieinfo.numfspiplus++; + if (P_mag > wclimit_pion){ + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfspipluscher++; + } + } + else if (pdgc == genie::kPdgPiM) { + thegenieinfo.numfspiminus++; + if (P_mag > wclimit_pion) { + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfspiminuscher++; + } + } + else if (pdgc == genie::kPdgPi0) thegenieinfo.numfspi0++; + else if (pdgc == genie::kPdgKP) { + thegenieinfo.numfskplus++; + if (P_mag > wclimit_kaon) { + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfskpluscher++; + } + } + else if (pdgc == genie::kPdgKM) { + thegenieinfo.numfskminus++; + if (P_mag > wclimit_kaon){ + pdgs.push_back(pdgc); + Pmag.push_back(P_mag); + thegenieinfo.numfskminuscher++; + } + } + } + + // kinematic information + Double_t NucleonM = genie::constants::kNucleonMass*1000.; //GeV->MeV + // Calculate kinematic variables "as an experimentalist would measure them; + // neglecting fermi momentum and off-shellness of bound nucleons" + TLorentzVector* k1 = new TLorentzVector(gevtRec->Probe()->P4()->Px()*1000., + gevtRec->Probe()->P4()->Py()*1000., + gevtRec->Probe()->P4()->Pz()*1000., + gevtRec->Probe()->P4()->E()*1000.); //GeV->MeV + TLorentzVector* k2 = new TLorentzVector(gevtRec->FinalStatePrimaryLepton()->P4()->Px()*1000., + gevtRec->FinalStatePrimaryLepton()->P4()->Py()*1000., + gevtRec->FinalStatePrimaryLepton()->P4()->Pz()*1000., + gevtRec->FinalStatePrimaryLepton()->P4()->E()*1000.); //GeV->MeV + /*Double_t*/ thegenieinfo.costhfsl = TMath::Cos( k2->Vect().Angle(k1->Vect()) ); + /*Double_t*/ thegenieinfo.fslangle = k2->Vect().Angle(k1->Vect()); + // q=k1-k2, 4-p transfer + /*TLorentzVector*/ thegenieinfo.q = TLorentzVectorToFourVectorRW((*k1)-(*k2)); +// /*Double_t*/ thegenieinfo.Q2 = genieint->Kine().Q2(); // not set in our GENIE files! + double q0 = (gevtRec->Probe()->P4()->E()*1000.) - (gevtRec->FinalStatePrimaryLepton()->P4()->E()*1000.); + double px1 = (gevtRec->FinalStatePrimaryLepton()->P4()->Px()*1000.) - (gevtRec->Probe()->P4()->Px()*1000.); + double py1 = (gevtRec->FinalStatePrimaryLepton()->P4()->Py()*1000.) - (gevtRec->Probe()->P4()->Py()*1000.); + double pz1 = (gevtRec->FinalStatePrimaryLepton()->P4()->Pz()*1000.) - (gevtRec->Probe()->P4()->Pz()*1000.); + double q3 = sqrt(px1*px1+py1*py1+pz1*pz1); + thegenieinfo.Q2 = q3*q3 - q0*q0; // MeV + eventq0 = q0; + eventq3 = q3; + // momemtum transfer + /*Double_t*/ thegenieinfo.Q2 = -1 * thegenieinfo.q.M2(); + // E transfer to the nucleus + /*Double_t*/ thegenieinfo.Etransf = (targetnucleon) ? thegenieinfo.q.E() : -1; + // Bjorken x + /*Double_t*/ thegenieinfo.x = + (targetnucleon) ? 0.5*thegenieinfo.Q2/(NucleonM*thegenieinfo.Etransf) : -1; + // Inelasticity, y = q*P1/k1*P1 + /*Double_t*/ thegenieinfo.y = + (targetnucleon) ? thegenieinfo.Etransf/k1->Energy() : -1; + // Hadronic Invariant mass ^ 2 + /*Double_t*/ thegenieinfo.W2 = + (targetnucleon) ? (NucleonM*NucleonM + 2*NucleonM*thegenieinfo.Etransf - thegenieinfo.Q2) : -1; + + if(printneutrinoevent){ + cout<<"This was a "<< thegenieinfo.procinfostring <<" (neut code "<-1){ + cout<<"producing a "<-1){ + cout<<" and a "<* LoadReweightGenieEvent::GenerateGnumiMap(){ + if(gnumicodetoname.size()!=0) return &gnumicodetoname; + gnumicodetoname.emplace(14 ,"Proton"); + gnumicodetoname.emplace(15 ,"Anti Proton"); + gnumicodetoname.emplace(3 ,"Electron"); + gnumicodetoname.emplace(2 ,"Positron"); + gnumicodetoname.emplace(53 ,"Electron Neutrino"); + gnumicodetoname.emplace(52 ,"Anti Electron Neutrino"); + gnumicodetoname.emplace(1 ,"Photon"); + gnumicodetoname.emplace(13 ,"Neutron"); + gnumicodetoname.emplace(25 ,"Anti Neutron"); + gnumicodetoname.emplace(5 ,"Muon+"); + gnumicodetoname.emplace(6 ,"Muon-"); + gnumicodetoname.emplace(10 ,"Kaonlong"); + gnumicodetoname.emplace(8 ,"Pion+"); + gnumicodetoname.emplace(9 ,"Pion-"); + gnumicodetoname.emplace(11 ,"Kaon+"); + gnumicodetoname.emplace(12 ,"Kaon-"); + gnumicodetoname.emplace(18 ,"Lambda"); + gnumicodetoname.emplace(26 ,"Antilambda"); + gnumicodetoname.emplace(16 ,"Kaonshort"); + gnumicodetoname.emplace(21 ,"Sigma-"); + gnumicodetoname.emplace(19 ,"Sigma+"); + gnumicodetoname.emplace(20 ,"Sigma0"); + gnumicodetoname.emplace(7 ,"Pion0"); + gnumicodetoname.emplace(99,"Kaon0"); // gnumi particle code for Kaon0 and Antikaon0 + gnumicodetoname.emplace(98,"Antikaon0"); // are both listed as "10 & 16" ... + gnumicodetoname.emplace(56 ,"Muon Neutrino"); + gnumicodetoname.emplace(55 ,"Anti Muon Neutrino"); + gnumicodetoname.emplace(27 ,"Anti Sigma-"); + gnumicodetoname.emplace(28 ,"Anti Sigma0"); + gnumicodetoname.emplace(29 ,"Anti Sigma+"); + gnumicodetoname.emplace(22 ,"Xsi0"); + gnumicodetoname.emplace(30 ,"Anti Xsi0"); + gnumicodetoname.emplace(23 ,"Xsi-"); + gnumicodetoname.emplace(31 ,"Xsi+"); + gnumicodetoname.emplace(24 ,"Omega-"); + gnumicodetoname.emplace(32 ,"Omega+"); + gnumicodetoname.emplace(33 ,"Tau+"); + gnumicodetoname.emplace(34 ,"Tau-"); + return &gnumicodetoname; +} + +std::map* LoadReweightGenieEvent::GeneratePdgMap(){ + if(pdgcodetoname.size()!=0) return &pdgcodetoname; + pdgcodetoname.emplace(2212,"Proton"); + pdgcodetoname.emplace(-2212,"Anti Proton"); + pdgcodetoname.emplace(11,"Electron"); + pdgcodetoname.emplace(-11,"Positron"); + pdgcodetoname.emplace(12,"Electron Neutrino"); + pdgcodetoname.emplace(-12,"Anti Electron Neutrino"); + pdgcodetoname.emplace(22,"Gamma"); + pdgcodetoname.emplace(2112,"Neutron"); + pdgcodetoname.emplace(-2112,"Anti Neutron"); + pdgcodetoname.emplace(-13,"Muon+"); + pdgcodetoname.emplace(13,"Muon-"); + pdgcodetoname.emplace(130,"Kaonlong"); + pdgcodetoname.emplace(211,"Pion+"); + pdgcodetoname.emplace(-211,"Pion-"); + pdgcodetoname.emplace(321,"Kaon+"); + pdgcodetoname.emplace(-321,"Kaon-"); + pdgcodetoname.emplace(3122,"Lambda"); + pdgcodetoname.emplace(-3122,"Antilambda"); + pdgcodetoname.emplace(310,"Kaonshort"); + pdgcodetoname.emplace(3112,"Sigma-"); + pdgcodetoname.emplace(3222,"Sigma+"); + pdgcodetoname.emplace(3212,"Sigma0"); + pdgcodetoname.emplace(111,"Pion0"); + pdgcodetoname.emplace(311,"Kaon0"); + pdgcodetoname.emplace(-311,"Antikaon0"); + pdgcodetoname.emplace(14,"Muon Neutrino"); + pdgcodetoname.emplace(-14,"Anti Muon Neutrino"); + pdgcodetoname.emplace(-3222,"Anti Sigma-"); + pdgcodetoname.emplace(-3212,"Anti Sigma0"); + pdgcodetoname.emplace(-3112,"Anti Sigma+"); + pdgcodetoname.emplace(3322,"Xsi0"); + pdgcodetoname.emplace(-3322,"Anti Xsi0"); + pdgcodetoname.emplace(3312,"Xsi-"); + pdgcodetoname.emplace(-3312,"Xsi+"); + pdgcodetoname.emplace(3334,"Omega-"); + pdgcodetoname.emplace(-3334,"Omega+"); + pdgcodetoname.emplace(-15,"Tau+"); + pdgcodetoname.emplace(15,"Tau-"); + pdgcodetoname.emplace(100,"OpticalPhoton"); + pdgcodetoname.emplace(3328,"Alpha"); + pdgcodetoname.emplace(3329,"Deuteron"); + pdgcodetoname.emplace(3330,"Triton"); + pdgcodetoname.emplace(3351,"Li7"); + pdgcodetoname.emplace(3331,"C10"); + pdgcodetoname.emplace(3345,"B11"); + pdgcodetoname.emplace(3332,"C12"); + pdgcodetoname.emplace(3350,"C13"); + pdgcodetoname.emplace(3349,"N13"); + pdgcodetoname.emplace(3340,"N14"); + pdgcodetoname.emplace(3333,"N15"); + pdgcodetoname.emplace(3334,"N16"); + pdgcodetoname.emplace(3335,"O16"); + pdgcodetoname.emplace(3346,"Al27"); + pdgcodetoname.emplace(3341,"Fe54"); + pdgcodetoname.emplace(3348,"Mn54"); + pdgcodetoname.emplace(3342,"Mn55"); + pdgcodetoname.emplace(3352,"Mn56"); + pdgcodetoname.emplace(3343,"Fe56"); + pdgcodetoname.emplace(3344,"Fe57"); + pdgcodetoname.emplace(3347,"Fe58"); + pdgcodetoname.emplace(3353,"Eu154"); + pdgcodetoname.emplace(3336,"Gd158"); + pdgcodetoname.emplace(3337,"Gd156"); + pdgcodetoname.emplace(3338,"Gd157"); + pdgcodetoname.emplace(3339,"Gd155"); + return &pdgcodetoname; +} + +std::map* LoadReweightGenieEvent::GenerateDecayMap(){ + if(decaymap.size()!=0) return &decaymap; + decaymap.emplace(1,"K0L -> nue, pi-, e+"); //→ + decaymap.emplace(2,"K0L -> nuebar, pi+, e-"); + decaymap.emplace(3,"K0L -> numu, pi-, mu+"); + decaymap.emplace(4,"K0L -> numubar, pi+, mu-"); + decaymap.emplace(5,"K+ -> numu, mu+"); + decaymap.emplace(6,"K+ -> nue, pi0, e+"); + decaymap.emplace(7,"K+ -> numu, pi0, mu+"); + decaymap.emplace(8,"K- -> numubar, mu-"); + decaymap.emplace(9,"K- -> nuebar, pi0, e-"); + decaymap.emplace(10,"K- -> numubar, pi0, mu-"); + decaymap.emplace(11,"mu+ -> numubar, nue, e+"); + decaymap.emplace(12,"mu- -> numu, nuebar, e-"); + decaymap.emplace(13,"pi+ -> numu, mu+"); + decaymap.emplace(14,"pi- -> numubar, mu-"); + return &decaymap; +} + +std::map* LoadReweightGenieEvent::GenerateMediumMap(){ + //gnumi material mapping taken from table 10 in https://minos-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=6316&filename=flugg_doc.pdf&version=10 + if(mediummap.size()!=0) return &mediummap; + mediummap.emplace(5,"Beryllium"); + mediummap.emplace(6,"Carbon"); + mediummap.emplace(9,"Aluminum"); + mediummap.emplace(10,"Iron"); + mediummap.emplace(11,"Slab Steel"); + mediummap.emplace(12,"Blu Steel"); + mediummap.emplace(15,"Air"); + mediummap.emplace(16,"Vacuum"); + mediummap.emplace(17,"Concrete"); + mediummap.emplace(18,"Target"); + mediummap.emplace(19,"Rebar Concrete"); + mediummap.emplace(20,"Shotcrete"); + mediummap.emplace(21,"Variable Density Aluminum"); + mediummap.emplace(22,"Variable Density Steel"); + mediummap.emplace(23,"1018 Steel"); + mediummap.emplace(24,"A500 Steel"); + mediummap.emplace(25,"Water"); + mediummap.emplace(26,"M1018 Steel"); + mediummap.emplace(28,"Decay Pipe Vacuum"); + mediummap.emplace(31,"CT852"); + return &mediummap; +} + + +Position TVector3ToPositionRW(TVector3 tvecin){ + Position pos(0,0,0); + pos.SetX(tvecin.X()); + pos.SetY(tvecin.Y()); + pos.SetZ(tvecin.Z()); + return pos; +} + +Direction TVector3ToDirectionRW(TVector3 tvecin){ + Direction dir(0,0,0); + dir.SetX(tvecin.X()); + dir.SetY(tvecin.Y()); + dir.SetZ(tvecin.Z()); + return dir; +} + +FourVector TLorentzVectorToFourVectorRW(TLorentzVector tlvecin){ + FourVector vec(0,0,0,0); + vec.SetT(tlvecin.T()); + vec.SetX(tlvecin.X()); + vec.SetY(tlvecin.Y()); + vec.SetZ(tlvecin.Z()); + return vec; +} + +bool LoadReweightGenieEvent::valid_knob_name( const std::string& knob_name, genie::rew::GSyst_t& knob ) { + std::set< genie::rew::GSyst_t > UNIMPLEMENTED_GENIE_KNOBS = { + kXSecTwkDial_RnubarnuCC, // tweak the ratio of \sigma(\bar\nu CC) / \sigma(\nu CC) + kXSecTwkDial_NormCCQEenu, // tweak CCQE normalization (maintains dependence on neutrino energy) + kXSecTwkDial_NormDISCC, // tweak the inclusive DIS CC normalization + kXSecTwkDial_DISNuclMod // unclear intent, does anyone else know? - S. Gardiner + }; + knob = genie::rew::GSyst::FromString( knob_name ); + if ( knob != kNullSystematic && knob != kNTwkDials ) { + if ( UNIMPLEMENTED_GENIE_KNOBS.count(knob) ) { + return false; + } + } + else { + return false; + } + return true; +} + +void LoadReweightGenieEvent::SetupWeightCalculators(genie::rew::GReWeight& rw, const std::map& modes_to_use){ + // Based on the list from the GENIE command-line tool grwght1p + + rw.AdoptWghtCalc( "xsec_ncel", new GReWeightNuXSecNCEL ); + rw.AdoptWghtCalc( "xsec_ccqe", new GReWeightNuXSecCCQE ); + rw.AdoptWghtCalc( "xsec_ccqe_axial", new GReWeightNuXSecCCQEaxial); + rw.AdoptWghtCalc( "xsec_ccqe_vec", new GReWeightNuXSecCCQEvec ); + rw.AdoptWghtCalc( "xsec_ccres", new GReWeightNuXSecCCRES ); + rw.AdoptWghtCalc( "xsec_ncres", new GReWeightNuXSecNCRES ); + rw.AdoptWghtCalc( "xsec_nonresbkg", new GReWeightNonResonanceBkg); + rw.AdoptWghtCalc( "xsec_coh", new GReWeightNuXSecCOH ); + rw.AdoptWghtCalc( "xsec_dis", new GReWeightNuXSecDIS ); + rw.AdoptWghtCalc( "nuclear_qe", new GReWeightFGM ); + rw.AdoptWghtCalc( "hadro_res_decay", new GReWeightResonanceDecay); + rw.AdoptWghtCalc( "hadro_fzone", new GReWeightFZone ); + rw.AdoptWghtCalc( "hadro_intranuke", new GReWeightINuke ); + rw.AdoptWghtCalc( "hadro_agky", new GReWeightAGKY ); + rw.AdoptWghtCalc( "xsec_nc", new GReWeightNuXSecNC ); + rw.AdoptWghtCalc( "xsec_empmec", new GReWeightXSecEmpiricalMEC ); + // GReWeightDISNuclMod::CalcWeight() is not implemented, so we won't + // bother to use it here. - S. Gardiner, 9 Dec 2019 + //rw.AdoptWghtCalc( "nuclear_dis", new GReWeightDISNuclMod ); + // Set the modes for the weight calculators that need them to be specified + //UBoone Patch + rw.AdoptWghtCalc( "xsec_mec", new GReWeightXSecMEC ); + rw.AdoptWghtCalc( "deltarad_angle", new GReWeightDeltaradAngle ); + rw.AdoptWghtCalc( "xsec_coh_ub", new GReWeightNuXSecCOHuB ); + rw.AdoptWghtCalc( "res_bug_fix", new GReWeightRESBugFix ); + + for ( const auto& pair : modes_to_use ) { + std::string calc_name = pair.first; + int mode = pair.second; + genie::rew::GReWeightI* calc = rw.WghtCalc( calc_name ); + // The GReWeightI base class doesn't have a SetMode(int) function, + // so we'll just try dynamic casting until we get the right one. + // If none work, then throw an exception. + // TODO: Add a virtual function GReWeightI::SetMode( int ) in GENIE's + // Reweight framework. Then we can avoid the hacky dynamic casts here. + auto* calc_ccqe = dynamic_cast< genie::rew::GReWeightNuXSecCCQE* >( calc ); + auto* calc_ccres = dynamic_cast< genie::rew::GReWeightNuXSecCCRES* >( calc ); + auto* calc_ncres = dynamic_cast< genie::rew::GReWeightNuXSecNCRES* >( calc ); + auto* calc_dis = dynamic_cast< genie::rew::GReWeightNuXSecDIS* >( calc ); + if ( calc_ccqe ) calc_ccqe->SetMode( mode ); + else if ( calc_ccres ) calc_ccres->SetMode( mode ); + else if ( calc_ncres ) calc_ncres->SetMode( mode ); + else if ( calc_dis ) calc_dis->SetMode( mode ); + } +} + +std::map< std::string, int > LoadReweightGenieEvent::CheckForIncompatibleSystematics(const std::vector& knob_vec){ + std::map< std::string, int > modes_to_use; + std::map< std::string, std::map > > INCOMPATIBLE_GENIE_KNOBS = { + // CCQE (genie::rew::GReWeightNuXSecCCQE) + { "xsec_ccqe", { + { genie::rew::GReWeightNuXSecCCQE::kModeNormAndMaShape, + { + // Norm + shape + kXSecTwkDial_NormCCQE, // tweak CCQE normalization (energy independent) + kXSecTwkDial_MaCCQEshape, // tweak Ma CCQE, affects dsigma(CCQE)/dQ2 in shape only (normalized to constant integral) + kXSecTwkDial_E0CCQEshape // tweak E0 CCQE RunningMA, affects dsigma(CCQE)/dQ2 in shape only (normalized to constant integral) + } + }, + { genie::rew::GReWeightNuXSecCCQE::kModeMa, + { + // Ma + kXSecTwkDial_MaCCQE, // tweak Ma CCQE, affects dsigma(CCQE)/dQ2 both in shape and normalization + kXSecTwkDial_E0CCQE, // tweak E0 CCQE RunningMA, affects dsigma(CCQE)/dQ2 both in shape and normalization + } + }, + { genie::rew::GReWeightNuXSecCCQE::kModeZExp, + { + // Z-expansion + kXSecTwkDial_ZNormCCQE, // tweak Z-expansion CCQE normalization (energy independent) + kXSecTwkDial_ZExpA1CCQE, // tweak Z-expansion coefficient 1, affects dsigma(CCQE)/dQ2 both in shape and normalization + kXSecTwkDial_ZExpA2CCQE, // tweak Z-expansion coefficient 2, affects dsigma(CCQE)/dQ2 both in shape and normalization + kXSecTwkDial_ZExpA3CCQE, // tweak Z-expansion coefficient 3, affects dsigma(CCQE)/dQ2 both in shape and normalization + kXSecTwkDial_ZExpA4CCQE // tweak Z-expansion coefficient 4, affects dsigma(CCQE)/dQ2 both in shape and normalization + } + }, + } }, + + // CCRES (genie::rew::GReWeightNuXSecCCRES) + { "xsec_ccres", { + { genie::rew::GReWeightNuXSecCCRES::kModeNormAndMaMvShape, + { + // Norm + shape + kXSecTwkDial_NormCCRES, /// tweak CCRES normalization + kXSecTwkDial_MaCCRESshape, /// tweak Ma CCRES, affects d2sigma(CCRES)/dWdQ2 in shape only (normalized to constant integral) + kXSecTwkDial_MvCCRESshape /// tweak Mv CCRES, affects d2sigma(CCRES)/dWdQ2 in shape only (normalized to constant integral) + } + }, + { genie::rew::GReWeightNuXSecCCRES::kModeMaMv, + { + // Ma + Mv + kXSecTwkDial_MaCCRES, // tweak Ma CCRES, affects d2sigma(CCRES)/dWdQ2 both in shape and normalization + kXSecTwkDial_MvCCRES // tweak Mv CCRES, affects d2sigma(CCRES)/dWdQ2 both in shape and normalization + } + } + } }, + + // NCRES (genie::rew::GReWeightNuXSecNCRES) + { "xsec_ncres", { + { genie::rew::GReWeightNuXSecNCRES::kModeNormAndMaMvShape, + { + // Norm + shape + kXSecTwkDial_NormNCRES, /// tweak NCRES normalization + kXSecTwkDial_MaNCRESshape, /// tweak Ma NCRES, affects d2sigma(NCRES)/dWdQ2 in shape only (normalized to constant integral) + kXSecTwkDial_MvNCRESshape /// tweak Mv NCRES, affects d2sigma(NCRES)/dWdQ2 in shape only (normalized to constant integral) + } + }, + { genie::rew::GReWeightNuXSecNCRES::kModeMaMv, + { + // Ma + Mv + kXSecTwkDial_MaNCRES, // tweak Ma NCRES, affects d2sigma(NCRES)/dWdQ2 both in shape and normalization + kXSecTwkDial_MvNCRES // tweak Mv NCRES, affects d2sigma(NCRES)/dWdQ2 both in shape and normalization + } + } + } }, + + // DIS (genie::rew::GReWeightNuXSecDIS) + { "xsec_dis", { + { genie::rew::GReWeightNuXSecDIS::kModeABCV12u, + { + kXSecTwkDial_AhtBY, // tweak the Bodek-Yang model parameter A_{ht} - incl. both shape and normalization effect + kXSecTwkDial_BhtBY, // tweak the Bodek-Yang model parameter B_{ht} - incl. both shape and normalization effect + kXSecTwkDial_CV1uBY, // tweak the Bodek-Yang model parameter CV1u - incl. both shape and normalization effect + kXSecTwkDial_CV2uBY // tweak the Bodek-Yang model parameter CV2u - incl. both shape and normalization effect + } + }, + { genie::rew::GReWeightNuXSecDIS::kModeABCV12uShape, + { + kXSecTwkDial_AhtBYshape, // tweak the Bodek-Yang model parameter A_{ht} - shape only effect to d2sigma(DIS)/dxdy + kXSecTwkDial_BhtBYshape, // tweak the Bodek-Yang model parameter B_{ht} - shape only effect to d2sigma(DIS)/dxdy + kXSecTwkDial_CV1uBYshape, // tweak the Bodek-Yang model parameter CV1u - shape only effect to d2sigma(DIS)/dxdy + kXSecTwkDial_CV2uBYshape // tweak the Bodek-Yang model parameter CV2u - shape only effect to d2sigma(DIS)/dxdy + } + } + } } + }; + for ( const auto& knob : knob_vec ) { + for ( const auto& pair1 : INCOMPATIBLE_GENIE_KNOBS ) { + std::string calc_name = pair1.first; + const auto& mode_map = pair1.second; + for ( const auto& pair2 : mode_map ) { + int mode = pair2.first; + std::set knob_set = pair2.second; + if ( knob_set.count(knob) ) { + auto search = modes_to_use.find( calc_name ); + if ( search != modes_to_use.end() ) { + if ( search->second != mode ) { + auto knob_str = genie::rew::GSyst::AsString( knob ); + std::cout << "ERROR: The GENIE knob " << knob_str << " is incompatible with others that are already configured" << std::endl; + } + } + else modes_to_use[ calc_name ] = mode; + } + } + } + } + return modes_to_use; +} + + diff --git a/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.h b/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.h new file mode 100644 index 000000000..177f898fe --- /dev/null +++ b/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.h @@ -0,0 +1,250 @@ +#ifndef LoadReweightGenieEvent_H +#define LoadReweightGenieEvent_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Tool.h" +#include "GenieInfo.h" +#include "CLHEP/Random/RandGaussQ.h" +#include "CLHEP/Random/JamesRandom.h" +#include "Framework/Conventions/KineVar.h" +#include "Framework/EventGen/EventRecord.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Interaction/Kinematics.h" +//#include "Framework/Messenger/Messenger.h" +#include "Framework/Utils/AppInit.h" +#include +#include +#include // neut reaction codes +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RwFramework/GSystSet.h" +#include "RwFramework/GSyst.h" +#include "RwFramework/GReWeight.h" +#include "RwCalculators/GReWeightNuXSecNCEL.h" +#include "RwCalculators/GReWeightNuXSecCCQE.h" +#include "RwCalculators/GReWeightNuXSecCCRES.h" +#include "RwCalculators/GReWeightNuXSecCOH.h" +#include "RwCalculators/GReWeightNonResonanceBkg.h" +#include "RwCalculators/GReWeightFGM.h" +#include "RwCalculators/GReWeightDISNuclMod.h" +#include "RwCalculators/GReWeightResonanceDecay.h" +#include "RwCalculators/GReWeightFZone.h" +#include "RwCalculators/GReWeightINuke.h" +#include "RwCalculators/GReWeightAGKY.h" +#include "RwCalculators/GReWeightNuXSecCCQEaxial.h" +#include "RwCalculators/GReWeightNuXSecCCQEvec.h" +#include "RwCalculators/GReWeightNuXSecNCRES.h" +#include "RwCalculators/GReWeightNuXSecDIS.h" +#include "RwCalculators/GReWeightINukeParams.h" +#include "RwCalculators/GReWeightNuXSecNC.h" +#include "RwCalculators/GReWeightXSecEmpiricalMEC.h" +//UBoone Patch +#include "RwCalculators/GReWeightXSecMEC.h" +#include "RwCalculators/GReWeightDeltaradAngle.h" +#include "RwCalculators/GReWeightNuXSecCOHuB.h" +#include "RwCalculators/GReWeightRESBugFix.h" + +#include +#include +#include // neut reaction codes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "TChain.h" +#include "TFile.h" +#include "TTree.h" +#include "TVector3.h" +#include "TLorentzVector.h" + +#include "MRDspecs.hh" +#include "MCXSEventWeight.h" + +class LoadReweightGenieEvent: public Tool { + + public: + + LoadReweightGenieEvent(); + bool Initialise(std::string configfile,DataModel &data); + bool Execute(); + bool Finalise(); + bool valid_knob_name( const std::string& knob_name, genie::rew::GSyst_t& knob ); + std::map< std::string, int > CheckForIncompatibleSystematics(const std::vector& knob_vec); + void SetupWeightCalculators(genie::rew::GReWeight& rw, const std::map& modes_to_use); + + // verbosity levels: if 'verbosity' < this level, the message type will be logged. + int verbosity; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; + int get_ok; + + private: + + // function to load the branch addresses + void SetBranchAddresses(); + + // function to fill the info into the handy genieinfostruct + void GetGenieEntryInfo(genie::EventRecord* gevtRec, genie::Interaction* genieint, + GenieInfo& thegenieinfo, bool printneutrinoevent=false); + // type conversion functions: + std::map pdgcodetoname; + std::map decaymap; + std::map gnumicodetoname; + std::map mediummap; + std::map* GenerateGnumiMap(); + std::map* GeneratePdgMap(); + std::map* GenerateDecayMap(); + std::map* GenerateMediumMap(); + std::string GnumiToString(int code); + std::string PdgToString(int code); + std::string DecayTypeToString(int code); + std::string MediumToString(int code); + + BoostStore* geniestore = nullptr; + int fluxstage; + std::string filedir, filepattern; + bool loadwcsimsource; + TChain* flux = nullptr; + TFile* curf = nullptr; // keep track of file changes + TFile* curflast = nullptr; + genie::NtpMCEventRecord* genieintx = nullptr; // = new genie::NtpMCEventRecord; + genie::NtpMCTreeHeader* geniehdr = nullptr; + // for fluxver 0 files + genie::flux::GNuMIFluxPassThroughInfo* gnumipassthruentry = nullptr; + // for fluxver 1 files + genie::flux::GSimpleNtpEntry* gsimpleentry = nullptr; + genie::flux::GSimpleNtpAux* gsimpleauxinfo = nullptr; + genie::flux::GSimpleNtpNuMI* gsimplenumientry = nullptr; + + //Reweight variables + std::string weight_options; + std::string sample; + std::string fGenieModuleWeight; + vector weight_names; + vector> reweightVector; + + // genie file variables + int fluxver; // 0 = old flux, 1 = new flux + std::string currentfilestring; + unsigned long local_entry=0; // + int tchainentrynum=0; // + bool manualmatch=0; //to be used when GENIE information is not stored properly in file + int fileevents=0; + int on_grid; + + // common input/output variables to both Robert/Zarko filesets + int parentpdg; + std::string parenttypestring; + int parentdecaymode; // some arbitrary number that maps to a decay mode string. + std::string parentdecaystring; // descriptive string. Should we store a map of the translation? + float parentdecayvtx_x, parentdecayvtx_y, parentdecayvtx_z; + Position parentdecayvtx; + float parentdecaymom_x, parentdecaymom_y, parentdecaymom_z; + Direction parentdecaymom; + float parentprodmom_x, parentprodmom_y, parentprodmom_z; + Direction parentprodmom; + int parentprodmedium; // they're all 0 + std::string parentprodmediumstring; // do we even have this mapping? --> There seems to be a mapping here: https://minos-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=6316&filename=flugg_doc.pdf&version=10 + int parentpdgattgtexit; + std::string parenttypestringattgtexit; + Direction parenttgtexitmom; + float parenttgtexitmom_x, parenttgtexitmom_y, parenttgtexitmom_z; + int pcodes; // Needed to evaluate whether the particle codes are stored in GEANT format or in PDG format + + // Additional zarko-only information, needed for flux systematic reweighting + int fluxrun; + int fluxentryno; + int fluxevtno; + int fluxntype; + double fluxnimpwt; + double fluxnenergyn; + double fluxnenergyf; + + // store the neutrino info from gntp files + // a load of variables to specify interaction type + bool IsQuasiElastic=false; + bool IsResonant=false; + bool IsDeepInelastic=false; + bool IsCoherent=false; + bool IsDiffractive=false; + bool IsInverseMuDecay=false; + bool IsIMDAnnihilation=false; + bool IsSingleKaon=false; + bool IsNuElectronElastic=false; + bool IsEM=false; + bool IsWeakCC=false; + bool IsWeakNC=false; + bool IsMEC=false; + std::string interactiontypestring=""; + int neutcode=-1; + // ok, moving on + double nuIntxVtx_X; // cm + double nuIntxVtx_Y; // cm + double nuIntxVtx_Z; // cm + double nuIntxVtx_T; // ns + bool isintank=false; + bool isinfiducialvol=false; + double eventq2=-1; + double eventw2=-1; + int TrueTargetZ = -1; + double eventbj_x=-1; + double eventelastic_y=-1; + double eventq0=-1; + double eventq3=-1; + std::vectorpdgs; + std::vectorPmag; + + double eventEnu=-1; + Direction eventPnu; + int neutrinopdg=-1; + double muonenergy=-1; + double muonangle=-1; + std::string fsleptonname; // assumed to be muon, but we should confirm + double fsleptonenergy; + int fsleptonpdg; + double fsleptonm; + Direction fsleptonmomentum; + Direction fsleptonmomentumdir; + Position fsleptonvtx; // cm + double fsleptont; // ns + // these may not be properly copied... --> temp fix applied that seems to be working + int numfsprotons; + int numfsneutrons; + int numfspi0; + int numfspiplus; + int numfspipluscher; // reach Cherenkov threshold + int numfspiminus; + int numfspiminuscher; // reach Cherenkov threshold + int numfskplus; + int numfskpluscher; // reach Cherenkov threshold + int numfskminus; + int numfskminuscher; // reach Cherenkov threshold + +}; + +#endif diff --git a/UserTools/LoadReweightGenieEvent/MCXSEventWeight.h b/UserTools/LoadReweightGenieEvent/MCXSEventWeight.h new file mode 100644 index 000000000..baea5040c --- /dev/null +++ b/UserTools/LoadReweightGenieEvent/MCXSEventWeight.h @@ -0,0 +1,22 @@ +#ifndef _MCXSECEVENTWEIGHT_H_ +#define _MCXSECEVENTWEIGHT_H_ + +#include +#include + +namespace xsecevwgh { + + struct xsecconfig{ + std::string title = ""; + std::string type = ""; + int random_seed = 0; + std::vector parameter_list; + std::vector parameter_sigma; + std::vector parameter_min; + std::vector parameter_max; + std::string mode = ""; + int number_of_multisims = 0; + }; + +} +#endif //_MCXSECEVENTWEIGHT_H_ diff --git a/UserTools/LoadReweightGenieEvent/README.md b/UserTools/LoadReweightGenieEvent/README.md new file mode 100644 index 000000000..7b4ac8241 --- /dev/null +++ b/UserTools/LoadReweightGenieEvent/README.md @@ -0,0 +1,115 @@ +# LoadReweightGenieEvent + +The `LoadReweightGenieEvent` tool loads information from the GENIE files about the neutrino interaction properties into a custom "GenieInfo" BoostStore that can be accessed by other tools AND performs cross section systematic reweighting. + +To be ran IN PLACE of `LoadGenieEvents` tool for reweighting cross section systematics. This is because of a bug when separating loading the Genie event and reweighting it in different tools. When separated, Genie software is unable to properly close and seg-faults during the Finalize step. + +I'm sorry but this is the best I can do given time constraints. - James + +## Configurations ## + +It is possible to look at GENIE files on their own (without corresponding WCSim files), in this case the `FileDir` and `FilePattern` need to be specified in the configuration file. +If one wants to get corresponding GENIE information for WCSim files, one should specify `LoadWCSimTool` in the `FilePattern` row. In this case the tool will try to extract the information about the corresponding GENIE file from the WCSim file and load the respective GENIE file automatically. For newer files, the path is SOMETIMES(*see below*) saved alongside the filename and one can set the `FileDir` to `NA`. For older files, only the filename is saved and one needs to specify the `FileDir` in which the GENIE files are to be found by hand. +Note that a lot of WCSim files do not have the complete information about their GENIE files saved. In this case, a manual matching of GENIE files to WCSim files is possible, although the following restrictions to the naming apply: The WCSim files must have the same nomenclature as Marcus' WCSim beam files, i.e. `wcsim_0.X.Y.root`, where `X` is the number of the corresponding GENIE file, and `Y` specifies which part of the GENIE file is being looked at, with each WCSim file corresponding to 500 entries (1000 entries for James' files) in a GENIE file. The matching GENIE file would be called `ghtp.X.ghep.root`, with the events `Y*(500) ... (Y+1)*500` (`Y*(1000) ... (Y+1)*1000`) corresponding to the events in the WCSim file. +If the WCSim file was generated from offset GENIE events (a non-zero Y in the WCSim file name), then the WCSim only saved the file path of the GENIE file, not the filename. IT IS STRONGLY RECOMMENDED to set the FileDir to the GENIE file location. + +## GenieInfo BoostStore ## + +The information is loaded from the GENIE file and saved into the "GenieInfo" BoostStore. The following variables are saved: + +* **file** `string`: The GENIE filename +* **fluxver** `int`: Flux version number (0/1) +* **evtnum** `unsigned int`: The GENIE event number +* **ParentPdg** `int`: PDG code of parent particle that produced neutrino +* **ParentTypeString** `string`: The type of the parent particle that produced neutrino +* **ParentDecayMode** `int`: The decay mode of the parent particle that produced the neutrino +* **ParentDecayVtx** `Position`: The decay vertex of the parent particle that produced the neutrino +* **ParentDecayVtx_X/Y/Z** `float`: The x/y/z component of the parent particle decay vertex +* **ParentDecayMom** `Position`: The momentum of the parent particle that produced the neutrino +* **ParentDecayMom_X/Y/Z** `float`: The x/y/z/ component of the parent particle decay momentum +* **ParentProdMom** `Position`: The momentum of the parent particle at production +* **ParentProdMom_X/Y/Z** `float`: The x/y/z/ component of the parent particle production momentum +* **ParentProdMedium** `int`: Gnumi code for material where parent particle was produced +* **ParentProdMediumString** `string`: Material where parent particle was produced +* **ParentPdgAtTgtExit** `int`: PDG code of parent particle at exit of target +* **ParentTypeAtTgtExitString** `string`: Name of parent particle at exit of target +* **ParentTgtExitMom** `Position`: momentum of parent particle at exit of target +* **ParentTgtExitMom_X/Y/Z** `float`: x/y/z component of parent particle momentum at exit of target +* **ParentEntryNo** `int`: entry number of parent particle that produced neutrino +* **ParentEventNo** `int`: event number of parent particle that produced neutrino +* **ParentRunNo** `int`: run number of flux file +* **ParentNEnergyN** `double`: The energy of the parent particle +* **ParentNEnergyF** `double`: The energy of the parent particle +* **ParentNType** `int`: The PDG code of the parent particle specific to gsimple file +* **ParentWgt** `double`: The weight of the parent particle + +* **IsQuasiElastic** `bool`: Neutrino interaction was quasi-elastic +* **IsResonant** `bool`: Neutrino interaction was RES +* **IsDeepInelastic** `bool`: Neutrino interaction was DIS +* **IsCoherent** `bool`: Neutrino interaction was COH +* **IsDiffractive** `bool`: Neutrino interaction was Diffractive +* **IsInverseMuDecay** `bool`: Neutrino interaction was Inverse Muon Decay +* **IsIMDAnnihilation** `bool`: Neutrino interaction was Inverse Muon Decay - Annihilation +* **IsSingleKaon** `bool`: Neutrino interaction was Single Kaon (?) +* **IsEM** `bool`: Interaction process was electromagnetic +* **IsWeakCC** `bool`: Interaction process was weak (CC) +* **IsWeakNC** `bool`: Interaction process was weak (NC) +* **IsMEC** `bool`: Interaction process involved Meson Exchange Currents (MEC) +* **InteractionTypeString** `string`: Interaction type +* **NeutCode** `int`: Neutrino code describing the interaction (not filled currently) +* **NuIntVtx_X/Y/Z** `double`: Neutrino interaction vertex (x/y/z) +* **NuIntVtx_T** `double`: Neutrino interaction vertex (time) +* **NuVtxInTank** `bool`: Was neutrino vertex in the ANNIE tank? +* **NuVtxInFidVol** `bool`: Was neutrino vertex in the Fiducial Volume of ANNIE? +* **EventQ2** `double`: Q^2-value of the interaction +* **NeutrinoEnergy** `double`: Neutrino energy +* **NeutrinoMomentum** `Direction`: Neutrino momentum +* **NeutrinoPDG** `double`: PDG code of neutrino +* **MuonEnergy** `double`: Energy of produced muon +* **MuonAngle** `double`: Angle of produced muon +* **FSLeptonName** `string`: Final State Lepton name +* **FSLeptonEnergy** `double`: Final State Lepton energy +* **FSLeptonPdg** `int`: Final State Lepton PDG code +* **FSLeptonMass** `double`: Final State Lepton mass +* **FSLeptonMomentum** `Position`: Final State Lepton momentum vector +* **FSLeptonMomentumDir** `Position`: Final State Lepton momentum unit vector +* **FSLeptonVertex** `Position`: Final State Lepton initial vertex +* **FSLeptonTime** `double`: Final State Lepton time of initial vertex +* **NumFSProtons** `int`: Number of final state protons +* **NumFSNeutrons** `int`: Number of final state neutrons +* **NumFSPi0** `int`: Number of final state pi^0 +* **NumFSPiPlus** `int`: Number of final state pi^+ +* **NumFSPiPlusCher** `int`: Number of final state pi^+ that pass Cherenkov threshold +* **NumFSPiMinus** `int`: Number of final state pi^- +* **NumFSPiMinusCher** `int`: Number of final state pi^- that pass Cherenkov threshold +* **NumFSKPlus** `int`: Number of final state K^+ +* **NumFSKPlusCher** `int`: Number of final state K^+ that pass Cherenkov threshold +* **NumFSKMinus** `int`: Number of final state K^- +* **NumFSKMinusCher** `int`: Number of final state K^- that pass Cherenkov threshold +* **GenieInfo** `GenieInfo`: GenieInfo object containing most of the listed properties (see DataModel header-file) +* **xsec_weights** `map>`: Cross section weight systematics + +## Configuration file ## + +LoadReweightGenieEvent has the following configuration options: + +``` +verbosity 1 +FluxVersion 1 #0: rhatcher files, 1: zarko files +#FileDir NA #specify "NA" for newer files: full path is saved in WCSim +#FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 +FileDir /pnfs/annie/persistent/simulations/genie3/G1810a0211a/standard/tank +#FileDir /pnfs/annie/persistent/users/moflaher/genie/BNB_World_10k_11-03-18_gsimpleflux +#FilePattern gntp.*.ghep.root ## for specifying specific files to load +FilePattern LoadWCSimTool ## use this pattern to load corresponding genie info with the LoadWCSimTool + ## N.B: FileDir must still be specified for now! +ManualFileMatching 0 ## to manually match GENIE event to corresponding WCSim event +FileEvents 1000 ## number of events in the WCSim file + ## 500 for Marcus files + ## 1000 for James files +``` +For reweighting: +``` +param1 key1:value1|key2:value2|key3:value3 +``` + diff --git a/UserTools/LoadWCSim/LoadWCSim.cpp b/UserTools/LoadWCSim/LoadWCSim.cpp index 8e5dc24ad..16ff3636a 100644 --- a/UserTools/LoadWCSim/LoadWCSim.cpp +++ b/UserTools/LoadWCSim/LoadWCSim.cpp @@ -1,1584 +1,1582 @@ -/* vim:set noexpandtab tabstop=4 wrap */ - #include "LoadWCSim.h" LoadWCSim::LoadWCSim():Tool(){} -bool LoadWCSim::Initialise(std::string configfile, DataModel &data){ - - /////////////////// Useful header /////////////////////// - - if(verbosity) cout<<"Initializing Tool LoadWCSim"<CStore.Set("SplitSubTriggers",splitSubtriggers); - get_ok = m_variables.Get("TriggerType",Triggertype); - if (not get_ok){ - Log("LoadWCSim Tool: No Triggertype specified. Assuming TriggerType = Beam",v_warning,verbosity); - Triggertype = "Beam"; //other options: Cosmic / No Loopback - } + if (!m_variables.Get("MaxEntries", MaxEntries)) MaxEntries = -1; + + if (!m_variables.Get("InputFile", MCFile)) { + logmessage = "LoadWCSim::Initialise: NO InputFile set in the config!"; + Log(logmessage, v_error, verbosity); + return false; + } + + if (!m_variables.Get("HistoricTriggeroffset", HistoricTriggeroffset)) { + logmessage = "LoadWCSim::Initialise: NO HistoricTriggeroffset set in the config! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + if (!m_variables.Get("WCSimVersion", WCSimVersion)) { + logmessage = "LoadWCSim::Initialise: WCSimVersion not set in the config! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + m_data->CStore.Set("WCSimVersion", WCSimVersion); + + if (!m_variables.Get("UseDigitSmearedTime", use_smeared_digit_time)) { + use_smeared_digit_time = 1; + logmessage = "LoadWCSim::Initialise: UseDigitSmearedTime flag not set in the config."; + logmessage += "Using default value: " + std::to_string(use_smeared_digit_time); + Log(logmessage, v_warning, verbosity); + + } + + if (!m_variables.Get("LappdNumStrips", LappdNumStrips)) { + LappdNumStrips = 56; + logmessage = "LoadWCSim::Initialise: LappdNumStrips not set in config. "; + logmessage += "Using default value: " + std::to_string(LappdNumStrips); + Log(logmessage, v_warning, verbosity); + } + + if(!m_variables.Get("LappdStripLength", LappdStripLength)){ + LappdStripLength = 200; + logmessage = "LoadWCSim::Initialise: LappdStripLength not set in config. "; + logmessage += "Using default value: " + std::to_string(LappdStripLength); + Log(logmessage, v_warning, verbosity); + } + + if (!m_variables.Get("LappdStripSeparation", LappdStripSeparation)) { + LappdStripSeparation = 7.14; + logmessage = "LoadWCSim::Initialise: LappdStripSeparation not set in config. "; + logmessage += "Using default value: " + std::to_string(LappdStripSeparation); + Log(logmessage, v_warning, verbosity); + } + + if (!m_variables.Get("RunStartDate", RunStartUser)) { + RunStartUser = 0; + logmessage = "LoadWCSim::Initialise: RunStartUser not set in config. "; + logmessage += "Using default value: " + std::to_string(LappdStripSeparation) + " ns since unix epoch"; + Log(logmessage, v_warning, verbosity); + } + + if (!m_variables.Get("SplitSubTriggers", splitSubtriggers)) { + splitSubtriggers = false; + logmessage = "LoadWCSim::Initialise: splitSubtriggers flag not set in config. "; + logmessage += "Using default value: " + std::to_string(splitSubtriggers); + Log(logmessage, v_warning, verbosity); + } + m_data->CStore.Set("SplitSubTriggers", splitSubtriggers); + + if (!m_variables.Get("TriggerType", TriggerType)) { + TriggerType = "Beam"; + logmessage = "LoadWCSim::Initialise: TriggerType not set in config. "; + logmessage += "Using default value: " + TriggerType; + Log(logmessage, v_warning, verbosity); + } - get_ok = m_variables.Get("TriggerWord",TriggerWord); - if (not get_ok){ - Log("LoadWCSim Tool: No Triggerword specified. Assuming TriggerWord = 5 (Beam)",v_warning,verbosity); - TriggerWord = 5; - } - path_chankeymap = "./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt"; - get_ok = m_variables.Get("ChankeyToPMTIDMap",path_chankeymap); - if (not get_ok){ - Log("LoadWCSim Tool: No Channelkey map provided. Use the standard one at ./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt",v_warning,verbosity); - } - ifstream file_pmtid(path_chankeymap.c_str()); - if (file_pmtid.is_open()){ - // watch out: comment or empty lines not supported here - while (!file_pmtid.eof()){ - unsigned long chankey; - int pmtid; - file_pmtid >> chankey >> pmtid; - channelkey_to_pmtid.emplace(chankey,pmtid); - pmtid_to_channelkey.emplace(pmtid,chankey); - } + if (!m_variables.Get("TriggerWord", TriggerWord)) { + TriggerWord = 5; + logmessage = "LoadWCSim::Initialise: TriggerWord not set in config. "; + logmessage += "Using default value: " + std::to_string(TriggerWord) + " (ie. Beam)"; + Log(logmessage, v_warning, verbosity); + } + + if (!m_variables.Get("RunType", RunType)) { + RunType = 3; + logmessage = "LoadWCSim::Initialise: RunType not set in config. "; + logmessage += "Using default value: " + std::to_string(RunType) + " (ie. Beam)"; + Log(logmessage, v_warning, verbosity); + } + + if (!m_variables.Get("PMTMask", PMTMask)) { + PMTMask = "None"; + logmessage = "LoadWCSim::Initialise: RunType not set in config. "; + logmessage += "Using default value: " + PMTMask; + Log(logmessage, v_warning, verbosity); + } + if (PMTMask != "None") masked_ids = this->LoadPMTMask(PMTMask); + + if (!m_variables.Get("FileStartOffset", WCSimEntryNum)) { + WCSimEntryNum = 0; + logmessage = "LoadWCSim::Initialise: FileStartOffset not set in config. "; + logmessage += "Using default value: " + std::to_string(WCSimEntryNum); + Log(logmessage, v_warning, verbosity); + } + + // TODO: should not use relative path. + // There should be an env var that points to the top directory + if (!m_variables.Get("ChankeyToPMTIDMap", path_chankeymap)) { + path_chankeymap = "./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt"; + logmessage = "LoadWCSim::Initialise: ChankeyToPMTIDMap not set in config. "; + logmessage += "Using default path: " + path_chankeymap; + Log(logmessage, v_warning, verbosity); + } + ifstream file_pmtid(path_chankeymap.c_str()); + if (file_pmtid.is_open()){ + // watch out: comment or empty lines not supported here + while (!file_pmtid.eof()) { + unsigned long chankey; + int pmtid; + file_pmtid >> chankey >> pmtid; + channelkey_to_pmtid.emplace(chankey,pmtid); + pmtid_to_channelkey.emplace(pmtid,chankey); + } - file_pmtid.close(); - m_data->CStore.Set("pmt_tubeid_to_channelkey_data",pmtid_to_channelkey); - m_data->CStore.Set("channelkey_to_pmtid_data",channelkey_to_pmtid); - } else { - Log("LoadWCSim Tool: PMT ID Configuration file "+path_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); - return false; - } - path_mrd_chankeymap = "./configfiles/LoadWCSim/MRD_Chankey_WCSimID.dat"; - get_ok = m_variables.Get("ChankeyToMRDIDMap",path_mrd_chankeymap); - ifstream file_mrdid(path_mrd_chankeymap.c_str()); - if (file_mrdid.is_open()){ - // watch out: comment or empty lines not supported here - while (!file_mrdid.eof()){ - unsigned long chankey; - int mrdid; - file_mrdid >> chankey >> mrdid; - mrdid_to_channelkey.emplace(mrdid,chankey); - } - file_mrdid.close(); - } else { - Log("LoadWCSim Tool: MRD ID Configuration file "+path_mrd_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); - return false; - } - path_fmv_chankeymap = "./configfiles/LoadWCSim/FMV_Chankey_WCSimID.dat"; - get_ok = m_variables.Get("ChankeyToFMVIDMap",path_fmv_chankeymap); - ifstream file_fmvid(path_fmv_chankeymap.c_str()); - if (file_fmvid.is_open()){ - // watch out: comment or empty lines not supported here - while (!file_fmvid.eof()){ - unsigned long chankey; - int fmvid; - file_fmvid >> chankey >> fmvid; - fmvid_to_channelkey.emplace(fmvid,chankey); - } - file_fmvid.close(); - } else { - Log("LoadWCSim Tool: FMV ID Configuration file "+path_fmv_chankeymap+" could not be opened! Is the path valid? Abort",v_warning,verbosity); - return false; - } - get_ok = m_variables.Get("RunType",RunType); - if (not get_ok){ - Log("LoadWCSim Tool: No RunType specified. Assuming RunType = 3 (Beam)",v_warning,verbosity); - RunType = 3; - } - - get_ok = m_variables.Get("PMTMask",PMTMask); - if (not get_ok){ - Log("LoadWCSim Tool: Assuming to use no PMTMask",v_warning,verbosity); - PMTMask = "None"; - } - - MCEventNum=0; - get_ok = m_variables.Get("FileStartOffset",MCEventNum); - - // put version in the CStore for downstream tools - m_data->CStore.Set("WCSimVersion", WCSimVersion); - - // Short Stores README - ////////////////////// - // n.b. m_data->vars is a Store (of ben's Store type) that is not saved to disk? - // m_data->CStore is a single entry binary BoostStore that is not saved to disk. - // m_data->Stores["StoreName"] is a map of binary BoostStores that are saved to disk. - // If using Stores->BoostStore->Set("MyVariable") it will always be saved to disk - // Using Stores->BoostStore.Set("MyVariable",&myvar) if myvar is a pointer (to an object on - // the heap) puts myvar in the Store and it's deletion will be handled by the Store. - // (provided your class has a suitable destructor.) - // Is 'BoostStore::Save' needed for single-entry stores? - // ---------------- - // create a new BoostStore with key "ANNIEEvent" in the Stores std::map - // BoostStore constructor args: typechecking (bool), m_format (0=binary, 1=ASCII, 2=multievent) - // A BoostStore has a header where useful constants may be saved. The header is a BoostStore itself, - // and can be accessed via: Store.Header->Get() and Store.Header->Set(). - // The method 'Store::Save()' writes everything 'Set' since the last 'Save' to the current entry. - // Store::Clear clears the map of the current entry, to start building a new one. - // Use 'Store::GetEntry(int entrynum)' to load an entry to then be able to 'Get' it's contents. - // 'Store->Header->Get("TotalEntries",NumEvents)' will load the num entries into NumEvents - // ------------------ - // When adding a BoostStore (or class object in general) to a BoostStore (such as ANNIEEvent) - // you call BoostStore::Set("key",ObjectPointer) - BUT be aware that serialization happens when the - // 'Set' method is called - although you pass it a pointer, any subsequent changes to the object - // will NOT get saved! You must call 'Set' AFTER making ALL changes to your object! - ///////////////////////////////////////////////////////////////// - - // Make class private members; e.g. the WCSimT and WCSimRootGeom - // ============================================================= -// file= new TFile(MCFile.c_str(),"READ"); -// wcsimtree= (TTree*) file->Get("wcsimT"); -// WCSimEntry= new wcsimT(wcsimtree); - WCSimEntry= new wcsimT(MCFile.c_str(),verbosity); - - gROOT->cd(); - wcsimrootgeom = WCSimEntry->wcsimrootgeom; - wcsimrootopts = WCSimEntry->wcsimrootopts; - int pretriggerwindow=wcsimrootopts->GetNDigitsPreTriggerWindow(); - int posttriggerwindow=wcsimrootopts->GetNDigitsPostTriggerWindow(); - - // put useful constants into the CStore - // ==================================== - //m_data->CStore.Set("WCSimEntry",WCSimEntry,false); // pass on the WCSim entry - not possible - // pass on root options. TODO should these be saved somewhere? - m_data->CStore.Set("WCSimPreTriggerWindow",pretriggerwindow); - m_data->CStore.Set("WCSimPostTriggerWindow",posttriggerwindow); - // store the WCSimRootGeom for LAPPD reader calculation of global coords - intptr_t geomptr = reinterpret_cast(wcsimrootgeom); - if(verbosity>1) cout<<"wcsimrootgeom at "<Stores.count("WCSimRootGeomStore"); -// if(wcsimgeomexists==0){ -// m_data->Stores["WCSimRootGeomStore"] = new BoostStore(false,0); -// //m_data->Stores.at("WCSimRootGeomStore")->Header->Set("WCSimRootGeom",wcsimrootgeom); -// m_data->Stores.at("WCSimRootGeomStore")->Set("WCSimRootGeom",&wcsimrootgeom); -// } -// -// // Make a WCSimStore to store additional WCSim info passed between tools -// // ===================================================================== -// int wcsimstoreexists = m_data->Stores.count("WCSimStore"); -// cout<<"wcsimstoreexists="<Stores["WCSimStore"] = new BoostStore(false,0); -// } -// m_data->Stores.at("WCSimStore")->Set("WCSimRootGeom",geomptr); -// m_data->Stores.at("WCSimStore")->Set("WCSimPreTriggerWindow",pretriggerwindow); -// m_data->Stores.at("WCSimStore")->Set("WCSimPostTriggerWindow",posttriggerwindow); - - // Make the ANNIEEvent Store if it doesn't exist - // ============================================= - int annieeventexists = m_data->Stores.count("ANNIEEvent"); - if(annieeventexists==0) m_data->Stores["ANNIEEvent"] = new BoostStore(false,2); - - // Convert WCSimRootGeom into ToolChain Geometry class - Geometry* anniegeom = ConstructToolChainGeometry(); - - // Set run-level information in the ANNIEEvent - // =========================================== - /* - At time of writing ANNIEEvent has the following that need to be Set before each Save: - RunNumber - SubrunNumber - EventNumber - MCParticles - RecoParticles - MCHits - TDCData - RawADCData - CalibratedADCData - RawLAPPDData - CalibratedLAPPDData - TriggerData - MCFlag - EventTime - MCEventNum - MCFile - BeamStatus - */ - - EventNumber=0; - MCTriggernum=0; - // pull the first entry to get the MCFile - int nbytesread = WCSimEntry->GetEntry(MCEventNum); // <0 if out of file - if(nbytesread<=0){ - logmessage = "LoadWCSim Tool had no entry "+to_string(MCEventNum); - if(nbytesread==-4){ - logmessage+=": Overran end of TChain! Have you specified more iterations than are available in ToolChainConfig?"; - } else if(nbytesread==0){ - logmessage+=": No TChain loaded! Is your filepath correct?"; - } - Log(logmessage,v_error,verbosity); - cerr<<"############################"<vars.Set("StopLoop",1); - return false; - } - - MCFile = WCSimEntry->GetCurrentFile()->GetName(); - m_data->Stores.at("ANNIEEvent")->Set("MCFile",MCFile); - - if (PMTMask != "None"){ - masked_ids = this->LoadPMTMask(PMTMask); - } - - // use nominal beam values TODO - double beaminten=4.777e+12; - double beampow=3.2545e+16; - uint64_t beamtimestamp=0; - RunStartTime.SetNs(RunStartUser); - beamstat.set_time(TimeClass(beamtimestamp)); - beamstat.set_pot(beampow); - BeamCondition bc = BeamCondition::Ok; - beamstat.set_condition(bc); - - // Construct the other objects we'll be setting at event level, - // pass managed pointers to the ANNIEEvent Store - MCParticles = new std::vector; - MCHits = new std::map>; - TDCData = new std::map>; - EventTime = new TimeClass(); - TriggerClass beamtrigger("beam",5,0,true,0); - TriggerData = new std::vector{beamtrigger}; // FIXME ? one trigger and resetting time is ok? - - // we'll put these in the CStore: so don't delete them in Finalise! It'll get handled by the Store - ParticleId_to_TankTubeIds = new std::map>; - ParticleId_to_MrdTubeIds = new std::map>; - ParticleId_to_VetoTubeIds = new std::map>; - ParticleId_to_TankCharge = new std::map; - ParticleId_to_MrdCharge = new std::map; - ParticleId_to_VetoCharge = new std::map; - trackid_to_mcparticleindex = new std::map; - - //anniegeom->GetChannel(0); // trigger InitChannelMap + file_pmtid.close(); + m_data->CStore.Set("pmt_tubeid_to_channelkey_data", pmtid_to_channelkey); + m_data->CStore.Set("channelkey_to_pmtid_data", channelkey_to_pmtid); + } else { + logmessage = "LoadWCSim::Initialise: PMT ID Configuration file: " + path_chankeymap; + logmessage += " could not be opened! Is the path valid? Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // TODO: should not use relative path. + // There should be an env var that points to the top directory + if (!m_variables.Get("ChankeyToMRDIDMap", path_mrd_chankeymap)) { + path_mrd_chankeymap = "./configfiles/LoadWCSim/MRD_Chankey_WCSimID.dat"; + logmessage = "LoadWCSim::Initialise: ChankeyToMRDIDMap not set in config. "; + logmessage += "Using default path: " + path_mrd_chankeymap; + Log(logmessage, v_warning, verbosity); + } + ifstream file_mrdid(path_mrd_chankeymap.c_str()); + if (file_mrdid.is_open()){ + // watch out: comment or empty lines not supported here + while (!file_mrdid.eof()){ + unsigned long chankey; + int mrdid; + file_mrdid >> chankey >> mrdid; + mrdid_to_channelkey.emplace(mrdid,chankey); + } + file_mrdid.close(); + } else { + logmessage = "LoadWCSim::Initialise: MRD ID Configuration file: " + path_mrd_chankeymap; + logmessage += " could not be opened! Is the path valid? Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // TODO: should not use relative path. + // There should be an env var that points to the top directory + if (!m_variables.Get("ChankeyToFMVIDMap", path_fmv_chankeymap)) { + path_fmv_chankeymap = "./configfiles/LoadWCSim/FMV_Chankey_WCSimID.dat"; + logmessage = "LoadWCSim::Initialise: ChankeyToFMVIDMap not set in config. "; + logmessage += "Using default path: " + path_fmv_chankeymap; + Log(logmessage, v_warning, verbosity); + } + ifstream file_fmvid(path_fmv_chankeymap.c_str()); + if (file_fmvid.is_open()){ + // watch out: comment or empty lines not supported here + while (!file_fmvid.eof()){ + unsigned long chankey; + int fmvid; + file_fmvid >> chankey >> fmvid; + fmvid_to_channelkey.emplace(fmvid,chankey); + } + file_fmvid.close(); + } else { + logmessage = "LoadWCSim::Initialise: FMV ID Configuration file: " + path_fmv_chankeymap; + logmessage += " could not be opened! Is the path valid? Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } - m_data->CStore.Set("UserEvent",false); //enables the ability for other tools to select a specific event number - triggers_event = 0; + // Short Stores README + // ====================================================== + // n.b. m_data->vars is a Store (of ben's Store type) that is not saved to disk. + // m_data->CStore is a single entry binary BoostStore that is not saved to disk. + // m_data->Stores["StoreName"] is a map of binary BoostStores that are saved to disk. + // With BoostStore::Set("MyVariable", myvar), if myvar is not a pointer it will always + // be saved to disk, but if myvar is a pointer the persist flag (default true) controls + // whether it will be saved to disk. In either case the BoostStore becomes the owner + // of the object and will handle its deletion. + // Is 'BoostStore::Save' needed for single-entry stores? + // ---------------- + // BoostStore constructor args: typechecking (bool), m_format (0=binary, 1=ASCII, 2=multievent) + // A BoostStore has a header where useful constants may be saved. The header is a BoostStore itself, + // and can be accessed via: Store.Header->Get() and Store.Header->Set(). + // The method 'BoostStore::Save()' writes everything 'Set' since the last 'Save' to the current entry. + // BoostStore::Clear clears the map of the current entry, to start building a new one. + // Use 'BoostStore::GetEntry(int entrynum)' to load an entry to then be able to 'Get' it's contents. + // 'BoostStore->Header->Get("TotalEntries",NumEvents)' will load the num entries into NumEvents + // ------------------ + // When adding a BoostStore (or class object in general) to a BoostStore (such as ANNIEEvent) + // you call BoostStore::Set("key",ObjectPointer) - BUT be aware that serialization happens when the + // 'Set' method is called - although you pass it a pointer, any subsequent changes to the object + // will NOT get saved! You must call 'Set' AFTER making ALL changes to your object! + ///////////////////////////////////////////////////////// + + // Make class private members; e.g. the WCSimT and WCSimRootGeom + WCSimEntry = new wcsimT(MCFile.c_str(),verbosity); + gROOT->cd(); + + // Make the ANNIEEvent Store if it doesn't exist + // ============================================= + if (m_data->Stores.count("ANNIEEvent") == 0) + m_data->Stores["ANNIEEvent"] = new BoostStore(false, 2); + + MCFile = WCSimEntry->GetCurrentFile()->GetName(); + m_data->Stores.at("ANNIEEvent")->Set("MCFile", MCFile); + + // Grab the geom and record it for LAPPD reader to use later + wcsimrootgeom = WCSimEntry->wcsimrootgeom; + intptr_t geomptr = reinterpret_cast(wcsimrootgeom); + m_data->CStore.Set("WCSimRootGeom", geomptr); + std::ostringstream ss_wcsimrootgeom; + std::ostringstream ss_geomptr; + ss_wcsimrootgeom << wcsimrootgeom; + ss_geomptr << geomptr; + logmessage = "LoadWCSim::Initialise: WCSimRootGeom at: " + ss_wcsimrootgeom.str(); + logmessage += ", and geomptr at: " + ss_geomptr.str(); + Log(logmessage, v_message, verbosity); + + // Convert WCSimRootGeom into ToolChain Geometry class + Geometry* anniegeom = ConstructToolChainGeometry(); + + // Grab root options and record them + wcsimrootopts = WCSimEntry->wcsimrootopts; + int pretriggerwindow = wcsimrootopts->GetNDigitsPreTriggerWindow(); + int posttriggerwindow = wcsimrootopts->GetNDigitsPostTriggerWindow(); + m_data->CStore.Set("WCSimPreTriggerWindow", pretriggerwindow); + m_data->CStore.Set("WCSimPostTriggerWindow", posttriggerwindow); + + // Set run-level information in the ANNIEEvent + // =========================================== + /* + At time of writing ANNIEEvent has the following that need to be Set before each Save: + RunNumber + SubrunNumber + EventNumber + MCParticles + RecoParticles + MCHits + TDCData + RawADCData + CalibratedADCData + RawLAPPDData + CalibratedLAPPDData + TriggerData + MCFlag + EventTime + WCSimEntryNum + MCFile + BeamStatus + */ + + EventNumber = 0; + MCTriggerNum = 0; + + // pull the first entry so it's ready to look at during the first execute loop + int nbytesread = WCSimEntry->GetEntry(WCSimEntryNum); + if (nbytesread <= 0) { + logmessage = "LoadWCSim::Initialise: Issue loading event number: "; + logmessage += std::to_string(WCSimEntryNum) + ". Aborting!"; + Log(logmessage, v_error, verbosity); + + if (nbytesread == -4) { + logmessage = "LoadWCSim::Initialise: Overran the end of TChain! "; + logmessage += "Have you specified more iterations than are available in ToolChainConfig?"; + Log(logmessage, v_error, verbosity); + } + + if (nbytesread==0) { + logmessage = "LoadWCSim::Initialise: No TChain loaded! Is your filepath correct?"; + Log(logmessage, v_error, verbosity); + } + + m_data->vars.Set("StopLoop", 1); + return false; + } + + // TODO: use nominal beam values + double beaminten = 4.777e+12; + double beampow = 3.2545e+16; + uint64_t beamtimestamp = 0; + RunStartTime.SetNs(RunStartUser); + beamstat.set_time(TimeClass(beamtimestamp)); + beamstat.set_pot(beampow); + BeamCondition bc = BeamCondition::Ok; + beamstat.set_condition(bc); + + + // Construct the other objects we'll be setting at event level, + // pass managed pointers to the ANNIEEvent Store + // ============================================= + MCParticles = new std::vector; + MCHits = new std::map>; + TDCData = new std::map>; + EventTime = new TimeClass(); + + // FIXME ? one trigger and resetting time is ok? + // TriggerClass should have a lower case type + std::string triggertype = TriggerType; + std::transform(triggertype.begin(), triggertype.end(), triggertype.begin(), + [](unsigned char c){ return std::tolower(c); }); + + TriggerClass beamtrigger(triggertype, TriggerWord, 0, true, 0); + TriggerData = new std::vector{beamtrigger}; - return true; + // we'll put these in the CStore: so don't delete them in Finalise! It'll get handled by the Store + ParticleId_to_TankTubeIds = new std::map>; + ParticleId_to_MrdTubeIds = new std::map>; + ParticleId_to_VetoTubeIds = new std::map>; + ParticleId_to_TankCharge = new std::map; + ParticleId_to_MrdCharge = new std::map; + ParticleId_to_VetoCharge = new std::map; + trackid_to_mcparticleindex = new std::map; + mapNeutronIsPrim = new std::map; + + // If true then other tools can select a specific event number + m_data->CStore.Set("UserEvent", false); + trigsInEntry = 0; + + return true; } +// Overview of process to extract WCSim files: +// The wcsimT object is a tree that we load into WCSimEntry. +// It contains WCSimRootEvent branches for the tank, MRD, and veto +// (along with geom. and root options). +// Each G4 "event" is obtained by using wcsimT::GetEntry(), +// which loads the specified entry from the WCSimRootEvent branches. +// We loaded the first entry in the initialize stage so we're ready +// at the first execute. We then load the next entry at the end of +// Execute (depending on the splitSubtriggers flag (see below)) +// WCSimRootEvent objects contain "triggers" +// The first trigger contains all the particles initially passed G4. +// Subsequent triggers contain delayed particles (eg. from decays). +// If splitSubtriggers is set to True then each Execute loop will +// add one subtrigger as a single event. +// If splitSubtriggers is set to False then each Execute loop will +// add all subtriggers as a single event. +// In this way the WCSimEntryNum may not match the EventNumber assigned by LoadWCSim. +bool LoadWCSim::Execute() +{ + // Check if another tool has specified an entry and trigger number to load. + // Currently e.g. the EventDisplay has the ability to do that + // ============================================= + bool userEvent; + m_data->CStore.Get("UserEvent", userEvent); + if (userEvent) { + // Grab the user-specified entry + if (m_data->CStore.Get("LoadEvNr", WCSimEntryNum)) { + logmessage = "LoadWCSim::Execute: Going to the user-defined event number: "; + logmessage += std::to_string(WCSimEntryNum); + Log(logmessage, v_message, verbosity); + } else { + logmessage = "LoadWCSim::Execute: Requested to a user-defined event number, "; + logmessage += "but LoadEvNr is not set in the CStore."; + Log(logmessage, v_error, verbosity); + return false; + } + + // Reset the flag and go to the first trigger in that event + m_data->CStore.Set("UserEvent", false); + MCTriggerNum = 0; -bool LoadWCSim::Execute(){ - - // probably not necessary, clears the map for this entry. We're going to re-Set the event entry anyway... - //m_data->Stores.at("ANNIEEvent")->Clear(); - - //check if another tool has specified a specific evnumber to load (currently e.g. the EventDisplay has the ability to do that) - bool user_event; - m_data->CStore.Get("UserEvent",user_event); - if (user_event){ - m_data->CStore.Set("UserEvent",false); - MCTriggernum = 0; //look at first trigger for user-specified event numbers - int user_evnum; - uint16_t currentTriggernum; - bool check_further_triggers=false; - m_data->CStore.Get("LoadEvNr",user_evnum); - m_data->CStore.Get("CheckFurtherTriggers",check_further_triggers); - m_data->CStore.Get("CurrentTriggernum",currentTriggernum); - MCEventNum = user_evnum; - currentTriggernum++; - if (verbosity > 3){ - std::cout <<"check_further_triggers = "<=MaxEntries && MaxEntries>0){ - std::cout<<"LoadWCSim Tool: Reached max entries specified in config file, terminating ToolChain"<vars.Set("StopLoop",1); - } else { - int nbytesread = WCSimEntry->GetEntry(MCEventNum); // <0 if out of file - if (verbosity > v_debug) std::cout <<"LoadWCSim tool: Trying to get next event, MCEventNum: "<vars.Set("StopLoop",1); - return true; - } - } - } - if(verbosity) cout<<"Executing tool LoadWCSim with MC entry "<vars.Get("StopLoop",loopstopped); - if(get_ok && loopstopped){ - // setting StopLoop doesn't terminate the ToolChain if the number of iterations - // is specified manually in the ToolChainConfig. - // This is almost certainly going to result in a segfault somewhere, - // (e.g. if this tool set it in the last loop iteration because it ran out of entries) - // but let's do what we can - Log("WARNING: STOPLOOP HAS BEEN SET. RETURNING",v_error,verbosity); - return 0; - } - MCFile = WCSimEntry->GetCurrentFile()->GetName(); - - MCHits->clear(); - TDCData->clear(); - MCNeutCap.clear(); - MCNeutCapGammas.clear(); - mrd_firstlayer=false; - mrd_lastlayer=false; + // Check if an additional trigger is available and which trigger was requested + bool checkFurtherTriggers = false; + uint16_t currentTriggerNum; + m_data->CStore.Get("CheckFurtherTriggers", checkFurtherTriggers); + m_data->CStore.Get("CurrentTriggernum", currentTriggerNum); + ++currentTriggerNum; - std::map neutcap_is_primary; //map to store whether a neutron capture was from primary neutron or secondary, key = ncapture time, value = was the capture primary? + logmessage = "LoadWCSim::Execute: Check further triggers: " + std::to_string(checkFurtherTriggers); + logmessage += ", current trigger num: " + std::to_string(currentTriggerNum); + logmessage += "\n total number triggers: " + std::to_string(trigsInEntry); + Log(logmessage, v_debug, verbosity); - triggers_event = WCSimEntry->wcsimrootevent->GetNumberOfEvents(); - - int MaxEventNr = MCTriggernum+1; - if (!splitSubtriggers){ - // we'll merge all subtriggers, so loop from 0 to triggers_event; - MCTriggernum = 0; - MaxEventNr = WCSimEntry->wcsimrootevent->GetNumberOfEvents(); - } // else if we're splitting subtriggers, loop from [current MCTriggernum] to [current MCTriggernum+1] - - while (MCTriggernum < MaxEventNr){ - if(verbosity>1) cout<<"getting triggers"<wcsimrootevent->GetTrigger(0); - firsttrigm=WCSimEntry->wcsimrootevent_mrd->GetTrigger(0); - firsttrigv=WCSimEntry->wcsimrootevent_facc->GetTrigger(0); - atrigt = WCSimEntry->wcsimrootevent->GetTrigger(MCTriggernum); - if(MCTriggernum<(WCSimEntry->wcsimrootevent_mrd->GetNumberOfEvents())){ - atrigm = WCSimEntry->wcsimrootevent_mrd->GetTrigger(MCTriggernum); - } else { atrigm=nullptr; } - if(MCTriggernum<(WCSimEntry->wcsimrootevent_facc->GetNumberOfEvents())){ - atrigv = WCSimEntry->wcsimrootevent_facc->GetTrigger(MCTriggernum); - } else { atrigv=nullptr; } - if(verbosity>2) cout<<"wcsimrootevent="<wcsimrootevent<2) cout<<"wcsimrootevent_mrd="<wcsimrootevent_mrd<2) cout<<"wcsimrootevent_facc="<wcsimrootevent_facc<2) cout<<"atrigt="<GetHeader()->GetRun(); - SubrunNumber = 0; - EventTimeNs = atrigt->GetHeader()->GetDate(); - EventTime->SetNs(EventTimeNs); - if(verbosity>2) cout<<"EventTime is "<clear(); - trackid_to_mcparticleindex->clear(); - primarymuonindex=-1; - - std::string geniefilename = firsttrigt->GetHeader()->GetGenieFileName().Data(); - int genieentry = firsttrigt->GetHeader()->GetGenieEntryNum(); - if(verbosity>1) cout<<"Genie file is "<CStore.Set("GenieFile",geniefilename); - m_data->CStore.Set("GenieEntry",std::to_string(genieentry)); - - for(int trigi=0; trigiwcsimrootevent->GetNumberOfEvents(); trigi++){ - - WCSimRootTrigger* atrigtt = WCSimEntry->wcsimrootevent->GetTrigger(trigi); - if(verbosity>1) cout<<"getting "<GetNtrack()<<" tracks from trigger "<GetNtrack(); tracki++){ - if(verbosity>2) cout<<"getting track "<GetTracks()->At(tracki); - /* a WCSimRootTrack has methods: - Int_t GetIpnu() pdg - Int_t GetFlag() -1: neutrino primary, -2: neutrino target, 0: other - Float_t GetM() mass - Float_t GetP() momentum magnitude - Float_t GetE() energy (inc rest mass^2) - Float_t GetEndE() energy on stopping of particle tracking - Float_t GetEndP() momentum on stopping of particle tracking - Int_t GetStartvol() starting volume: 10 is tank, 20 is facc, 30 is mrd - Int_t GetStopvol() stopping volume: but these may not be set. - Float_t GetDir(Int_t i=0) momentum unit vector - Float_t GetPdir(Int_t i=0) momentum vector - Float_t GetPdirEnd(Int_t i=0) direction vector on stop tracking - Float_t GetStop(Int_t i=0) stopping vertex x,y,z for i=0-2, in cm - Float_t GetStart(Int_t i=0) starting vertex x,y,z for i=0-2, in cm - Int_t GetParenttype() parent pdg, 0 for primary. - Float_t GetTime() trj->GetGlobalTime(); starting time of particle - Float_t GetStopTime() - Int_t GetId() wcsim trackid - */ - - tracktype startstoptype = tracktype::UNDEFINED; - //MC particle times are relative to the trigger time - if(nextrack->GetFlag()!=0) { - if (nextrack->GetFlag()==-1){ - double starttime, stoptime = -1; - if (splitSubtriggers){ - //MC particle times now stored relative to the trigger time - starttime = (static_cast(nextrack->GetTime()-EventTimeNs)); - stoptime = (static_cast(nextrack->GetStopTime()-EventTimeNs)); - } else { - starttime = (static_cast(nextrack->GetTime())); - stoptime = (static_cast(nextrack->GetStopTime())); - } - MCParticle neutrino( - nextrack->GetIpnu(), nextrack->GetE(), nextrack->GetEndE(), - Position(nextrack->GetStart(0) / 100., - nextrack->GetStart(1) / 100., - nextrack->GetStart(2) / 100.), - Position(nextrack->GetStop(0) / 100., - nextrack->GetStop(1) / 100., - nextrack->GetStop(2) / 100.), - starttime, - stoptime, - Direction(nextrack->GetDir(0), nextrack->GetDir(1), nextrack->GetDir(2)), - (sqrt(pow(nextrack->GetStop(0)-nextrack->GetStart(0),2.)+ - pow(nextrack->GetStop(1)-nextrack->GetStart(1),2.)+ - pow(nextrack->GetStop(2)-nextrack->GetStart(2),2.))) / 100., - startstoptype, - nextrack->GetId(), - nextrack->GetParenttype(), - nextrack->GetFlag(), - trigi); - - //Set the neutrino as its own particle - m_data->Stores["ANNIEEvent"]->Set("NeutrinoParticle",neutrino); - - continue; // flag 0 only is normal particles: excludes neutrino - } - } - double starttime, stoptime = -1; - if (splitSubtriggers){ - //MC particle times now stored relative to the trigger time - starttime = (static_cast(nextrack->GetTime()-EventTimeNs)); - stoptime = (static_cast(nextrack->GetStopTime()-EventTimeNs)); - } else { - starttime = (static_cast(nextrack->GetTime())); - stoptime = (static_cast(nextrack->GetStopTime())); - } - if (verbosity > 2) std::cout <<"LoadWCSim tool, loaded particle with PDG: "<GetIpnu()<<", Time: "<GetParenttype() << ", EndProcess: "<GetEndProcess()<GetIpnu() == 2112 && nextrack->GetEndProcess() == "nCapture"){ - if (verbosity > 2) std::cout <<"LoadWCSim tool: Neutron capture! Parent: "<GetParenttype()<<", Time: "<GetParenttype()==0)); //store whether neutron was primary - } - MCParticle thisparticle( - nextrack->GetIpnu(), nextrack->GetE(), nextrack->GetEndE(), - Position(nextrack->GetStart(0) / 100., - nextrack->GetStart(1) / 100., - nextrack->GetStart(2) / 100.), - Position(nextrack->GetStop(0) / 100., - nextrack->GetStop(1) / 100., - nextrack->GetStop(2) / 100.), - starttime, - stoptime, - Direction(nextrack->GetDir(0), nextrack->GetDir(1), nextrack->GetDir(2)), - (sqrt(pow(nextrack->GetStop(0)-nextrack->GetStart(0),2.)+ - pow(nextrack->GetStop(1)-nextrack->GetStart(1),2.)+ - pow(nextrack->GetStop(2)-nextrack->GetStart(2),2.))) / 100., - startstoptype, - nextrack->GetId(), - nextrack->GetParenttype(), - nextrack->GetFlag(), - trigi); - // not currently in constructor call, but we now have it in latest WCSim files - // XXX this will fall over with older WCSim files, whose WCSimLib doesn't have this method! - thisparticle.SetTankExitPoint(Position(nextrack->GetTankExitPoint(0)/ 100., - nextrack->GetTankExitPoint(1)/ 100., - nextrack->GetTankExitPoint(2)/ 100.)); - if( (nextrack->GetIpnu()==13) && - (nextrack->GetParenttype()==0) && - (nextrack->GetFlag()==0) && - (primarymuonindex<0) ){ - // call this the primary muon. If we have more than one, use the first - primarymuonindex = MCParticles->size(); - } - if((abs(nextrack->GetIpnu())==13)|| - (abs(nextrack->GetIpnu())==211)|| - (nextrack->GetIpnu()==111)){ - if (verbosity > 0) { - std::cout<<"Found "<GetIpnu()<<" with parent pdg " - <GetParenttype()<<", flag "<GetFlag() - <<" track id "<GetId() - << ", start vertex (" + to_string(nextrack->GetStart(0)/100.) - << ", " + to_string(nextrack->GetStart(1)/100.) - << ", " + to_string(nextrack->GetStart(2)/100.) - << "), and end vertex (" + to_string(nextrack->GetStop(0)/100.) - << ", " + to_string(nextrack->GetStop(1)/100.) - << ", " + to_string(nextrack->GetStop(2)/100.) - << ")" - <GetIpnu()==13) && (nextrack->GetParenttype()==0))|| - (MCParticles->size()==0)){ - if (verbosity) std::cout<<"Found "<GetIpnu()<<" with parent pdg " - <GetParenttype()<<", flag "<GetFlag() - <<" track id "<GetId() - <<" at position "<size()<GetIpnu())==211)|| - (nextrack->GetIpnu()==111)){ - if (verbosity) std::cout<<"Found "<GetIpnu()<<" with parent pdg " - <GetParenttype()<<", flag "<GetFlag() - <<" track id "<GetId() - << ", start vertex (" + to_string(nextrack->GetStart(0)/100.) - << ", " + to_string(nextrack->GetStart(1)/100.) - << ", " + to_string(nextrack->GetStart(2)/100.) - << "), and end vertex (" + to_string(nextrack->GetStop(0)/100.) - << ", " + to_string(nextrack->GetStop(1)/100.) - << ", " + to_string(nextrack->GetStop(2)/100.) - << ")" - <GetIpnu())==13)||(nextrack->GetIpnu()==22)) && - ((abs(nextrack->GetParenttype())==211)||(nextrack->GetParenttype()==111))){ - if (verbosity) std::cout<<"Found "<GetIpnu()<<" with parent pdg " - <GetParenttype()<<", flag "<GetFlag() - <<" track id "<GetId() - <<" at position "<size()<GetIpnu()==13){ - logmessage = "Muon found with flag: "+to_string(nextrack->GetFlag()) - + ", parent type " + to_string(nextrack->GetParenttype()) - + ", Id " + to_string(nextrack->GetId()) - + ", start vertex (" + to_string(nextrack->GetStart(0)/100.) - + ", " + to_string(nextrack->GetStart(1)/100.) - + ", " + to_string(nextrack->GetStart(2)/100.) - + "), and end vertex (" + to_string(nextrack->GetStop(0)/100.) - + ", " + to_string(nextrack->GetStop(1)/100.) - + ", " + to_string(nextrack->GetStop(2)/100.) - + ")"; - Log(logmessage,v_debug,verbosity); - } - - trackid_to_mcparticleindex->emplace(nextrack->GetId(),MCParticles->size()); - MCParticles->push_back(thisparticle); - } - if(verbosity>2) cout<<"MCParticles has "<size()<<" entries"<0, since particle times are relative to the trigger time, - // we need to update all the particle times - double timediff = EventTimeNs - firsttrigt->GetHeader()->GetDate(); - for(MCParticle& aparticle : *MCParticles){ - if (splitSubtriggers){ - aparticle.SetStartTime(aparticle.GetStartTime()-timediff); - aparticle.SetStopTime (aparticle.GetStopTime() -timediff); - } - else { - aparticle.SetStartTime(aparticle.GetStartTime()); - aparticle.SetStopTime (aparticle.GetStopTime()); - } - } - } // end updating particle times - - int numtankdigits = atrigt ? atrigt->GetCherenkovDigiHits()->GetEntries() : 0; - if(verbosity>1) cout<<"looping over "<2) cout<<"getting digit "<GetCherenkovDigiHits()->At(digiti); - //WCSimRootChernkovDigiHit has methods GetTubeId(), GetT(), GetQ(), GetPhotonIds() - if(verbosity>2) cout<<"LoadWCSim tool: next digihit at "<GetTubeId(); // geometry TubeID->channelkey map is made INCLUDING offset of 1 - if(pmt_tubeid_to_channelkey.count(tubeid)==0){ - cerr<<"LoadWCSim ERROR: tank PMT with no associated ChannelKey!"<2) cout<<"LoadWCSim tool: tubeid = "<(digihit->GetT()-HistoricTriggeroffset); // relative to trigger - } else { - // instead take the true time of the first photon - std::vector photonids = digihit->GetPhotonIds(); // indices of the digit's photons - double earliestphotontruetime=999999999999; - for(int& aphotonindex : photonids){ - WCSimRootCherenkovHitTime* thehittimeobject = - (WCSimRootCherenkovHitTime*)firsttrigt->GetCherenkovHitTimes()->At(aphotonindex); - if(thehittimeobject==nullptr){ - cerr<<"LoadWCSim Tool: ERROR! Retrieval of photon from digit returned nullptr!"<(thehittimeobject->GetTruetime()); - if(aphotontime2){ cout<<"digittime is "<GetQ(); - if(verbosity>2) cout<<"digit Q is "< parents = GetHitParentIds(digihit, firsttrigt); - //std::cout <<"digittime before adding event time: "<count(key)==0) MCHits->emplace(key, std::vector{nexthit}); - else MCHits->at(key).push_back(nexthit); - if(verbosity>2) cout<<"digit added"<2) cout<<"done with tank digits"<GetCherenkovDigiHits()->GetEntries() : 0; - if(verbosity>1) cout<<"adding "<2) cout<<"getting digit "<GetCherenkovDigiHits()->At(digiti); - if(verbosity>2) cout<<"next digihit at "<GetTubeId(); - if(verbosity>2) cout<<"tubeid="<(digihit->GetT()-HistoricTriggeroffset); // relative to trigger - } else { - // instead take the true time of the first photon - std::vector photonids = digihit->GetPhotonIds(); // indices of the digit's photons - double earliestphotontruetime=999999999999; - for(int& aphotonindex : photonids){ - WCSimRootCherenkovHitTime* thehittimeobject = - (WCSimRootCherenkovHitTime*)firsttrigm->GetCherenkovHitTimes()->At(aphotonindex); - if(thehittimeobject==nullptr){ - cerr<<"LoadWCSim Tool: ERROR! Retrieval of photon from digit returned nullptr!"<(thehittimeobject->GetTruetime()); - if(aphotontime2){ cout<<"digittime is "<GetQ(); - if(verbosity>2) cout<<"digit Q is "< parents = GetHitParentIds(digihit, firsttrigm); - if (!splitSubtriggers) digittime += EventTimeNs; - - MCHit nexthit(key, digittime, digiq, parents); - if(TDCData->count(key)==0) {TDCData->emplace(key, std::vector{nexthit}); if (Mrd_Chankey_Layer.at(key)==0) mrd_firstlayer=true; if (Mrd_Chankey_Layer.at(key)==10) mrd_lastlayer=true;} - else TDCData->at(key).push_back(nexthit); - if(verbosity>2) cout<<"digit added"<2) cout<<"done with mrd digits"<GetCherenkovDigiHits()->GetEntries() : 0; - if(verbosity>1) cout<<"adding "<2) cout<<"getting digit "<GetCherenkovDigiHits()->At(digiti); - if(verbosity>2) cout<<"next digihit at "<GetTubeId(); - if(verbosity>2) cout<<"tubeid="<(digihit->GetT()-HistoricTriggeroffset); // relative to trigger - } else { - // instead take the true time of the first photon - std::vector photonids = digihit->GetPhotonIds(); // indices of the digit's photons - double earliestphotontruetime=999999999999; - for(int& aphotonindex : photonids){ - WCSimRootCherenkovHitTime* thehittimeobject = - (WCSimRootCherenkovHitTime*)firsttrigv->GetCherenkovHitTimes()->At(aphotonindex); - if(thehittimeobject==nullptr){ - cerr<<"LoadWCSim Tool: ERROR! Retrieval of photon from digit returned nullptr!"<(thehittimeobject->GetTruetime()); - if(aphotontime2){ cout<<"digittime is "<GetQ(); - if(verbosity>2) cout<<"digit Q is "< parents = GetHitParentIds(digihit, firsttrigv); - digittime += EventTimeNs; - - MCHit nexthit(key, digittime, digiq, parents); - if(TDCData->count(key)==0) TDCData->emplace(key, std::vector{nexthit}); - else TDCData->at(key).push_back(nexthit); - if(verbosity>2) cout<<"digit added"<2) cout<<"done with veto digits"<2) cout<<"setting triggerdata time to "<front().SetTime(EventTimeNs); + // If there is a further trigger in the previous event then we'll load that entry + if (checkFurtherTriggers && currentTriggerNum != trigsInEntry) { + --WCSimEntryNum; + MCTriggerNum = currentTriggerNum; + } + + // Load the desired entry + // If this is the last one in the chain then stop the loop + if ((int)WCSimEntryNum >= MaxEntries && MaxEntries > 0) { + logmessage = "LoadWCSim::Execute: Reached max entries specified in the config file. Terminating ToolChain"; + Log(logmessage, v_error, verbosity); + m_data->vars.Set("StopLoop", 1); + } else { + int nBytesRead = WCSimEntry->GetEntry(WCSimEntryNum); // <0 if out of file + + logmessage = "LoadWCSim::Execute: Trying to get next event, WCSimEntryNum: " + std::to_string(WCSimEntryNum); + logmessage += ", N bytes read: " + std::to_string(nBytesRead); + Log(logmessage, v_debug, verbosity); + + if (nBytesRead <= 0) { + logmessage = "LoadWCSim Tool: Reached last entry of WCSim input file, terminating ToolChain"; + Log(logmessage, v_warning, verbosity); + m_data->vars.Set("StopLoop", 1); + return true; + } + } + }// endif userEvent + + logmessage = "LoadWCSim::Execute: Executing with MC entry: " + std::to_string(WCSimEntryNum); + logmessage += " and trigger: " + std::to_string(MCTriggerNum); + Log(logmessage, v_warning, verbosity); + + // setting StopLoop doesn't terminate the ToolChain if the number of iterations + // is specified manually in the ToolChainConfig. + // This is almost certainly going to result in a segfault somewhere, + // (e.g. if this tool set it in the last loop iteration because it ran out of entries) + // but let's do what we can + int loopStopped = 0; + get_ok = m_data->vars.Get("StopLoop",loopStopped); + if (get_ok && loopStopped){ + logmessage = "LoadWCSim::Execute: WARNING: STOPLOOP HAS BEEN SET. RETURNING"; + Log(logmessage, v_warning, verbosity); + return false; + } + + // Start extracting the things from the WCSim file + // ============================================= + MCFile = WCSimEntry->GetCurrentFile()->GetName(); + + // Clean slate + TDCData->clear(); + MCHits->clear(); + MCNeutCap.clear(); + MCNeutCapGammas.clear(); + //MCHitsToParticles.clear(); + mrd_firstlayer = false; + mrd_lastlayer = false; + + // CherenkovHit(Times) are all in first trigger so just grab them once per execute + WCSimRootTrigger* firstTrigTank = WCSimEntry->wcsimrootevent ->GetTrigger(0); + WCSimRootTrigger* firstTrigMRD = WCSimEntry->wcsimrootevent_mrd ->GetTrigger(0); + WCSimRootTrigger* firstTrigVeto = WCSimEntry->wcsimrootevent_facc->GetTrigger(0); + + // Grab GENIE info and record it + std::string genieFilename = firstTrigTank->GetHeader()->GetGenieFileName().Data(); + int genieEntry = firstTrigTank->GetHeader()->GetGenieEntryNum(); + m_data->CStore.Set("GenieFile",genieFilename); + m_data->CStore.Set("GenieEntry",genieEntry); + + logmessage = "LoadWCSim::Execute: GENIE file is " + genieFilename; + logmessage += ", GENIE evt num is: " + std::to_string(genieEntry); + Log(logmessage, v_message, verbosity); + + + // How many triggers to loop over in this Execute? + // If splitSubtriggers is True then we will "loop" over a single trigger + // defined by previously set MCTriggerNum + // If splitSubtriggers is False then we will loop from 0 up to the total + // number of triggers + trigsInEntry = WCSimEntry->wcsimrootevent->GetNumberOfEvents(); + MCTriggerNum = splitSubtriggers ? MCTriggerNum : 0; + int MaxEventNr = splitSubtriggers ? MCTriggerNum + 1 : trigsInEntry; + + logmessage = "LoadWCSim::Execute: There are " + std::to_string(trigsInEntry); + logmessage += " triggers in this entry"; + Log(logmessage, v_warning, verbosity); + + int nMRDTriggers = WCSimEntry->wcsimrootevent_mrd->GetNumberOfEvents(); + int nVetoTriggers = WCSimEntry->wcsimrootevent_facc->GetNumberOfEvents(); + + // Loop over over the triggers + // ============================================= + while (MCTriggerNum < MaxEventNr) { + logmessage = "LoadWCSim::Execute: Getting trigger " + std::to_string(MCTriggerNum); + logmessage += " of " + std::to_string(trigsInEntry); + Log(logmessage, v_message, verbosity); + + WCSimRootTrigger* aTrigTank = WCSimEntry->wcsimrootevent->GetTrigger(MCTriggerNum); + WCSimRootTrigger* aTrigMRD = ( (MCTriggerNum < nMRDTriggers) + ? WCSimEntry->wcsimrootevent_mrd->GetTrigger(MCTriggerNum) + : nullptr ); + WCSimRootTrigger* aTrigVeto = ( (MCTriggerNum < nVetoTriggers) + ? WCSimEntry->wcsimrootevent_facc->GetTrigger(MCTriggerNum) + : nullptr ); + + std::ostringstream ssEventTank, ssEventMRD, ssEventVeto; + std::ostringstream ssTrigTank, ssTrigMRD, ssTrigVeto; + ssEventTank << WCSimEntry->wcsimrootevent; + ssEventMRD << WCSimEntry->wcsimrootevent_mrd; + ssEventVeto << WCSimEntry->wcsimrootevent_facc; + ssTrigTank << aTrigTank; ssTrigMRD << aTrigMRD; ssTrigVeto << aTrigVeto; + logmessage = "LoadWCSim::Execute: memory locations\n"; + logmessage += " wcsimrootevent: " + ssEventTank.str(); + logmessage += ", wcsimrootevent_mrd: " + ssEventMRD.str(); + logmessage += ", wcsimrootevent_facc: " + ssEventVeto.str() + "\n"; + logmessage += " aTrigTank: " + ssTrigTank.str(); + logmessage += ", aTrigMRD: " + ssTrigMRD.str(); + logmessage += ", aTrigVeto: " + ssTrigVeto.str(); + Log(logmessage, v_debug, verbosity); + + + logmessage = "LoadWCSim::Execute: Getting event date"; + Log(logmessage, v_message, verbosity); + + RunNumber = aTrigTank->GetHeader()->GetRun(); + SubrunNumber = 0; + EventTimeNs = aTrigTank->GetHeader()->GetDate(); + EventTime->SetNs(EventTimeNs); + + logmessage = "LoadWCSim::Execute: EventTime is: " + std::to_string(EventTimeNs); + Log(logmessage, v_debug, verbosity); + + // Load everything + // LoadHits returns a bool that we could use, but don't + // ============================================= + LoadMCParticles(firstTrigTank); + LoadNeutronCaptures(aTrigTank); + LoadHits(aTrigTank, firstTrigTank, "Tank"); + LoadHits(aTrigMRD, firstTrigMRD, "MRD" ); + LoadHits(aTrigVeto, firstTrigVeto, "Veto"); + + // Set the event time + logmessage = "LoadWCSim::Execute: Setting triggerdata time to " + std::to_string(EventTimeNs) + " ns"; + Log(logmessage, v_message, verbosity); + TriggerData->front().SetTime(EventTimeNs); - //Load neutron capture information - int numcaptures = atrigt ? atrigt->GetNcaptures() : 0; - if(verbosity>1) cout<<"LoadWCSim tool: looping over "<2) cout<<"getting capture # "<GetCaptures()->At(capi); - - int capt_parent = capt->GetCaptureParent(); - double capt_vtxx = capt->GetCaptureVtx(0); - double capt_vtxy = capt->GetCaptureVtx(1); - double capt_vtxz = capt->GetCaptureVtx(2); - int capt_ngamma = capt->GetNGamma(); - double capt_totalE = capt->GetTotalGammaE(); - double capt_t = capt->GetCaptureT(); - if (splitSubtriggers){ - capt_t -= EventTimeNs; - } - int capt_nucleus = capt->GetCaptureNucleus(); - double double_primary = -9999; - if (neutcap_is_primary.count(capt_t) > 0){ - bool is_primary = neutcap_is_primary.at(capt_t); - if (verbosity > 2) std::cout <<"LoadWCSim tool: NeutCap object at "< check WCSim options - Log("LoadWCSim tool: Capture parent: "+std::to_string(capt_parent)+", capt_nucleus: "+std::to_string(capt_nucleus)+ ", time " + std::to_string(capt_t) + " was not found in neutcap_is_primary map. Was the EndProcess saved in the WCSim output file?",v_warning,verbosity); - } - std::vector gamma_energies; - for (int i_gamma=0; i_gamma < capt_ngamma; i_gamma++){ - WCSimRootCaptureGamma* captgamma = (WCSimRootCaptureGamma*) capt->GetGammas()->At(i_gamma); - gamma_energies.push_back(captgamma->GetE()); - } - if (MCNeutCap.size()==0){ - MCNeutCap.emplace("CaptParent",std::vector{double(capt_parent)}); - MCNeutCap.emplace("CaptVtxX",std::vector{capt_vtxx}); - MCNeutCap.emplace("CaptVtxY",std::vector{capt_vtxy}); - MCNeutCap.emplace("CaptVtxZ",std::vector{capt_vtxz}); - MCNeutCap.emplace("CaptNGamma",std::vector{double(capt_ngamma)}); - MCNeutCap.emplace("CaptTotalE",std::vector{capt_totalE}); - MCNeutCap.emplace("CaptTime",std::vector{capt_t}); - MCNeutCap.emplace("CaptNucleus",std::vector{double(capt_nucleus)}); - MCNeutCapGammas.emplace("CaptGammas",std::vector>{gamma_energies}); - MCNeutCap.emplace("CaptPrimary",std::vector{double_primary}); - } else { - MCNeutCap.at("CaptParent").push_back(capt_parent); - MCNeutCap.at("CaptVtxX").push_back(capt_vtxx); - MCNeutCap.at("CaptVtxY").push_back(capt_vtxy); - MCNeutCap.at("CaptVtxZ").push_back(capt_vtxz); - MCNeutCap.at("CaptNGamma").push_back(capt_ngamma); - MCNeutCap.at("CaptTotalE").push_back(capt_totalE); - MCNeutCap.at("CaptTime").push_back(capt_t); - MCNeutCap.at("CaptNucleus").push_back(capt_nucleus); - MCNeutCapGammas.at("CaptGammas").push_back(gamma_energies); - MCNeutCap.at("CaptPrimary").push_back(double_primary); - } - } - // update the information about tracks and which tank/mrd/veto PMTs they hit - // this needs updating with each MC trigger, as digits are grouped into MC trigger - // so these maps will then only contain the digits respective particles create - // in the active trigger - // - // ParticleId_to_TankTubeIds is a std::map> - // where TotalCharge is the total charge from that particle on that tube - // (in the event that the particle generated several hits on the tube) - // ParticleId_to_TankCharge is a std::map - // where TotalCharge is summed over all digits, on all pmts, which contained - // light from that particle - ParticleId_to_TankTubeIds->clear(); - ParticleId_to_MrdTubeIds->clear(); - ParticleId_to_VetoTubeIds->clear(); - ParticleId_to_TankCharge->clear(); - ParticleId_to_MrdCharge->clear(); - ParticleId_to_VetoCharge->clear(); - MakeParticleToPmtMap(atrigt, firsttrigt, ParticleId_to_TankTubeIds, ParticleId_to_TankCharge, pmt_tubeid_to_channelkey); - MakeParticleToPmtMap(atrigm, firsttrigm, ParticleId_to_MrdTubeIds, ParticleId_to_MrdCharge, mrd_tubeid_to_channelkey); - MakeParticleToPmtMap(atrigv, firsttrigv, ParticleId_to_VetoTubeIds, ParticleId_to_VetoCharge, facc_tubeid_to_channelkey); - MCTriggernum++; - } //End of MCTriggerNum loop - - //int mrdentries; - //m_data->Stores.at("TDCData")->Get("TotalEntries",mrdentries); // ?? -// m_data->Stores("WCSimEntries")->Set("wcsimrootevent",WCSimEntry->wcsimrootevent); -// m_data->Stores("WCSimEntries")->Set("wcsimrootevent_mrd",WCSimEntry->wcsimrootevent_mrd); -// m_data->Stores("WCSimEntries")->Set("wcsimrootevent_facc",*(WCSimEntry->wcsimrootevent_facc)); - - - // set event level variables - if(verbosity>1) cout<<"setting the store variables"<Stores.at("ANNIEEvent")->Set("RunNumber",RunNumber); - m_data->Stores.at("ANNIEEvent")->Set("SubrunNumber",SubrunNumber); - m_data->Stores.at("ANNIEEvent")->Set("RunType",RunType); - m_data->Stores.at("ANNIEEvent")->Set("EventNumber",EventNumber); - if(verbosity>2) cout<<"particles"<Stores.at("ANNIEEvent")->Set("MCParticles",MCParticles,true); - //Set up Particles object for reconstructed particles - std::vector Particles_Reco; - m_data->Stores["ANNIEEvent"]->Set("Particles",Particles_Reco); - if(verbosity>2) cout<<"hits"<Stores.at("ANNIEEvent")->Set("MCHits",MCHits,true); - if(verbosity>2) cout<<"tdcdata"<Stores.at("ANNIEEvent")->Set("TDCData",TDCData,true); - // TODO? - // right now we have three Time variables: - // 1. "RunStartTime" which stores just a user passed start time. - // 2. "TriggerData", a one-element vector of TriggerClass objects, each of which has a time member. - // The one used entry has its time member set to the time between MC event start (always 0) - // and the MC trigger time. - // 3. "EventTime" which stores this same time difference between MC Trigger and MC event start - // This means we simulate many events all happening ~ the unix epoch (time 0). - // If we want to simulate a 'run' of events, we need to throw some cumulative running time and - // add this to RunStartTime, and store the Event and Trigger times separately. - // This is done by PulseSimulation tool (timefileout_Time), but maybe should be here... - if(verbosity>2) cout<<"triggerdata"<Stores.at("ANNIEEvent")->Set("TriggerData",TriggerData,true); - if(verbosity>2) cout<<"eventtime"<Stores.at("ANNIEEvent")->Set("RunStartTime",runstarttime); - m_data->Stores.at("ANNIEEvent")->Set("EventTimeTank",runstarttime); - m_data->Stores.at("ANNIEEvent")->Set("EventTimeMRD",RunStartTime); - m_data->Stores.at("ANNIEEvent")->Set("EventTime",EventTime,true); - m_data->Stores.at("ANNIEEvent")->Set("MCEventNum",MCEventNum); - // if we merged the subtriggers, report an MCTriggernum of 0 - // so downstream tools know it's a new event - int reported_triggernum = splitSubtriggers ? MCTriggernum-1 : 0; - m_data->Stores.at("ANNIEEvent")->Set("MCTriggernum",reported_triggernum); - m_data->Stores.at("ANNIEEvent")->Set("MCFile",MCFile); - m_data->Stores.at("ANNIEEvent")->Set("MCFlag",true); - //m_data->Stores.at("ANNIEEvent")->Set("BeamStatus",BeamStatus,true); - m_data->Stores.at("ANNIEEvent")->Set("BeamStatus",beamstat); - m_data->Stores.at("ANNIEEvent")->Set("MCNeutCap",MCNeutCap); - m_data->Stores.at("ANNIEEvent")->Set("MCNeutCapGammas",MCNeutCapGammas); - m_data->CStore.Set("NumTriggersThisMCEvt",WCSimEntry->wcsimrootevent->GetNumberOfEvents()); - // auxilliary information about MC Truth particles - m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_TankTubeIds", ParticleId_to_TankTubeIds, false); - m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_TankCharge", ParticleId_to_TankCharge, false); - m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_MrdTubeIds", ParticleId_to_MrdTubeIds, false); - m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_MrdCharge", ParticleId_to_MrdCharge, false); - m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_VetoTubeIds", ParticleId_to_VetoTubeIds, false); - m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_VetoCharge", ParticleId_to_VetoCharge, false); - m_data->Stores.at("ANNIEEvent")->Set("TrackId_to_MCParticleIndex",trackid_to_mcparticleindex,false); - //Change MRD Triggertype if first and last layer saw a hit (Hardware Cosmic Trigger) - if (mrd_lastlayer && mrd_firstlayer) Triggertype = "Cosmic"; - m_data->Stores.at("ANNIEEvent")->Set("MRDTriggerType",Triggertype); - m_data->Stores.at("ANNIEEvent")->Set("PrimaryMuonIndex",primarymuonindex); - m_data->Stores.at("ANNIEEvent")->Set("TriggerWord",TriggerWord); - - std::map DataStreams; - DataStreams.emplace(std::make_pair("Tank",true)); - DataStreams.emplace(std::make_pair("MRD",true)); - DataStreams.emplace(std::make_pair("Trigger",true)); - DataStreams.emplace(std::make_pair("LAPPD",true)); - m_data->Stores.at("ANNIEEvent")->Set("DataStreams",DataStreams); + // update the information about tracks and which tank/mrd/veto PMTs they hit + // this needs updating with each MC trigger, as digits are grouped into MC trigger + // so these maps will then only contain the digits respective particles create + // in the active trigger + // + // ParticleId_to_TankTubeIds is a std::map> + // where TotalCharge is the total charge from that particle on that tube + // (in the event that the particle generated several hits on the tube) + // ParticleId_to_TankCharge is a std::map + // where TotalCharge is summed over all digits, on all pmts, which contained + // light from that particle + ParticleId_to_TankTubeIds->clear(); + ParticleId_to_MrdTubeIds->clear(); + ParticleId_to_VetoTubeIds->clear(); + ParticleId_to_TankCharge->clear(); + ParticleId_to_MrdCharge->clear(); + ParticleId_to_VetoCharge->clear(); + MakeParticleToPmtMap(aTrigTank, firstTrigTank, ParticleId_to_TankTubeIds, + ParticleId_to_TankCharge, pmt_tubeid_to_channelkey); + MakeParticleToPmtMap(aTrigMRD, firstTrigMRD, ParticleId_to_MrdTubeIds, + ParticleId_to_MrdCharge, mrd_tubeid_to_channelkey); + MakeParticleToPmtMap(aTrigVeto, firstTrigVeto, ParticleId_to_VetoTubeIds, + ParticleId_to_VetoCharge, facc_tubeid_to_channelkey); + MCTriggerNum++; + } //End of MCTriggerNum loop - int TriggerExtended = 1; //1: We have an extended readout for all MC events - m_data->Stores.at("ANNIEEvent")->Set("TriggerExtended",TriggerExtended); - //Things that need to be set by later tools: - //RawADCData - //CalibratedADCData - //RawLAPPDData - //CalibratedLAPPDData - //RecoParticles - if(verbosity>1) cout<<"done loading event"<Stores.at("ANNIEEvent")->Set("RunNumber", RunNumber); + m_data->Stores.at("ANNIEEvent")->Set("SubrunNumber", SubrunNumber); + m_data->Stores.at("ANNIEEvent")->Set("RunType", RunType); + m_data->Stores.at("ANNIEEvent")->Set("EventNumber", EventNumber); + + logmessage = "LoadWCSim::Execute: Setting the MCParticles"; + Log(logmessage, v_debug, verbosity); + m_data->Stores.at("ANNIEEvent")->Set("MCParticles", MCParticles, true); + + // Set up Particles object for reconstructed particles + std::vector Particles_Reco; + m_data->Stores.at("ANNIEEvent")->Set("Particles", Particles_Reco); + + logmessage = "LoadWCSim::Execute: Setting the MCHits"; + Log(logmessage, v_debug, verbosity); + m_data->Stores.at("ANNIEEvent")->Set("MCHits", MCHits, true); + + logmessage = "LoadWCSim::Execute: Setting the TDCData"; + Log(logmessage, v_debug, verbosity); + m_data->Stores.at("ANNIEEvent")->Set("TDCData", TDCData, true); + + // TODO? + // right now we have three Time variables: + // 1. "RunStartTime" which stores just a user passed start time. + // 2. "TriggerData", a one-element vector of TriggerClass objects, each of which has a time member. + // The one used entry has its time member set to the time between MC event start (always 0) + // and the MC trigger time. + // 3. "EventTime" which stores this same time difference between MC Trigger and MC event start + // This means we simulate many events all happening ~ the unix epoch (time 0). + // If we want to simulate a 'run' of events, we need to throw some cumulative running time and + // add this to RunStartTime, and store the Event and Trigger times separately. + // This is done by PulseSimulation tool (timefileout_Time), but maybe should be here... + logmessage = "LoadWCSim::Execute: Setting the TriggerData"; + Log(logmessage, v_debug, verbosity); + m_data->Stores.at("ANNIEEvent")->Set("TriggerData", TriggerData, true); + + logmessage = "LoadWCSim::Execute: Setting the EventTime"; + Log(logmessage, v_debug, verbosity); + long runstarttime = RunStartTime.GetNs(); + m_data->Stores.at("ANNIEEvent")->Set("RunStartTime", runstarttime); + m_data->Stores.at("ANNIEEvent")->Set("EventTimeTank", runstarttime); + m_data->Stores.at("ANNIEEvent")->Set("EventTimeMRD", RunStartTime); + m_data->Stores.at("ANNIEEvent")->Set("EventTime", EventTime, true); + m_data->Stores.at("ANNIEEvent")->Set("MCEventNum", WCSimEntryNum); + + // If we merged the subtriggers, report an MCTriggerNum of 0 + // so downstream tools know it's a new event + int reported_triggernum = splitSubtriggers ? MCTriggerNum-1 : 0; + m_data->Stores.at("ANNIEEvent")->Set("MCTriggerNum", reported_triggernum); + m_data->Stores.at("ANNIEEvent")->Set("MCFile", MCFile); + m_data->Stores.at("ANNIEEvent")->Set("MCFlag", true); + m_data->Stores.at("ANNIEEvent")->Set("BeamStatus", beamstat); + m_data->Stores.at("ANNIEEvent")->Set("MCNeutCap", MCNeutCap); + m_data->Stores.at("ANNIEEvent")->Set("MCNeutCapGammas", MCNeutCapGammas); + m_data->CStore.Set("NumTriggersThisMCEvt", trigsInEntry); + + // auxilliary information about MC Truth particles + m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_TankTubeIds", ParticleId_to_TankTubeIds, false); + m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_TankCharge", ParticleId_to_TankCharge, false); + m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_MrdTubeIds", ParticleId_to_MrdTubeIds, false); + m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_MrdCharge", ParticleId_to_MrdCharge, false); + m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_VetoTubeIds", ParticleId_to_VetoTubeIds, false); + m_data->Stores.at("ANNIEEvent")->Set("ParticleId_to_VetoCharge", ParticleId_to_VetoCharge, false); + m_data->Stores.at("ANNIEEvent")->Set("TrackId_to_MCParticleIndex",trackid_to_mcparticleindex,false); + + //Change MRD TriggerType if first and last layer saw a hit (Hardware Cosmic Trigger) + if (mrd_lastlayer && mrd_firstlayer) TriggerType = "Cosmic"; + m_data->Stores.at("ANNIEEvent")->Set("MRDTriggerType", TriggerType); + m_data->Stores.at("ANNIEEvent")->Set("PrimaryMuonIndex", primaryMuonIndex); + m_data->Stores.at("ANNIEEvent")->Set("TriggerWord", TriggerWord); - EventNumber++; - if(verbosity>2) cout<<"checking if we're done on trigs in this event"<wcsimrootevent->GetNumberOfEvents()){ - MCTriggernum=0; - MCEventNum++; - newentry=true; - if(verbosity>2) cout<<"this is the last trigger in the event: next loop will process a new event"<2) cout<<"there are further triggers in this event: next loop will process the trigger "<wcsimrootevent->GetNumberOfEvents()<=MaxEntries && MaxEntries>0){ - cout<<"LoadWCSim Tool: Reached max entries specified in config file, terminating ToolChain"<vars.Set("StopLoop",1); - } else { - int nbytesread = WCSimEntry->GetEntry(MCEventNum); // <0 if out of file - if (verbosity > 2) std::cout <<"LoadWCSim tool: Trying to get next event, MCEventNum: "<vars.Set("StopLoop",1); - } - } - } + std::map DataStreams; + DataStreams.emplace(std::make_pair("Tank", true)); + DataStreams.emplace(std::make_pair("MRD", true)); + DataStreams.emplace(std::make_pair("Trigger", true)); + DataStreams.emplace(std::make_pair("LAPPD", true)); + m_data->Stores.at("ANNIEEvent")->Set("DataStreams", DataStreams); + + // We have an extended readout for all MC events, set to 1 + m_data->Stores.at("ANNIEEvent")->Set("TriggerExtended", 1); + + logmessage = "LoadWCSim::Execute: Done loading event"; + Log(logmessage, v_message, verbosity); + + ++EventNumber; + + // Things that will be set by later tools: + // RawADCData + // CalibratedADCData + // RawLAPPDData + // CalibratedLAPPDData + // RecoParticles + + logmessage = "LoadWCSim::Execute: Checking if we're done with trigs from this event"; + Log(logmessage, v_debug, verbosity); + + bool newentry = false; + if (MCTriggerNum == trigsInEntry) { + MCTriggerNum = 0; + ++WCSimEntryNum; + newentry = true; + + logmessage = "LoadWCSim::Execute: This is the last trigger in the event. "; + logmessage += "Next loop with process a new event"; + Log(logmessage, v_debug, verbosity); + } else { + logmessage = "LoadWCSim::Execute: There are additional trigger in this event. "; + logmessage += "Next loop with process trigger: " + std::to_string(MCTriggerNum); + logmessage += "/" + std::to_string(trigsInEntry); + + } + + // Load the next entry to get it ready for the next Execute loop + // If this is the last one in the chain then stop the loop + if (newentry) { + // if next loop is processing the next trigger in the same entry, no need to re-load it + if ((int)WCSimEntryNum >= MaxEntries && MaxEntries > 0) { + logmessage = "LoadWCSim::Execute: Reached the max number of entries specified in the config. "; + logmessage += "Terminating the ToolChain"; + Log(logmessage, v_warning, verbosity); + + m_data->vars.Set("StopLoop", 1); + } else { + int nBytesRead = WCSimEntry->GetEntry(WCSimEntryNum); // <0 if out of file + + logmessage = "LoadWCSim::Execute: Trying to get the next event. "; + logmessage += "WCSimEntryNum: " + std::to_string(WCSimEntryNum); + logmessage += ", nBytesRead: " + std::to_string(nBytesRead); + Log(logmessage, v_debug, verbosity); + + + // Check if we've reached the end of the file + if (nBytesRead <= 0){ + logmessage = "LoadWCSim::Execute: Reached the last entry of the WCSim input file. "; + logmessage += "Terminating the ToolChain"; + Log(logmessage, v_warning, verbosity); + + m_data->vars.Set("StopLoop", 1); + } + } + } - //gObjectTable->Print(); - return true; + return true; } -bool LoadWCSim::Finalise(){ - WCSimEntry->GetCurrentFile()->Close(); - delete WCSimEntry; - - // any pointers put in Stores to objects we do not want the Store to clean up - // must be nullified before in finalise to prevent double free - // can't just put 0 or nullptr directly as type must be recognisable as a pointer -// std::map>* ParticleId_to_TankTubeIds_nullptr = nullptr; -// std::map>* ParticleId_to_MrdTubeIds_nullptr = nullptr; -// std::map>* ParticleId_to_VetoTubeIds_nullptr = nullptr; -// std::map* ParticleId_to_TankCharge_nullptr = nullptr; -// std::map* ParticleId_to_MrdCharge_nullptr = nullptr; -// std::map* ParticleId_to_VetoCharge_nullptr = nullptr; +bool LoadWCSim::Finalise() +{ + WCSimEntry->GetCurrentFile()->Close(); + delete WCSimEntry; -// m_data->CStore.Set("ParticleId_to_TankTubeIds", ParticleId_to_TankTubeIds_nullptr, false); -// m_data->CStore.Set("ParticleId_to_TankCharge", ParticleId_to_TankCharge_nullptr, false); -// m_data->CStore.Set("ParticleId_to_MrdTubeIds", ParticleId_to_MrdTubeIds_nullptr, false); -// m_data->CStore.Set("ParticleId_to_MrdCharge", ParticleId_to_MrdCharge_nullptr, false); -// m_data->CStore.Set("ParticleId_to_VetoTubeIds", ParticleId_to_VetoTubeIds_nullptr, false); -// m_data->CStore.Set("ParticleId_to_VetoCharge", ParticleId_to_VetoCharge_nullptr, false); - - return true; + return true; } -Geometry* LoadWCSim::ConstructToolChainGeometry(){ - // Pull details from the WCSimRootGeom - // =================================== - double WCSimGeometryVer = 1; // TODO: pull this from some suitable variable - // some variables are available from wcsimrootgeom. TODO: put everything into wcsimrootgeom - numtankpmts = wcsimrootgeom->GetWCNumPMT(); - numlappds = wcsimrootgeom->GetWCNumLAPPD(); - nummrdpmts = wcsimrootgeom->GetWCNumMRDPMT(); - numvetopmts = wcsimrootgeom->GetWCNumFACCPMT(); - double tank_xcentre = (wcsimrootgeom->GetWCOffset(0)) / 100.; // convert [cm] to [m] - double tank_ycentre = (wcsimrootgeom->GetWCOffset(1)) / 100.; - double tank_zcentre = (wcsimrootgeom->GetWCOffset(2)) / 100.; - Position tank_centre(tank_xcentre, tank_ycentre, tank_zcentre); - double tank_radius = (wcsimrootgeom->GetWCCylRadius()) / 100.; //GetWCCylRadius() returns the black sheet radius not the tank radius - double tank_halfheight = (wcsimrootgeom->GetWCCylLength()) / 200.; //GetWCCylLength() returns the main annulus height not the tank height - //Currently hard-coded; estimated with a tape measure on the ANNIE frame :) - double pmt_enclosed_radius = 1.0; - double pmt_enclosed_halfheight = 1.45; - // geometry variables not yet in wcsimrootgeom are in MRDSpecs.hh - double mrd_width = (MRDSpecs::MRD_width) / 100.; - double mrd_height = (MRDSpecs::MRD_height) / 100.; - double mrd_depth = (MRDSpecs::MRD_depth) / 100.; - double mrd_start = (MRDSpecs::MRD_start) / 100.; - if(verbosity>1) cout<<"we have "<1){ - cout<<"constructed anniegeom at "<Stores.at("ANNIEEvent")->Header->Set("AnnieGeometry",anniegeom,true); +Geometry* LoadWCSim::ConstructToolChainGeometry() +{ + // Pull details from the WCSimRootGeom + // ====================================================== + double WCSimGeometryVer = 1; // TODO: pull this from some suitable variable + // some variables are available from wcsimrootgeom. TODO: put everything into wcsimrootgeom + numtankpmts = wcsimrootgeom->GetWCNumPMT(); + numlappds = wcsimrootgeom->GetWCNumLAPPD(); + nummrdpmts = wcsimrootgeom->GetWCNumMRDPMT(); + numvetopmts = wcsimrootgeom->GetWCNumFACCPMT(); + + Position tank_centre(wcsimrootgeom->GetWCOffset(0), + wcsimrootgeom->GetWCOffset(1), + wcsimrootgeom->GetWCOffset(2)); + tank_centre.UnitToMeter(); + + // GetWCCylRadius() returns the black sheet radius not the tank radius + double tank_radius = (wcsimrootgeom->GetWCCylRadius()) / 100.; + + // GetWCCylLength() returns the main annulus height not the tank height + double tank_halfheight = 0.5*(wcsimrootgeom->GetWCCylLength()) / 100.; + + //Currently hard-coded; estimated with a tape measure on the ANNIE frame :) + double pmt_enclosed_radius = 1.0; + double pmt_enclosed_halfheight = 1.45; + + // geometry variables not yet in wcsimrootgeom are in MRDSpecs.hh + double mrd_width = (MRDSpecs::MRD_width) / 100.; + double mrd_height = (MRDSpecs::MRD_height) / 100.; + double mrd_depth = (MRDSpecs::MRD_depth) / 100.; + double mrd_start = (MRDSpecs::MRD_start) / 100.; + + logmessage = "LoadWCSim::ConstructToolChainGeometry: We have "; + logmessage += std::to_string(numtankpmts) + " tank PMTs, "; + logmessage += std::to_string(nummrdpmts) + " MRD PMTs, and"; + logmessage += std::to_string(numlappds) + " LAPPDs"; + Log(logmessage, v_message, verbosity); - // Construct the Detectors and Channels - // ==================================== - // PMTs - unsigned int ADC_Crate_Num = 0; - unsigned int ADC_Card_Num = 0; - unsigned int ADC_Chan_Num = 0; - unsigned int MT_Crate_Num = 0; - unsigned int MT_Card_Num = 0; - unsigned int MT_Chan_Num = 0; - // LAPPDs - unsigned int ACDC_Crate_Num = 0; - unsigned int ACDC_Card_Num = 0; - unsigned int ACDC_Chan_Num = 0; - unsigned int ACC_Crate_Num = 0; - unsigned int ACC_Card_Num = 0; - unsigned int ACC_Chan_Num = 0; - // TDCs - unsigned int TDC_Crate_Num = 0; - unsigned int TDC_Card_Num = 0; - unsigned int TDC_Chan_Num = 0; - // HV - unsigned int CAEN_HV_Crate_Num = 0; - unsigned int CAEN_HV_Card_Num = 0; - unsigned int CAEN_HV_Chan_Num = 0; - unsigned int LeCroy_HV_Crate_Num = 0; - unsigned int LeCroy_HV_Card_Num = 0; - unsigned int LeCroy_HV_Chan_Num = 0; - unsigned int LAPPD_HV_Crate_Num = 0; - unsigned int LAPPD_HV_Card_Num = 0; - unsigned int LAPPD_HV_Chan_Num = 0; + // construct the ToolChain Goemetry + // ====================================================== + auto* anniegeom = new Geometry(WCSimGeometryVer, + tank_centre, + tank_radius, + tank_halfheight, + pmt_enclosed_radius, + pmt_enclosed_halfheight, + mrd_width, + mrd_height, + mrd_depth, + mrd_start, + numtankpmts, + nummrdpmts, + numvetopmts, + numlappds, + geostatus::FULLY_OPERATIONAL); + + logmessage = "LoadWCSim::ConstructToolChainGeometry: Constructed anniegeom "; + logmessage += "with tank origin (x, y, z): (" + std::to_string(tank_centre.X()); + logmessage += ", " + std::to_string(tank_centre.Y()); + logmessage += ", " + std::to_string(tank_centre.Z()) + ")"; + Log(logmessage, v_message, verbosity); + + m_data->Stores.at("ANNIEEvent")->Header->Set("AnnieGeometry", anniegeom, true); + // Construct the Detectors and Channels + // ====================================================== + ConstructDetectors(anniegeom, numtankpmts, "Tank" ); + ConstructDetectors(anniegeom, nummrdpmts, "MRD" ); + ConstructDetectors(anniegeom, numvetopmts, "Veto" ); + ConstructDetectors(anniegeom, numlappds, "LAPPD"); + + // for other WCSim tools that may need the WCSim Tube IDs + m_data->CStore.Set("lappd_tubeid_to_detectorkey", lappd_tubeid_to_detectorkey); + m_data->CStore.Set("pmt_tubeid_to_channelkey", pmt_tubeid_to_channelkey ); + m_data->CStore.Set("mrd_tubeid_to_channelkey", mrd_tubeid_to_channelkey ); + m_data->CStore.Set("facc_tubeid_to_channelkey", facc_tubeid_to_channelkey ); + // inverse + m_data->CStore.Set("detectorkey_to_lappdid", detectorkey_to_lappdid ); + m_data->CStore.Set("channelkey_to_pmtid", channelkey_to_pmtid ); + m_data->CStore.Set("channelkey_to_mrdpmtid", channelkey_to_mrdpmtid ); + m_data->CStore.Set("channelkey_to_faccpmtid", channelkey_to_faccpmtid); - // tank PMTs - for(int pmti=0; pmtiGetPMT(pmti); - - // Construct the detector associated with this PMT - //unsigned long uniquedetectorkey = anniegeom->ConsumeNextFreeDetectorKey(); - unsigned long uniquedetectorkey = pmtid_to_channelkey[pmti+1]; - std::string CylLocString; - int cylloc = apmt.GetCylLoc(); - if(apmt.GetName().find("EMI9954KB")!= std::string::npos){ cylloc=6; } // FIXME set OD pmts in WCSim - switch (cylloc){ - case 0: CylLocString = "TopCap"; break; - case 2: CylLocString = "BottomCap"; break; - case 1: CylLocString = "Barrel"; break; - case 4: CylLocString = "MRD"; break; // TODO set this as H or V paddle? And layer? - case 5: CylLocString = "Veto"; break; // TODO set layer? - case 6: CylLocString = "OD"; break; - default: CylLocString = "NA"; break; // unknown - } - Detector adet(uniquedetectorkey, - "Tank", - CylLocString, - Position( apmt.GetPosition(0)/100., - apmt.GetPosition(1)/100., - apmt.GetPosition(2)/100.), - Direction(apmt.GetOrientation(0), - apmt.GetOrientation(1), - apmt.GetOrientation(2)), - apmt.GetName(), - detectorstatus::ON, - 0.); + return anniegeom; +} + +//////////////////////////////////////////////////////////////////////////////// +void LoadWCSim::ConstructDetectors(Geometry* anniegeom, int numDets, std::string system) +{ + // Check the "system" string. Only Tank, MRD, and Veto are allowed + if (system != "Tank" && system != "MRD" && system != "Veto" && system != "LAPPD") { + logmessage = "LoadWCSim::ConstructDetectors: \"system\" must be Tank, MRD, Veto, or LAPPD; but you passed: "; + logmessage += system; + Log(logmessage, v_error, verbosity); + return; + } + + // To fill up crates, cards, and channels monotonically + // they're arbitrary for simulation + int lvl1_crt = 0; + int lvl1_crd = 0; + int lvl1_chn = 0; + int lvl2_crt = 0; + int lvl2_crd = 0; + int lvl2_chn = 0; + int hv_crt = 0; + int hv_crd = 0; + int hv_chn = 0; + + // Loop and build the detectors + // ====================================================== + for (int detIdx = 0; detIdx < numDets; ++detIdx) { + WCSimRootPMT apmt; + if (system == "Tank") apmt = wcsimrootgeom->GetPMT(detIdx); + if (system == "MRD") apmt = wcsimrootgeom->GetMRDPMT(detIdx); + if (system == "Veto") apmt = wcsimrootgeom->GetFACCPMT(detIdx); + if (system == "LAPPD") apmt = wcsimrootgeom->GetLAPPD(detIdx); - // construct the channel associated with this PMT - //unsigned long uniquechannelkey = anniegeom->ConsumeNextFreeChannelKey(); - unsigned long uniquechannelkey = uniquedetectorkey; + // Construct the detector associated with this PMT + // ====================================================== + unsigned long uniquedetectorkey; + if (system == "Tank") uniquedetectorkey = pmtid_to_channelkey[detIdx + 1]; + if (system == "MRD") uniquedetectorkey = mrdid_to_channelkey[detIdx]; + if (system == "Veto") uniquedetectorkey = fmvid_to_channelkey[detIdx]; + if (system == "LAPPD") uniquedetectorkey = anniegeom->ConsumeNextFreeDetectorKey(); + + std::string CylLocString; + int cylloc = apmt.GetCylLoc(); + + // FIXME set OD pmts in WCSim + if (apmt.GetName().find("EMI9954KB") != std::string::npos) cylloc = 6; + + switch (cylloc) { + case 0: CylLocString = "TopCap"; break; + case 2: CylLocString = "BottomCap"; break; + case 1: CylLocString = "Barrel"; break; + case 4: CylLocString = "MRD"; break; // TODO set this as H or V paddle? And layer? + case 5: CylLocString = "Veto"; break; // TODO set layer? + case 6: CylLocString = "OD"; break; + default: CylLocString = "NA"; break; // unknown + } + + Detector adet(uniquedetectorkey, system, CylLocString, + Position( apmt.GetPosition(0)/100., + apmt.GetPosition(1)/100., + apmt.GetPosition(2)/100.), + Direction(apmt.GetOrientation(0), + apmt.GetOrientation(1), + apmt.GetOrientation(2)), + apmt.GetName(), detectorstatus::ON, 0.); + + // Construct the channel associated with this PMT + // Tank, MRD, and Veto have one channel per detector + // LAPPDs have two channels per strip + // ====================================================== + unsigned long uniquechannelkey; + if (system != "LAPPD") { + // Tank, MRD, or Veto + uniquechannelkey = uniquedetectorkey; + ++lvl1_chn; + ++hv_chn; + + if (system == "Tank") { pmt_tubeid_to_channelkey.emplace(apmt.GetTubeNo(), uniquechannelkey); - if (verbosity > 3) std::cout <<"LoadWCSim tool: WCSim ID: "<=ADC_CHANNELS_PER_CARD) { ADC_Chan_Num=0; ADC_Card_Num++; MT_Chan_Num++; } - if(ADC_Card_Num>=ADC_CARDS_PER_CRATE) { ADC_Card_Num=0; ADC_Crate_Num++; } - if(MT_Chan_Num>=MT_CHANNELS_PER_CARD) { MT_Chan_Num=0; MT_Card_Num++; } - if(MT_Card_Num>=MT_CARDS_PER_CRATE) { MT_Card_Num=0; MT_Crate_Num++; } - // same for HV - CAEN_HV_Chan_Num++; - if(CAEN_HV_Chan_Num>=CAEN_HV_CHANNELS_PER_CARD) { CAEN_HV_Chan_Num=0; CAEN_HV_Card_Num++; } - if(CAEN_HV_Card_Num>=CAEN_HV_CARDS_PER_CRATE) { CAEN_HV_Card_Num=0; CAEN_HV_Crate_Num++; } - - Channel pmtchannel( uniquechannelkey, - Position(0,0,0.), - 0, // stripside - 0, // stripnum - ADC_Crate_Num, - ADC_Card_Num, - ADC_Chan_Num, - MT_Crate_Num, - MT_Card_Num, - MT_Chan_Num, - CAEN_HV_Crate_Num, - CAEN_HV_Card_Num, - CAEN_HV_Chan_Num, - channelstatus::ON); - - // Add this channel to the geometry - if(verbosity>4) cout<<"Adding channel "<4) cout<<"Adding detector "<AddDetector(adet); - if(verbosity>4) cout<<"printing geometry"<4) anniegeom->PrintChannels(); - } - - // mrd PMTs - for(int mrdpmti=0; mrdpmtiGetMRDPMT(mrdpmti); - - // Construct the detector associated with this PMT - //unsigned long uniquedetectorkey = anniegeom->ConsumeNextFreeDetectorKey(); - unsigned long uniquedetectorkey = mrdid_to_channelkey[mrdpmti]; - std::string CylLocString; - switch (apmt.GetCylLoc()){ - case 0: CylLocString = "TopCap"; break; - case 2: CylLocString = "BottomCap"; break; - case 1: CylLocString = "Barrel"; break; - case 4: CylLocString = "MRD"; break; // TODO set this as H or V paddle? And layer? - case 5: CylLocString = "Veto"; break; // TODO set layer? - default: CylLocString = "NA"; break; // unknown - } - Detector adet(uniquedetectorkey, - "MRD", - CylLocString, - Position( apmt.GetPosition(0)/100., - apmt.GetPosition(1)/100., - apmt.GetPosition(2)/100.), - Direction(apmt.GetOrientation(0), - apmt.GetOrientation(1), - apmt.GetOrientation(2)), - apmt.GetName(), - detectorstatus::ON, - 0.); - - // construct the channel associated with this PMT - //unsigned long uniquechannelkey = anniegeom->ConsumeNextFreeChannelKey(); - unsigned long uniquechannelkey = uniquedetectorkey; + channelkey_to_pmtid.emplace(uniquechannelkey, apmt.GetTubeNo()); + + if (lvl1_chn >= ADC_CHANNELS_PER_CARD) { lvl1_chn = 0; ++lvl1_crd; ++lvl2_chn; } + if (lvl1_crd >= ADC_CARDS_PER_CRATE) { lvl1_crd = 0; ++lvl1_crt; } + if (lvl2_chn >= MT_CHANNELS_PER_CARD) { lvl2_chn = 0; ++lvl2_crd; } + if (lvl2_crd >= MT_CARDS_PER_CRATE) { lvl2_crd = 0; ++lvl2_crt; } + if (hv_chn >= CAEN_HV_CHANNELS_PER_CARD) { hv_chn = 0; ++hv_crd; } + if (hv_crd >= CAEN_HV_CARDS_PER_CRATE) { hv_crd = 0; ++hv_crt; } + } + + // Technically the LeCroy is for both MRD and Veto. Thus the veto HV + // channel/card/crate should pickup from where the MRD left off + // But these things elements are never called in practice and these + // numbers are largely aribitrary for simulation anyway. + + if (system == "MRD") { mrd_tubeid_to_channelkey.emplace(apmt.GetTubeNo(), uniquechannelkey); channelkey_to_mrdpmtid.emplace(uniquechannelkey, apmt.GetTubeNo()); - - // fill up TDC cards and channels monotonically, they're arbitrary for simulation - TDC_Chan_Num++; - if(TDC_Chan_Num>=TDC_CHANNELS_PER_CARD) { TDC_Chan_Num=0; TDC_Card_Num++; } - if(TDC_Card_Num>=TDC_CARDS_PER_CRATE) { TDC_Card_Num=0; TDC_Crate_Num++; } - // same for HV - LeCroy_HV_Chan_Num++; - if(LeCroy_HV_Chan_Num>=LECROY_HV_CHANNELS_PER_CARD) { LeCroy_HV_Chan_Num=0; LeCroy_HV_Card_Num++; } - if(LeCroy_HV_Card_Num>=LECROY_HV_CARDS_PER_CRATE) { LeCroy_HV_Card_Num=0; LeCroy_HV_Crate_Num++; } - - Channel pmtchannel( uniquechannelkey, - Position(0,0,0.), - 0, // stripside - 0, // stripnum - TDC_Crate_Num, - TDC_Card_Num, - TDC_Chan_Num, - -1, // TDC has no level 2 signal handling - -1, - -1, - LeCroy_HV_Crate_Num, - LeCroy_HV_Card_Num, - LeCroy_HV_Chan_Num, - channelstatus::ON); - + + if (lvl1_chn >= TDC_CHANNELS_PER_CARD) { lvl1_chn = 0; ++lvl1_crd; } + if (lvl1_crd >= TDC_CARDS_PER_CRATE) { lvl1_crd = 0; ++lvl1_crt; } + if (hv_chn >= LECROY_HV_CHANNELS_PER_CARD) { hv_chn = 0; ++hv_crd; } + if (hv_crd >= LECROY_HV_CARDS_PER_CRATE) { hv_crd = 0; ++hv_crt; } + lvl2_crt = -1; lvl2_crd = -1; lvl2_chn = -1; + } + + if (system == "Veto") { + facc_tubeid_to_channelkey.emplace(apmt.GetTubeNo(), uniquechannelkey); + channelkey_to_faccpmtid.emplace(uniquechannelkey, apmt.GetTubeNo()); + + if (lvl1_chn >= TDC_CHANNELS_PER_CARD) { lvl1_chn = 0; ++lvl1_crd; } + if (lvl1_crd >= TDC_CARDS_PER_CRATE) { lvl1_crd = 0; ++lvl1_crt; } + if (hv_chn >= LECROY_HV_CHANNELS_PER_CARD) { hv_chn = 0; ++hv_crd; } + if (hv_crd >= LECROY_HV_CARDS_PER_CRATE) { hv_crd = 0; ++hv_crt; } + lvl2_crt = -1; lvl2_crd = -1; lvl2_chn = -1; + } + + Channel channel(uniquechannelkey, Position(0, 0, 0.), + 0, 0, + lvl1_crt, lvl1_crd, lvl1_chn, + lvl2_crt, lvl2_crd, lvl2_chn, + hv_crt, hv_crd, hv_chn, + channelstatus::ON); + + // Add this channel to the geometry + logmessage = "LoadWCSim::ConstructDetectors: " + system ; + logmessage += ", WCSim ID: " + std::to_string(apmt.GetTubeNo()); + logmessage += " Adding channel: " + std::to_string(uniquechannelkey); + logmessage += " to detector: " + std::to_string(uniquedetectorkey); + Log(logmessage, v_debuggier, verbosity); + + adet.AddChannel(channel); + } else { + // LAPPDs get one channel per strip + lappd_tubeid_to_detectorkey.emplace(apmt.GetTubeNo(), uniquedetectorkey); + detectorkey_to_lappdid.emplace(uniquedetectorkey, apmt.GetTubeNo()); + + for (int stripIdx = 0; stripIdx < LappdNumStrips; ++stripIdx) { + uniquechannelkey = anniegeom->ConsumeNextFreeChannelKey(); + + // Calc strip info + // StripSide == 0 for LHS, StripSide == 1 for RHS + int stripside = ((stripIdx % 2) == 0); + int stripnum = (int)(stripIdx / 2); + double xpos = (stripside) ? -LappdStripLength : LappdStripLength; + double ypos = (stripnum * LappdStripSeparation) - ((LappdNumStrips * LappdStripSeparation) / 2.); + ++lvl1_chn; + ++hv_chn; + if (lvl1_chn >= ACDC_CHANNELS_PER_CARD) { lvl1_chn = 0; ++lvl1_crd; ++lvl2_chn; } + if (lvl1_crd >= ACDC_CARDS_PER_CRATE) { lvl1_crd = 0; ++lvl1_crt; } + if (lvl2_chn >= ACC_CHANNELS_PER_CARD) { lvl2_chn = 0; ++lvl2_crd; } + if (lvl2_crd >= ACC_CARDS_PER_CRATE) { lvl2_crd = 0; ++lvl2_crt; } + if (hv_chn >= LAPPD_HV_CHANNELS_PER_CARD) { hv_chn = 0; ++hv_crd; } + if (hv_crd >= LAPPD_HV_CARDS_PER_CRATE) { hv_crd = 0; ++hv_crt; } + + Channel channel(uniquechannelkey, Position(xpos, ypos, 0.), + stripside, stripnum, + lvl1_crt, lvl1_crd, lvl1_chn, + lvl2_crt, lvl2_crd, lvl2_chn, + hv_crt, hv_crd, hv_chn, + channelstatus::ON); + // Add this channel to the geometry - if(verbosity>4) cout<<"Adding channel "<4) cout<<"Adding detector "<AddDetector(adet); - - // Create a paddle - // FIXME remove dependency on MRDSpecs - if(mrdpmti!=(apmt.GetTubeNo()-1)){ - cerr<<"LoadWCSim: mrdpmti!=pmt.GetTubeNo-1!"<AddDetector(adet); + + if (verbosity >= v_debuggier) anniegeom->PrintChannels(); + + // Finished for the Tank and LAPPDs + // Gotta create paddles for the MRD and Veto + // ====================================================== + if (system == "MRD" || system == "Veto") { + + // Things to fill for paddles + int pad_x, pad_y, pad_z; + int orientation = 0; + Position origin; + std::pair ext_x; + std::pair ext_y; + std::pair ext_z; + + if (system == "MRD") { + if (detIdx != (apmt.GetTubeNo()-1) ) { + logmessage = "LoadWCSim::ConstructDetectors: " + system; + logmessage += "detIdx != pmt.GetTubeNo-1! "; + logmessage += "detIdx = " + std::to_string(detIdx); + logmessage += ", pmt.GetTubeNo = " + std::to_string(apmt.GetTubeNo()); + assert(false); } + // calculate MRD_x_y_z ... MRDSpecs doesn't provide a nice way to do this - int layernum=0; - while ((mrdpmti+1) > MRDSpecs::layeroffsets.at(layernum+1)){ layernum++; } - Mrd_Chankey_Layer.emplace(uniquechannelkey,layernum); - int in_layer_pmtnum = mrdpmti - MRDSpecs::layeroffsets.at(layernum); + int layernum = 0; + while ((detIdx + 1) > MRDSpecs::layeroffsets.at(layernum + 1)) ++layernum; + + Mrd_Chankey_Layer.emplace(uniquechannelkey, layernum); + int in_layer_pmtnum = detIdx - MRDSpecs::layeroffsets.at(layernum); + // paddles in each layer alternate on sides; i.e. paddles 0 and 1 are on opposite sides - int side = in_layer_pmtnum%2; - in_layer_pmtnum = std::floor(in_layer_pmtnum/2); - int orientation = MRDSpecs::paddle_orientations.at(mrdpmti); - int MRD_x = (orientation) ? in_layer_pmtnum : side; - int MRD_y = (orientation) ? side : in_layer_pmtnum; - int MRD_z = layernum+2; // first MRD z layer num is 2 (veto are 0,1) - - Paddle apaddle( uniquedetectorkey, - MRD_x, - MRD_y, - MRD_z, - orientation, - Position( MRDSpecs::paddle_originx.at(mrdpmti)/1000., - MRDSpecs::paddle_originy.at(mrdpmti)/1000., - MRDSpecs::paddle_originz.at(mrdpmti)/1000.), - std::pair{MRDSpecs::paddle_extentsx.at(mrdpmti).first/1000., - MRDSpecs::paddle_extentsx.at(mrdpmti).second/1000.}, - std::pair{MRDSpecs::paddle_extentsy.at(mrdpmti).first/1000., - MRDSpecs::paddle_extentsy.at(mrdpmti).second/1000.}, - std::pair{MRDSpecs::paddle_extentsz.at(mrdpmti).first/1000., - MRDSpecs::paddle_extentsz.at(mrdpmti).second/1000.}); - if(verbosity>4) cout<<"Setting paddle for detector "<SetDetectorPaddle(uniquedetectorkey,apaddle); - - if(verbosity>4) cout<<"printing geometry"<4) anniegeom->PrintChannels(); - } + int side = in_layer_pmtnum % 2; + in_layer_pmtnum = std::floor(in_layer_pmtnum / 2); + orientation = MRDSpecs::paddle_orientations.at(detIdx); + pad_x = (orientation) ? in_layer_pmtnum : side; + pad_y = (orientation) ? side : in_layer_pmtnum; + pad_z = layernum + 2; // first MRD z layer num is 2 (veto are 0,1) + + origin = Position(MRDSpecs::paddle_originx.at(detIdx), + MRDSpecs::paddle_originy.at(detIdx), + MRDSpecs::paddle_originz.at(detIdx)); + + origin *= 1./1000.; + + ext_x = std::make_pair(MRDSpecs::paddle_extentsx.at(detIdx).first/1000., + MRDSpecs::paddle_extentsx.at(detIdx).second/1000.); + + ext_y = std::make_pair(MRDSpecs::paddle_extentsy.at(detIdx).first/1000., + MRDSpecs::paddle_extentsy.at(detIdx).second/1000.); + + ext_z = std::make_pair(MRDSpecs::paddle_extentsz.at(detIdx).first/1000., + MRDSpecs::paddle_extentsz.at(detIdx).second/1000.); + }// endif MRD + + else { // system == "Veto" + pad_z = (uniquedetectorkey>12); // 13 paddles per layer + pad_x = pad_z; // i believe PMTs are on LHS for layer 0, RHS for layer 1 + pad_y = uniquedetectorkey - (13*pad_z); + + // numbers from geofile.txt + origin = Position(0, facc_paddle_yorigins.at(uniquedetectorkey)/100., (pad_z) ? 0.0728 : 0.0508); + + // numbers from WCSim source files / measurements + ext_x = std::make_pair(-1.6,1.6); + ext_y = std::make_pair(origin.Y() - 0.1525, origin.Y() + 0.1525); + ext_z = std::make_pair(origin.Z() - 0.01, origin.Z() + 0.01 ); + }// endif Veto + + Paddle apaddle(uniquedetectorkey, pad_x, pad_y, pad_z, + orientation, origin, ext_x, ext_y, ext_z); + + logmessage = "LoadWCSim::ConstructDetectors: " + system; + logmessage += " Setting paddle for detector: " + std::to_string(uniquedetectorkey); + Log(logmessage, v_debuggier, verbosity); + + anniegeom->SetDetectorPaddle(uniquedetectorkey,apaddle); + }// end paddle things for MRD/Veto + }// end loop over detectors +} +//////////////////////////////////////////////////////////////////////////////// +void LoadWCSim::LoadMCParticles(WCSimRootTrigger* firstTrig) +{ + // MCParticles will only be loaded during trigger 0 of a given entry + // This means that particles from subtriggers are loaded as well + // When we reach those subtriggers then we'll simply update the relevant info + if (MCTriggerNum == 0) { + // Reset the things + MCParticles->clear(); + trackid_to_mcparticleindex->clear(); + mapNeutronIsPrim->clear(); + primaryMuonIndex = -1; + + // Loop over ALL triggers so we can load all MCParticles + for (int trigIdx = 0; trigIdx < WCSimEntry->wcsimrootevent->GetNumberOfEvents(); ++trigIdx) { + + WCSimRootTrigger* aTrigTank = WCSimEntry->wcsimrootevent->GetTrigger(trigIdx); + + // Loop over tracks within this trigger and extract MCParticles + logmessage = "LoadWCSim::LoadMCParticles: Getting " + std::to_string(aTrigTank->GetNtrack()); + logmessage += " tracks from trigger # " + std::to_string(trigIdx); + Log(logmessage, v_message, verbosity); + + for (int trackIdx = 0; trackIdx < aTrigTank->GetNtrack(); trackIdx++) { + logmessage = "LoadWCSim::LoadMCParticles: Getting WCSim track # " + std::to_string(trackIdx); + Log(logmessage, v_message, verbosity); + + auto* nextTrack = (WCSimRootTrack*)aTrigTank->GetTracks()->At(trackIdx); + + tracktype startStopType = tracktype::UNDEFINED; + + // Extract the neutrino information + if (nextTrack->GetFlag() == -1) { + double startTime = AdjustTime((double)nextTrack->GetTime()); + double stopTime = AdjustTime((double)nextTrack->GetStopTime()); + Position startPos(nextTrack->GetStart(0), nextTrack->GetStart(1), nextTrack->GetStart(2)); + Position stopPos(nextTrack->GetStop(0), nextTrack->GetStop(1), nextTrack->GetStop(2)); + startPos.UnitToMeter(); + stopPos.UnitToMeter(); + double length = (stopPos-startPos).Mag(); + + MCParticle neutrino(nextTrack->GetIpnu(), nextTrack->GetE(), nextTrack->GetEndE(), + startPos, stopPos, startTime, stopTime, + Direction(nextTrack->GetDir(0), nextTrack->GetDir(1), nextTrack->GetDir(2)), + length, startStopType, + nextTrack->GetId(), + nextTrack->GetParenttype(), + nextTrack->GetFlag(), + trigIdx); + + // Save the neutrino own particle in the store + m_data->Stores["ANNIEEvent"]->Set("NeutrinoParticle", neutrino); + + // Don't also create a particle for the neutrino + continue; + + }// done extracting the neutrino information + + // Now load the other particles + double startTime = AdjustTime((double)nextTrack->GetTime()); + double stopTime = AdjustTime((double)nextTrack->GetStopTime()); + Position startPos(nextTrack->GetStart(0), nextTrack->GetStart(1), nextTrack->GetStart(2)); + Position stopPos(nextTrack->GetStop(0), nextTrack->GetStop(1), nextTrack->GetStop(2)); + startPos.UnitToMeter(); + stopPos.UnitToMeter(); + double length = (stopPos-startPos).Mag(); - // veto PMTs - for(int faccpmti=0; faccpmtiGetFACCPMT(faccpmti); - - // Construct the detector associated with this PMT - //unsigned long uniquedetectorkey = anniegeom->ConsumeNextFreeDetectorKey(); - unsigned long uniquedetectorkey = fmvid_to_channelkey[faccpmti]; - std::string CylLocString; - switch (apmt.GetCylLoc()){ - case 0: CylLocString = "TopCap"; break; - case 2: CylLocString = "BottomCap"; break; - case 1: CylLocString = "Barrel"; break; - case 4: CylLocString = "MRD"; break; // TODO set this as H or V paddle? And layer? - case 5: CylLocString = "Veto"; break; // TODO set layer? - default: CylLocString = "NA"; break; // unknown - } - Detector adet( uniquedetectorkey, - "Veto", - CylLocString, - Position( apmt.GetPosition(0)/100., - apmt.GetPosition(1)/100., - apmt.GetPosition(2)/100.), - Direction(apmt.GetOrientation(0), - apmt.GetOrientation(1), - apmt.GetOrientation(2)), - apmt.GetName(), - detectorstatus::ON, - 0.); - if (verbosity > 3) std::cout <<"LoadWCSim tool: FACC tube channelkey: "<ConsumeNextFreeChannelKey(); - unsigned long uniquechannelkey = uniquedetectorkey; - facc_tubeid_to_channelkey.emplace(apmt.GetTubeNo(), uniquechannelkey); - channelkey_to_faccpmtid.emplace(uniquechannelkey, apmt.GetTubeNo()); - - // fill up TDC cards and channels monotonically, they're arbitrary for simulation - TDC_Chan_Num++; - if(TDC_Chan_Num>=TDC_CHANNELS_PER_CARD) { TDC_Chan_Num=0; TDC_Card_Num++; } - if(TDC_Card_Num>=TDC_CARDS_PER_CRATE) { TDC_Card_Num=0; TDC_Crate_Num++; } - // same for HV - LeCroy_HV_Chan_Num++; - if(LeCroy_HV_Chan_Num>=LECROY_HV_CHANNELS_PER_CARD) { LeCroy_HV_Chan_Num=0; LeCroy_HV_Card_Num++; } - if(LeCroy_HV_Card_Num>=LECROY_HV_CARDS_PER_CRATE) { LeCroy_HV_Card_Num=0; LeCroy_HV_Crate_Num++; } - - Channel pmtchannel( uniquechannelkey, - Position(0,0,0.), - 0, // stripside - 0, // stripnum - TDC_Crate_Num, - TDC_Card_Num, - TDC_Chan_Num, - -1, // TDC has no level 2 signal handling - -1, - -1, - LeCroy_HV_Crate_Num, - LeCroy_HV_Card_Num, - LeCroy_HV_Chan_Num, - channelstatus::ON); - - // Add this channel to the geometry - if(verbosity>4) cout<<"Adding channel "<4) cout<<"Adding detector "<AddDetector(adet); - - // Create a paddle - // FIXME even MRDSpecs can't save us here; instead hard-code the values for now, - // this will all be replaced eventually anyway - int MRD_z = (uniquedetectorkey>12); // 13 paddles per layer - int MRD_x = MRD_z; // i believe PMTs are on LHS for layer 0, RHS for layer 1 - int MRD_y = uniquedetectorkey - (13*MRD_z); - double paddle_zorigin = (MRD_z) ? 0.0728 : 0.0508; // numbers from geofile.txt - double paddle_yorigin = facc_paddle_yorigins.at(uniquedetectorkey)/100.; - - Paddle apaddle( uniquedetectorkey, - MRD_x, - MRD_y, - MRD_z, - 0, // orientation 0=horizontal, 1=vertical - Position(0,paddle_yorigin,paddle_zorigin), - std::pair{-1.6,1.6}, // numbers from WCSim source files / measurements - std::pair{paddle_yorigin-0.1525,paddle_yorigin+0.1525}, - std::pair{paddle_zorigin-0.01,paddle_zorigin+0.01}); - - //std::cout <<"FACC detkey: "<4) cout<<"Setting paddle for detector "<SetDetectorPaddle(uniquedetectorkey,apaddle); - - if(verbosity>4) cout<<"printing geometry"<4) anniegeom->PrintChannels(); - } + logmessage = "LoadWCSim::LoadMCParticles: Loaded particle with PDG: " + std::to_string(nextTrack->GetIpnu()); + logmessage += ", stop time: " + std::to_string(stopTime); + logmessage += ", end process: " + nextTrack->GetEndProcess(); + Log(logmessage, v_debug, verbosity); + + // Record neutron primary/secondary + if (nextTrack->GetIpnu() == 2112) + mapNeutronIsPrim->emplace(nextTrack->GetId(), (nextTrack->GetParenttype() == 0)); - // lappds - // lappds moved to end such that all the other channels are assigned first - for(int lappdi=0; lappdiGetLAPPD(lappdi); - - // Construct the detector associated with this tile - unsigned long uniquedetectorkey = anniegeom->ConsumeNextFreeDetectorKey(); - std::cout <<"LAPPD unique detectorkey: "<GetIpnu(), nextTrack->GetE(), nextTrack->GetEndE(), + startPos, stopPos, startTime, stopTime, + Direction(nextTrack->GetDir(0), nextTrack->GetDir(1), nextTrack->GetDir(2)), + length, startStopType, + nextTrack->GetId(), + nextTrack->GetParenttype(), + nextTrack->GetFlag(), + trigIdx); + + // Exit point is not currently in constructor call so set it separately + // Older WCSim files do not recor this info. This breaks backward compatibility + Position exitPoint(nextTrack->GetTankExitPoint(0), + nextTrack->GetTankExitPoint(1), + nextTrack->GetTankExitPoint(2)); + exitPoint.UnitToMeter(); + thisparticle.SetTankExitPoint(exitPoint); + + // Check if this is a primary muon. Only record the first one + if (nextTrack->GetIpnu() == 13 && nextTrack->GetParenttype() == 0 && + nextTrack->GetFlag() == 0 && primaryMuonIndex < 0 ) + primaryMuonIndex = MCParticles->size(); + + // Some print outs for "interesting" particles + if (abs(nextTrack->GetIpnu()) == 13 || abs(nextTrack->GetIpnu()) == 211 || nextTrack->GetIpnu() == 111){ + logmessage = "LoadWCSim::LoadMCParticles: Found " + std::to_string(nextTrack->GetIpnu()); + logmessage += " with flag: " + std::to_string(nextTrack->GetFlag()); + logmessage += ", parent type " + std::to_string(nextTrack->GetParenttype()); + logmessage += ", Id " + std::to_string(nextTrack->GetId()); + logmessage += ", start vertex (" + std::to_string(nextTrack->GetStart(0)/100.); + logmessage += ", " + std::to_string(nextTrack->GetStart(1)/100.); + logmessage += ", " + std::to_string(nextTrack->GetStart(2)/100.); + logmessage += "), and end vertex (" + std::to_string(nextTrack->GetStop(0)/100.); + logmessage += ", " + std::to_string(nextTrack->GetStop(1)/100.); + logmessage += ", " + std::to_string(nextTrack->GetStop(2)/100.) + ")"; + Log(logmessage, v_debug, verbosity); } - Detector adet( uniquedetectorkey, - "LAPPD", - CylLocString, - Position( anlappd.GetPosition(0)/100., - anlappd.GetPosition(1)/100., - anlappd.GetPosition(2)/100.), - Direction(anlappd.GetOrientation(0), - anlappd.GetOrientation(1), - anlappd.GetOrientation(2)), - anlappd.GetName(), - detectorstatus::ON, - 0.); - - // construct all the channels associated with this LAPPD - for(int stripi=0; stripiConsumeNextFreeChannelKey(); - - int stripside = ((stripi%2)==0); // StripSide=0 for LHS (x<0), StripSide=1 for RHS (x>0) - int stripnum = (int)(stripi/2); // Strip number: add 2 channels per strip as we go - double xpos = (stripside) ? -LappdStripLength : LappdStripLength; - double ypos = (stripnum*LappdStripSeparation) - ((LappdNumStrips*LappdStripSeparation)/2.); - - // fill up ADC cards and channels monotonically, they're arbitrary for simulation - ACDC_Chan_Num++; - if(ACDC_Chan_Num>=ACDC_CHANNELS_PER_CARD) { ACDC_Chan_Num=0; ACDC_Card_Num++; ACC_Chan_Num++; } - if(ACDC_Card_Num>=ACDC_CARDS_PER_CRATE) { ACDC_Card_Num=0; ACDC_Crate_Num++; } - if(ACC_Chan_Num>=ACC_CHANNELS_PER_CARD) { ACC_Chan_Num=0; ACC_Card_Num++; } - if(ACC_Card_Num>=ACC_CARDS_PER_CRATE) { ACC_Card_Num=0; ACC_Crate_Num++; } - // same for HV - LAPPD_HV_Chan_Num++; - if(LAPPD_HV_Chan_Num>=LAPPD_HV_CHANNELS_PER_CARD) { LAPPD_HV_Chan_Num=0; LAPPD_HV_Card_Num++; } - if(LAPPD_HV_Card_Num>=LAPPD_HV_CARDS_PER_CRATE) { LAPPD_HV_Card_Num=0; LAPPD_HV_Crate_Num++; } - - Channel lappdchannel( uniquechannelkey, - Position(xpos,ypos,0.), - stripside, - stripnum, - ACDC_Crate_Num, - ACDC_Card_Num, - ACDC_Chan_Num, - ACC_Crate_Num, - ACC_Card_Num, - ACC_Chan_Num, - LAPPD_HV_Crate_Num, - LAPPD_HV_Card_Num, - LAPPD_HV_Chan_Num, - channelstatus::ON); + + trackid_to_mcparticleindex->emplace(nextTrack->GetId(),MCParticles->size()); + MCParticles->push_back(thisparticle); + }// end loop over tracks + + logmessage = "LoadWCSim::LoadMCParticles: Loaded " + std::to_string(MCParticles->size()) + " MCParticles"; + Log(logmessage, v_debug, verbosity); + } // end loop over events + }// endif MCTriggerNum == 0 + else { + // if MCTrigger > 0 we need to update all the particle times + // since particle times are relative to the trigger time + double timeDiff = EventTimeNs - firstTrig->GetHeader()->GetDate(); + for (MCParticle& aparticle : *MCParticles) { + if (splitSubtriggers) { + aparticle.SetStartTime(aparticle.GetStartTime() - timeDiff); + aparticle.SetStopTime (aparticle.GetStopTime() - timeDiff); + } + } + } // end updating particle times +} + +//////////////////////////////////////////////////////////////////////////////// +void LoadWCSim::LoadNeutronCaptures(WCSimRootTrigger* aTrig) +{ + int numCaptures = aTrig ? aTrig->GetNcaptures() : 0; + + logmessage = "LoadWCSim::LoadNeutronCaptures: looping over "; + logmessage += std::to_string(numCaptures) + "neutron captures"; + Log(logmessage, v_message, verbosity); + + for (int captIdx = 0; captIdx < numCaptures; ++captIdx) { + logmessage = "LoadWCSim::Execute: getting capture # " + std::to_string(captIdx); + Log(logmessage, v_debug, verbosity); + + auto* capt = (WCSimRootCapture*)aTrig->GetCaptures()->At(captIdx); - // Add this channel to the geometry - if(verbosity>4) cout<<"Adding channel "<4) cout<<"Adding detector "<AddDetector(adet); - if(verbosity>4) cout<<"printing geometry"<4) anniegeom->PrintChannels(); - } - - // for other WCSim tools that may need the WCSim Tube IDs - m_data->CStore.Set("lappd_tubeid_to_detectorkey",lappd_tubeid_to_detectorkey); - m_data->CStore.Set("pmt_tubeid_to_channelkey",pmt_tubeid_to_channelkey); - m_data->CStore.Set("mrd_tubeid_to_channelkey",mrd_tubeid_to_channelkey); - m_data->CStore.Set("facc_tubeid_to_channelkey",facc_tubeid_to_channelkey); - // inverse - m_data->CStore.Set("detectorkey_to_lappdid",detectorkey_to_lappdid); - m_data->CStore.Set("channelkey_to_pmtid",channelkey_to_pmtid); - m_data->CStore.Set("channelkey_to_mrdpmtid",channelkey_to_mrdpmtid); - m_data->CStore.Set("channelkey_to_faccpmtid",channelkey_to_faccpmtid); + int captParent = capt->GetCaptureParent(); + double captVtxX = capt->GetCaptureVtx(0); + double captVtxY = capt->GetCaptureVtx(1); + double captVtxZ = capt->GetCaptureVtx(2); + int captNGamma = capt->GetNGamma(); + double captTotalE = capt->GetTotalGammaE(); + double captT = capt->GetCaptureT(); + int captNucleus = capt->GetCaptureNucleus(); + + // Adjust the time if we're splitting subtriggers + if (splitSubtriggers) captT -= EventTimeNs; + + // Check if capture is from a primary + double doubleIsPrimary = -9999; + if (mapNeutronIsPrim->count(captParent) > 0) { + bool isPrimary = mapNeutronIsPrim->at(captParent); - return anniegeom; + logmessage = "LoadWCSim::Execute: NeutCap object at " + std::to_string(captT); + logmessage += " is from a"; + logmessage += isPrimary ? " primary" : " secondary" ; + logmessage += " neutron parent with ID: " + std::to_string(captParent); + logmessage += " on nucleus: " + std::to_string(captNucleus); + Log(logmessage, v_debug, verbosity); + } else { + // The parent neutron to this capture was not recorded by WCSim + logmessage = "LoadWCSim::Execute: NeutCap object at time " + std::to_string(captT); + logmessage += " is from an unrecorded neutron parent"; + logmessage += " with ID: " + std::to_string(captParent); + logmessage += " on nucleus: " + std::to_string(captNucleus); + Log(logmessage, v_message, verbosity); + } + + // Record the photons from the neutron capture + std::vector gammaEnergies; + for (int gammaIdx = 0; gammaIdx < captNGamma; ++gammaIdx) { + auto* captGamma = (WCSimRootCaptureGamma*) capt->GetGammas()->At(gammaIdx); + gammaEnergies.push_back(captGamma->GetE()); + } + + // Push back the things + if (MCNeutCap.size()==0){ + MCNeutCap.emplace("CaptParent",std::vector{double(captParent)}); + MCNeutCap.emplace("CaptVtxX",std::vector{captVtxX}); + MCNeutCap.emplace("CaptVtxY",std::vector{captVtxY}); + MCNeutCap.emplace("CaptVtxZ",std::vector{captVtxZ}); + MCNeutCap.emplace("CaptNGamma",std::vector{double(captNGamma)}); + MCNeutCap.emplace("CaptTotalE",std::vector{captTotalE}); + MCNeutCap.emplace("CaptTime",std::vector{captT}); + MCNeutCap.emplace("CaptNucleus",std::vector{double(captNucleus)}); + MCNeutCapGammas.emplace("CaptGammas",std::vector>{gammaEnergies}); + MCNeutCap.emplace("CaptPrimary",std::vector{doubleIsPrimary}); + } else { + MCNeutCap.at("CaptParent").push_back(captParent); + MCNeutCap.at("CaptVtxX").push_back(captVtxX); + MCNeutCap.at("CaptVtxY").push_back(captVtxY); + MCNeutCap.at("CaptVtxZ").push_back(captVtxZ); + MCNeutCap.at("CaptNGamma").push_back(captNGamma); + MCNeutCap.at("CaptTotalE").push_back(captTotalE); + MCNeutCap.at("CaptTime").push_back(captT); + MCNeutCap.at("CaptNucleus").push_back(captNucleus); + MCNeutCapGammas.at("CaptGammas").push_back(gammaEnergies); + MCNeutCap.at("CaptPrimary").push_back(doubleIsPrimary); + } + }// end loop over neutron captures } -void LoadWCSim::MakeParticleToPmtMap(WCSimRootTrigger* thistrig, WCSimRootTrigger* firstTrig, std::map>* ParticleId_to_TubeIds, std::map* ParticleId_to_Charge, std::map tubeid_to_channelkey){ - if(thistrig==nullptr) return; - ParticleId_to_TubeIds->clear(); - ParticleId_to_Charge->clear(); - // scan through the parents IDs of the photons contributing to each digit - // make note of which parent contributes to which digit, and which digits are associated with each parent - Log("Making Particle to PMT Map",v_message,verbosity); - // technically the charge will be a lower limit as this sums the charge from all digits - // that a given particle contributed to, but not all this digit's charge may have been - // from this particle. +//////////////////////////////////////////////////////////////////////////////// +bool LoadWCSim::LoadHits(WCSimRootTrigger* thisTrig, WCSimRootTrigger* firstTrig, std::string system) +{ + // Check the "system" string. Only Tank, MRD, and Veto are allowed + if (system != "Tank" && system != "MRD" && system != "Veto") { + logmessage = "LoadWCSim::LoadHits: \"system\" must be Tank, MRD, or Veto; but you passed: "; + logmessage += system; + Log(logmessage, v_error, verbosity); + return false; + } + + int numDigiHits = thisTrig ? thisTrig->GetCherenkovDigiHits()->GetEntries() : 0; + logmessage = "LoadWCSim::LoadHits: Looping over " + std::to_string(numDigiHits); + logmessage += " " + system + " digi. hits"; + Log(logmessage, v_message, verbosity); + + for (int hitIdx = 0; hitIdx < numDigiHits; ++hitIdx) { + logmessage = "LoadWCSim::LoadHits: Getting hit: " + std::to_string(hitIdx); + Log(logmessage, v_debug, verbosity); + + auto* digiHit = (WCSimRootCherenkovDigiHit*)thisTrig->GetCherenkovDigiHits()->At(hitIdx); + int tubeID = digiHit->GetTubeId(); + + if ((system == "Tank" && pmt_tubeid_to_channelkey.count(tubeID) == 0) || + (system == "MRD" && mrd_tubeid_to_channelkey.count(tubeID) == 0) || + (system == "Veto" && facc_tubeid_to_channelkey.count(tubeID) == 0) ) { + logmessage = "LoadWCSim::LoadHits: NO PMT ASSOCIATED WITH ID: " + std::to_string(tubeID); + Log(logmessage, v_error, verbosity); + return false; + } + + uint64_t key; + if (system == "Tank") key = pmt_tubeid_to_channelkey.at(tubeID); + if (system == "MRD") key = mrd_tubeid_to_channelkey.at(tubeID); + if (system == "Veto") key = facc_tubeid_to_channelkey.at(tubeID); + + logmessage = "LoadWCSim::LoadHits: tubeid: " + std::to_string(tubeID); + logmessage += " has ChannelKey: " + std::to_string(key); + Log(logmessage, v_debug, verbosity); + + // Omit masked tank PMTs + if (system == "Tank" && PMTMask != "None" && + std::find(masked_ids.begin(), masked_ids.end(), tubeID) != masked_ids.end()) { + logmessage = "LoadWCSim::LoadHits: Skipping masked PMT: " + std::to_string(tubeID); + Log(logmessage, v_debug, verbosity); + continue; + } + + // Grab the hit charge and time + float digiQ = digiHit->GetQ(); + double digiTime; + if (use_smeared_digit_time) { + // relative to trigger + digiTime = static_cast(digiHit->GetT()-HistoricTriggeroffset); + } else { + // Use the true time of the first photon in the hit + double earliestTime = 999999999999; + + // Loop over indices of the digit's photons not "IDs" + std::vector photonIdxs = digiHit->GetPhotonIds(); + for (int& photonIdx : photonIdxs) { + auto* theHitTimeObject = (WCSimRootCherenkovHitTime*)firstTrig->GetCherenkovHitTimes()->At(photonIdx); + + if (theHitTimeObject == nullptr) { + logmessage = "LoadWCSim::LoadHits: Retrieval of photon from digi. hit returned nullptr!"; + Log(logmessage, v_error, verbosity); + continue; + } + + double thisTime = static_cast(theHitTimeObject->GetTruetime()); + if (thisTime < earliestTime) earliestTime = thisTime; + }// end loop over photons + digiTime = earliestTime; + }// endif use_smeared_digit_time + + // Adjust hit time as necessary based on settings and system + if ( (system == "Tank" && !splitSubtriggers && use_smeared_digit_time) || + (system == "MRD" && !splitSubtriggers) || + (system == "Veto") ) { + digiTime += EventTimeNs; + } + + logmessage = "LoadWCSim::LoadHits: digi. hit time is " + std::to_string(digiTime); + logmessage +=" [ns] from the start of the Trigger"; + logmessage += " and charge is: " + std::to_string(digiQ); + Log(logmessage, v_debug, verbosity); + + // Create the hit and put it in the correct map + MCHit nextHit(key, digiTime, digiQ, GetHitParentIdxs(digiHit, firstTrig)); + + if (system == "Tank") { + if (MCHits->count(key) == 0) MCHits->emplace(key, std::vector{nextHit}); + else MCHits->at(key).push_back(nextHit); + } + + if (system == "MRD") { + if (TDCData->count(key) == 0) TDCData->emplace(key, std::vector{nextHit}); + else TDCData->at(key).push_back(nextHit); + + if (Mrd_Chankey_Layer.at(key) == 0) mrd_firstlayer = true; + if (Mrd_Chankey_Layer.at(key) == 10) mrd_lastlayer = true; + } + + if (system == "Veto") { + if (TDCData->count(key) == 0) TDCData->emplace(key, std::vector{nextHit}); + else TDCData->at(key).push_back(nextHit); + } + + logmessage = "LoadWCSim::LoadHits: Tank hit added for " + system; + Log(logmessage, v_debug, verbosity); + + }// end loop over hits + + logmessage = "LoadWCSim::LoadHits: Finished loading " + system + " hits"; + Log(logmessage, v_message, verbosity); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +void LoadWCSim::MakeParticleToPmtMap(WCSimRootTrigger* thistrig, + WCSimRootTrigger* firstTrig, + std::map>* ParticleId_to_TubeIds, + std::map* ParticleId_to_Charge, + std::map tubeid_to_channelkey) +{ + if (thistrig==nullptr) return; + ParticleId_to_TubeIds->clear(); + ParticleId_to_Charge->clear(); + // scan through the parents IDs of the photons contributing to each digit + // make note of which parent contributes to which digit, and which digits are associated with each parent + Log("Making Particle to PMT Map",v_message, verbosity); + // technically the charge will be a lower limit as this sums the charge from all digits + // that a given particle contributed to, but not all this digit's charge may have been + // from this particle. - // To match digits to their parent particles we need the corresponding CherenkovHitTimes - // both CherenkovHits and CherenkovHitTimes are stored in the first trigger - //-------------------------------------------------------------------------------------- + // To match digits to their parent particles we need the corresponding CherenkovHitTimes + // both CherenkovHits and CherenkovHitTimes are stored in the first trigger + //-------------------------------------------------------------------------------------- - // Loop over all digits - int numdigits = thistrig->GetCherenkovDigiHits()->GetEntries(); - for(int digiti=0; digitiGetCherenkovDigiHits()->At(digiti); - int tubeid = digihit->GetTubeId(); - // loop over the photons in this digit - std::vector truephotonindices = digihit->GetPhotonIds(); - for(int truephoton=0; truephoton<(int)truephotonindices.size(); truephoton++){ - int thephotonsid = truephotonindices.at(truephoton); - // get the index of the photon CherenkovHit object in the TClonesArray - if(WCSimVersion<2){ - if(timeArrayOffsetMap.size()==0) BuildTimeArrayOffsetMap(firstTrig); - thephotonsid+=timeArrayOffsetMap.at(tubeid); } - // Get the CherenkovHitTime object that records the photon's Parent ID - WCSimRootCherenkovHitTime *thehittimeobject = - (WCSimRootCherenkovHitTime*)(firstTrig->GetCherenkovHitTimes()->At(thephotonsid)); - if(thehittimeobject==nullptr) cerr<<"HITTIME IS NULL"<GetParentID() : -1; - // We'll want a map of particle ID to channel keys, so convert WCSim TubeId to channelkey - int channelkey = tubeid_to_channelkey.at(tubeid); + // Loop over all digits + int numdigits = thistrig->GetCherenkovDigiHits()->GetEntries(); + for (int digitIdx=0; digitIdxGetCherenkovDigiHits()->At(digitIdx); + int tubeID = digihit->GetTubeId(); + double hitQ = digihit->GetQ(); + + + // loop over the photons in this digit + std::vector truephotonindices = digihit->GetPhotonIds(); + for (int thephotonsid : truephotonindices) { + + // get the index of the photon CherenkovHit object in the TClonesArray + if (WCSimVersion < 2) { + if (!timeArrayOffsetMap.size()) BuildTimeArrayOffsetMap(firstTrig); + thephotonsid += timeArrayOffsetMap.at(tubeID); + } + + // Get the CherenkovHitTime object that records the photon's Parent ID + auto* thehittimeobject = (WCSimRootCherenkovHitTime*)(firstTrig->GetCherenkovHitTimes()->At(thephotonsid)); + + // get the parent ID from the CherenkovHitTime + Int_t parentID = (thehittimeobject) ? thehittimeobject->GetParentID() : -1; + + // We'll want a map of particle ID to channel keys, so convert WCSim TubeID to channelkey + int chankey = tubeid_to_channelkey.at(tubeID); - // Finally we can record this pairing of Tube to Particle - if(ParticleId_to_TubeIds->count(thephotonsparenttrackid)==0){ - // we've not recorded any hits for this particle: make an empty map for it - ParticleId_to_TubeIds->emplace(thephotonsparenttrackid,std::map{}); - } - if(ParticleId_to_TubeIds->at(thephotonsparenttrackid).count(channelkey)==0){ - // in the map for this particle record that this tube was hit - ParticleId_to_TubeIds->at(thephotonsparenttrackid).emplace(channelkey,digihit->GetQ()); -// -// double particletime = -1; -// int particletrigger = -1; -// if(trackid_to_mcparticleindex->count(thephotonsparenttrackid)){ -// int particleindex = trackid_to_mcparticleindex->at(thephotonsparenttrackid); -// MCParticle theparticle = MCParticles->at(particleindex); -// particletime = theparticle.GetStartTime(); -// particletrigger = theparticle.GetMCTriggerNum(); -// } -// double hittime = digihit->GetT(); -// double triggertime = thistrig->GetHeader()->GetDate(); -// std::cout<<"Particle "<at(thephotonsparenttrackid).at(channelkey)+=digihit->GetQ(); - } - if(ParticleId_to_Charge->count(thephotonsparenttrackid)==0){ - // first time seeing this particle - ParticleId_to_Charge->emplace(thephotonsparenttrackid,digihit->GetQ()); - } else { - ParticleId_to_Charge->at(thephotonsparenttrackid)+=digihit->GetQ(); - } - } - } // end loop over digits + // Finally we can record the things + // Check for parentID not in outer map, place it there empty + auto outerIt = ParticleId_to_TubeIds->find(parentID); + if (outerIt == ParticleId_to_TubeIds->end()) + outerIt = ParticleId_to_TubeIds->emplace(parentID, std::map()).first; + + // Now emplace the charge value + // Will succeed (result.second == true) if tubeID is not present + // Will fail if tubeID is present. In which case we'll increment the charge + auto result_PartToTubeIDs = outerIt->second.emplace(tubeID, hitQ); + if (!result_PartToTubeIDs.second) + result_PartToTubeIDs.first->second += hitQ; + + // Similar for the total charge map, but this is not nested + auto result_PartToCharge = ParticleId_to_Charge->emplace(parentID, hitQ); + if (!result_PartToCharge.second) + result_PartToCharge.first->second += hitQ; + + }// end loop over photons + }// end loop over digits } -std::vector LoadWCSim::GetHitParentIds(WCSimRootCherenkovDigiHit* digihit, WCSimRootTrigger* firstTrig){ - /* Get the ID of the MCParticle(s) that produced this digit */ - std::vector parentids; // a hit could technically have more than one contrbuting particle +//////////////////////////////////////////////////////////////////////////////// +// Get the ID of the primary MCParticle(s) that produced this digi. hit +std::vector LoadWCSim::GetHitParentIDs(WCSimRootCherenkovDigiHit* digiHit, WCSimRootTrigger* firstTrig) +{ + std::vector parentIDs; // a hit could technically have more than one contrbuting particle - // loop over the photons in this digit - std::vector truephotonindices = digihit->GetPhotonIds(); - for(int truephoton=0; truephoton<(int)truephotonindices.size(); truephoton++){ - int thephotonsid = truephotonindices.at(truephoton); - // get the indices of the digit's photon CherenkovHitTime objects - if(WCSimVersion<2){ - if(timeArrayOffsetMap.size()==0) BuildTimeArrayOffsetMap(firstTrig); - thephotonsid+=timeArrayOffsetMap.at(digihit->GetTubeId()); - } - // get the CherenkovHitTime objects themselves, which contain the photon parent IDs - WCSimRootCherenkovHitTime *thehittimeobject = - (WCSimRootCherenkovHitTime*)(firstTrig->GetCherenkovHitTimes()->At(thephotonsid)); - if(thehittimeobject==nullptr) cerr<<"HITTIME IS NULL"<GetParentID(); - // check if this parent track was saved. Not all particles are saved. - if(trackid_to_mcparticleindex->count(theparenttrackid)){ - parentids.push_back(trackid_to_mcparticleindex->at(theparenttrackid)); - } // else this photon may have come from e.g. an electron or gamma that wasn't recorded - } - } - return parentids; + // loop over the photons in this digit + std::vector photonIdxs = digiHit->GetPhotonIds(); + for (int photonIdx : photonIdxs) { + // Special offset for older WCSim + if (WCSimVersion < 2) { + if (timeArrayOffsetMap.size() == 0) BuildTimeArrayOffsetMap(firstTrig); + photonIdx += timeArrayOffsetMap.at(digiHit->GetTubeId()); + } + + // Get the CherenkovHitTime objects themselves, which contain the primary parent IDs + auto* theHitTimeObject = (WCSimRootCherenkovHitTime*)(firstTrig->GetCherenkovHitTimes()->At(photonIdx)); + + if (theHitTimeObject == nullptr) { + logmessage = "LoadWCSim::GetHitParentIDs: HitTime object is NULL!!"; + Log(logmessage, v_error, verbosity); + } + else + parentIDs.push_back(theHitTimeObject->GetParentID()); + + }// end loop over photons + return parentIDs; } -void LoadWCSim::BuildTimeArrayOffsetMap(WCSimRootTrigger* firstTrig){ - if(WCSimVersion<2){ - // The CherenkovHitTimes is a flattened array (over PMTs) of arrays (over photons) - // For WCSimVersion<2, the PhotonIds available from a digit are the indices - // *within the subarray for that PMT* - // we therefore need we need to offset these indices by the start of the pmt's subarray. - // This offset may be found by scanning the CherenkovHits array (over PMTs), - // finding the correct TubeID, and retrieving the 'GetTotalPe(0)' member for this entry. - int ncherenkovhits=firstTrig->GetCherenkovHits()->GetEntries(); //atrigt->GetNcherenkovhits(); - //int nhittimes = firstTrig->GetCherenkovHitTimes()->GetEntries(); - - for(int ihit = 0; ihit < ncherenkovhits; ihit++){ - // each WCSimRootCherenkovHit represents a hit PMT - WCSimRootCherenkovHit* hitobject = - (WCSimRootCherenkovHit*)firstTrig->GetCherenkovHits()->At(ihit); - if(hitobject==nullptr) cerr<<"HITOBJECT IS NULL!"<GetTubeID(); - int timeArrayOffset = hitobject->GetTotalPe(0); - timeArrayOffsetMap.emplace(tubeNumber,timeArrayOffset); - } - } else { - Log("LoadWCSim Tool: BuildTimeArrayOffsetMap called with WCSimVersion<2: This is not needed!?",v_error,verbosity); - } +//////////////////////////////////////////////////////////////////////////////// +// Get the index within the the MCParticle vector of the primaries that produced this digi. hit +std::vector LoadWCSim::GetHitParentIdxs(WCSimRootCherenkovDigiHit* digiHit, WCSimRootTrigger* firstTrig) +{ + std::vector parentIDs = GetHitParentIDs(digiHit, firstTrig); + std::vector parentIdxs; + + // Check if the parent was recorded, and if so then translate ID to index + for (int parentID : parentIDs) { + if (trackid_to_mcparticleindex->count(parentID)) + parentIdxs.push_back(trackid_to_mcparticleindex->at(parentID)); + } + + return parentIdxs; +} + +//////////////////////////////////////////////////////////////////////////////// +void LoadWCSim::BuildTimeArrayOffsetMap(WCSimRootTrigger* firstTrig) +{ + if (WCSimVersion < 2) { + // The CherenkovHitTimes is a flattened array (over PMTs) of arrays (over photons) + // For WCSimVersion<2, the PhotonIds available from a digit are the indices + // *within the subarray for that PMT* + // we therefore need we need to offset these indices by the start of the pmt's subarray. + // This offset may be found by scanning the CherenkovHits array (over PMTs), + // finding the correct TubeID, and retrieving the 'GetTotalPe(0)' member for this entry. + int ncherenkovhits = firstTrig->GetCherenkovHits()->GetEntries(); + + // each WCSimRootCherenkovHit represents a hit PMT + for (int hitIdx = 0; hitIdx < ncherenkovhits; ++hitIdx){ + auto* hitobject = (WCSimRootCherenkovHit*)firstTrig->GetCherenkovHits()->At(hitIdx); + if (hitobject == nullptr) { + logmessage = "LoadWCSim::BuildTimeArrayOffsetMap: Hit object is NULL!!"; + Log(logmessage, v_error, verbosity); + } + + int tubeNumber = hitobject->GetTubeID(); + int timeArrayOffset = hitobject->GetTotalPe(0); + timeArrayOffsetMap.emplace(tubeNumber, timeArrayOffset); + } + } else { + logmessage = "LoadWCSim::BuildTimeArrayOffsetMap: Called with WCSimVersion < 2. "; + logmessage += "This is not needed!?"; + Log(logmessage, v_error, verbosity); + } } -std::vector LoadWCSim::LoadPMTMask(std::string path_to_pmtmask){ +//////////////////////////////////////////////////////////////////////////////// +std::vector LoadWCSim::LoadPMTMask(std::string path_to_pmtmask) +{ - std::vector mask_vector; - int temp_id; - ifstream maskfile(path_to_pmtmask.c_str()); - while (!maskfile.eof()){ - maskfile >> temp_id; - mask_vector.push_back(temp_id); - if (maskfile.eof()) break; - } + std::vector mask_vector; + int temp_id; + ifstream maskfile(path_to_pmtmask.c_str()); + while (!maskfile.eof()){ + maskfile >> temp_id; + mask_vector.push_back(temp_id); + if (maskfile.eof()) break; + } - return mask_vector; + return mask_vector; +} + +//////////////////////////////////////////////////////////////////////////////// +double LoadWCSim::AdjustTime(double time) +{ + if (splitSubtriggers) return time - EventTimeNs; + else return time; } diff --git a/UserTools/LoadWCSim/LoadWCSim.h b/UserTools/LoadWCSim/LoadWCSim.h index c85e12454..ad2069ec5 100644 --- a/UserTools/LoadWCSim/LoadWCSim.h +++ b/UserTools/LoadWCSim/LoadWCSim.h @@ -23,25 +23,25 @@ namespace{ //PMTs - constexpr int ADC_CHANNELS_PER_CARD=4; - constexpr int ADC_CARDS_PER_CRATE=20; - constexpr int MT_CHANNELS_PER_CARD=4; - constexpr int MT_CARDS_PER_CRATE=20; + constexpr int ADC_CHANNELS_PER_CARD = 4; + constexpr int ADC_CARDS_PER_CRATE = 20 ; + constexpr int MT_CHANNELS_PER_CARD = 4; + constexpr int MT_CARDS_PER_CRATE = 20; //LAPPDs - constexpr int ACDC_CHANNELS_PER_CARD=30; - constexpr int ACDC_CARDS_PER_CRATE=20; - constexpr int ACC_CHANNELS_PER_CARD=8; - constexpr int ACC_CARDS_PER_CRATE=20; + constexpr int ACDC_CHANNELS_PER_CARD = 30; + constexpr int ACDC_CARDS_PER_CRATE = 20; + constexpr int ACC_CHANNELS_PER_CARD = 8; + constexpr int ACC_CARDS_PER_CRATE = 20; //TDCs - constexpr int TDC_CHANNELS_PER_CARD=32; - constexpr int TDC_CARDS_PER_CRATE=6; + constexpr int TDC_CHANNELS_PER_CARD = 32; + constexpr int TDC_CARDS_PER_CRATE = 6; //HV - constexpr int CAEN_HV_CHANNELS_PER_CARD=16; - constexpr int CAEN_HV_CARDS_PER_CRATE=10; - constexpr int LECROY_HV_CHANNELS_PER_CARD=16; - constexpr int LECROY_HV_CARDS_PER_CRATE=16; - constexpr int LAPPD_HV_CHANNELS_PER_CARD=4; // XXX ??? XXX - constexpr int LAPPD_HV_CARDS_PER_CRATE=10; // XXX ??? XXX + constexpr int CAEN_HV_CHANNELS_PER_CARD = 16; + constexpr int CAEN_HV_CARDS_PER_CRATE = 10; + constexpr int LECROY_HV_CHANNELS_PER_CARD = 16; + constexpr int LECROY_HV_CARDS_PER_CRATE = 16; + constexpr int LAPPD_HV_CHANNELS_PER_CARD = 4; // XXX ??? XXX + constexpr int LAPPD_HV_CARDS_PER_CRATE = 10; // XXX ??? XXX } class LoadWCSim: public Tool { @@ -53,6 +53,11 @@ class LoadWCSim: public Tool { bool Execute(); bool Finalise(); std::vector LoadPMTMask(std::string path_to_pmtmask); + void LoadMCParticles(WCSimRootTrigger* firstTrig); + void LoadNeutronCaptures(WCSimRootTrigger* aTrig); + bool LoadHits(WCSimRootTrigger* thisTrig, WCSimRootTrigger* firstTrig, std::string system); + + double AdjustTime(double time); private: @@ -76,9 +81,9 @@ class LoadWCSim: public Tool { ////////////////// //TFile* file; //TTree* wcsimtree; - wcsimT* WCSimEntry; // from makeclass - WCSimRootTrigger* atrigt, *atrigm, *atrigv; - WCSimRootTrigger* firsttrigt, *firsttrigm, *firsttrigv; + wcsimT* WCSimEntry; + WCSimRootTrigger* aTrigTank, *aTrigMRD, *aTrigVeto; + WCSimRootTrigger* firstTrigTank, *firstTrigMRD, *firstTrigVeto; WCSimRootGeom* wcsimrootgeom; WCSimRootOptions* wcsimrootopts; int WCSimVersion; // WCSim version @@ -98,30 +103,48 @@ class LoadWCSim: public Tool { // For constructing ToolChain Geometry ////////////////////////////////////// Geometry* ConstructToolChainGeometry(); - std::map lappd_tubeid_to_detectorkey; - std::map pmt_tubeid_to_channelkey; - std::map mrd_tubeid_to_channelkey; - std::map facc_tubeid_to_channelkey; + void ConstructDetectors(Geometry* anniegeom, int numDets, std::string system); + + std::map lappd_tubeid_to_detectorkey; + std::map pmt_tubeid_to_channelkey; + std::map mrd_tubeid_to_channelkey; + std::map facc_tubeid_to_channelkey; // inverse - std::map detectorkey_to_lappdid; - std::map channelkey_to_pmtid; - std::map channelkey_to_mrdpmtid; - std::map channelkey_to_faccpmtid; - // alternatively? Better? Save the parentage in each MCHit. Each MCHit will contain - // the index of it's parent MCParticle in the MCParticles vector - std::map* trackid_to_mcparticleindex=nullptr; - std::vector GetHitParentIds(WCSimRootCherenkovDigiHit* digihit, WCSimRootTrigger* firstTrig); - std::map timeArrayOffsetMap; + std::map detectorkey_to_lappdid; + std::map channelkey_to_pmtid; + std::map channelkey_to_mrdpmtid; + std::map channelkey_to_faccpmtid; + + // map to store if a neutron is a primary or secondary, + // key = neutron track ID, value == true if prim. + std::map* mapNeutronIsPrim = nullptr; + + // Each MCHit will contain the idx of it's parent MCParticle's + // position within the MCParticles vector + std::map* trackid_to_mcparticleindex = nullptr; + std::vector GetHitParentIDs(WCSimRootCherenkovDigiHit* digiHit, WCSimRootTrigger* firstTrig); + std::vector GetHitParentIdxs(WCSimRootCherenkovDigiHit* digiHit, WCSimRootTrigger* firstTrig); + + std::map timeArrayOffsetMap; void BuildTimeArrayOffsetMap(WCSimRootTrigger* firstTrig); - int triggers_event; - std::map pmtid_to_channelkey; - std::map mrdid_to_channelkey; - std::map fmvid_to_channelkey; + int trigsInEntry; + + std::map pmtid_to_channelkey; + std::map mrdid_to_channelkey; + std::map fmvid_to_channelkey; // FIXME temporary!! remove me when we have a better way to get FACC paddle origins - std::vector facc_paddle_yorigins{-198.699875000, -167.999875000, -137.299875000, -106.599875000, -75.899875000, -45.199875000, -14.499875000, 16.200125000, 46.900125000, 77.600125000, 108.300125000, 139.000125000, 169.700125000, -198.064875000, -167.364875000, -136.664875000, -105.964875000, -75.264875000, -44.564875000, -13.864875000, 16.835125000, 47.535125000, 78.235125000, 108.935125000, 139.635125000, 170.335125000}; // taken from geofile.txt + // taken from geofile.txt + std::vector facc_paddle_yorigins = + {-198.699875000, -167.999875000, -137.299875000, -106.599875000, + -75.899875000, -45.199875000, -14.499875000, 16.200125000, + 46.900125000, 77.600125000, 108.300125000, 139.000125000, + 169.700125000, -198.064875000, -167.364875000, -136.664875000, + -105.964875000, -75.264875000, -44.564875000, -13.864875000, + 16.835125000, 47.535125000, 78.235125000, 108.935125000, + 139.635125000, 170.335125000}; //////////////// // things that will be filled into the store from this WCSim file. @@ -130,8 +153,8 @@ class LoadWCSim: public Tool { // from WCSim to Raw and the proper RawReader Tools // bool MCFlag=true; std::string MCFile; - uint64_t MCEventNum; - uint16_t MCTriggernum; + uint64_t WCSimEntryNum; + uint16_t MCTriggerNum; uint32_t RunNumber; uint32_t SubrunNumber; uint32_t EventNumber; // will need to be tracked separately, since we flatten triggers @@ -140,37 +163,42 @@ class LoadWCSim: public Tool { TimeClass RunStartTime; // as set from user uint64_t EventTimeNs; std::vector* MCParticles; - std::map>* TDCData; - std::map>* MCHits; + std::map>* TDCData; + std::map>* MCHits; std::vector* TriggerData; BeamStatus beamstat; std::map> MCNeutCap; std::map>> MCNeutCapGammas; - //BeamStatusClass* BeamStatus; - - int primarymuonindex; + + int primaryMuonIndex; // additional info - void MakeParticleToPmtMap(WCSimRootTrigger* thisTrig, WCSimRootTrigger* firstTrig, std::map>* ParticleId_to_DigitIds, std::map* ChargeFromParticleId, std::map tubeid_to_channelkey); - std::map>* ParticleId_to_TankTubeIds = nullptr; - std::map>* ParticleId_to_MrdTubeIds = nullptr; - std::map>* ParticleId_to_VetoTubeIds = nullptr; - std::map* ParticleId_to_TankCharge = nullptr; - std::map* ParticleId_to_MrdCharge = nullptr; - std::map* ParticleId_to_VetoCharge = nullptr; - std::map Mrd_Chankey_Layer; + void MakeParticleToPmtMap(WCSimRootTrigger* thisTrig, + WCSimRootTrigger* firstTrig, + std::map>* ParticleId_to_DigitIds, + std::map* ChargeFromParticleId, + std::map tubeid_to_channelkey); + + std::map>* ParticleId_to_TankTubeIds = nullptr; + std::map>* ParticleId_to_MrdTubeIds = nullptr; + std::map>* ParticleId_to_VetoTubeIds = nullptr; + std::map* ParticleId_to_TankCharge = nullptr; + std::map* ParticleId_to_MrdCharge = nullptr; + std::map* ParticleId_to_VetoCharge = nullptr; + std::map Mrd_Chankey_Layer; bool mrd_firstlayer, mrd_lastlayer; - std::string Triggertype; + std::string TriggerType; int TriggerWord; // verbosity levels: if 'verbosity' < this level, the message type will be logged. - int v_error=0; - int v_warning=1; - int v_message=2; - int v_debug=3; + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + int v_debuggier = 4; std::string logmessage; - int get_ok; + int get_ok; }; diff --git a/UserTools/MuonFitter/MuonFitter.cpp b/UserTools/MuonFitter/MuonFitter.cpp new file mode 100644 index 000000000..c01a2fb51 --- /dev/null +++ b/UserTools/MuonFitter/MuonFitter.cpp @@ -0,0 +1,2569 @@ +#include "MuonFitter.h" + +/* ***************************************************************** + * tool name: MuonFitter + * author: Julie He + * + * desc: This tool takes + * + * versions: + * ... + * 240331v1JH: fixed line of code defining reco_mu_e (prev defined + * using mrdEnergyLoss) + * 240401v2JH: removed unnecessary code, old algorithms + * 240405v1JH: add option to use simple energy reco (just add eloss) + * 240407v1JH: reco mode no longer includes finding muon, added + * cluster_time to m_tank_track_fits + * 240425v1JH: incorporated scattering effects into MRD track length + * 240503v1JH: added SimpleReco* variables for NeutronMultiplicity + * toolchain + * 240506v1JH: adjusted nlyrs method (additional 0.5 iron layer) + * 240508v1JH: I am once again, updating the dEdx + * 240514v1JH: Removed FMV and spherical FV cut + * 240515v1JH: Added in FMV cut from EventSelector + * 240516v1JH: Reorganized script, added spherical FV cut back in + * 240520v1JH: added original veto cut back in + * 240520v2JH: removed original veto cut + * 240520v3JH: added different FV cuts + * 240524v1JH: fixed FV cut logic, added more plots to NM tool + * ***************************************************************** + */ + +MuonFitter::MuonFitter():Tool(){} + + +bool MuonFitter::Initialise(std::string configfile, DataModel &data){ + + ///////////////////////// Useful header ///////////////////////// + //-- Load config file + if(configfile!="") m_variables.Initialise(configfile); + //m_variables.Print(); + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + //-- Set default values + verbosity = 3; + isData = true; + PMTMRDOffset = 745.; + + // ------------------------------------------------------------- + // --- Retrieve config variables ------------------------------- + // ------------------------------------------------------------- + m_variables.Get("verbosity", verbosity); + m_variables.Get("IsData", isData); + m_variables.Get("LuxArea", LUX_AREA); + m_variables.Get("EtelArea", ETEL_AREA); + m_variables.Get("HamamatsuArea", HAMAMATSU_AREA); + m_variables.Get("WatchboyArea", WATCHBOY_AREA); + m_variables.Get("WatchmanArea", WATCHMAN_AREA); + m_variables.Get("PMTMRDOffset", PMTMRDOffset); + m_variables.Get("Plot3D", plot3d); + m_variables.Get("Draw3DFMV", draw3d_fmv); + m_variables.Get("Draw3DMRD", draw3d_mrd); + m_variables.Get("SaveHistograms", save_hists); + m_variables.Get("StepSizeAi", step_size_ai); + m_variables.Get("InsideAngle", insideAngle); + m_variables.Get("OutsideAngle", outsideAngle); + m_variables.Get("PMTChargeThreshold", PMTQCut); + m_variables.Get("EtaThreshold", EtaThreshold); + m_variables.Get("DisplayTruth", display_truth); + m_variables.Get("RecoMode", reco_mode); + m_variables.Get("AiEtaFile", aiEtaFile); + m_variables.Get("TankTrackFitFile", tankTrackFitFile); + m_variables.Get("UseNumLayers", use_nlyrs); + m_variables.Get("UsePCA", use_pca); + m_variables.Get("UseConnDots", use_conn_dots); + m_variables.Get("UseELoss", use_eloss); + m_variables.Get("UseSimpleEReco", use_simple_ereco); + m_variables.Get("RecoEnergyShift", ERECO_SHIFT); + + Log("MuonFitter Tool: Version 240524v1", v_message, verbosity); + if (use_nlyrs) Log("MuonFitter Tool: Using num layers to determine MRD track length", v_message, verbosity); + if (use_pca) Log("MuonFitter Tool: Using PCA to determine MRD track angle", v_message, verbosity); + if (use_conn_dots) Log("MuonFitter Tool: Using connect the dots method to determine MRD track angle", v_message, verbosity); + if (use_eloss) Log("MuonFitter Tool: Using current ANNIE tools to determine MRD energy loss", v_message, verbosity); + if (use_simple_ereco) Log("MuonFitter Tool: Just add tank and MRD energy depositions (don't update dEdx values)", v_message, verbosity); + + + // Output ROOT file + std::string outfile; + m_variables.Get("OutputFile", outfile); + Log("MuonFitter Tool: Saving output into " + outfile, v_message, verbosity); + root_outp = new TFile(outfile.c_str(), "RECREATE"); + + + // ------------------------------------------------------------- + // --- Initialize canvases, graphs, histograms ----------------- + // ------------------------------------------------------------- + this->InitCanvases(); + this->InitHistograms(); + this->InitGraphs(); + + + // ------------------------------------------------------------- + // --- Retrieve Store variables -------------------------------- + // ------------------------------------------------------------- + m_data->CStore.Get("ChannelNumToTankPMTSPEChargeMap", ChannelKeyToSPEMap); //same for data and mc + + + // ------------------------------------------------------------- + // --- Get Geometry -------------------------------------------- + // ------------------------------------------------------------- + //-- Code based on UserTools/EventDisplay/EventDisplay.cpp + auto get_geo = m_data->Stores["ANNIEEvent"]->Header->Get("AnnieGeometry", geom); + if (!get_geo) + { + Log("MuonFitter Tool: Error retrieving Geometry from ANNIEEvent!", v_error, verbosity); + return false; + } + tank_radius = geom->GetTankRadius(); + tank_height = geom->GetTankHalfheight(); + tank_height *= 2; + detector_version = geom->GetVersion(); + Log("MuonFitter Tool: Using detector version " + std::to_string(detector_version), v_message, verbosity); + double barrel_compression = 0.82; + //-- Use compressed barrel radius for ANNIEp2v6 detector configuration (only MC) + if (detector_config == "ANNIEp2v6" && !isData) { tank_height *= barrel_compression; } + else if (isData) { tank_height = 1.2833; } + //-- Set tank radius to standard value of old anniev2 configuration (v4/v6 seems to have very different radius?) + if (tank_radius < 1. || isData) { tank_radius = 1.37504; } + + Position detector_center = geom->GetTankCentre(); + tank_center_x = 100.*detector_center.X(); //convert to cm + tank_center_y = 100.*detector_center.Y(); + tank_center_z = 100.*detector_center.Z(); + //-- QA: Check tank center, radius, and height being used + std::cout << " MuonFitter Tool: tank_center xyz [cm]: " << tank_center_x << "," << tank_center_y << "," << tank_center_z << std::endl; + std::cout << " MuonFitter Tool: tank_radius [m]: " << tank_radius << std::endl; + std::cout << " MuonFitter Tool: tank_height [m]: " << tank_height << std::endl; + + //-- QA: Check number of PMTs in each subdetector + n_tank_pmts = geom->GetNumDetectorsInSet("Tank"); + n_mrd_pmts = geom->GetNumDetectorsInSet("MRD"); + n_veto_pmts = geom->GetNumDetectorsInSet("Veto"); + std::cout << " MuonFitter Tool: Number of Tank / MRD / Veto PMTs in this geometry: " << n_tank_pmts << " / " << n_mrd_pmts << " / " << n_veto_pmts << std::endl; + + + // ------------------------------------------------------------- + // --- ANNIE in 3D --------------------------------------------- + // ------------------------------------------------------------- + // --- Set up 3D geometry for viewing + Log("MuonFitter Tool: Creating 3D Geometry", v_debug, verbosity); + ageom = new TGeoManager("ageom", "ANNIE in 3D"); + TGeoNode *node; + + //-- material + vacuum = new TGeoMaterial("vacuum",0,0,0); + Fe = new TGeoMaterial("Fe",55.845,26,7.87); + + //-- create media + Air = new TGeoMedium("Vacuum",0,vacuum); + Iron = new TGeoMedium("Iron",1,Fe); + + //-- create volume + EXPH = ageom->MakeBox("EXPH",Air,300,300,300); + ageom->SetTopVolume(EXPH); + ageom->SetTopVisible(0); + //-- If you want to see the boundary, input the number 1 instead of 0: + // geom->SetTopVisible(1); + + //-- draw CANVAS/TOP CENTER + bBlock = ageom->MakeSphere("EXPH_vol_center", Iron, 0,3,0,180,0,360); + bBlock->SetLineColor(1); + EXPH->AddNodeOverlap(bBlock,N++,new TGeoTranslation(0,0,0)); + + //-- draw TANK + TGeoVolume *annietank = ageom->MakeTubs("annietank", Iron, 0, tank_radius*100., tank_height*100., 0, 360); //convert to cm + annietank->SetLineColor(38); + EXPH->AddNodeOverlap(annietank,N++,new TGeoCombiTrans(0,0,0,new TGeoRotation("annietank",0,90,0))); + node = EXPH->GetNode(N-1); + + + // ------------------------------------------------------------- + // --- Read in TANK PMTs --------------------------------------- + // ------------------------------------------------------------- + //-- Code based on UserTools/EventDisplay/EventDisplay.cpp + std::map> *Detectors = geom->GetDetectors(); + + Log("MuonFitter Tool: Adding tank PMTs to 3D geometry", v_debug, verbosity); + for (std::map::iterator it = Detectors->at("Tank").begin(); it != Detectors->at("Tank").end(); ++it) + { + Detector *apmt = it->second; + unsigned long detkey = it->first; + std::string det_type = apmt->GetDetectorType(); + Position position_PMT = apmt->GetDetectorPosition(); //in meters + //-- PMT xyz corrected by tank center, in cm + x_pmt.insert(std::pair(detkey, 100.*position_PMT.X()-tank_center_x)); + y_pmt.insert(std::pair(detkey, 100.*position_PMT.Y()-tank_center_y)); + z_pmt.insert(std::pair(detkey, 100.*position_PMT.Z()-tank_center_z)); + //-- PMT orientation + Direction direction_PMT = apmt->GetDetectorDirection(); + x_pmt_dir.insert(std::pair(detkey, direction_PMT.X())); + y_pmt_dir.insert(std::pair(detkey, direction_PMT.Y())); + z_pmt_dir.insert(std::pair(detkey, direction_PMT.Z())); + + //-- Get PMT areas for ring area overlap later + double det_area = 0.; + if (det_type == "LUX" || det_type == "ANNIEp2v7-glassFaceWCPMT_R7081") { det_area = LUX_AREA; } + else if (det_type == "ETEL" || det_type == "ANNIEp2v7-glassFaceWCPMT_D784KFLB") { det_area = ETEL_AREA; } + else if (det_type == "Hamamatsu" || det_type == "ANNIEp2v7-glassFaceWCPMT_R5912HQE") { det_area = HAMAMATSU_AREA; } + else if (det_type == "Watchboy" || det_type == "ANNIEp2v7-glassFaceWCPMT_R7081") { det_area = WATCHBOY_AREA; } + else if (det_type == "Watchman" || det_type == "ANNIEp2v7-glassFaceWCPMT_R7081HQE") { det_area = WATCHMAN_AREA; } + else { Log("MuonFitter Tool: Unrecognized detector type! Setting det_area to 0.", v_error, verbosity); } + m_pmt_area.insert(std::pair(detkey, det_area)); + + //-- ANNIE in 3D: Drawing TANK PMTs + sprintf(blockName,"tank_pmt%lu",detkey); + bBlock = ageom->MakeSphere(blockName, Iron, 0,1.5,0,180,0,360); + bBlock->SetLineColor(41); + EXPH->AddNodeOverlap(bBlock,1,new TGeoTranslation(x_pmt[detkey], y_pmt[detkey], z_pmt[detkey])); + detkey_to_node.insert(std::pair(detkey, N++)); + } + + + // ------------------------------------------------------------- + // --- Read in MRD PMTs ---------------------------------------- + // ------------------------------------------------------------- + //-- Code based on UserTools/EventDisplay/EventDisplay.cpp + Log("MuonFitter Tool: Adding MRD PMTs to 3D geoemtry", v_debug, verbosity); + for (std::map::iterator it = Detectors->at("MRD").begin(); it != Detectors->at("MRD").end(); ++it) + { + Detector *amrdpmt = it->second; + unsigned long detkey = it->first; + unsigned long chankey = amrdpmt->GetChannels()->begin()->first; + Paddle *mrdpaddle = (Paddle *)geom->GetDetectorPaddle(detkey); + + //-- Retrieve xyz bounds of paddle, orientation, etc + //-- NOTE: so far this has not been used + double xmin = mrdpaddle->GetXmin(); + double xmax = mrdpaddle->GetXmax(); + double ymin = mrdpaddle->GetYmin(); + double ymax = mrdpaddle->GetYmax(); + double zmin = mrdpaddle->GetZmin(); + double zmax = mrdpaddle->GetZmax(); + int orientation = mrdpaddle->GetOrientation(); //0:horizontal,1:vertical + int half = mrdpaddle->GetHalf(); //0 or 1 + int side = mrdpaddle->GetSide(); + + std::vector xdim{xmin,xmax}; + std::vector ydim{ymin,ymax}; + std::vector zdim{zmin,zmax}; + + //-- Store the detkey and the bounds of the MRD paddle + //-- NOTE: mrd_{xyz} is type std::vector> + mrd_x.emplace(detkey,xdim); + mrd_y.emplace(detkey,ydim); + mrd_z.emplace(detkey,zdim); + + //-- Store detkey and paddle center xyz (tank center corrected) + mrd_center_x.emplace(detkey,100.*(mrdpaddle->GetOrigin()).X()-tank_center_x); + mrd_center_y.emplace(detkey,100.*(mrdpaddle->GetOrigin()).Y()-tank_center_y); + mrd_center_z.emplace(detkey,100.*(mrdpaddle->GetOrigin()).Z()-tank_center_z); + + + //-- ANNIE in 3D: drawing MRD + if (draw3d_mrd) + { + Position position_MRD = mrdpaddle->GetOrigin(); + sprintf(blockName,"mrd_pmt%lu",detkey); + bBlock = ageom->MakeBox(blockName, Iron, (xmax-xmin)*100., (ymax-ymin)*100., (zmax-zmin)*100.); + bBlock->SetLineColor(16); + EXPH->AddNodeOverlap(bBlock,detkey,new TGeoTranslation(100.*position_MRD.X()-tank_center_x, 100.*position_MRD.Y()-tank_center_y, 100.*position_MRD.Z()-tank_center_z)); + detkey_to_node.insert(std::pair(detkey, N++)); + + //-- QA: Check detkey_to_node map + if (verbosity > v_debug) + { + std::cout << " [debug] blockName: " << blockName << std::endl; + std::cout << " [debug] detkey_to_node[detkey]: " << detkey_to_node[detkey] << std::endl; + } + } + } + + // ------------------------------------------------------------ + // --- Read in FMV PMTs --------------------------------------- + // ------------------------------------------------------------ + //-- Code based on UserTools/EventDisplay/EventDisplay.cpp + Log("MuonFitter Tool: Adding FMV PMTs to 3D geoemtry", v_debug, verbosity); + for (std::map::iterator it = Detectors->at("Veto").begin(); it != Detectors->at("Veto").end(); ++it) + { + Detector *avetopmt = it->second; + unsigned long detkey = it->first; + unsigned long chankey = avetopmt->GetChannels()->begin()->first; + Paddle *vetopaddle = (Paddle *)geom->GetDetectorPaddle(detkey); + + double xmin = vetopaddle->GetXmin(); + double xmax = vetopaddle->GetXmax(); + double ymin = vetopaddle->GetYmin(); + double ymax = vetopaddle->GetYmax(); + double zmin = vetopaddle->GetZmin(); + double zmax = vetopaddle->GetZmax(); + + //-- ANNIE in 3D: drawing FMV + if (draw3d_fmv) + { + Position position_FMV = vetopaddle->GetOrigin(); + sprintf(blockName,"fmv_pmt%lu",detkey); + bBlock = ageom->MakeBox(blockName, Iron, (xmax-xmin)*100., (ymax-ymin)*100., (zmax-zmin)*100.); + bBlock->SetLineColor(20); + EXPH->AddNodeOverlap(bBlock,detkey,new TGeoTranslation(100.*position_FMV.X()-tank_center_x, 100.*position_FMV.Y()-tank_center_y, 100.*position_FMV.Z()-tank_center_z)); + detkey_to_node.insert(std::pair(detkey, N++)); + + //-- QA: Check detkey_to_node map + if (verbosity > v_debug) + { + std::cout << " [debug] blockName: " << blockName << std::endl; + std::cout << " [debug] detkey_to_node[detkey]: " << detkey_to_node[detkey] << std::endl; + } + } + } + + //-- ANNIE in 3D: Set max number of nodes + maxN = N; + Log("MuonFitter Tool: Number of nodes in 3D geometry: " + std::to_string(maxN), v_debug, verbosity); + + + //-- Save 3D plots + ageom->CloseGeometry(); //close 3d geometry + EXPH->SetVisibility(0); + if (plot3d) + { + canvas_3d = new TCanvas("canvas_3d", "3D Event Display", 800, 600); + canvas_3d->cd(1); + EXPH->Draw(); + canvas_3d->Modified(); + canvas_3d->Update(); + } + + // ------------------------------------------------------------ + // --- Create txt files for separate analyses ----------------- + // ------------------------------------------------------------ + //-- Save start & stop vertices to file; Save (ai,eta) values + //std::string pos_fname = "posFile.txt"; + //pos_file.open(pos_fname.c_str()); + //pos_file << "##evnum,startX,startY,startZ,stopX,stopY,stopZ" << std::endl; + //std::string pos_fname = "ev_ai_eta.txt"; + std::string pos_fname = aiEtaFile.c_str(); + pos_file.open(pos_fname.c_str(), std::ostream::app); + if (!pos_file) + { + std::cout << " [pos_file] File " << pos_fname << " does not exist! Creating now.." << std::endl; + pos_file.open(pos_fname.c_str()); + pos_file << "##ev_id,cluster_time,ai,eta" << std::endl; + } + + //-- Save avg eta to left and right of true tank track length + if (!isData) + { + truetrack_file.open("true_track_len.txt", std::ostream::app); + if (!truetrack_file) + { + std::cout << " [debug] true_track_len.txt does not exist! Creating now..." << std::endl; + truetrack_file.open("true_track_len.txt"); + truetrack_file << "#event_id,true_track_len,left_avg,right_avg" << std::endl; + } + } + + + //-- Save info about events with Ediff > 200 MeV + if (!isData) + { + lg_ediff_file.open("lg_ediff.txt", std::ostream::app); + if (!lg_ediff_file) + { + std::cout << "File lg_ediff.txt does not exist! Creating now..." << std::endl; + lg_ediff_file.open("lg_ediff.txt"); + lg_ediff_file << "##event_id,ediff,pions,tanktrackF,tanktrackT,mrdtrackF,mrdtrackT,muonEF,muonET" << std::endl; + } + } + + // ------------------------------------------------------------ + // --- Load vertex fits (RECO MODE ONLY) ---------------------- + // ------------------------------------------------------------ + if (reco_mode) + { + if (this->FileExists(tankTrackFitFile)) + { + //-- Load event part, number and track fit + std::cout << "MuonFitter Tool: Loading tank track fits from " << tankTrackFitFile << std::endl; + this->LoadTankTrackFits(); + } + else + { + Log("MuonFitter Tool: File for tank track fit does not exist! Continuing tool NOT in RECO MODE.", v_error, verbosity); + reco_mode = false; + } + } + + Log("MuonFitter Tool: Initialization complete", v_debug, verbosity); + + return true; +} + + +bool MuonFitter::Execute(){ + Log("MuonFitter Tool: Executing", v_debug, verbosity); + + //-- Retrieve ANNIEEvent + int eventExists = m_data->Stores.count("ANNIEEvent"); + if (!eventExists) + { + Log("MuonFitter Tool: No ANNIEEvent store!", v_error, verbosity); + return false; + } + + // ------------------------------------------------------------ + // --- Reset variables ---------------------------------------- + // ------------------------------------------------------------ + this->ResetVariables(); + + bool drawEvent = false; //-- Make graphs for this event (e.g. ev displays, eta vs ai) + + gr_eta_ai->Set(0); + gr_running_avg->Set(0); + + if (h_tzero) h_tzero->Delete(); + h_tzero = new TH1D("h_tzero", "t0", 60, -15, 15); + h_tzero->GetXaxis()->SetTitle("[ns]"); + + //-- Initialize tank track length and muon vertex to be saved in + //-- CStore for downstream tools + Position dummy_vtx(-888, -888, -888); + m_data->CStore.Set("FittedTrackLengthInWater", -888.); + m_data->CStore.Set("FittedMuonVertex", dummy_vtx); + m_data->CStore.Set("RecoMuonKE", -888.); + m_data->CStore.Set("NLyrs", -888); + + + // ------------------------------------------------------------- + // --- Get event info (DATA) ----------------------------------- + // ------------------------------------------------------------- + int get_ok = false; + if (isData) + { + get_ok = m_data->Stores["ANNIEEvent"]->Get("EventNumber", evnum); + std::cout << "MuonFitter Tool: Working on event " << evnum << std::endl; + if (not get_ok) { Log("MuonFitter Tool: Error retrieving EventNumber from ANNIEEvent!", v_error, verbosity); return false; } + get_ok = m_data->Stores["ANNIEEvent"]->Get("RunNumber", runnumber); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving RunNumber from ANNIEEvent!", v_error, verbosity); return false; } + get_ok = m_data->Stores["ANNIEEvent"]->Get("PartNumber", partnumber); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving PartNumber from ANNIEEvent!", v_error, verbosity); partnumber = -1; } + } + + // ------------------------------------------------------------- + // --- Get event info (MC) ------------------------------------- + // ------------------------------------------------------------- + TVector3 trueTrackDir; + RecoVertex *truevtx = 0; + if (!isData) + { + get_ok = m_data->Stores["ANNIEEvent"]->Get("MCParticles", mcParticles); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving MCParticles from ANNIEEvent!", v_error, verbosity); return false; } //<< needed to retrieve true vertex and direction + get_ok = m_data->Stores["ANNIEEvent"]->Get("MCEventNum", mcevnum); + std::cout << "MuonFitter Tool: Working on event " << mcevnum << std::endl; + if (not get_ok) { Log("MuonFitter Tool: Error retrieving MCEventNum from ANNIEEvent!", v_error, verbosity); return false; } + get_ok = m_data->Stores["ANNIEEvent"]->Get("MCTriggernum", mctrignum); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving MCTriggernum from ANNIEEvent!", v_error, verbosity); return false; } + get_ok = m_data->Stores["ANNIEEvent"]->Get("MCFile", mcFile); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving MCFile from ANNIEEvent!", v_error, verbosity); mcFile = "-1"; } + + //-- Extract file part number + //-- NOTE: event numbers weren't incrementing properly... + std::string delim = "."; + std::string end = ".root"; + std::string tmp_str = mcFile.erase(mcFile.rfind(delim), end.length()); + partnumber = stoi(tmp_str.substr(0, tmp_str.find(delim))); + + /*for(unsigned int particlei=0; particleisize(); particlei++){ + + MCParticle aparticle = mcParticles->at(particlei); + std::string logmessage = "EventDisplay tool: Particle # "+std::to_string(particlei)+", parent ID = "+std::to_string(aparticle.GetParentPdg())+", pdg = "+std::to_string(aparticle.GetPdgCode())+", flag = "+std::to_string(aparticle.GetFlag()); + Log(logmessage,v_message,verbosity); + }*/ + + //-- Get RecoEvent variables + get_ok = m_data->Stores["RecoEvent"]->Get("TrueVertex", truevtx); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving TrueVertex from RecoEvent Store!", v_error, verbosity); return false; } + trueVtxX = truevtx->GetPosition().X(); //already in cm + trueVtxY = truevtx->GetPosition().Y(); //and center corrected + trueVtxZ = truevtx->GetPosition().Z(); + trueVtxTime = truevtx->GetTime(); + trueDirX = truevtx->GetDirection().X(); + trueDirY = truevtx->GetDirection().Y(); + trueDirZ = truevtx->GetDirection().Z(); + trueTrackDir = TVector3(trueDirX,trueDirY,trueDirZ).Unit(); + + trueAngleRad = TMath::ACos(trueDirZ); //calculated like this in other tools + trueAngleDeg = trueAngleRad/(TMath::Pi()/180.); + h_truevtx_angle->Fill(trueAngleDeg); + + RecoVertex *truestopvtx = 0; + get_ok = m_data->Stores["RecoEvent"]->Get("TrueStopVertex", truestopvtx); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving TrueStopVertex from RecoEvent Store!", v_error, verbosity); return false; } + trueStopVtxX = truestopvtx->GetPosition().X(); //already in cm + trueStopVtxY = truestopvtx->GetPosition().Y(); + trueStopVtxZ = truestopvtx->GetPosition().Z(); + + get_ok = m_data->Stores["RecoEvent"]->Get("TrueTrackLengthInWater", trueTrackLengthInWater); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving TrueTrackLengthInWater from RecoEvent Store!", v_error, verbosity); trueTrackLengthInWater = -1; } + trueTrackLengthInWater = trueTrackLengthInWater*100.; //convert to cm + h_true_tanktrack_len->Fill(trueTrackLengthInWater); + + get_ok = m_data->Stores["RecoEvent"]->Get("TrueTrackLengthInMRD", trueTrackLengthInMRD); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving TrueTrackLengthInMRD from RecoEvent Store!", v_error, verbosity); trueTrackLengthInMRD = -1; } + + get_ok = m_data->Stores["RecoEvent"]->Get("TrueMuonEnergy", trueMuonEnergy); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving TrueMuonEnergy from RecoEvent Store!", v_error, verbosity); trueMuonEnergy = -1; } + + get_ok = m_data->Stores["RecoEvent"]->Get("NRings", nrings); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving NRings, true from RecoEvent!", v_error, verbosity); } + get_ok = m_data->Stores["RecoEvent"]->Get("IndexParticlesRing", particles_ring); + if (not get_ok) { Log("MuonFitter Tool: Error retrieving IndexParticlesRing, true from RecoEvent!", v_error, verbosity); } + } + + //-- Get ev_id for matching + std::stringstream ev_id; + ev_id << "p" << partnumber << "_"; + if (isData) ev_id << evnum; + else ev_id << mcevnum; + std::cout << "MuonFitter Tool: Working on event " << ev_id.str() << std::endl; + + if (reco_mode) + { + //-- Skip events that weren't fitted to make processing faster + std::map>::iterator it = m_tank_track_fits.find(ev_id.str()); + if (it == m_tank_track_fits.end()) return true; + } + + // ------------------------------------------------------------ + // --- Get event info (both) ---------------------------------- + // ------------------------------------------------------------ + uint32_t trigword; + get_ok = m_data->Stores.at("ANNIEEvent")->Get("TriggerWord",trigword); + std::cout << " trigword: " << trigword << std::endl; + + + // ------------------------------------------------------------ + // --- CUT: Select beam only events --------------------------- + // ------------------------------------------------------------ + if (trigword != 5) return true; + + + // ------------------------------------------------------------ + // --- Check for particles other than muon (MC ONLY) ---------- + // ------------------------------------------------------------ + bool hasPion = false; + int n_rings = 0; + if (!isData) + { + for (unsigned int mcp_i = 0; mcp_i < mcParticles->size(); mcp_i++) + { + MCParticle aparticle = mcParticles->at(mcp_i); + //-- QA: Check MC evnum and particle PDG code + //std::cout << " [debug] Ev " << mcevnum << ", particle pdg code: " << aparticle.GetPdgCode() << std::endl; + if (std::find(particles_ring.begin(), particles_ring.end(), mcp_i) != particles_ring.end()) + { + //-- Use number of rings to determine if there are particles other than muon + ++n_rings; + } + } + std::cout << " [debug] n_rings (my counter): " << n_rings << std::endl; + if (n_rings > 1) hasPion = true; //might include other particles + } + if (hasPion) std::cout << " [debug] has pion / other particle!" << std::endl; + + + // ------------------------------------------------------------ + // --- CUT: Check for FMV hits -------------------------------- + // ------------------------------------------------------------ + get_ok = m_data->Stores["ANNIEEvent"]->Get("TDCData", tdcdata); //'TDCData' for both data and MC + if (!get_ok) { Log("MuonFitter Tool: No TDCData object in ANNIEEvent! Abort!", v_error, verbosity); return true; } + + bool passVetoCut = false; + get_ok = m_data->Stores.at("RecoEvent")->Get("NoVeto", passVetoCut); + if (!get_ok) { Log("MuonFitter Tool: Could not retrieve NoVeto variable", v_error, verbosity); } + + //-- Skip event if there is a veto hit + //-- NOTE: Will let EventSelector tool determine whether FMV was hit + //-- since it uses timing information + if (!passVetoCut) + { + Log("MuonFitter Tool: Found FMV/Veto hit!", v_debug, verbosity); + return true; + } + + + // ------------------------------------------------------------ + // --- CUT: Check for MRD tracks ------------------------------ + // ------------------------------------------------------------ + //get_ok = m_data->Stores["ANNIEEvent"]->Get("MRDTriggerType", mrdTriggerType); //XXX:care about this? not defined yet + get_ok = m_data->Stores["MRDTracks"]->Get("NumMrdTracks", numTracksInEv); + get_ok = m_data->Stores["MRDTracks"]->Get("MRDTracks", mrdTracks); //XXX:might need MC version + + if (!get_ok) { Log("MuonFitter Tool: Couldn't retrieve MRD tracks info. Did you run TimeClustering/FindMRDTracks first?", v_debug, verbosity); return false; } + + //-- Skip event if num tracks not equal to 1 in MRD + if (numTracksInEv != 1) + { + Log("MuonFitter Tool: More than 1 reconstructed track found!", v_debug, verbosity); + return true; + } + + + // ------------------------------------------------------------ + // --- Get MRD track params ----------------------------------- + // ------------------------------------------------------------ + double reco_mrd_track = 0.; + double nlyrs_mrd_track = 0.; + double conn_dots_mrd_track = 0.; + bool isMrdStopped; + bool isMrdPenetrating; + bool isMrdSideExit; + + for(int track_i = 0; track_i < numTracksInEv; track_i++) + { + BoostStore* thisTrackAsBoostStore = &(mrdTracks->at(track_i)); + + thisTrackAsBoostStore->Get("StartVertex", mrdStartVertex); //m + thisTrackAsBoostStore->Get("StopVertex", mrdStopVertex); //m + thisTrackAsBoostStore->Get("MrdEntryPoint", mrdEntryPoint); //m + thisTrackAsBoostStore->Get("TankExitPoint", tankExitPoint); //m + thisTrackAsBoostStore->Get("StartTime", mrdStartTime); + thisTrackAsBoostStore->Get("TrackAngle", trackAngleRad); + thisTrackAsBoostStore->Get("TrackAngleError", trackAngleError); + thisTrackAsBoostStore->Get("PenetrationDepth", penetrationDepth); + thisTrackAsBoostStore->Get("NumLayersHit", numLayersHit); + thisTrackAsBoostStore->Get("LayersHit", LayersHit); + thisTrackAsBoostStore->Get("PMTsHit", MrdPMTsHit); + thisTrackAsBoostStore->Get("EnergyLoss", mrdEnergyLoss); + thisTrackAsBoostStore->Get("EnergyLossError", mrdEnergyLossError); + thisTrackAsBoostStore->Get("IsMrdStopped", isMrdStopped); + thisTrackAsBoostStore->Get("IsMrdPenetrating", isMrdPenetrating); + thisTrackAsBoostStore->Get("IsMrdSideExit", isMrdSideExit); + + //-- Calculate MRD track length using MRD track start and stop + //-- NOTE: this was done in other tools + reco_mrd_track = sqrt(pow((mrdStopVertex.X()-mrdStartVertex.X()),2)+pow(mrdStopVertex.Y()-mrdStartVertex.Y(),2)+pow(mrdStopVertex.Z()-mrdStartVertex.Z(),2)); + + //-- Do some conversions + reco_mrd_track = reco_mrd_track*100.; //convert to cm + penetrationDepth = penetrationDepth*100.; + trackAngleDeg = trackAngleRad*180./TMath::Pi(); + + //-- QA: Check MRD track variables + std::cout << " [debug] mrdStartVertex: " << mrdStartVertex.X() << "," << mrdStartVertex.Y() << "," << mrdStartVertex.Z() << std::endl; + std::cout << " [debug] mrdStopVertex: " << mrdStopVertex.X() << "," << mrdStopVertex.Y() << "," << mrdStopVertex.Z() << std::endl; + std::cout << " [debug] tankExitPoint: " << tankExitPoint.X() << "," << tankExitPoint.Y() << "," << tankExitPoint.Z() << std::endl; + std::cout << " [debug] mrdEntryPoint: " << mrdEntryPoint.X() << "," << mrdEntryPoint.Y() << "," << mrdEntryPoint.Z() << std::endl; + std::cout << " [debug] mrdStartTime: " << mrdStartTime << std::endl; + std::cout << " [debug] trackAngleRad: " << trackAngleRad << std::endl; + std::cout << " [debug] penetrationDepth: " << penetrationDepth << std::endl; + std::cout << " [debug] reco_mrd_track (ANNIE tools): " << reco_mrd_track << std::endl; + std::cout << " [debug] mrdEnergyLoss: " << mrdEnergyLoss << std::endl; + std::cout << " [debug] isMrdStopped: " << isMrdStopped << std::endl; + std::cout << " [debug] isMrdPenetrating: " << isMrdPenetrating << std::endl; + std::cout << " [debug] isMrdSideExit: " << isMrdSideExit << std::endl; + std::cout << " [debug] numLayersHit: " << numLayersHit << std::endl; + std::cout << " [debug] LayersHit.size(): " << LayersHit.size() << std::endl; + std::cout << " [debug] MrdPMTsHit.size(): " << MrdPMTsHit.size() << std::endl; + + } //-- Done retrieving MRD track params + + //-- QA: Check the values of LayersHit vector + for (int i = 0; i < LayersHit.size(); ++i) + { + std::cout << " [debug] LayersHit at " << i << ": " << LayersHit.at(i) << std::endl; + } //-- returns numbers from 0-11 (layer number ordered) + + //-- Histogram number of layers traversed + h_num_mrd_layers->Fill(LayersHit.size()); + + + //-- QA: Check the values of MrdPMTsHit vector + for (int i = 0; i < MrdPMTsHit.size(); ++i) + { + std::cout << " [debug] MrdPMTsHit at " << i << ": " << MrdPMTsHit.at(i) << std::endl; + } //-- returns unsorted list of MRD detkeys + + + //-- Use num layers to determine amount of track length in iron + //-- NOTE: this is an "effective" track length + //-- (5cm)*(num layers)/cos(theta) << 5cm is thickness of iron slab + nlyrs_mrd_track = 5.*(LayersHit.size()+0.5)/abs(TMath::Cos(trackAngleRad)); + + //-- Compare MRD tracks reconstructed w/ ANNIE methods and num layers + double pcaAngleRad = this->PCATrackAngle(MrdPMTsHit); + double pcaAngleDeg = pcaAngleRad*180./TMath::Pi(); + std::cout << " [debug] PCA angle (rad): " << pcaAngleRad << std::endl; + std::cout << " [debug] PCA angle (deg): " << pcaAngleDeg << std::endl; + h_pca_angle->Fill(pcaAngleDeg); + + //-- Update nlyrs_mrd_track so that it uses the PCA-reconstructed track angle + double pca_mrd_track = 5.*(LayersHit.size()+0.5)/abs(TMath::Cos(pcaAngleRad)); + std::cout << " [debug] PCA nlyrs_mrd_track: " << pca_mrd_track << std::endl; + if (use_pca) { nlyrs_mrd_track = pca_mrd_track; } + + + //TODO:Move to separate function + //-- Determine MRD track length by "connecting the dots" + conn_dots_mrd_track = this->MRDConnectDots(MrdPMTsHit); + std::cout << " [debug] FINAL conn_dots_mrd_track: " << conn_dots_mrd_track << std::endl; + std::cout << " [debug] FINAL nlyrs_mrd_track: " << nlyrs_mrd_track << std::endl; + + + //-- Select for tracks that end in MRD + if (!isMrdStopped) + { + std::cout << " MuonFitter Tool: MUON DID NOT STOP IN MRD. Skipping..." << std::endl; + return true; + } + + if (isMrdSideExit) //<< Not working + { + std::cout << " MuonFitter Tool: MUON EXITTED SIDE OF MRD. Skipping..." << std::endl; + //return true; + } + + + // ------------------------------------------------------------ + // --- Now look at tank exit and MRD points ------------------- + // ------------------------------------------------------------ + double tankExitPointX = 100.*tankExitPoint.X()-tank_center_x; + double tankExitPointY = 100.*tankExitPoint.Y()-tank_center_y; + double tankExitPointZ = 100.*tankExitPoint.Z()-tank_center_z; + TVector3 tankExit(tankExitPointX, tankExitPointY, tankExitPointZ); + h_tankExitX->Fill(tankExitPointX); + h_tankExitY->Fill(tankExitPointY); + h_tankExitZ->Fill(tankExitPointZ); + + double mrdEntryPointX = 100.*mrdEntryPoint.X()-tank_center_x; + double mrdEntryPointY = 100.*mrdEntryPoint.Y()-tank_center_y; + double mrdEntryPointZ = 100.*mrdEntryPoint.Z()-tank_center_z; + + //-- Create vectors for MRD start/stop + TVector3 mrdStart(100.*mrdStartVertex.X()-tank_center_x, 100.*mrdStartVertex.Y()-tank_center_y, 100.*mrdStartVertex.Z()-tank_center_z); //cm + TVector3 mrdStop(100.*mrdStopVertex.X()-tank_center_x, 100.*mrdStopVertex.Y()-tank_center_y, 100.*mrdStopVertex.Z()-tank_center_z); + //-- Get track direction from MRD start/stop + TVector3 mrdTrackDir = (mrdStop - mrdStart).Unit(); + //-- QA:Compare angle from mrdTrackDir to trackAngleRad + std::cout << " [debug] mrdTrackDir, trackAngleRad: " << mrdTrackDir.Angle(TVector3(0,0,1)) << "," << trackAngleRad << std::endl; + + //-- ANNIE in 3D: Add mrdStart and mrdStop to 3D geo + if (isData) sprintf(blockName,"mrdStart_%u",evnum); + else sprintf(blockName,"mrdStart_%u",mcevnum); + bBlock = ageom->MakeSphere(blockName, Iron, 0,1.5,0,180,0,360); + bBlock->SetLineColor(8); + EXPH->AddNodeOverlap(bBlock,69,new TGeoTranslation(mrdStart.X(), mrdStart.Y(), mrdStart.Z())); + N++; + + if (isData) sprintf(blockName,"mrdStop_%u",evnum); + else sprintf(blockName,"mrdStop_%u",mcevnum); + bBlock = ageom->MakeSphere(blockName, Iron, 0,1.5,0,180,0,360); + bBlock->SetLineColor(2); + EXPH->AddNodeOverlap(bBlock,69,new TGeoTranslation(mrdStop.X(), mrdStop.Y(), mrdStop.Z())); + N++; + + + // ------------------------------------------------------------ + // --- Calculate several vertex candidates -------------------- + // ------------------------------------------------------------ + //-- This is kind of like an angle cut + std::vector vtxCandidates; + int c = 1; + bool outsideTank = false; + bool inFV = false; //FV around tank center + while (!outsideTank) + { + TVector3 v = mrdStart - c*10.*mrdTrackDir; //cm + if (c <= 5) { vtxCandidates.push_back(v); } //get into tank first + else if (c > 5) + { + //-- Check that vtx is contained in tank cylinder + if ((pow(v.X(),2) + pow(v.Z(),2) >= pow(tank_radius*100.,2)) || (v.Y() > tank_height*100.) || (v.Y() < -tank_height*100.)) + { + outsideTank = true; + } + else { vtxCandidates.push_back(v); } + + //-- Check if any vtx intersects FV around center + if ((v.Y() > -100.)&&(v.Y() < 100.)&&(100. > std::sqrt(v.X()*v.X() + v.Z()*v.Z()))) + { + inFV = true; + } + } + c++; + } //-- Done calculating vtx candidates + + //-- CUT: Make sure track originates in tank + if (!inFV) + { + std::cout << "MuonFitter Tool: Not in FV!" << std::endl; + return true; + } + + std::cout << "MuonFitter Tool: Num of vtxCandidates: " << vtxCandidates.size() << std::endl; + + //-- Check distance btwn vertices to make sure it's 10cm +/* for (int i = 1; i < vtxCandidates.size(); ++i) + { + TVector3 v0(vtxCandidates.at(i-1)); + TVector3 v1(vtxCandidates.at(i)); + double d = TMath::Sqrt(pow(v1.X()-v0.X(),2) + pow(v1.Y()-v0.Y(),2) + pow(v1.Z()-v0.Z(),2)); + std::cout << " [debug] distance btwn candidate vtx: " << d << std::endl; + } //-- yes, it's 10cm */ + + + // ------------------------------------------------------------ + // --- Load Tank Clusters ------------------------------------- + // ------------------------------------------------------------ + bool has_clusters = false; + if (isData) { has_clusters = m_data->CStore.Get("ClusterMap", m_all_clusters); } + else { has_clusters = m_data->CStore.Get("ClusterMapMC", m_all_clusters_MC); } + if (!has_clusters) + { + std::cout << " MuonFitter Tool: No clusters found in CStore! Did you run ClusterFinder tool before this?" << std::endl; + return false; + } + + has_clusters = m_data->CStore.Get("ClusterMapDetkey", m_all_clusters_detkeys); //same for data and mc + if (!has_clusters) + { + std::cout << " MuonFitter Tool: No cluster detkeys found in CStore! Did you run ClusterFinder tool before this?" << std::endl; + return false; + } + + Log("MuonFitter Tool: Accessing pairs in all_clusters map", v_debug, verbosity); + 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::cout << " [debug] cluster_size (num clusters in event): " << cluster_size << std::endl; + + + // ------------------------------------------------------------ + // --- Find main cluster when more than one cluster ----------- + // ------------------------------------------------------------ + //-- Max charge and in [0..2000ns] time window + //-- Code based on UserTools/EventDisplay/EventDisplay.cpp + bool found_muon = false; + double main_cluster_time = 0; + double main_cluster_charge = 0; + double main_cluster_hits = 0; + + //bool found_muon = false; + double earliest_hittime = 0; + std::vector v_cluster_times; + if (isData) + { + for (std::pair>&& apair : *m_all_clusters) + { + std::vector& cluster_hits = apair.second; + double temp_time = 0; + double temp_charge = 0; + int temp_hits = 0; + + for (int ihit = 0; ihit < cluster_hits.size(); ihit++) + { + temp_hits++; + temp_time += cluster_hits.at(ihit).GetTime(); + temp_charge += cluster_hits.at(ihit).GetCharge(); + + //XXX: check single cluster hit positions + int chankey = cluster_hits.at(ihit).GetTubeId(); + std::map::iterator it = ChannelKeyToSPEMap.find(chankey); + if (it != ChannelKeyToSPEMap.end()) + { + Detector* this_detector = geom->ChannelToDetector(chankey); + unsigned long detkey = this_detector->GetDetectorID(); //chankey same as detkey + } + } + if (temp_hits > 0) temp_time /= temp_hits; //mean time + std::cout << " [debug] temp_time [ns]: " << temp_time << std::endl; + if (temp_time > 2000. || temp_time < 0.) continue; // not in time window + if (temp_charge > main_cluster_charge) + { + found_muon = true; + main_cluster_charge = temp_charge; //sum of all charges + main_cluster_time = apair.first; //same as mean time above + main_cluster_hits = cluster_hits.size(); + } + } + } + else //is MC + { + for (std::pair>&& apair : *m_all_clusters_MC) + { + std::vector& cluster_hits_MC = apair.second; + double temp_time = 0; + double temp_charge = 0; + int temp_hits = 0; + std::vector v_cluster_hits; + + for (int ihit = 0; ihit < cluster_hits_MC.size(); ihit++) + { + temp_hits++; + v_cluster_hits.push_back(cluster_hits_MC.at(ihit).GetTime()); + temp_time += cluster_hits_MC.at(ihit).GetTime(); + temp_charge += cluster_hits_MC.at(ihit).GetCharge(); + + //XXX: check single cluster hit positions + int chankey = cluster_hits_MC.at(ihit).GetTubeId(); + std::map::iterator it = ChannelKeyToSPEMap.find(chankey); + if (it != ChannelKeyToSPEMap.end()) + { + Detector* this_detector = geom->ChannelToDetector(chankey); + unsigned long detkey = this_detector->GetDetectorID(); //chankey same as detkey + + //-- QA: Check if coordinates are the same. If so, just use existing map + Position det_pos = this_detector->GetDetectorPosition(); + } + } + + //-- Sort cluster hit times to determine diff btwn earliest and latest times + sort(v_cluster_hits.begin(), v_cluster_hits.end()); + std::cout << " [debug] all MC cluster hit times (sorted): "; + for (int ct = 0; ct < v_cluster_hits.size(); ++ct) + { + std::cout << v_cluster_hits.at(ct) << ","; + } + std::cout << std::endl; + h_clusterhit_timespread->Fill(v_cluster_hits.at(v_cluster_hits.size()-1)-v_cluster_hits.at(0)); + + if (temp_hits > 0) temp_time /= temp_hits; //mean time + v_cluster_times.push_back(temp_time); + if (temp_time > 2000. || temp_time < 0.) continue; // not in time window + if (temp_charge > main_cluster_charge) + { + found_muon = true; + main_cluster_charge = temp_charge; + main_cluster_time = apair.first; //same as mean time above + main_cluster_hits = cluster_hits_MC.size(); + earliest_hittime = v_cluster_hits.at(0); + std::cout << " [debug] earliest_hittime: " << earliest_hittime << std::endl; + } + } + } + //-- QA: Check cluster times, main cluster time, charge, num hits + std::cout << " [debug] all cluster times: "; + for (int ct = 0; ct < v_cluster_times.size(); ++ct) + { + std::cout << v_cluster_times.at(ct) << ","; + } + std::cout << std::endl; + std::cout << " [debug] main_cluster_time [ns]: " << main_cluster_time << std::endl; + std::cout << " [debug] main_cluster_charge [nC/pe]: " << main_cluster_charge << std::endl; + std::cout << " [debug] main_cluster_hits [#]: " << main_cluster_hits << std::endl; + + + // ------------------------------------------------------------ + // --- Check coincidence tank and MRD activity ---------------- + // ------------------------------------------------------------ + //-- Select events that are within +/- 50ns of PMTMRDOffset + //-- in data: PMTMRDOffset ~745ns; in MC: PMTMRDOffset = 0 + //-- Code based on UserTools/EventSelector/EventSelector.cpp + double tankmrd_tdiff = mrdStartTime - main_cluster_time; + std::cout << " MuonFitter Tool: Time difference between tank and MRD activity [ns]: " << tankmrd_tdiff << std::endl; + if ((tankmrd_tdiff > PMTMRDOffset-50) && (tankmrd_tdiff < PMTMRDOffset+50)) + { + std::cout << "MuonFitter Tool: Main cluster is coincident with MRD cluster!" << std::endl; + } + else + { + found_muon = false; + std::cout << "MuonFitter Tool: Main cluster is NOT coincident with MRD cluster! " + << "Tank cluster and MRD cluster times are too different." << std::endl; + } + + //-- Save num hits and charge of main/max cluster + //-- NOTE: in MC, charge is given in PE + //h_total_pe_hits->Fill(main_cluster_hits, main_cluster_charge); + + + // ------------------------------------------------------------ + // --- FOUND MUON CANDIDATE ----------------------------------- + // ------------------------------------------------------------ + double max_eta = 0.; //for plotting + + if (!reco_mode) + { + if (found_muon) + { + std::cout << "MuonFitter Tool: Found muon candidate! Event: p" << partnumber << "_"; + if (isData) std::cout << evnum; + else std::cout << mcevnum; + std::cout << std::endl; + drawEvent = true; + + //-- Save nhits, cluster_charge to txt files + //-- TODO: get rid of this + /*pehits_file << "p" << partnumber << "_"; + if (isData) pehits_file << evnum; + else pehits_file << mcevnum; + pehits_file << "," << main_cluster_hits << "," << main_cluster_charge << std::endl;*/ + + //-- Save main cluster charge + h_clusterPE->Fill(main_cluster_charge); + + + // ------------------------------------------------------------ + // --- Load MAIN cluster hits and detkeys --------------------- + // ------------------------------------------------------------ + std::vector cluster_hits; + std::vector cluster_hits_MC; + if (isData) { cluster_hits = m_all_clusters->at(main_cluster_time); } + else { cluster_hits_MC = m_all_clusters_MC->at(main_cluster_time); } + std::vector cluster_detkeys = m_all_clusters_detkeys->at(main_cluster_time); + std::vector x_hits, y_hits, z_hits; + + // ------------------------------------------------------------ + // --- Ring Imaging: Calculate ai for each PMT ---------------- + // ------------------------------------------------------------ + std::map charge; //-- used for making charge cuts at PMT level + std::map> hittime; //-- used for t0 calc + std::map> m_PE_ai; + std::map> m_fpmt_ai; + + charge.clear(); + hittime.clear(); + for (unsigned long detkey = 332; detkey < 464; ++detkey) + { + charge.emplace(detkey, 0.); + hittime.emplace(detkey, std::vector{-99.}); + } + + //-- First collect all the charges seen by the PMT in the cluster + if (isData) + { + for (int i = 0; i < (int)cluster_hits.size(); ++i) + { + //for each cluster hit + int chankey = cluster_hits.at(i).GetTubeId(); + std::map::iterator it = ChannelKeyToSPEMap.find(chankey); + if (it != ChannelKeyToSPEMap.end()) + { + Detector* this_detector = geom->ChannelToDetector(chankey); + unsigned long detkey = this_detector->GetDetectorID(); //chankey same as detkey + double hit_charge = cluster_hits.at(i).GetCharge(); + double hit_PE = hit_charge / ChannelKeyToSPEMap.at(chankey); + double hit_time = cluster_hits.at(i).GetTime(); + hittime[detkey].push_back(hit_time); + + // keep track of total charge seen by each PMT + charge[detkey] += hit_PE; + + } //end if ChannelKeyToSPEMap + } //end cluster_hits loop + } + else //is MC + { + for (int i = 0; i < (int)cluster_hits_MC.size(); ++i) + { + //for each cluster hit + int chankey = cluster_hits_MC.at(i).GetTubeId(); + std::map::iterator it = ChannelKeyToSPEMap.find(chankey); + if (it != ChannelKeyToSPEMap.end()) + { + Detector* this_detector = geom->ChannelToDetector(chankey); + unsigned long detkey = this_detector->GetDetectorID(); //chankey same as detkey + double hit_PE = cluster_hits_MC.at(i).GetCharge(); //charge in MC is in PE + double hit_charge = hit_PE * ChannelKeyToSPEMap.at(chankey); + double hit_time = cluster_hits_MC.at(i).GetTime(); + hittime[detkey].push_back(hit_time); + + // keep track of total charge seen by each PMT + charge[detkey] += hit_PE; + + } //end if ChannelKetToSPEMap + } //end cluster_hits_MC loop + } + + //-- Now go through charge, hittime maps + int gi = 0; //counter for TGraph + int nhits = 0, nhits_incone = 0; + double totalpe = 0, totalpe_incone = 0; + std::vector v_tzero; + + for (unsigned long detkey = 332; detkey < 464; ++detkey) + { + //-- Get the charge for this PMT + double pmt_PE = charge[detkey]; + + //-- NOTE: there are PMTs w/ 0pe from charge map initialization + if (pmt_PE == 0) continue; + + std::vector v_hittimes = hittime[detkey]; + double pmt_t = 0; + int nhits_pmt = v_hittimes.size(); + std::cout << " [debug] all hit times for detkey " << detkey << ": "; + for (int ht = 0; ht < nhits_pmt; ++ht) { std::cout << v_hittimes.at(ht) << ","; } + std::cout << std::endl; + + //-- Get earliest hit time bc Cherenkov radiation is usu earliest + sort(v_hittimes.begin(), v_hittimes.end()); + pmt_t = v_hittimes.at(0); + if (pmt_t == -99.) pmt_t = v_hittimes.at(1); + std::cout << " MuonFitter Tool: Earliest time for this PMT: " << pmt_t << std::endl; + + + //-- CUT: Skip PMTs in this cluster that don't see enough light + if (pmt_PE < PMTQCut) + { + std::cout << " MuonFitter Tool: SKIPPING charge[" << detkey << "] < " << PMTQCut << "pe: " << charge[detkey] << std::endl; + pmt_PE = 0.; //set PMT charge to 0 + continue; //skip PMT entirely + } + + //-- Keep track of total hits, PE that meet cut in this cluster + nhits += 1; + totalpe += pmt_PE; + + //-- Get position and direction of PMT + double hitX = x_pmt[detkey]; + double hitY = y_pmt[detkey]; + double hitZ = z_pmt[detkey]; + double dirPMTX = x_pmt_dir[detkey]; + double dirPMTY = y_pmt_dir[detkey]; + double dirPMTZ = z_pmt_dir[detkey]; + + TVector3 pmt_dir = TVector3(dirPMTX, dirPMTY, dirPMTZ).Unit(); + + //-- Get vector from tankExitPoint to PMT (Ri) + TVector3 vec_Ri = TVector3(hitX,hitY,hitZ) - tankExit; + double Ri = vec_Ri.Mag(); + h_tankexit_to_pmt->Fill(Ri); + //-- QA: Check that vector was calculated correctly + std::cout << " [debug] hitXYZ: " << hitX << "," << hitY << "," << hitZ << std::endl; + std::cout << " [debug] tankExitXYZ: " << tankExit.X() << "," << tankExit.Y() << "," << tankExit.Z() << std::endl; + std::cout << " [debug] vec_Ri: " << vec_Ri.X() << "," << vec_Ri.Y() << "," << vec_Ri.Z() << std::endl; + std::cout << " [debug] vec_Ri direction: " << vec_Ri.Unit().X() << "," << vec_Ri.Unit().Y() << "," << vec_Ri.Unit().Z() << std::endl; + + //-- Get angle btwn Ri and muon direction (ai) + double ang_alpha = vec_Ri.Angle(-mrdTrackDir); //rad + double ai = Ri * TMath::Sin(ang_alpha) / TMath::Tan(CHER_ANGLE_RAD) + Ri * TMath::Cos(ang_alpha); + h_tanktrack_ai->Fill(ai); + + //-- Get the vector from vertex of ai to the PMT (bi) + TVector3 vec_ai = tankExit - ai*mrdTrackDir; + TVector3 vec_bi = TVector3(hitX,hitY,hitZ) - vec_ai; + double bi = TMath::Sqrt(pow(hitX-vec_ai.X(),2) + pow(hitY-vec_ai.Y(),2) + pow(hitZ-vec_ai.Z(),2)); + //-- QA: Check that vector was calculated correctly + std::cout << " [debug] vec_ai: " << vec_ai.X() << "," << vec_ai.Y() << "," << vec_ai.Z() << std::endl; + std::cout << " [debug] ai: " << ai << std::endl; + std::cout << " [debug] vec_bi: " << vec_bi.X() << "," << vec_bi.Y() << "," << vec_bi.Z() << std::endl; + std::cout << " [debug] bi: " << bi << std::endl; + + + //-- Find angle btwn true vertex and hit (MC ONLY) + //-- not sure what is being done w this rn + if (!isData) + { + TVector3 vec_truevtx_hit = TVector3(hitX,hitY,hitZ) - TVector3(trueVtxX,trueVtxY,trueVtxZ); + double anglePmtTrueVtx = vec_truevtx_hit.Angle(mrdTrackDir)*180./TMath::Pi(); + } + + //-- Get angle btwn vector bi and PMT direction + double psi = vec_bi.Angle(-pmt_dir); //used only to get angle; don't use for magnitude + if (psi > TMath::Pi()/2.) psi = TMath::Pi()-psi; + //-- QA: Check that angle was calculated correctly + //std::cout << " [debug] psi(+), psi(-): " << psi*180./TMath::Pi() << ", " << vec_bi.Angle(pmt_dir)*180./TMath::Pi() << std::endl; + + //-- Calculate the area of PMT & frustum (ring) + double eff_area_pmt = 0.5 * m_pmt_area[detkey] * (1. + TMath::Cos(psi)); // effective area seen by photons from emission point + h_eff_area_pmt->Fill(eff_area_pmt); + double area_frustum = 2. * TMath::Pi() * step_size_ai * Ri; + double f_pmt = eff_area_pmt / area_frustum; //fraction of photocathode of total frustrum (ring) area + h_fpmt->Fill(f_pmt); + + + //-- For each distance (ai) from tank exit point bin, collect the + //-- charges associated w/ this distance + for (int a = 55; a < 500; a+=step_size_ai) + { + if (ai >= a-step_size_ai/2 && ai < a+step_size_ai/2) + { + m_PE_ai[a].push_back(pmt_PE); + m_fpmt_ai[a].push_back(f_pmt); + } + } + + ++gi; + + } //-- Done going through charge[detkey] map + + // ------------------------------------------------------------ + // -- Make eta vs ai (tank track segment) graphs for fitting -- + // ------------------------------------------------------------ + //-- eta represents photon density. In principle, it should be + //-- a high, constant value inside Cherenkov disc, and should + //-- drop off once outside the disc + int j = 0; + double running_avg = 0; + + //-- Go thru ai and PMT area fraction maps and add up fractions + //-- and charges seen at each track segment (ai) + for (auto const &pair: m_fpmt_ai) + { + double total_PE_ai = 0; + double total_fpmt_ai = 0; + for (int e = 0; e < pair.second.size(); ++e) + { + total_fpmt_ai += pair.second.at(e); + total_PE_ai += m_PE_ai[pair.first].at(e); + } + //-- Calculate photon density at this track segment (ai) + double total_eta = total_PE_ai / total_fpmt_ai; + + //-- Used to indicate where highest photon density occurs + if (total_eta > max_eta) max_eta = total_eta; //for plotting + + //-- Plot (ai,eta) pair + gr_eta_ai->SetPoint(j, pair.first, total_eta); + + //-- Save (ev_id,cluster_time,ai,eta) data to txt file for ML scripts + pos_file << "p" << partnumber << "_"; + if (isData) pos_file << evnum; + else pos_file << mcevnum; + pos_file << "," << main_cluster_time << "," << pair.first << "," << total_eta << std::endl; + + //-- Get the overall avg photon density (eta) + avg_eta += total_eta; + + if (j == 0) running_avg = avg_eta; + else + { + std::cout << " [debug] avg_eta (before dividing j, so right now it is total eta): " << avg_eta << std::endl; + running_avg = avg_eta / (j+1); + } + + std::cout << " [debug] ai, running_avg: " << pair.first << ", " << running_avg << std::endl; + gr_running_avg->SetPoint(j, pair.first, running_avg); + + //-- Keep track of avg eta to the left and right of the trueTrackLegnthInWater: + if (!isData) + { + if (pair.first < trueTrackLengthInWater) //left of true track length + { + std::cout << " [debug] total_eta (left): " << total_eta << std::endl; + num_left_eta++; + left_avg_eta += total_eta; + } + if (pair.first > trueTrackLengthInWater) //right of true track length + { + std::cout << " [debug] total_eta (right): " << total_eta << std::endl; + num_right_eta++; + right_avg_eta += total_eta; + } + } + j+=1; + } + avg_eta /= j; + h_avg_eta->Fill(avg_eta); + std::cout << " [debug] avg eta: " << avg_eta << ", j: " << j << std::endl; + + //-- Keep track of avg eta to the left and right of the trueTrackLegnthInWater: + if (!isData) + { + std::cout << " [debug] num pmts (left, right): " << num_left_eta << ", " << num_right_eta << std::endl; + if (num_left_eta != 0) left_avg_eta /= num_left_eta; + if (num_right_eta != 0) right_avg_eta /= num_right_eta; + std::cout << " [debug] left avg: " << left_avg_eta << ", right avg: " << right_avg_eta << std::endl; + } + + //-- Save truth info to txt files + if (!isData) + { + truetrack_file << "p" << partnumber << "_" << mcevnum << ","; + truetrack_file << trueTrackLengthInWater << "," << trueTrackLengthInMRD << "," << trueMuonEnergy << std::endl; + //truetrack_file << trueTrackLengthInWater << "," << left_avg_eta << "," << right_avg_eta << std::endl; + } + } //-- End if found_muon + }//-- End !reco_mode + + + // ------------------------------------------------------------ + // --- RECO MODE: Fit tank track, muon energy, vertex --------- + // ------------------------------------------------------------ + double fitted_tank_track = -999.; + TVector3 fitted_vtx(-999,-999,-999); + double reco_muon_ke = -999.; + int num_mrd_lyrs = -999.; + num_mrd_lyrs = LayersHit.size(); + if (reco_mode) + { + double t0 = -999.; + bool save_t0 = false; + + //-- Get ev_id for matching << this has been moved further up in script + /*std::stringstream ev_id; + ev_id << "p" << partnumber << "_"; + if (isData) ev_id << evnum; + else ev_id << mcevnum;*/ + + if (abs(trackAngleRad*180./TMath::Pi()) > 5.) + { + std::cout << " [debug] angle more than 5 degrees! Event: p" << partnumber << "_"; + if (isData) std::cout << evnum; + else std::cout << mcevnum; + std::cout << std::endl; + } + + //-- Get the fitted tank track length for this event from file + std::map>::iterator it = m_tank_track_fits.find(ev_id.str()); + if (it != m_tank_track_fits.end()) + { + std::vector v_fit_ctime = m_tank_track_fits.at(ev_id.str()); + double fit_cluster_time = (double)v_fit_ctime.at(0); + fitted_tank_track = (double)v_fit_ctime.at(1); + std::cout << " MuonFitter Tool: Found track, cluster time for " << ev_id.str() << ": " << fitted_tank_track << ", " << fit_cluster_time << endl; + h_fitted_tank_track->Fill(fitted_tank_track); + + //-- Skip the bad fits + //-- NOTE: This may no longer be needed if using RNN to fit; might need different cuts + if (fitted_tank_track < 0) return false; + + if (!isData) + { + //-- Check diff btwn reco and true info + } + + //-- Load cluster + //-- NOTE: Must use main_cluster_time from above since precision is lost when saving to file + std::vector cluster_hits; + std::vector cluster_hits_MC; + if (isData) + { + cluster_hits = m_all_clusters->at(main_cluster_time); + //main_cluster_nhits = cluster_hits.size(); + for (int ihit = 0; ihit < cluster_hits.size(); ihit++) + { + main_cluster_charge += cluster_hits.at(ihit).GetCharge(); + } + } + else + { + cluster_hits_MC = m_all_clusters_MC->at(main_cluster_time); + //main_cluster_nhits = cluster_hits_MC.size(); + for (int ihit = 0; ihit < cluster_hits.size(); ihit++) + { + main_cluster_charge += cluster_hits_MC.at(ihit).GetCharge(); + } + } + std::vector cluster_detkeys = m_all_clusters_detkeys->at(main_cluster_time); + + //-- Save main cluster charge for fitted events + h_clusterPE_fit->Fill(main_cluster_charge); + if (hasPion) h_clusterPE_fit_haspion->Fill(main_cluster_charge); //look at charge for events with pions + + // ------------------------------------------------------------ + // --- Fit muon vertex from fitted tank track length ---------- + // ------------------------------------------------------------ + //-- Start from tank exit point and move backwards into tank + fitted_vtx = tankExit - fitted_tank_track * mrdTrackDir; + std::cout << " MuonFitter Tool: Fitted vtx xyz: " << fitted_vtx.X() << "," << fitted_vtx.Y() << "," << fitted_vtx.Z() << std::endl; + + //-- Check if hit falls inside cone of FITTED vertex + TVector3 vtx2tankExit = tankExit - fitted_vtx; //similar to ai vector +/* TVector3 vtx2pmt = TVector3(hitX,hitY,hitZ) - fitted_vtx; + + double ang = vtx2pmt.Angle(mrdTrackDir); + + if (!isData && display_truth) + { + std::cout << " [debug] vtx2tankExit (before truth): " << vtx2tankExit.X() << "," << vtx2tankExit.Y() << "," << vtx2tankExit.Z() << std::endl; + vtx2tankExit = TVector3(trueStopVtxX,trueStopVtxY,trueStopVtxZ) - TVector3(trueVtxX,trueVtxY,trueVtxZ); + vtx2pmt = TVector3(hitX,hitY,hitZ) - TVector3(trueVtxX,trueVtxY,trueVtxZ); + std::cout << " [debug] vtx2tankExit (after truth): " << vtx2tankExit.X() << "," << vtx2tankExit.Y() << "," << vtx2tankExit.Z() << std::endl; + ang = vtx2pmt.Angle(trueTrackDir); + std::cout << " [debug] ang (w/ trueTrackDir, w/ vtx2tankExit): " << ang << "," << vtx2pmt.Angle(vtx2tankExit) << std::endl; + } + + if (ang <= CHER_ANGLE_RAD) + { + //t0 = pmt_t - (TVector3(hitX,hitY,hitZ).Dot(mrdTrackDir) + ai) - TMath::Sqrt(1.33*1.33-1)*TVector3(hitX,hitY,hitZ).Cross(mrdTrackDir).Mag(); + t0 = pmt_t - (vtx2pmt.Dot(mrdTrackDir) + TMath::Sqrt(1.33*1.33-1)*vtx2pmt.Cross(mrdTrackDir).Mag()) / 30.; + + if (!isData && display_truth) + { + t0 = pmt_t - (vtx2pmt.Dot(trueTrackDir) + TMath::Sqrt(1.33*1.33-1)*vtx2pmt.Cross(trueTrackDir).Mag()) / 30.; + } + std::cout << " [debug] pmt_t made it inside cone! " << pmt_t << "," << t0 << std::endl; + v_tzero.push_back(t0); + nhits_incone += 1; + totalpe_incone += pmt_PE; + } + else { std::cout << " [debug] pmt_t did not make it inside cone! " << pmt_t << std::endl; } +*/ + + // ------------------------------------------------------------ + // --- Reconstruct Muon Energy -------------------------------- + // ------------------------------------------------------------ + //-- Calculate initial MIP energy loss in TANK from tank track length + double tank_track = fitted_tank_track; + if (!isData && display_truth) + { + // Check energy calc with trueTrackLengthInWater + tank_track = trueTrackLengthInWater; + } + double tank_dEdx = 2.000; //1.992 MeV/cm + double tank_edep = tank_track * tank_dEdx; + double tank_mrd_dist = TMath::Sqrt(pow(tankExitPointX-mrdEntryPointX,2) + pow(tankExitPointY-mrdEntryPointY,2) + pow(tankExitPointZ-mrdEntryPointZ,2)); + double outtank_edep = tank_mrd_dist * 1.05; //this should be dE/dx in air..; currently not used + std::cout << " [debug] tank_mrd_dist [cm]: " << tank_mrd_dist << std::endl; + std::cout << " [debug] outtank_edep: " << outtank_edep << std::endl; + + //-- Calculate initial MIP energy loss in MRD from MRD track length + //-- TODO: Use another dEdx value for iron? + double mrd_track = reco_mrd_track; + if (use_nlyrs) mrd_track = nlyrs_mrd_track; + if (use_conn_dots) mrd_track = conn_dots_mrd_track; + + double mrd_dEdx = 11.5; //MeV/cm; 10.1, 11.3 + double mrd_edep = mrd_track * mrd_dEdx; + if (use_eloss) mrd_edep = mrdEnergyLoss; //use official ANNIE tool reco MRD energy loss as the starting point + std::cout << " [debug] mrd_edep: " << mrd_edep << std::endl; //check which MRD energy is used + + if (use_nlyrs) + { + std::cout << " [debug] Adjust MRD track length based on initial mrd_edep" << std::endl; + if (mrd_edep >= 400.) + { + mrd_track = mrd_track / 0.95; + } + else if (mrd_edep < 400.) + { + mrd_track = mrd_track / 0.80; + } + + // Update with new track length + mrd_edep = mrd_track * mrd_dEdx; + std::cout << " [debug] nlyrs upd mrd_track: " << mrd_track << std::endl; + std::cout << " [debug] nlyrs upd mrd_edep: " << mrd_edep << std::endl; + } + + //-- Get initial reco muon energy by adding tank and MRD energy depositions + double reco_mu_e = tank_edep + mrd_edep; + + + //-- Fine-tune reconstructed muon energy by finding best dE/dx + //-- and updating the muon energy until it doesn't change by 2% + double T_before = reco_mu_e; + bool eres_ok = false; + int n_tries = 0; + std::cout << " [debug] initial tank_dEdx: " << tank_dEdx << std::endl; + +/* while (!eres_ok) + { + double new_dEdx = CalcTankdEdx(T_before); + std::cout << " [debug] new_dEdx: " << new_dEdx << std::endl; + double T_after = tank_track*new_dEdx + mrdEnergyLoss + tank_mrd_dist*new_dEdx; + double E_res = TMath::Abs(T_after-T_before)/T_before; + std::cout << " [debug] T_before: " << T_before << std::endl; + std::cout << " [debug] T_after: " << T_after << std::endl; + std::cout << " [debug] Eres: " << E_res << std::endl; + if (E_res <= 0.02) + { + reco_mu_e = T_after; //set as new reco muon energy + eres_ok = true; + } + else + { + T_before = T_after; + n_tries++; + if (n_tries > 10) + { + std::cout << " [debug] Did 10 tries!" << std::endl; + eres_ok = true; + } + } + } //end while eres_ok loop +*/ + + // ------------------------------------------------------------ + // --- Fine-tune reco muon energy by finding dEdx for changing + // --- muon energy after traveling some distance dx ----------- + // ------------------------------------------------------------ + std::cout << " MuonFitter Tool: Calculating muon energy iteratively..." << std::endl; + double dx = 10; //cm; step size to update dE/dx + double input_Emu = reco_mu_e; //input energy for dE/dx calculation + + //-- Use true energy minus muon's rest mass as initial input energy + //if (!isData && display_truth) { input_Emu = trueMuonEnergy-105.66; } + + //-- Start with energy deposition in tank + double sum_tank_Emu = 0.; //keep track of new reco muon energy in tank + double d_tanktrack = fitted_tank_track; //this will be used to keep track (haha get it) of remaining tank track length + if (!isData && display_truth) + { + //-- Check energy calc with true track length in water + d_tanktrack = trueTrackLengthInWater; + } + std::cout << " [debug] Initial d_tanktrack: " << d_tanktrack << std::endl; + + while (d_tanktrack > 0) + { + if (d_tanktrack < dx) + { + std::cout << " [debug] remaining d_tanktrack: " << d_tanktrack << std::endl; + + double deltaE = CalcTankdEdx(input_Emu) * d_tanktrack; + sum_tank_Emu += deltaE; + //-- Calculate new input energy for MRD energy calc + input_Emu -= deltaE; + d_tanktrack -= d_tanktrack; + std::cout << " [debug] input_Emu: " << input_Emu << std::endl; + std::cout << " [debug] sum_tank_Emu: " << sum_tank_Emu << std::endl; + std::cout << " [debug] d_tanktrack: " << d_tanktrack << std::endl; //should be 0 + std::cout << " [debug] final dEdx: " << deltaE/dx << std::endl; + } + else + { + double deltaE = CalcTankdEdx(input_Emu) * dx; + sum_tank_Emu += deltaE; + //-- Calculate new input energy and remaining tank track length + input_Emu -= deltaE; + d_tanktrack -= dx; + std::cout << " [debug] input_Emu: " << input_Emu << std::endl; + std::cout << " [debug] sum_tank_Emu: " << sum_tank_Emu << std::endl; + std::cout << " [debug] d_tanktrack: " << d_tanktrack << std::endl; + std::cout << " [debug] dEdx: " << deltaE/dx << std::endl; + } + } + std::cout << " [debug] input_Emu (for MRD): " << input_Emu << "," << reco_mu_e-sum_tank_Emu << std::endl; //should be equal + std::cout << " [debug] Initial reconstructed Emu: " << reco_mu_e << std::endl; + //-- Update reco muon energy with the new tank energy (same initial MRD energy deposition) + reco_mu_e = sum_tank_Emu + mrd_edep; + std::cout << " [debug] New reconstructed Emu (updated tank energy): " << reco_mu_e << std::endl; + + //-- Now update energy deposition in MRD + std::cout << " [debug] Now calculating muon energy in MRD..." << std::endl; + double d_mrdtrack = mrd_track; + double sum_mrd_Emu = 0.; + //-- Use trueTrackLengthInMRD to check energy calculation + //if (!isData && display_truth) { d_mrdtrack = trueTrackLengthInMRD; } + + std::cout << " [debug] Initial d_mrdtrack: " << d_mrdtrack << std::endl; + while (d_mrdtrack > 0) + { + if (input_Emu < 0) break; + + //-- TODO: Need condition on remaining track length + if (input_Emu < 20.) + { + std::cout << " [debug] input_Emu is LESS THAN 20 MeV: " << input_Emu << std::endl; + std::cout << " [debug] Remaining d_mrdtrack: " << d_mrdtrack << std::endl; + + /*if (use_nlyrs && (d_mrdtrack > dx)) + { + // Up the remaining energy since we still have a lot of track left + input_Emu = d_mrdtrack * 10.1; + }*/ + + //-- If input energy < 20 MeV, just add remaining energy + sum_mrd_Emu += input_Emu; + + //-- If input energy < 20, add (remaining track)*(previous dE/dx) + //sum_mrd_Emu += d_mrdtrack * mrd_dEdx; + + std::cout << " [debug] sum_mrd_Emu: " << sum_mrd_Emu << std::endl; + input_Emu -= input_Emu; + + //-- hist: How much track length do we have left? + h_remainder_track_last20MeV->Fill(d_mrdtrack); + //-- hist: What is the diff btwn reco_mu_e now and true_mu_e? + h_true_reco_Ediff_last20MeV->Fill((sum_tank_Emu+sum_mrd_Emu)-(trueMuonEnergy-105.66)); + h_remainder_track_Ediff_last20MeV->Fill((sum_tank_Emu+sum_mrd_Emu)-(trueMuonEnergy-105.66), d_mrdtrack); + break; + } + + if (d_mrdtrack < dx) + { + std::cout << " [debug] remaining d_mrdtrack: " << d_mrdtrack << std::endl; + double deltaE = CalcMRDdEdx(input_Emu) * d_mrdtrack; + sum_mrd_Emu += deltaE; + input_Emu -= deltaE; + d_mrdtrack -= d_mrdtrack; + mrd_dEdx = deltaE/dx; //save for remaining track length calc + + std::cout << " [debug] input_Emu: " << input_Emu << std::endl; + std::cout << " [debug] sum_mrd_Emu: " << sum_mrd_Emu << std::endl; + std::cout << " [debug] d_mrdtrack: " << d_mrdtrack << std::endl; + std::cout << " [debug] final dEdx: " << deltaE/dx << std::endl; + } + else + { + double deltaE = CalcMRDdEdx(input_Emu) * dx; + sum_mrd_Emu += deltaE; + input_Emu -= deltaE; + d_mrdtrack -= dx; + mrd_dEdx = deltaE/dx; + + std::cout << " [debug] input_Emu: " << input_Emu << std::endl; + std::cout << " [debug] sum_mrd_Emu: " << sum_mrd_Emu << std::endl; + std::cout << " [debug] d_mrdtrack: " << d_mrdtrack << std::endl; + std::cout << " [debug] dEdx: " << deltaE/dx << std::endl; + } + } //-- Done updating MRD energy + std::cout << " [debug] Updated reconstructed MRD energy (mrd_edep) vs mrdEnergyLoss: " << mrd_edep << "," << mrdEnergyLoss << std::endl; + //-- Update reconstructed muon energy with new MRD energy deposition + reco_mu_e = sum_tank_Emu + sum_mrd_Emu; + std::cout << " [debug] New reconstructed Emu (after updating MRD): " << reco_mu_e << std::endl; + + if (use_simple_ereco) + { + reco_mu_e = tank_edep + mrd_edep; //-- mrd_edep diff if use_eloss is 1 + //reco_mu_e = sum_tank_Emu + mrd_edep; //-- TODO:later do this where tank gets dynamically updated but MRD doesn't + std::cout << " [debug] reconstructed Emu (Simple E Reco): " << reco_mu_e << std::endl; + } + + reco_muon_ke = reco_mu_e; //-- store for CStore + + h_mrd_eloss_diff->Fill(sum_mrd_Emu - mrdEnergyLoss); //-- Diff btwn const dE/dx and ANNIE method + + //-- Calculated deltaR and other variables (MC ONLY -- requires truth info) + if (!isData) + { + //-- Calculate spatial resolution (deltaR) + double deltaR = TMath::Sqrt(pow(fitted_vtx.X()-trueVtxX,2) + pow(fitted_vtx.Y()-trueVtxY,2) + pow(fitted_vtx.Z()-trueVtxZ,2)); + h_deltaR->Fill(deltaR); + + TVector3 true_vtx = TVector3(trueVtxX,trueVtxY,trueVtxZ); + double transverse = deltaR * TMath::Sin((true_vtx-fitted_vtx).Angle(mrdTrackDir)); + h_transverse->Fill(TMath::Abs(transverse)); + + double parallel = deltaR * TMath::Cos((true_vtx-fitted_vtx).Angle(mrdTrackDir)); + h_parallel->Fill(TMath::Abs(parallel)); + + //-- Compare with true muon energy + double true_mu_e = trueMuonEnergy - 105.66; //minus rest mass + reco_mu_e = reco_mu_e + ERECO_SHIFT; + double ediff = reco_mu_e - true_mu_e; + h_true_reco_E->Fill(true_mu_e, reco_mu_e); + h_true_reco_Ediff->Fill(ediff); + + //-- Use timing to select good vertex fits + /*if (h_tzero->GetStdDev() < 2.) + { + std::cout << " [debug] h_t0 width: " << h_tzero->GetStdDev() << std::endl; + h_true_reco_E->Fill(true_mu_e, reco_mu_e); + h_true_reco_Ediff->Fill(ediff); + //if (main_cluster_charge < 3500.) h_true_reco_Ediff->Fill(ediff); //make a charge cut + }*/ + + if (abs(ediff) > 100) + { + std::cout << " !!HEY! THERE IS A HUGE ENERGY DIFFERENCE!! Event: " << ev_id.str() <<", Ediff: " << ediff << std::endl; + std::cout << " >> TANK track lengths (reco; true): " << tank_track << "; " << trueTrackLengthInWater << std::endl; + std::cout << " >> MRD track lengths (reco; true): " << mrd_track << "; " << trueTrackLengthInMRD << std::endl; + std::cout << " >> Muon energy (reco; true): " << reco_mu_e << "; " << true_mu_e << std::endl; + std::cout << " >> Muon vertex (reco; true): " << fitted_vtx.X() << "," << fitted_vtx.Y() << "," << fitted_vtx.Z() << "; " << trueVtxX << "," << trueVtxY << "," << trueVtxZ << std::endl; + + h_tank_track_diff_large->Fill(tank_track-trueTrackLengthInWater); + + + //-- Save info to file + //save_t0 = true; + lg_ediff_file << ev_id.str() << "," + << ediff << "," + << hasPion << "," + << tank_track << "," + << trueTrackLengthInWater << "," + << mrd_track << "," + << trueTrackLengthInMRD << "," + << reco_mu_e << "," + << true_mu_e << std::endl; + + //-- Save main_cluster_charge of events with ediff > 100 and/or has pion + h_clusterPE_lrg_ediff->Fill(main_cluster_charge); + if (hasPion) h_clusterPE_lrg_ediff_haspion->Fill(main_cluster_charge); + } + else + { + //-- Save info for events with ediff < 100 + h_tank_track_diff_small->Fill(tank_track-trueTrackLengthInWater); + } + + + //-- Look at fractions of the tank and MRD track lengths out of entire track length + double f_tanktrack = (tank_track + tank_mrd_dist) / (tank_track + tank_mrd_dist + reco_mrd_track); + double f_mrdtrack = (reco_mrd_track) / (tank_track + tank_mrd_dist + reco_mrd_track); + + } + //-- histogram: Compare energy deposition in MRD and tank + h_tank_mrd_E->Fill(mrdEnergyLoss, tank_edep); + } + else std::cout << " MuonFitter Tool: womp womp. No fitted track found for: " << ev_id.str() << std::endl; + + + // Find mean t0 and subtract to center hist around 0 + //double mean_t0 = 0.; +/* for (int t = 0; t < v_tzero.size(); ++t) { mean_t0 += v_tzero.at(t); } + if (v_tzero.size() != 0) mean_t0 /= v_tzero.size(); + std::cout << " [debug] mean_t0: " << mean_t0 << std::endl; + + for (int t = 0; t < v_tzero.size(); ++t) { h_tzero->Fill(v_tzero.at(t)-mean_t0); } + + h_uber_t0widths->Fill(h_tzero->GetStdDev()); + if (!isData && reco_mode && save_t0) + { + lg_ediff_file << "," << h_tzero->GetStdDev() << std::endl; + } +*/ + //save_t0 = false; //reset + + + // find which pmt charges are inside/outside cone of true track direction +/* if (!isData) + { + for (unsigned long detkey = 332; detkey < 464; ++detkey) + { + if (charge[detkey] != 0.) + { + // find vector from true vertex to PMT + TVector3 vec_pmt = TVector3(x_pmt[detkey],y_pmt[detkey],z_pmt[detkey]) - TVector3(trueVtxX,trueVtxY,trueVtxZ); + std::cout << " [debug] xyz_pmt[detkey] " << detkey << ": " << x_pmt[detkey] << "," << y_pmt[detkey] << "," << z_pmt[detkey] << std::endl; + // find angle between pmt vector (vec_pmt) and true track direction + double pmt_angle = vec_pmt.Angle(trueTrackDir)*180./TMath::Pi(); + std::cout << " [debug] vec_pmt: " << vec_pmt.X() << "," << vec_pmt.Y() << "," << vec_pmt.Z() << std::endl; + std::cout << " [debug] pmt_angle: " << pmt_angle << std::endl; + std::cout << " [debug] trueTrackDir: " << trueTrackDir.X() << "," << trueTrackDir.Y() << "," << trueTrackDir.Z() << std::endl; + std::cout << " [debug] trueVtx: " << trueVtxX << "," << trueVtxY << "," << trueVtxZ << std::endl; + std::cout << " [debug] trueStopVtx: " << trueStopVtxX << "," << trueStopVtxY << "," << trueStopVtxZ << std::endl; + + if (pmt_angle < CHER_ANGLE_DEG+insideAngle) h_qincone_truevtx->Fill(charge[detkey]); + if (pmt_angle > CHER_ANGLE_DEG+outsideAngle) h_qoutcone_truevtx->Fill(charge[detkey]); + } + } + }*/ + + } //-- End reco_mode + + + // ------------------------------------------------------------ + // --- Store variables to CStore for downstream tools --------- + // ------------------------------------------------------------ + std::cout << " MuonFitter Tool: Setting FittedTrackLengthInWater to CStore: " << fitted_tank_track << std::endl; + m_data->CStore.Set("FittedTrackLengthInWater", fitted_tank_track); //could be -888 or -999 if no fit + std::cout << " MuonFitter Tool: Setting FittedMuonVertex to CStore" << std::endl; + Position fitted_muon_vtx(fitted_vtx.X(), fitted_vtx.Y(), fitted_vtx.Z()); //could be -888 or -999 if no fit + m_data->CStore.Set("FittedMuonVertex", fitted_muon_vtx); + std::cout << " MuonFitter Tool: Setting RecoMuonKE to CStore: " << reco_muon_ke << std::endl; + m_data->CStore.Set("RecoMuonKE", reco_muon_ke); //could be -888 or -999 if no fit + m_data->CStore.Set("NLyers", num_mrd_lyrs); + + + // ------------------------------------------------------------ + // --- SimpleReconstruction variables ------------------------- + // ------------------------------------------------------------ + // -- Code based on SimpleReconstruction tool + // if able to fit a vertex, set SimpleRecoFlag (int) to 1 + if (fitted_tank_track > 0) SimpleRecoFlag = 1; + std::cout << " [debug] SimpleRecoFlag: " << SimpleRecoFlag << std::endl; + + SimpleRecoEnergy = reco_muon_ke; + + Position reco_vtx(fitted_vtx.X()/100., fitted_vtx.Y()/100. - 0.1446, fitted_vtx.Z()/100. + 1.681); //convert to [m] and set in same reference frame as Michael's SimpleRecoVtx + SimpleRecoVtx = reco_vtx; + SimpleRecoStopVtx = mrdStopVertex; //already in [m] + + SimpleRecoCosTheta = TMath::Cos(trackAngleRad); //diff from dirz in SimpleReco by factor of 2 + + double SimpleRecoTotalEnergy = SimpleRecoEnergy + 105.66; + SimpleRecoPt = sqrt((1-SimpleRecoCosTheta*SimpleRecoCosTheta)*(SimpleRecoTotalEnergy*SimpleRecoTotalEnergy-105.66*105.66)); + + std::cout << " [debug] DownstreamFV (before): " << DownstreamFV << std::endl; + std::cout << " [debug] FullCylFV (before): " << FullCylFV << std::endl; + + //if (sqrt(fitted_vtx.X()*fitted_vtx.X()+(fitted_vtx.Z()-1.681)*(fitted_vtx.Z()-1.681))<1.0 && fabs(fitted_vtx.Y())<0.5 && ((fitted_vtx.Z()-1.681) < 0.)) SimpleRecoFV = true; //original FV cut with center correction + // FV 1 - upstream half cylinder + if (sqrt(reco_vtx.X()*reco_vtx.X()+reco_vtx.Z()*reco_vtx.Z())<1.0 && fabs(reco_vtx.Y())<0.5 && (reco_vtx.Z()<0.)) + { //no tank center correction needed + std::cout << " MuonFitter Tool: Made FV cut!" << std::endl; + SimpleRecoFV = true; + std::cout << " MuonFitter Tool: Found in FV region 1 (upstream half of cylinder)! " << reco_vtx.X() << "," << reco_vtx.Y() << "," << reco_vtx.Z() << std::endl; + } + else { std::cout << " MuonFitter Tool: Did not make FV cut! reco_vtx(x,y,z): " << reco_vtx.X() << "," << reco_vtx.Y() << "," << reco_vtx.Z() << std::endl; } + + // FV 2 - downstream half cylinder + if (sqrt(reco_vtx.X()*reco_vtx.X()+reco_vtx.Z()*reco_vtx.Z())<1.0 && fabs(reco_vtx.Y())<0.5 && (reco_vtx.Z()>0.) && (reco_vtx.Z()<1.)) + { + DownstreamFV = 1; + std::cout << " MuonFitter Tool: Found in FV region 2 (downstream half of cylinder)! " << reco_vtx.X() << "," << reco_vtx.Y() << "," << reco_vtx.Z() << std::endl; + } + // FV 3 - 1m full right cylinder + if (sqrt(reco_vtx.X()*reco_vtx.X()+reco_vtx.Z()*reco_vtx.Z())<1.0 && fabs(reco_vtx.Y())<0.5) + { + FullCylFV = 1; + std::cout << " MuonFitter Tool: Found in FV region 3 (full cylinder volume)! " << reco_vtx.X() << "," << reco_vtx.Y() << "," << reco_vtx.Z() << std::endl; + } + + std::cout << " [debug] DownstreamFV (after): " << DownstreamFV << std::endl; + std::cout << " [debug] FullCylFV (after): " << FullCylFV << std::endl; + + SimpleRecoMrdEnergyLoss = mrdEnergyLoss; //placeholder; not used in NM tool + SimpleRecoTrackLengthInMRD = reco_mrd_track/100.; //placeholder; not used in NM tool + SimpleRecoMRDStart = mrdStartVertex; + SimpleRecoMRDStop = mrdStopVertex; + + SimpleRecoNeutrinoEnergy = this->CalcNeutrinoEnergy(SimpleRecoTotalEnergy, SimpleRecoCosTheta); + SimpleRecoQ2 = this->CalcQ2(SimpleRecoTotalEnergy, SimpleRecoCosTheta, SimpleRecoNeutrinoEnergy); + + //Set variables in RecoEvent Store + m_data->Stores["RecoEvent"]->Set("SimpleRecoFlag",SimpleRecoFlag); + m_data->Stores["RecoEvent"]->Set("SimpleRecoEnergy",SimpleRecoEnergy); + m_data->Stores["RecoEvent"]->Set("SimpleRecoVtx",SimpleRecoVtx); + m_data->Stores["RecoEvent"]->Set("SimpleRecoStopVtx",SimpleRecoStopVtx); + m_data->Stores["RecoEvent"]->Set("SimpleRecoCosTheta",SimpleRecoCosTheta); + m_data->Stores["RecoEvent"]->Set("SimpleRecoPt",SimpleRecoPt); + m_data->Stores["RecoEvent"]->Set("SimpleRecoFV",SimpleRecoFV); + m_data->Stores["RecoEvent"]->Set("SimpleRecoMrdEnergyLoss",SimpleRecoMrdEnergyLoss); + m_data->Stores["RecoEvent"]->Set("SimpleRecoTrackLengthInMRD",SimpleRecoTrackLengthInMRD); + m_data->Stores["RecoEvent"]->Set("SimpleRecoMRDStart",SimpleRecoMRDStart); + m_data->Stores["RecoEvent"]->Set("SimpleRecoMRDStop",SimpleRecoMRDStop); + m_data->Stores["RecoEvent"]->Set("DownstreamFV",DownstreamFV); + m_data->Stores["RecoEvent"]->Set("FullCylFV",FullCylFV); + m_data->Stores["RecoEvent"]->Set("SimpleRecoNeutrinoEnergy",SimpleRecoNeutrinoEnergy); + m_data->Stores["RecoEvent"]->Set("SimpleRecoQ2",SimpleRecoQ2); + + int test_fv = -1; + m_data->Stores["RecoEvent"]->Get("DownstreamFV", test_fv); + std::cout << " [debug] test_fv (DownstreamFV): " << test_fv << std::endl; + m_data->Stores["RecoEvent"]->Get("FullCylFV", test_fv); + std::cout << " [debug] test_fv (FullCylFV): " << test_fv << std::endl; + + //Fill Particles object with muon + if (SimpleRecoFlag){ + + //Define muon particle + int muon_pdg = 13; + tracktype muon_tracktype = tracktype::CONTAINED; + double muon_E_start = SimpleRecoEnergy; + double muon_E_stop = 0; + Position muon_vtx_start = SimpleRecoVtx; + Position muon_vtx_stop = SimpleRecoStopVtx; + Position muon_dir = SimpleRecoStopVtx - SimpleRecoVtx; + Direction muon_start_dir = Direction(muon_dir.X(),muon_dir.Y(),muon_dir.Z()); + double muon_start_time; + m_data->Stores["RecoEvent"]->Get("PromptMuonTime", muon_start_time); + double muon_tracklength = muon_dir.Mag(); + double muon_stop_time = muon_start_time + muon_tracklength/3.E8*1.33; + + Particle muon(muon_pdg,muon_E_start,muon_E_stop,muon_vtx_start,muon_vtx_stop,muon_start_time,muon_stop_time,muon_start_dir,muon_tracklength,muon_tracktype); + if (verbosity > 2){ + Log(" MuonFitter Tool: Added muon with the following properties as a particle:",v_message,verbosity); + muon.Print(); + } + + //Add muon particle to Particles collection + std::vector Particles; + get_ok = m_data->Stores["ANNIEEvent"]->Get("Particles",Particles); + if (!get_ok){ + Particles = {muon}; + } else { + Particles.push_back(muon); + } + m_data->Stores["ANNIEEvent"]->Set("Particles",Particles); + } + + + // ------------------------------------------------------------ + // --- Draw event --------------------------------------------- + // ------------------------------------------------------------ + root_outp->cd(); + this->SaveHistograms(); + + //-- ANNIE in 3D + //-- Code based on UserTools/EventDisplay/EventDisplay.cpp + if (plot3d && drawEvent) + { + if (verbosity > v_debug) { std::cout << "MuonFitter Tool: Saving 3D plots..." << std::endl; } + + std::stringstream ss_evdisplay3d_title, ss_evdisplay3d_name; + ss_evdisplay3d_title << "evdisplay3d_ev"; + ss_evdisplay3d_name << "canvas_evdisplay3d_p" << partnumber << "_ev"; + if (!isData) + { + ss_evdisplay3d_title << mcevnum; + ss_evdisplay3d_name << mcevnum; + } + else + { + ss_evdisplay3d_title << evnum; + ss_evdisplay3d_name << evnum; + } + canvas_3d->SetTitle(ss_evdisplay3d_title.str().c_str()); + canvas_3d->SetName(ss_evdisplay3d_name.str().c_str()); + ageom->DrawTracks(); + canvas_3d->Modified(); + canvas_3d->Update(); + canvas_3d->Write(); + } + + //-- Save canvases/graphs for fitting + if (!reco_mode && found_muon) + { + //------------------------------------------------------------ + //-- Photon density (eta) vs tank track segment (ai) --------- + //------------------------------------------------------------ + + c_eta_ai->cd(); + std::stringstream ss_eta_title, ss_eta_ai_name, ss_truetrack; + ss_eta_title << "#eta: #PE Divided By f (tot PMT charge > " << PMTQCut << ") Ev_"; + ss_eta_ai_name << "c_eta_ai"; + if (isData) ss_eta_ai_name << "_r" << runnumber; + else ss_eta_ai_name << "_wcsim"; + ss_eta_ai_name << "_p" << partnumber << "_ev"; + if (isData) + { + ss_eta_title << evnum; + ss_eta_ai_name << evnum; + } + else + { + ss_eta_title << mcevnum; + ss_eta_ai_name << mcevnum; + ss_truetrack << "true track length in water: " << trueTrackLengthInWater << " cm"; + if (display_truth) gr_eta_ai->SetTitle(ss_truetrack.str().c_str()); + } + gr_eta_ai->Draw("alp"); + gr_eta_ai->GetXaxis()->SetLimits(45., 505.); + gr_eta_ai->GetHistogram()->SetMinimum(0.); + //gr_running_avg->Draw("lp"); + c_eta_ai->Modified(); + c_eta_ai->Update(); + c_eta_ai->SetTitle(ss_eta_title.str().c_str()); + c_eta_ai->SetName(ss_eta_ai_name.str().c_str()); + + TLegend *legend = new TLegend(0.55, 0.65, 0.89, 0.89); + legend->AddEntry(gr_eta_ai, "#eta", "lp"); + //legend->AddEntry(gr_running_avg, "running avg #eta", "lp"); + + if (!isData) + { //indicate distance btwn trueVtx and tankExitPoint + /*TLine *lTrueTankTrack = new TLine(trueTrackLengthInWater, 0, trueTrackLengthInWater, max_eta+1); + lTrueTankTrack->SetLineColor(4); + lTrueTankTrack->SetLineWidth(2); + if (display_truth) + { + lTrueTankTrack->Draw(); + legend->AddEntry(lTrueTankTrack, "true tank track length", "l"); + }*/ + + TLine *lLeftAvgEta = new TLine(50, left_avg_eta, trueTrackLengthInWater, left_avg_eta); + lLeftAvgEta->SetLineColor(2); + lLeftAvgEta->SetLineWidth(2); + if (display_truth) + { + lLeftAvgEta->Draw(); + legend->AddEntry(lLeftAvgEta, "avg #eta to left of true track length", "l"); + } + + TLine *lRightAvgEta = new TLine(trueTrackLengthInWater, right_avg_eta, 455, right_avg_eta); + lRightAvgEta->SetLineColor(8); + lRightAvgEta->SetLineWidth(2); + if (display_truth) + { + lRightAvgEta->Draw(); + legend->AddEntry(lRightAvgEta, "avg #eta to right of true track length", "l"); + } + } + TLine *lAvgEta = new TLine(55, avg_eta, 500-step_size_ai/2, avg_eta); + lAvgEta->SetLineColor(46); + lAvgEta->SetLineWidth(2); + lAvgEta->Draw(); + legend->AddEntry(lAvgEta, "avg #eta", "l"); + legend->Draw(); + c_eta_ai->Write(); + if (!isData && display_truth) ss_eta_ai_name << "_truth"; + ss_eta_ai_name << ".png"; + c_eta_ai->SaveAs(ss_eta_ai_name.str().c_str()); + } //-- End !reco_mode + + + if (reco_mode) + { + c_h_tzero->cd(); + std::stringstream ss_t0_title, ss_t0_name; + ss_t0_title << "t0" << " p" << partnumber << "_ev"; + ss_t0_name << "c_h_tzero"; + if (isData) ss_t0_name << "_r" << runnumber; + else ss_t0_name << "_wcsim"; + ss_t0_name << "_p" << partnumber << "_ev"; + if (isData) + { + ss_t0_title << evnum; + ss_t0_name << evnum; + } + else + { + ss_t0_title << mcevnum; + ss_t0_name << mcevnum; + } + h_tzero->Draw(); + c_h_tzero->Modified(); + c_h_tzero->Update(); + c_h_tzero->SetTitle(ss_t0_title.str().c_str()); + if (!isData && display_truth) ss_t0_name << "_truth"; + c_h_tzero->SetName(ss_t0_name.str().c_str()); + c_h_tzero->Write(); + ss_t0_name << ".png"; + c_h_tzero->SaveAs(ss_t0_name.str().c_str()); + } + + return true; +} + + +bool MuonFitter::Finalise(){ + // Save output + root_outp->cd(); + + // Close 3D canvas + if (plot3d) + { + canvas_3d->Clear(); + canvas_3d->Close(); + delete canvas_3d; + } + + delete c_eta_ai; + delete c_h_tzero; + + root_outp->Close(); + pos_file.close(); + if (!isData) truetrack_file.close(); + if (!isData) lg_ediff_file.close(); + + Log("MuonFitter Tool: Exiting", v_message, verbosity); + return true; +} + + +//------------------------------------------------------------ +//--- Custom Functions --------------------------------------- +//------------------------------------------------------------ + +Position MuonFitter::Line3D(double x1, double y1, double z1, double x2, double y2, double z2, double C, std::string coord) +{ + // returns the XYZ coordinates of a new point in a 3D line + // given two initial points and one X,Y,Z value + double a = x2-x1; + double b = y2-y1; + double c = z2-z1; + double x = -69., y = -69., z = -69., L = -69.; + + if (coord == "x" || coord == "X") + { + L = (C-x1)/a; + x = C; + y = b*L+y1; + z = c*L+z1; + } + else if (coord == "y" || coord == "Y") + { + L = (C-y1)/b; + x = a*L+x1; + y = C; + z = c*L+z1; + } + else if (coord == "z" || coord == "Z") + { + L = (C-z1)/c; + x = a*L+x1; + y = b*L+y1; + z = C; + } + else { Log("MuonFitter Tool: Unable to recognize coordinate!", v_debug, verbosity); } + + return(Position(x,y,z)); +} + +void MuonFitter::reset_3d() +{ + //reset TANK PMTs + TGeoNode *node; + TGeoSphere *sphere; + for (unsigned long detkey=332; detkey<464; detkey++) + { + node = EXPH->GetNode(detkey_to_node[detkey]); + sphere = (TGeoSphere *)(node->GetVolume()->GetShape()); + sphere->SetSphDimensions(0,1.5,0,180,0,180); + node->GetVolume()->SetLineColor(41); + } + + //remove extra node(s) + if (N > maxN) + { + while (N > maxN) + { + node = EXPH->GetNode(maxN); + EXPH->RemoveNode(node); + --N; + } + } + + //remove tracks + if(ageom->GetNtracks() > 0) + { + ageom->ClearTracks(); + if (verbosity > v_debug) { std::cout << "Clearing tracks... current number: " << ageom->GetNtracks() << std::endl; } + } + + canvas_3d->Modified(); + canvas_3d->Update(); + +} + +bool MuonFitter::FileExists(std::string fname) +{ + ifstream myfile(fname.c_str()); + return myfile.good(); +} + +void MuonFitter::LoadTankTrackFits() +{ + ifstream myfile(tankTrackFitFile.c_str()); + std::cout << "opened file" << std::endl; + std::string line; + if (myfile.is_open()) + { + // Loop over lines, get event id, fit (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 fileLine; + boost::split(fileLine, line, boost::is_any_of(","), boost::token_compress_on); + std::string event_id = ""; + double tank_track_fit = -9999.; + double cluster_time = -9999.; + event_id = fileLine.at(0); + cluster_time = std::stod(fileLine.at(1)); + tank_track_fit = std::stod(fileLine.at(2)); + std::vector v_fit_ctime{cluster_time, tank_track_fit}; + if (verbosity > 5) std::cout << "Loading tank track fit: " << event_id << ", " << cluster_time << ", " << tank_track_fit << std::endl; + m_tank_track_fits.insert(std::pair>(event_id, v_fit_ctime)); + } + } + return; +} + +double MuonFitter::CalcTankdEdx(double input_E) +{ + double gamma = (input_E+105.66)/105.66; + std::cout << " [debug] water dEdx: gamma: " << gamma << std::endl; + double beta = TMath::Sqrt(gamma*gamma-1.)/gamma; + std::cout << " [debug] water dEdx: beta: " << beta << std::endl; + double Tmax = (2.*0.511*beta*beta*gamma*gamma)/(1.+2.*0.511*gamma/105.66 + pow(0.511/105.66,2)); + std::cout << " [debug] water dEdx: Tmax: " << Tmax << std::endl; + double ox_ln = TMath::Log(2.*0.511*beta*beta*gamma*gamma*Tmax/(I_O*I_O)); + std::cout << " [debug] water dEdx: log factory oxy: " << ox_ln << std::endl; + double ox_dEdx = (0.999)*(16./18.)*WATER_DENSITY*0.307*0.5*pow(1./beta,2)*(0.5*ox_ln-beta*beta-0.5); + std::cout << " [debug] water dEdx: dE/dx oxy: " << ox_dEdx << std::endl; + double h_ln = TMath::Log(2.*0.511*beta*beta*gamma*gamma*Tmax/(I_H*I_H)); + std::cout << " [debug] water dEdx: log factor H: " << h_ln << std::endl; + double h_dEdx = (0.999)*(2./18.)*WATER_DENSITY*0.307*1.0*pow(1./beta,2)*(0.5*h_ln-beta*beta-0.5); + std::cout << " [debug] water dEdx: dE/dx H: " << h_dEdx << std::endl; + + // including Gd2(SO4)3 + double gd_ln = TMath::Log(2.*0.511*beta*beta*gamma*gamma*Tmax/(I_GD*I_GD)); + double gd_dEdx = (0.001)*(314./602.)*1.0*0.307*0.5*pow(1./beta,2)*(0.5*gd_ln-beta*beta-0.5); + //double s_ln = TMath::Log(2.*0.511*beta*beta*gamma*gamma*Tmax/(I_S*I_S)); + //double s_dEdx = (0.001)*(96./602.)*1.0*0.307*0.5*pow(1./beta,2)*(0.5*s_ln-beta*beta-0.5); + //double gdox_dEdx = (0.001)*(192./602.)*1.0*0.307*0.5*pow(1./beta,2)*(0.5*ox_ln-beta*beta-0.5); + + //return (ox_dEdx + h_dEdx + gd_dEdx + s_dEdx + gdox_dEdx); + return (ox_dEdx + h_dEdx + gd_dEdx); +} + +double MuonFitter::CalcMRDdEdx(double input_E) +{ + // Using iterative dE/dx method + double gamma = (input_E+105.66)/105.66; + double beta = TMath::Sqrt(gamma*gamma-1.)/gamma; + double Tmax = (2.*0.511*beta*beta*gamma*gamma)/(1.+2.*0.511*gamma/105.66 + pow(0.511/105.66,2)); + double fe_ln = TMath::Log(2.*0.511*beta*beta*gamma*gamma*Tmax/(I_FE*I_FE)); + double fe_dEdx = 7.874*0.307*0.464*pow(1./beta,2)*(0.5*fe_ln-beta*beta-0.5); + double b_tot = 1.0338*TMath::Log(input_E/1000.) + 0.89287; //fitted + if (b_tot < 0.) b_tot = 0; + //fe_dEdx = fe_dEdx + b_tot*input_E*7.874; + + return fe_dEdx; +} + +void MuonFitter::ResetVariables() +{ + // photon density (eta) variables + avg_eta = 0; + left_avg_eta = 0.; + right_avg_eta = 0.; + num_left_eta = 0; + num_right_eta = 0; + + // 3D plotting + if (plot3d) { reset_3d(); } + + // Set default values for reconstruction variables + SimpleRecoFlag = -9999; + SimpleRecoEnergy = -9999; + SimpleRecoVtx.SetX(-9999); + SimpleRecoVtx.SetY(-9999); + SimpleRecoVtx.SetZ(-9999); + SimpleRecoCosTheta = -9999; + SimpleRecoPt = -9999; + SimpleRecoStopVtx.SetX(-9999); + SimpleRecoStopVtx.SetY(-9999); + SimpleRecoStopVtx.SetZ(-9999); + SimpleRecoFV = false; + SimpleRecoMrdEnergyLoss = -9999; + SimpleRecoTrackLengthInMRD = -9999; + SimpleRecoMRDStart.SetX(-9999); + SimpleRecoMRDStart.SetY(-9999); + SimpleRecoMRDStart.SetZ(-9999); + SimpleRecoMRDStop.SetX(-9999); + SimpleRecoMRDStop.SetY(-9999); + SimpleRecoMRDStop.SetZ(-9999); + DownstreamFV = -9999; + FullCylFV = -9999; + SimpleRecoNeutrinoEnergy = -9999; + SimpleRecoQ2 = -9999; + +} + +void MuonFitter::InitHistograms() +{ + //-- Initialize Histograms + h_num_mrd_layers = new TH1D("h_num_mrd_layers", "Num MRD Layers Hit", 50, 0, 50.); + h_num_mrd_layers->GetXaxis()->SetTitle("# layers"); + + h_truevtx_angle = new TH1D("h_truevtx_angle", "Angle of True Muon Vertex", 360, -180., 180.); + h_truevtx_angle->GetXaxis()->SetTitle("angle [deg]"); + + h_tankexit_to_pmt = new TH1D("h_tankexit_to_pmt", "Distance from Tank Exit Point to PMT Position", 350, 0., 350.); + h_tankexit_to_pmt->GetXaxis()->SetTitle("Ri [cm]"); + + h_tanktrack_ai = new TH1D("h_tanktrack_ai", "Segment of Tank Track (a_{i})", 250, 0., 500.); + h_tanktrack_ai->GetXaxis()->SetTitle("a_{i} [cm]"); + + h_eff_area_pmt = new TH1D("h_eff_area_pmt", "Effective Area of PMT Seen by Photons", 650, 0., 650.); + h_eff_area_pmt->GetXaxis()->SetTitle("effective area [cm^2]"); + + h_fpmt = new TH1D("h_fpmt", "area fraction f", 100, 0., 1.); + h_fpmt->GetXaxis()->SetTitle("f"); + + h_clusterhit_timespread = new TH1D("h_clusterhit_timespread", "Time Spread of Clusters (Latest - Earliest)", 200, 0, 200); + h_clusterhit_timespread->GetXaxis()->SetTitle("latest t - earliest t [ns]"); + + h_avg_eta = new TH1D("h_avg_eta", "Overall Average Eta", 100, 0, 5000); + h_avg_eta->GetXaxis()->SetTitle("eta [PE/cm]"); + + h_tdiff = new TH1D("h_tdiff", "Time Residuals", 1000, -1000., 1000.); + h_tdiff->GetXaxis()->SetTitle("time residual [ns]"); + + h_uber_t0widths = new TH1D("h_uber_t0widths", "Distribution of Timing Distribution Widths", 31, -1., 30.); + h_uber_t0widths->GetXaxis()->SetTitle("std devs [ns]"); + + h_true_tanktrack_len = new TH1D("h_true_tanktrack_len", "Distribution of True Track Lengths", 400, 0, 2000); + h_true_tanktrack_len->GetXaxis()->SetTitle("track length [cm]"); + + h_fitted_tank_track = new TH1D("h_fitted_tank_track", "Distribution of Fitted Track Length", 200, 0, 400); + h_fitted_tank_track->GetXaxis()->SetTitle("track length [cm]"); + + h_deltaR = new TH1D("h_deltaR", "#Deltar", 75, 0., 150.); + h_deltaR->GetXaxis()->SetTitle("#Deltar [cm]"); + + h_transverse = new TH1D("h_transverse", "transverse distance", 75, 0., 150.); + h_transverse->GetXaxis()->SetTitle("[cm]"); + + h_parallel = new TH1D("h_parallel", "parallel distance", 75, 0., 150.); + h_parallel->GetXaxis()->SetTitle("[cm]"); + + h_true_reco_E = new TH2D("h_true_reco_E", "Reco vs True #mu Energy", 250, 0., 5000., 250, 0., 5000.); + h_true_reco_E->GetXaxis()->SetTitle("TrueE [MeV]"); + h_true_reco_E->GetYaxis()->SetTitle("RecoE (tank+mrd) [MeV]"); + + h_true_reco_Ediff = new TH1D("h_true_reco_Ediff", "Diff in Reco and True #mu Energy", 100, -500, 500); + h_true_reco_Ediff->GetXaxis()->SetTitle("recoE - trueE [MeV]"); + + h_tank_mrd_E = new TH2D("h_tank_mrd_E", "Reco #mu Energy in Tank vs in MRD", 250, 0., 5000., 250, 0., 5000.); + h_tank_mrd_E->GetXaxis()->SetTitle("Reco MrdE [MeV]"); + h_tank_mrd_E->GetYaxis()->SetTitle("Reco TankE [MeV]"); + + h_mrd_eloss_diff = new TH1D("h_mrd_eloss_diff", "diff in MRD energy loss", 200, -500, 1500); + h_mrd_eloss_diff->GetXaxis()->SetTitle("[MeV]"); + + h_tank_track_diff_small = new TH1D("h_tank_track_diff_small", "Difference in TANK track lengths (Reco-True) When E_{diff} < 200 MeV", 150, -150, 150); + h_tank_track_diff_small->GetXaxis()->SetTitle("reco-truth [cm]"); + + h_tank_track_diff_large = new TH1D("h_tank_track_diff_large", "Difference in TANK track lengths (Reco-True) When E_{diff} > 200 MeV", 150, -150, 150); + h_tank_track_diff_large->GetXaxis()->SetTitle("reco-truth [cm]"); + + h_clusterPE = new TH1D("h_clusterPE", "Cluster PE of Events with Found Muon", 100, 0, 10000); + h_clusterPE->GetXaxis()->SetTitle("cluster PE [p.e.]"); + + h_clusterPE_fit = new TH1D("h_clusterPE_fit", "Cluster PE of Events with Tank Track Fits", 100, 0, 10000); + h_clusterPE_fit->GetXaxis()->SetTitle("cluster PE [p.e.]"); + + h_clusterPE_fit_haspion = new TH1D("h_clusterPE_fit_haspion", "Cluster PE of Events with Tank Track Fits", 100, 0, 10000); + h_clusterPE_fit_haspion->GetXaxis()->SetTitle("cluster PE [p.e.]"); + + h_clusterPE_lrg_ediff = new TH1D("h_clusterPE_lrg_ediff", "Cluster PE of Events with Large E Diff", 100, 0, 10000); + h_clusterPE_lrg_ediff->GetXaxis()->SetTitle("cluster PE [p.e.]"); + + h_clusterPE_lrg_ediff_haspion = new TH1D("h_clusterPE_lrg_ediff_haspion", "Cluster PE of Events with Large E Diff and Has Pion", 100, 0, 10000); + h_clusterPE_lrg_ediff_haspion->GetXaxis()->SetTitle("cluster PE [p.e.]"); + + h_pca_angle = new TH1D("h_pca_angle", "Reconstructed Muon Direction Angle Using PCA", 200, -50, 50); + h_pca_angle->GetXaxis()->SetTitle("pca angle [deg]"); + + h_remainder_track_last20MeV = new TH1D("h_remainder_track_last20MeV", "Remaining Track Length in MRD When Input E_{#mu} < 20 MeV", 25, 0, 50); + h_remainder_track_last20MeV->GetXaxis()->SetTitle("remaining MRD track [cm]"); + + h_true_reco_Ediff_last20MeV = new TH1D("h_true_reco_Ediff_last20MeV", "Energy Difference Btwn True and Reco Energy When Input E_{#mu} < 20 MeV", 100, -500, 500); + h_true_reco_Ediff_last20MeV->GetXaxis()->SetTitle("E diff (reco-true) [MeV]"); + + h_remainder_track_Ediff_last20MeV = new TH2D("h_remainder_track_Ediff_last20MeV", "Remaining MRD Track Length vs True/Reco Energy Diff When Input E_{#mu} < 20 MeV", 100, -500, 500, 25, 0, 50); + h_remainder_track_Ediff_last20MeV->GetXaxis()->SetTitle("E diff (reco-true) [MeV]"); + h_remainder_track_Ediff_last20MeV->GetYaxis()->SetTitle("remaining MRD track [cm]"); + + h_tankExitX = new TH1D("h_tankExitX", "Tank Exit Point X", 200, -500, 500); + h_tankExitX->GetXaxis()->SetTitle("x [cm]"); + + h_tankExitY = new TH1D("h_tankExitY", "Tank Exit Point Y", 200, -500, 500); + h_tankExitY->GetXaxis()->SetTitle("y [cm]"); + + h_tankExitZ = new TH1D("h_tankExitZ", "Tank Exit Point Z", 200, -500, 500); + h_tankExitZ->GetXaxis()->SetTitle("z [cm]"); + +} + +void MuonFitter::SaveHistograms() +{ + h_num_mrd_layers->Write(); + //h_clusterhit_timespread->Write(); + if (!isData) + { + //h_truevtx_angle->Write(); + h_true_tanktrack_len->Write(); + h_clusterPE->Write(); + h_clusterPE_fit->Write(); + h_clusterPE_fit_haspion->Write(); + h_clusterPE_lrg_ediff->Write(); + h_clusterPE_lrg_ediff_haspion->Write(); + h_pca_angle->Write(); + h_remainder_track_last20MeV->Write(); + h_true_reco_Ediff_last20MeV->Write(); + h_remainder_track_Ediff_last20MeV->Write(); + } + h_tankexit_to_pmt->Write(); + h_tanktrack_ai->Write(); + h_eff_area_pmt->Write(); + h_fpmt->Write(); + //h_tdiff->Write(); + if (reco_mode) + { + h_uber_t0widths->Write(); + h_fitted_tank_track->Write(); + h_tank_mrd_E->Write(); + if (!isData) + { + h_deltaR->Write(); + h_transverse->Write(); + h_parallel->Write(); + h_true_reco_E->Write(); + h_true_reco_Ediff->Write(); + h_mrd_eloss_diff->Write(); + h_tank_track_diff_small->Write(); + h_tank_track_diff_large->Write(); + } + } +} + +void MuonFitter::InitCanvases() +{ + //-- Canvases + c_eta_ai = new TCanvas("c_eta_ai", "Charge per cm (#eta)", 800, 600); + c_h_tzero = new TCanvas("c_h_tzero", "t0", 800, 600); +} + +void MuonFitter::SaveCanvases() +{ + +} + +void MuonFitter::InitGraphs() +{ + //-- Graphs + // photon density (eta) vs tank track segment (ai) plot + gr_eta_ai = new TGraph(); + gr_eta_ai->SetLineWidth(0); + gr_eta_ai->SetMarkerStyle(25); + gr_eta_ai->SetMarkerColor(46); + gr_eta_ai->SetFillColor(0); + gr_eta_ai->GetXaxis()->SetTitle("a_{i} [cm]"); + gr_eta_ai->GetYaxis()->SetTitle("#eta (n_{PE}/f)"); + + // running avg of photon density (eta) + gr_running_avg = new TGraph(); + gr_running_avg->SetLineWidth(0); + gr_running_avg->SetMarkerStyle(8); + gr_running_avg->SetMarkerColor(38); + gr_running_avg->SetFillColor(0); + gr_running_avg->GetXaxis()->SetTitle("a_{i} [cm]"); + gr_running_avg->GetYaxis()->SetTitle("#eta (n_{PE}/f)"); + +} + +double MuonFitter::PCATrackAngle(std::vector v_MrdPMTsHit) +{ + // ------------------------------------------------------------ + // --- Use PCA to determine track angle in MRD ---------------- + // ------------------------------------------------------------ + //-- Code based on https://github.com/JaydipSingh/EnergyStudies/blob/main/trackAna_module.cc#L468 + //-- First define vectors to store xyz of each hit + std::vector fRec_SpacePoint_X; + std::vector fRec_SpacePoint_Y; + std::vector fRec_SpacePoint_Z; + + for (int i = 0; i < v_MrdPMTsHit.size(); ++i) + { + unsigned long detkey = (unsigned long)v_MrdPMTsHit.at(i); + //std::cout << " [debug] PCA algorithm - detkey: " << detkey << std::endl; + if (detkey < 26) continue; //skip FMV hits + Paddle *mrdpaddle = (Paddle *)geom->GetDetectorPaddle(detkey); + Position position_MRD = mrdpaddle->GetOrigin(); + + fRec_SpacePoint_X.push_back(mrd_center_x[detkey]); + fRec_SpacePoint_Y.push_back(mrd_center_y[detkey]); + fRec_SpacePoint_Z.push_back(mrd_center_z[detkey]); + } + + //-- Put all the xyz info into one array + double *xyz[3]; + TVector3 pos(0,0,0); + TVector3 dir; + xyz[0] = fRec_SpacePoint_X.data(); + xyz[1] = fRec_SpacePoint_Y.data(); + xyz[2] = fRec_SpacePoint_Z.data(); + size_t npts = fRec_SpacePoint_X.size(); + + if (npts < 2) + { + //throw std::exception("tpcvechitfinder2_module.cc: too few TPCClusters to fit a line in linefit"); + std::cout << " MuonFitter Tool: PCA Method: Too few TPCClusters to fit a line in linefit" << std::endl; + } + + TMatrixDSym covmat(3); //covariance matrix (use symmetric version) + + // position is just the average of the coordinates + double psum[3] = {0,0,0}; + for (size_t ipoint=0; ipoint v_MrdPMTsHit) +{ + //-- Calculate MRD track by "connecting the dots (hits)" + + double conn_dots_mrd_track = 0; + + //-- First sort MRD PMTs IDs; MrdPMTsHit is type std::vector + std::sort(v_MrdPMTsHit.begin(), v_MrdPMTsHit.end()); + + //-- QA: Check that MRD pmts have been sorted + std::cout << " [debug] sorted MRD PMTs: "; + for (int i = 0; i < v_MrdPMTsHit.size(); ++i) { std::cout << v_MrdPMTsHit.at(i) << ","; } + std::cout << std::endl; + + //-- Now connect the dots + for (int i = 1; i < v_MrdPMTsHit.size(); ++i) + { + unsigned long detkey1 = (unsigned long)v_MrdPMTsHit.at(i-1); + unsigned long detkey2 = (unsigned long)v_MrdPMTsHit.at(i); + + //-- XXX:For some reason, there are FMV PMTs in these clusters + if (detkey1 < 26) continue; + + double dist_btwn_lyrs = TMath::Sqrt(pow((mrd_center_x[detkey2]-mrd_center_x[detkey1]),2) + pow((mrd_center_y[detkey2]-mrd_center_y[detkey1]),2) + pow((mrd_center_z[detkey2]-mrd_center_z[detkey1]),2)); + + conn_dots_mrd_track += dist_btwn_lyrs; + + //-- QA: Check calculations + std::cout << " [debug] detkey 1,2: " << detkey1 << "," << detkey2 << std::endl; + std::cout << " [debug] dist_btwn_lyrs: " << dist_btwn_lyrs << std::endl; + std::cout << " [debug] conn_dots_mrd_track: " << conn_dots_mrd_track << std::endl; + } //-- Done connecting the dots + + return conn_dots_mrd_track; +} + +double MuonFitter::CalcNeutrinoEnergy(double Emu, double cosT) +{ + //-- Calculate the neutrino energy from reconstructed muon energy + //-- and track angle + //-- Emu: SimpleRecoTotalEnergy + //-- cosT: SimpleRecoCosTheta + + double Ev = 0; + double Mp = 938.272; //MeV + double Mn = 939.565; //MeV + double Eb = 26; + double Mmu = 105.658; //MeV + double pmu = sqrt(Emu*Emu-Mmu*Mmu); + Ev = ((Mp*Mp-pow((Mn-Eb),2)-Mmu*Mmu+2*(Mn-Eb)*Emu)/(2*(Mn-Eb-Emu+pmu*cosT))); + std::cout <<"Emu: "< +#include +#include +//#include +#include + +#include "Tool.h" + +#include "TFile.h" +#include "TCanvas.h" +#include "TEllipse.h" +#include "TGraph.h" +#include "TH1D.h" +#include "TH2D.h" +#include "TLegend.h" +#include "TLine.h" +#include "TMath.h" +#include "TMarker.h" +#include "TPolyMarker.h" +#include "TTree.h" +#include "TVector3.h" +#include "TVectorD.h" +#include "TPolyLine3D.h" +#include "TGeoManager.h" +#include "TGeoMaterial.h" +#include "TGeoMedium.h" +#include "TGeoVolume.h" +#include "TGeoNode.h" +#include "TGeoSphere.h" +#include "TVirtualGeoTrack.h" +#include "TLatex.h" +#include "TMatrixD.h" +#include "TMatrixDSym.h" + +#include "Hit.h" + +/** + * \class MuonFitter + * + * $ Author: J.He $ + * $ Last Updated: 2024/05/03 $ + * Contact: juhe@ucdavis.edu +*/ + +class MuonFitter: public Tool { + + + public: + + MuonFitter(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); + bool Execute(); + bool Finalise(); + Position Line3D(double x1, double y1, double z1, double x2, double y2, double z2, double C, std::string coord); + void reset_3d(); + bool FileExists(std::string fname); + void LoadTankTrackFits(); + double CalcTankdEdx(double input_E); + double CalcMRDdEdx(double input_E); + void ResetVariables(); + void InitHistograms(); + void SaveHistograms(); + void InitCanvases(); + void SaveCanvases(); + void InitGraphs(); + double PCATrackAngle(std::vector v_MrdPMTHits); + double MRDConnectDots(std::vector v_MrdPMTHits); + double CalcNeutrinoEnergy(double Emu, double cosT); + double CalcQ2(double Emu, double cosT, double Ev); + + + private: + + //constants + double LUX_AREA = 470.; //10-inch R7081 Hamamatsu + double ETEL_AREA = 613.; //11-inch D784UKFLB ETEL + double HAMAMATSU_AREA = 330.; //8-inch R5912-100 Hamamatsu + double WATCHBOY_AREA = 470.; //10-inch R7081 Hamamatsu + double WATCHMAN_AREA = 470.; //10-inch R7081-100 Hamamatsu + + double PHOTON_DENSITY = 328.; // [#photons/cm] + double CHER_ANGLE_DEG = 41.; //[deg] 41 or 42? + double CHER_ANGLE_RAD = CHER_ANGLE_DEG*TMath::Pi()/180.; //[rads] + double ALPHA_FACTOR = PHOTON_DENSITY / (4.*TMath::Pi()*TMath::Sin(CHER_ANGLE_RAD)*TMath::Tan(CHER_ANGLE_RAD)); + + double I_O = 9.200e-5; //=11.5*8*0.000001 + double I_H = 1.920e-5; //=19.2*1*0.000001 + double I_GD = 5.888e-4; //=19.2*1*0.000001 + double I_S = 1.632e-4; //=10.6*16*0.000001 + double I_FE = 2.86e-4; //=11*26*0.000001 + double WATER_DENSITY = 1.0; //g/cm3 + double IRON_DENSITY = 7.874; //g/cm3 + + double ERECO_SHIFT = 0.; + + + //logging + int verbosity; + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + std::string logmessage; + + //config variables + bool isData; + bool plot3d = false; + bool draw3d_fmv = false; + bool draw3d_mrd = false; + bool save_hists = false; + double PMTMRDOffset; + double step_size_ai = 5.; + double insideAngle = -5.; + double outsideAngle = 5.; + double PMTQCut = 3.; + double EtaThreshold = 500.; + bool display_truth = false; + bool reco_mode = false; + std::string tankTrackFitFile; + std::string aiEtaFile; + bool use_nlyrs = false; + bool use_pca = false; + bool use_conn_dots = false; + bool use_eloss = true; + bool use_simple_ereco = false; + + //text files + std::ofstream pos_file; + std::ofstream truetrack_file; + std::ofstream lg_ediff_file; + + //root,plots + TFile *root_outp = nullptr; + + TCanvas *canvas_3d; + TCanvas *c_eta_ai; + TCanvas *c_h_tzero; + + TGraph *gr_eta_ai = nullptr; + TGraph *gr_running_avg = nullptr; + + TH1D *h_tzero = nullptr; + TH1D *h_num_mrd_layers = nullptr; + TH1D *h_truevtx_angle = nullptr; + TH1D *h_tankexit_to_pmt = nullptr; + TH1D *h_tanktrack_ai = nullptr; + TH1D *h_eff_area_pmt = nullptr; + TH1D *h_fpmt = nullptr; + TH1D *h_clusterhit_timespread = nullptr; + TH1D *h_avg_eta = nullptr; + TH1D *h_tdiff = nullptr; + TH1D *h_uber_t0widths = nullptr; + TH1D *h_true_tanktrack_len = nullptr; + TH1D *h_fitted_tank_track = nullptr; + TH1D *h_deltaR = nullptr; + TH1D *h_transverse = nullptr; + TH1D *h_parallel = nullptr; + TH2D *h_true_reco_E = nullptr; + TH1D *h_true_reco_Ediff = nullptr; + TH2D *h_tank_mrd_E = nullptr; + TH1D *h_mrd_eloss_diff = nullptr; + TH1D *h_tank_track_diff_small = nullptr; + TH1D *h_tank_track_diff_large = nullptr; + TH1D *h_clusterPE = nullptr; + TH1D *h_clusterPE_fit = nullptr; + TH1D *h_clusterPE_fit_haspion = nullptr; + TH1D *h_clusterPE_lrg_ediff = nullptr; + TH1D *h_clusterPE_lrg_ediff_haspion = nullptr; + TH1D *h_pca_angle = nullptr; + TH1D *h_remainder_track_last20MeV = nullptr; + TH1D *h_true_reco_Ediff_last20MeV = nullptr; + TH2D *h_remainder_track_Ediff_last20MeV = nullptr; + TH1D *h_tankExitX = nullptr; + TH1D *h_tankExitY = nullptr; + TH1D *h_tankExitZ = nullptr; + + //event variables + int partnumber; + uint32_t evnum; + int runnumber; + int subrunnumber; + int mcevnum; + uint16_t mctrignum; + std::string mcFile; + double trueVtxTime; + double trueVtxX, trueVtxY, trueVtxZ; + double trueDirX, trueDirY, trueDirZ; + double trueStopVtxX, trueStopVtxY, trueStopVtxZ; + double trueAngleRad, trueAngleDeg; + double trueTrackLengthInWater; + double trueTrackLengthInMRD; + double trueMuonEnergy; + int nrings; + std::vector particles_ring; + std::map>* m_hits = nullptr; + + //geometry + Geometry *geom = nullptr; + double tank_height; + double tank_radius; + double tank_center_x; + double tank_center_y; + double tank_center_z; + double detector_version; + std::string detector_config; + int n_tank_pmts; + int n_mrd_pmts; + int n_veto_pmts; + + //3d geometry + TGeoManager *ageom = nullptr; + TGeoMaterial *vacuum = nullptr; + TGeoMaterial *Fe = nullptr; + TGeoMedium *Air = nullptr; + TGeoMedium *Iron = nullptr; + TGeoVolume *EXPH = nullptr; //experimental hall + char blockName[100]; //char array to form strings w/ sprintf + int N = 0, maxN = 0; //Nth node + TGeoVolume *bBlock = nullptr; //building block of PMTs + std::map detkey_to_node; + std::map x_pmt, y_pmt, z_pmt; + std::map x_pmt_dir, y_pmt_dir, z_pmt_dir; + Int_t track_index = 0; + Int_t ntracks = 0; + TVirtualGeoTrack *track = nullptr; + std::map> mrd_x, mrd_y, mrd_z; + std::map mrd_center_x, mrd_center_y, mrd_center_z; + + //maps,vectors + std::map ChannelKeyToSPEMap; + std::map> *tdcdata = nullptr; + std::map m_pmt_area; + std::map> *m_all_clusters = nullptr; + std::map> *m_all_clusters_MC = nullptr; + std::map> *m_all_clusters_detkeys = nullptr; + std::map> m_tank_track_fits; + std::vector *mcParticles = nullptr; + std::vector LayersHit; + std::vector MrdPMTsHit; + + //mrd + int numTracksInEv = 0; + std::vector* mrdTracks; //the reconstructed tracks + Position mrdStartVertex; + Position mrdStopVertex; + Position tankExitPoint; + double trackAngleRad = -69., trackAngleDeg = -69.; + double trackAngleError = -69.; + double penetrationDepth = -69.; + Position mrdEntryPoint; + int numLayersHit = 0; + double mrdEnergyLoss = 0.; + double mrdEnergyLossError = 0.; + double mrdStartTime = -69.; + + //misc + double avg_eta; + double left_avg_eta; + double right_avg_eta; + int num_left_eta; + int num_right_eta; + + // reconstruction variables (for NeutronMultiplicity toolchain) + int SimpleRecoFlag; + double SimpleRecoEnergy; + Position SimpleRecoVtx; + Position SimpleRecoStopVtx; + double SimpleRecoCosTheta; + double SimpleRecoPt; + bool SimpleRecoFV; + double SimpleRecoMrdEnergyLoss; + double SimpleRecoTrackLengthInMRD; + Position SimpleRecoMRDStart; + Position SimpleRecoMRDStop; + int DownstreamFV; + int FullCylFV; + double SimpleRecoNeutrinoEnergy; + double SimpleRecoQ2; + +}; + + +#endif diff --git a/UserTools/MuonFitter/README.md b/UserTools/MuonFitter/README.md new file mode 100644 index 000000000..e00a0dd32 --- /dev/null +++ b/UserTools/MuonFitter/README.md @@ -0,0 +1,24 @@ +#MuonFitter Tool Documentation +*********************** +Created by: Julie He + +Maintained by: James Minock + +Last updated: 10-2-2024 +*********************** + +This Tool functions for vertex and energy reconstruction, with the primary purpose being vertex reconstruction. This Tool operates on a ML generated model that fits tank tracks according to MRD information. + +This Tool is intended to act as a substitution to Michael's SimpleReconstruction Tool, filling "SimpleReco" values expected in PhaseIITreeMaker. + +The vertex saved to "SimpleRecoVtx" is given in meters and is oriented such that the center of the tank is represented by (0,-0.1446,1.681). + +There are additional variables created to be passed downstream including: + +FittedTrackLengthInWater - estimated track length in water of tank + +FittedMuonVertex - vertex of interaction assuming tank center at (0,0,0) + +RecoMuonKE - estimated kinetic energy of reconstructed muon + +Nlyrs - number of layers penetrated in MRD diff --git a/UserTools/NeutronCheck/NeutronCheck.cpp b/UserTools/NeutronCheck/NeutronCheck.cpp new file mode 100755 index 000000000..443ad40cf --- /dev/null +++ b/UserTools/NeutronCheck/NeutronCheck.cpp @@ -0,0 +1,489 @@ +#include "NeutronCheck.h" + +NeutronCheck::NeutronCheck():Tool(){} + + +bool NeutronCheck::Initialise(std::string configfile, DataModel &data){ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + //m_variables.Print(); + + m_variables.Get("verbosity",verbosity); + m_variables.Get("outfile",outfile); + m_variables.Get("UseClean",useClean); + m_variables.Get("FinderCompare",fFinderCompare); + m_variables.Get("ParticleInfo",fParticleInfo); + + outfile+=".root"; + + fOutput_tfile = new TFile(outfile.c_str(), "recreate"); + NeutCheckTree = new TTree("NeutCheckTree", "Neutron Check Tree"); + + NeutCheckTree->Branch("eventNumber", &fMCEventNum, "eventNumber/I"); + + NeutCheckTree->Branch("eventCutStatus", &fEventStatusFlagged,"eventStatusFlagged/I"); + NeutCheckTree->Branch("ClusterNumber",&fClusterNum); + NeutCheckTree->Branch("TrueEnu",&true_Enu,"true_Enu/D"); + NeutCheckTree->Branch("TrueEmu",&true_Emu,"true_Emu/D"); + NeutCheckTree->Branch("TrueQ2",&TrueQ2,"true_Q2/D"); + NeutCheckTree->Branch("ClusterCount", &fClusterCount,"clusterCount/I"); + NeutCheckTree->Branch("RecoClusters",&fRecoClusters,"RecoClusters"); + + NeutCheckTree->Branch("TrueNeutronMult",&fTrueNeutronMult,"trueNeutronMult/I"); + NeutCheckTree->Branch("TrueNeutronDelayed",&fTrueNeutronDelayed,"trueNeutronDel/I"); + NeutCheckTree->Branch("TrueNeutCapT",&fMCNeutCapTimes); + + + NeutCheckTree->Branch("ClusterNeutronMult",&fNeutronMult,"neutronMult/I"); + + NeutCheckTree->Branch("ClusterMode",&fClusterMode); + NeutCheckTree->Branch("ClusterPDG",&fClusterPDG); + NeutCheckTree->Branch("ClusterParentPDG",&fClusterParentPDG); + NeutCheckTree->Branch("ClusterParticleEnergy",&fClusterParticleEnergy); + NeutCheckTree->Branch("ClusterHits", &fClusterHits); + NeutCheckTree->Branch("ClusterTime",&fClusterTime); + NeutCheckTree->Branch("ClusterCharge",&fClusterCharge); + NeutCheckTree->Branch("ClusterPurity",&fClusterPurity); + NeutCheckTree->Branch("ClusterCB",&fClusterCB); + NeutCheckTree->Branch("ClusterAS0",&fClusterAS0); + NeutCheckTree->Branch("ClusterAS1",&fClusterAS1); + NeutCheckTree->Branch("ClusterAS2",&fClusterAS2); + //NeutCheckTree->Branch("ClusterSA",&fClusterSA); + NeutCheckTree->Branch("ClusterCVX",&fClusterCVX); + NeutCheckTree->Branch("ClusterCVY", &fClusterCVY); + NeutCheckTree->Branch("ClusterCVZ", &fClusterCVZ); + NeutCheckTree->Branch("ClusterCVR", &fClusterCVR); + NeutCheckTree->Branch("ClusterAMD", &fClusterAMD); + + + if(fFinderCompare){ + NeutCheckTree->Branch("FinderClusterNumber",&fFinderClusterNum); + NeutCheckTree->Branch("FinderClusterCount",&fFinderClusterCount,"FinderCount/I"); + NeutCheckTree->Branch("FinderPDG",&fFinderPDG); + NeutCheckTree->Branch("FinderParentPDG",&fFinderParentPDG); + NeutCheckTree->Branch("FinderCharge",&fFinderCharge); + NeutCheckTree->Branch("FinderPurity",&fFinderPurity); + NeutCheckTree->Branch("FinderTime",&fFinderTime); + } + + if (fParticleInfo) { + //Log("Particle Information to be added.",v_debug,verbosity); + NeutCheckTree->Branch("ParticlePDG",&fParticlePDG); + NeutCheckTree->Branch("ParticleParent",&fParticleParent); + NeutCheckTree->Branch("ParticleStartEnergy",&fParticleStartEnergy); + NeutCheckTree->Branch("ParticleStartTime", &fParticleStartTime); + NeutCheckTree->Branch("TrueNeutCapX", &fMCNeutCapX); + NeutCheckTree->Branch("TrueNeutCapY", &fMCNeutCapY); + NeutCheckTree->Branch("TrueNeutCapZ", &fMCNeutCapZ); + } + + + + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + return true; +} + + +bool NeutronCheck::Execute(){ + + Log("NeutronCheck Tool Executing:",v_message,verbosity); + + ResetVariables(); + + // MC entry number + m_data->Stores.at("ANNIEEvent")->Get("MCEventNum", fMCEventNum); + + // MC trigger number + m_data->Stores.at("ANNIEEvent")->Get("MCTriggernum", fMCTriggerNum); + + // ANNIE Event number + m_data->Stores.at("ANNIEEvent")->Get("EventNumber", fEventNumber); + + auto get_flags = m_data->Stores.at("RecoEvent")->Get("EventFlagged", fEventStatusFlagged); + + if ((fEventStatusFlagged) != 0 && useClean) { + // if (!fEventCutStatus){ + Log("NeutronCheck Tool: Event was flagged with one of the active cuts.", v_debug, verbosity); + return true; + } + + + + + + + //if(EventStore=="ANNIEEvent"){ + + GetClusterInformation(); + + m_data->Stores.at("ANNIEEvent")->Get("ClusterToBestParticleID", fClusterToBestParticleID); + m_data->Stores.at("ANNIEEvent")->Get("ClusterToBestParticlePDG", fClusterToBestParticlePDG); + m_data->Stores.at("ANNIEEvent")->Get("ClusterEfficiency", fClusterEfficiency); + m_data->Stores.at("ANNIEEvent")->Get("ClusterPurity", fClusterPurityMap); + m_data->Stores.at("ANNIEEvent")->Get("ClusterTotalCharge", fClusterTotalCharge); + //bool get_q2 = m_data->Stores["GenieInfo"]->Get("EventQ2", TrueQ2); + + //if(get_q2) Log("True Q2 from GENIE: "+to_string(TrueQ2),v_debug,verbosity); + //else Log("Error finding Q2 info from GENIE",v_debug,verbosity); + //m_data->CStore.Get("ClausterMapMC", m_all_clusters); + + int bestPartId; + for (int i=0;iat(cluster_times.at(i)); + fFinderParentPDG.push_back(fMCParticles->at(bestPartId).GetParentPdg()); + fFinderPDG.push_back(fClusterToBestParticlePDG->at(cluster_times.at(i))); + fFinderPurity.push_back(fClusterPurityMap->at(cluster_times.at(i))); + + } + fFinderClusterCount=fFinderClusterNum.size()+1; + + fTrueNeutronMult=0; + fTrueNeutronDelayed=0; + Log("NeutCheck Tool: Scanning "+to_string(fMCParticles->size())+" MCParticles",v_debug,verbosity); + for (int i = 0; i < fMCParticles->size(); i++) { + if(fMCParticles->at(i).GetPdgCode()==2112 && fMCParticles->at(i).GetParentPdg()==0) { + fTrueNeutronMult++; + + if(fMCParticles->at(i).GetStopTime()>10000) fTrueNeutronDelayed++; + } + else if(fMCParticles->at(i).GetPdgCode()==2112 && fMCParticles->at(i).GetParentPdg()!=0){ + Log("Found non-primary neutron at particle "+to_string(i)+" with parent PDG "+ to_string(fMCParticles->at(i).GetParentPdg()), v_debug, verbosity); + } + if(fParticleInfo){ + fParticlePDG.push_back(fMCParticles->at(i).GetPdgCode()); + fParticleParent.push_back(fMCParticles->at(i).GetParentPdg()); + fParticleStartEnergy.push_back(fMCParticles->at(i).GetStartEnergy()); + fParticleStartTime.push_back(fMCParticles->at(i).GetStartTime()); + if (fMCParticles->at(i).GetPdgCode() == 2112) { + fMCNeutCapTimes.push_back(fMCParticles->at(i).GetStopTime()); + fMCNeutCapX.push_back(fMCParticles->at(i).GetStopVertex().X()); + fMCNeutCapY.push_back(fMCParticles->at(i).GetStopVertex().Y()); + fMCNeutCapZ.push_back(fMCParticles->at(i).GetStopVertex().Z()); + } + } + } + + auto get_muonMCEnergy = m_data->Stores.at("RecoEvent")->Get("TrueMuonEnergy", true_Emu); + bool get_neutrino_energy = m_data->Stores["GenieInfo"]->Get("NeutrinoEnergy", true_Enu); + + RecoVertex* truevtx = 0; + auto get_muonMC = m_data->Stores.at("RecoEvent")->Get("TrueVertex", truevtx); + + //true_Emu*=1000; //GeV->MeV to match other energies(unneeded, possibly) + + double theta = truevtx->GetDirection().GetTheta(); + double p = sqrt(pow(true_Emu,2)-pow(105.7,2)); + TrueQ2=2*true_Enu*(true_Emu-p*cos(theta))-pow(105.7,2); + Log("NeutCheck TrueQ2: "+to_string(TrueQ2), v_debug, verbosity); + + CSCheck(); + + //MapRecoCheck->Fill(fClusterToBestParticleID->size(), fRecoClusters->size()); + //} + + NeutCheckTree->Fill(); + return true; +} + + +bool NeutronCheck::Finalise(){ + + Log("NeutronCheck Tool: Finalizing",v_message,verbosity); + fOutput_tfile->cd(); + + + NeutCheckTree->Write(); + + + + fOutput_tfile->Close(); + + + return true; +} + + +bool NeutronCheck::GetClusterInformation() { + + bool return_value = true; + + bool get_cluster_idxN = m_data->Stores["RecoEvent"]->Get("ClusterIndicesNeutron", cluster_neutron); + if (!get_cluster_idxN) Log("NeutronCheck tool: No ClusterIndicesNeutron In RecoEvent!", v_error, verbosity); + bool get_cluster_tN = m_data->Stores["RecoEvent"]->Get("ClusterTimesNeutron", cluster_times_neutron); + if (!get_cluster_tN) Log("NeutronCheck tool: No ClusterTimesNeutron In RecoEvent!", v_error, verbosity); + bool get_cluster_qN = m_data->Stores["RecoEvent"]->Get("ClusterChargesNeutron", cluster_charges_neutron); + if (!get_cluster_qN) Log("NeutronCheck tool: No ClusterChargesNeutron In RecoEvent!", v_error, verbosity); + bool get_cluster_cbN = m_data->Stores["RecoEvent"]->Get("ClusterCBNeutron", cluster_cb_neutron); + if (!get_cluster_cbN) Log("NeutronCheck tool: No ClusterCBNeutron In RecoEvent!", v_error, verbosity); + bool get_cluster_t = m_data->Stores["RecoEvent"]->Get("ClusterTimes", cluster_times); + if (!get_cluster_t) Log("NeutronCheck tool: No ClusterTimes In RecoEvent!", v_error, verbosity); + bool get_cluster_q = m_data->Stores["RecoEvent"]->Get("ClusterCharges", cluster_charges); + if (!get_cluster_q) Log("NeutronCheck tool: No ClusterCharges In RecoEvent!", v_error, verbosity); + bool get_cluster_cb = m_data->Stores["RecoEvent"]->Get("ClusterCB", cluster_cb); + if (!get_cluster_cb) Log("NeutronCheck tool: No ClusterCB In RecoEvent!", v_error, verbosity); + + bool goodMCParticles = m_data->Stores.at("ANNIEEvent")->Get("MCParticles", fMCParticles); + if (!goodMCParticles) { + std::cerr << "BackTracker: no MCParticles in the ANNIEEvent!" << endl; + return false; + } + + return_value = (get_cluster_idxN && get_cluster_tN && get_cluster_qN && get_cluster_cbN && get_cluster_t && get_cluster_q && get_cluster_cb); + + + + reco_Clusters = cluster_cb.size(); + + + + return return_value; + +} + +double NeutronCheck::ASCheck(vector*& digits, int mode) { + //mode config. 0 is maximal distance; 1 is max distance from highest charge + + double max_angle = 0; + double max_angle2 = 0; + if (mode == 0||mode==2) { + + double angle; + Position i_position,j_position; + for (int i = 0; i < digits->size(); i++) { + if (useClean && !digits->at(i).GetFilterStatus())continue; + i_position = digits->at(i).GetPosition(); + for (int j = 0; j < digits->size(); j++) { + if (j == i)continue; + if (useClean && !digits->at(j).GetFilterStatus())continue; + j_position = digits->at(j).GetPosition(); + + angle = j_position.Angle(i_position); + if (angle > max_angle)max_angle = angle; + + } + } + cout<<"Neutcheck max_angle: "<size(); i++) { + if (digits->at(i).GetCalCharge() > max_charge) { + if(useClean && !digits->at(i).GetFilterStatus())continue; + max_charge = digits->at(i).GetCalCharge(); + max_index = i; + max_position = digits->at(i).GetPosition(); + } + } + + + for (int i = 0; i < digits->size(); i++) { + if (i == max_index)continue; + if (useClean && !digits->at(i).GetFilterStatus())continue; + i_position = digits->at(i).GetPosition(); + angle = i_position.Angle(max_position); + if (angle > max_angle2)max_angle2 = angle; + } + cout<<"Neutcheck max_angle2: "<0) ratio = max_angle2/max_angle; + if(mode==2)return ratio; + + return 0; +} + +void NeutronCheck::CSCheck() { + + std::map* fMCParticleIndexMap; + + Log("Cluster Check!",v_debug,verbosity); + bool goodMCParticleIndexMap = m_data->Stores.at("ANNIEEvent")->Get("TrackId_to_MCParticleIndex", fMCParticleIndexMap); + if (!goodMCParticleIndexMap) { + std::cerr << "NeutCheck: no TrackId_to_MCParticleIndex in the ANNIEEvent!" << endl; + return; + } + + + + bool cluster_status = m_data->Stores.at("RecoEvent")->Get("RecoClusters", fRecoClusters); + if (!cluster_status) { + Log("Neutcheck tool found no recoclusters.",v_debug,verbosity); + return; + } + + int cluster_size = fRecoClusters->size(); + if (cluster_size == 0) { + Log("Neutcheck tool found empty recoclusterlist.",v_debug,verbosity); + return; + } + Log("Neutcheck tool found this many clusters: "+to_string(cluster_size),v_debug,verbosity); + + int bestParent; + int bestParticleID=-5; + int bestPDG=-5; + double CVX,CVY,CVZ,CVR; + + for (int i = 0; i < fRecoClusters->size(); i++) { + fClusterNum.push_back(i); + fClusterCount++; + bestParent = fRecoClusters->at(i)->calcBestParent(); + //bestParent = fRecoClusters->at(i)->GetBestParent(); + Log("Check 1: Particle ID "+to_string(bestParent),v_debug,verbosity); + if (bestParent >= fMCParticles->size()) { + Log("Invalid particle ID " + to_string(bestParent) + " vs number of particles: " + to_string(fMCParticles->size()) + "; skipping.",v_error,verbosity); + continue; + } + + //for (std::pair apair : *fMCParticleIndexMap) { + //Log("Testing match for particle: "+to_string(apair.first) + " corresponding to ID " + to_string(apair.second), v_debug, verbosity); + //if(apair.second==bestParent){ + //bestParticleID=apair.first; + bestPDG=fMCParticles->at(bestParent).GetPdgCode(); + //if (bestPDG == 22) { + + if (fMCParticles->at(bestParent).GetFlag() != 0) { + Log("Flagged particle! PDG "+to_string(bestPDG)+" excluding.",v_message,verbosity); + bestPDG=-5; + } + if (fMCParticles->at(bestParent).GetParentPdg() != 0) { + + Log("NeutCheck: PDG "+to_string(bestPDG)+" Finding parent.",v_message,verbosity); + fClusterParentPDG.push_back(fMCParticles->at(bestParent).GetParentPdg()); + Log("Parent PDG "+to_string(fClusterParentPDG.at(fClusterParentPDG.size()-1)),v_message,verbosity); + } + else { + Log("NeutCheck tool: no parent found. Treating as primary. PDG "+to_string(bestPDG), v_message, verbosity); + fClusterParentPDG.push_back(0); + if (bestPDG == 2212 && fRecoClusters->at(i)->GetTime()>10000) { + + Log("Primary proton found ID " + to_string(bestParent) + " at time " +to_string(fRecoClusters->at(i)->GetTime())+" but particle start, stop "+to_string(fMCParticles->at(bestParent).GetStartTime())+", "+to_string(fMCParticles->at(bestParent).GetStopTime()),v_debug,verbosity); + } + if (bestPDG == 13 && fRecoClusters->at(i)->GetTime() > 10000) { + + Log("Primary muon found ID " + to_string(bestParent) + " at time " + to_string(fRecoClusters->at(i)->GetTime()) + " but particle start, stop " + to_string(fMCParticles->at(bestParent).GetStartTime()) + ", " + to_string(fMCParticles->at(bestParent).GetStopTime()), v_debug, verbosity); + } + if (bestPDG == 2112 && fRecoClusters->at(i)->GetTime() > 10000) { + + Log("Primary neutron found ID " + to_string(bestParent) + " at time " + to_string(fRecoClusters->at(i)->GetTime()) + " but particle start, stop " + to_string(fMCParticles->at(bestParent).GetStartTime()) + ", " + to_string(fMCParticles->at(bestParent).GetStopTime()), v_debug, verbosity); + } + } + + //} + fRecoClusters->at(i)->SetPDG(bestPDG); + fClusterParticleEnergy.push_back(fMCParticles->at(bestParent).GetStartEnergy()); + + //} + + //} + /*if (matchCheck == false) { + Log("NeutCheck: Failed to match Particle. IndexMap size: "+to_string(fMCParticleIndexMap->size()), v_error, verbosity); + //continue; + }*/ + + + //ClusterSearchCheck->Fill(fRecoClusters->at(i)->GetClusterMode()); + //recoPDGHist->Fill(fRecoClusters->at(i)->GetPDG()); + fClusterMode.push_back(fRecoClusters->at(i)->GetClusterMode()); + fClusterPDG.push_back(fRecoClusters->at(i)->GetPDG()); + if (fClusterPDG.at(fClusterPDG.size() - 1) == 2112) { + fNeutronMult++; + + } + + fClusterCharge.push_back(fRecoClusters->at(i)->GetCharge()); + fClusterPurity.push_back(fRecoClusters->at(i)->Purity()); + fClusterTime.push_back(fRecoClusters->at(i)->GetTime()); + fClusterCB.push_back(fRecoClusters->at(i)->GetCB()); + fClusterHits.push_back(fRecoClusters->at(i)->GetNDigits()); + //if(fRecoClusters->at(i)->GetTime()>10000) recoPDGHistDelayed->Fill(fRecoClusters->at(i)->GetPDG()); + + //AS0RecoCheck->Fill(fRecoClusters->at(i)->GetAS(0)); + //AS1RecoCheck->Fill(fRecoClusters->at(i)->GetAS(1)); + + fClusterAS0.push_back(fRecoClusters->at(i)->GetAS(0)); + fClusterAS1.push_back(fRecoClusters->at(i)->GetAS(1)); + fClusterAMD.push_back(fRecoClusters->at(i)->GetAMD()); + + if(fRecoClusters->at(i)->GetAS(0)>0){ + //AS2RecoCheck->Fill(fRecoClusters->at(i)->GetAS(1)/fRecoClusters->at(i)->GetAS(0)); + fClusterAS2.push_back(fClusterAS1.at(fClusterAS1.size()-1)/fClusterAS0.at(fClusterAS0.size()-1)); + } + fClusterASC.push_back(fRecoClusters->at(i)->GetASC()); + CVX= fRecoClusters->at(i)->GetCV().X(); + CVY = fRecoClusters->at(i)->GetCV().Y(); + CVZ = fRecoClusters->at(i)->GetCV().Z(); + CVR = pow(pow(CVX,2)+pow(CVY,2)+pow(CVZ,2),0.5); + fClusterCVX.push_back(CVX); + fClusterCVY.push_back(CVY); + fClusterCVZ.push_back(CVZ); + fClusterCVR.push_back(CVR); + //fClusterSA.push_back(fRecoClusters->at(i)->GetSA()); + + + } + + return; +} + +void NeutronCheck::ResetVariables() { + fMCEventNum=-9999; + fClusterNum.clear(); + fClusterCount=0; + fClusterMode.clear(); + fClusterPDG.clear(); + fClusterParentPDG.clear(); + fClusterParticleEnergy.clear(); + fClusterCharge.clear(); + fClusterPurity.clear(); + fClusterCB.clear(); + fClusterTime.clear(); + fClusterAS0.clear(); + fClusterAS1.clear(); + fClusterAS2.clear(); + fClusterASC.clear(); + //fClusterSA.clear(); + fClusterCVX.clear(); + fClusterCVY.clear(); + fClusterCVZ.clear(); + fClusterCVR.clear(); + fClusterAMD.clear(); + fNeutronMult=0; + fMCNeutCapTimes.clear(); + fMCNeutCapX.clear(); + fMCNeutCapY.clear(); + fMCNeutCapZ.clear(); + + fParticlePDG.clear(); + fParticleParent.clear(); + fParticleStartEnergy.clear(); + fParticleStartTime.clear(); + + + fFinderClusterNum.clear(); + fFinderClusterCount=0; + fFinderPDG.clear(); + fFinderParentPDG.clear(); + fFinderCharge.clear(); + fFinderPurity.clear(); + fFinderCB.clear(); + fFinderTime.clear(); +} \ No newline at end of file diff --git a/UserTools/NeutronCheck/NeutronCheck.h b/UserTools/NeutronCheck/NeutronCheck.h new file mode 100755 index 000000000..16a01af72 --- /dev/null +++ b/UserTools/NeutronCheck/NeutronCheck.h @@ -0,0 +1,176 @@ +#ifndef NeutronCheck_H +#define NeutronCheck_H + +#include +#include +#include +#include + +#include "Tool.h" +#include "Particle.h" +#include "Position.h" +#include "RecoVertex.h" +#include "RecoCluster.h" + +#include "TTree.h" +#include "TFile.h" +#include "TH1.h" +#include "TH2.h" +#include "TH3.h" +#include "TGraph.h" +#include "TGraphErrors.h" +#include "TMath.h" + + + +/** + * \class NeutronCheck + * + * 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: F. A. Lemmons $ +* $Date: 2025/02/28 10:44:00 $ +* Contact: franklin.lemmons@mines.sdsmt.edu +*/ +class NeutronCheck: public Tool { + + + public: + + NeutronCheck(); ///< 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: + + bool GetClusterInformation(); + double ASCheck(std::vector*& digits,int mode); + void CSCheck(); + void ResetVariables(); + + int verbosity; + std::string outfile; + bool useClean=0; + std::string EventStore; + bool fFinderCompare; + bool fParticleInfo; + + TTree* NeutCheckTree = nullptr; + + /* + -EventNumber + -Clusternumber + -number of clusters + -neutron multiplicity + + + -Cluster PDG + -Cluster Charge + -Cluster Time + -CB + -AS 0,1,2 + + */ + + std::vector cluster_neutron; + std::vector cluster_times_neutron; + std::vector cluster_charges_neutron; + std::vector cluster_cb_neutron; + std::vector cluster_times; + std::vector cluster_charges; + std::vector cluster_cb; + + std::map* fClusterToBestParticleID = nullptr; + std::map* fClusterToBestParticlePDG = nullptr; + std::map* fClusterEfficiency = nullptr; + std::map* fClusterPurityMap = nullptr; + std::map* fClusterTotalCharge = nullptr; + std::vector* fDigitList=nullptr; + vector* fRecoClusters; + + std::vector* fMCParticles; + std::vector fMCNeutCapTimes; + std::vector fMCNeutCapX; + std::vector fMCNeutCapY; + std::vector fMCNeutCapZ; + + + std::map>* m_all_clusters; + + Geometry* fGeometry = nullptr; ///< ANNIE Geometry + + /// \brief MC entry number + uint32_t fMCEventNum; + vector fClusterNum; + int fClusterCount; + + vector fClusterPDG; + vector fClusterParentPDG; + vector fClusterParticleEnergy; + vector fClusterCharge; + vector fClusterPurity; + vector fClusterCB; + vector fClusterTime; + vector fClusterAS0; + vector fClusterAS1; + vector fClusterAS2; + vector fClusterASC; + vector fClusterAMD; + //vector fClusterSA; + //vector fClusterCV; + vector fClusterCVX,fClusterCVY,fClusterCVZ,fClusterCVR; + + vector fClusterMode; + vector fClusterHits; + + vector fParticlePDG; + vector fParticleParent; + vector fParticleStartEnergy; + vector fParticleStartTime; + + vector fFinderClusterNum; + int fFinderClusterCount; + vector fFinderPDG; + vector fFinderParentPDG; + vector fFinderCharge; + vector fFinderPurity; + vector fFinderCB; + vector fFinderTime; + + + int fTrueNeutronMult; + int fTrueNeutronDelayed; + int fNeutronMult; + double true_Emu; + double true_Enu; + double TrueQ2; + + /// \brief trigger number + uint16_t fMCTriggerNum; + + /// \brief ANNIE event number + uint32_t fEventNumber; + + int fEventStatusApplied; + int fEventStatusFlagged; + + + + int reco_Clusters; + + TFile* fOutput_tfile; + + //verbosity variables + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + int vv_debug = 4; + + +}; + + +#endif diff --git a/UserTools/NeutronCheck/README.md b/UserTools/NeutronCheck/README.md new file mode 100644 index 000000000..d2be28214 --- /dev/null +++ b/UserTools/NeutronCheck/README.md @@ -0,0 +1,71 @@ +# NeutronCheck + +NeutronCheck +Output tool for RecoCluster information and parameters. Creates NeutCheckTree in the outfile.root, for use making analysis and comparison plots. + +## Data + + +From ANNIEEvent store +**MCEventNum** +*simple event number + +**ClusterToBestParticleID** +**ClusterToBestParticlePDG** +**ClusterEfficiency** +**ClusterPurity** +**ClusterTotalCharge** +**ClusterMapMC** +*ClusterFinder-made cluster maps from BackTracker tool for comparison + +**MCParticles** +*vector of all MC Particles in the event + +**TrueMuonEnergy** +*True energy of the muon for inclusion in the output + +**TrackId_to_MCParticleIndex** DEPRECATED +*map of track ID to MCParticle Index. No longer used, as MCParticle Index is used directly in all relevant cases. + + + +From RecoEvent store +**EventFlagged** +*Which event selection cuts were triggered by the current event. + +**ClusterIndiccesNeutron** +**ClusterTimesNeutron** +**ClusterChargesNeutron** +**ClusterCBNeutron** +*ClusterFinder-made cluster maps of neutrons specifically for comparison + +**ClusterTimes** +**ClusterCharges** +**ClusterCB** +*ClusterFinder-made cluster maps of all particles for comparison + +**RecoClusters** +*vector list of all RecoClusters generated from all iterations of ClusterSearcher + + + +From GenieInfo Store +**NeutrinoEnergy +*True neutrino energy for inclusion in the output + +Output .root file +**NeutCheckTree** +*Tree written into output file + + +## Configuration + +Describe any configuration variables for NeutronCheck. + +``` +verbosity 1 +outfile /path/to/output/file #'.root' is added to the end. +UseClean 0 #whether to exclude events that do not pass event selection +FinderCompare 0 #whether to add similar plots from ClusterFinder map-clusters to output for comparison purposes (not all parameters are written into Finder clusters) +ParticleInfo 1 #whether to add true particle information directly from MCParticles list to output +``` diff --git a/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp b/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp index 1b51d95b7..bf4b31899 100644 --- a/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp +++ b/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp @@ -104,6 +104,7 @@ bool NeutronMultiplicity::Initialise(std::string configfile, DataModel &data){ bool NeutronMultiplicity::Execute(){ isMC = m_data->Stores.at("ANNIEEvent")->Get("MCFile",MCFile); + if (isMC) std::cout << "NeutronMultiplicity Tool: MCFile found!" << std::endl; //Reset tree variables this->ResetVariables(); @@ -334,6 +335,11 @@ bool NeutronMultiplicity::InitialiseHistograms(){ h_neutrons_energy_fv = new TH2F("h_neutrons_energy_fv","Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); h_neutrons_energy_zoom = new TH2F("h_neutrons_energy_zoom","Neutron multiplicity vs muon energy",8,400,1200,20,0,20); h_neutrons_energy_fv_zoom = new TH2F("h_neutrons_energy_fv_zoom","Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + h_neutrons_energy_fv_down = new TH2F("h_neutrons_energy_fv_down","Neutron multiplicity vs muon energy (Downstream FV)",10,0,2000,20,0,20); + h_neutrons_energy_fv_cyl = new TH2F("h_neutrons_energy_fv_cyl","Neutron multiplicity vs muon energy (Cylindrical FV)",10,0,2000,20,0,20); + h_neutrons_q2 = new TH2F("h_neutrons_q2","Neutron multiplicity vs Q^{2}",100,0,2,20,0,20); + h_neutrons_q2_fv = new TH2F("h_neutrons_q2_fv","Neutron multiplicity vs Q^{2} (FV)",100,0,2,20,0,20); + h_neutrons_q2_fv_down = new TH2F("h_neutrons_q2_fv_down","Neutron multiplicity vs Q^{2} (Downstream FV)",100,0,2,20,0,20); h_neutrons_costheta = new TH2F("h_neutrons_costheta","Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); h_neutrons_costheta_fv = new TH2F("h_neutrons_costheta_fv","Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); h_neutrons_pT = new TH2F("h_neutrons_pT","Neutron multiplicity vs transverse muon momentum",10,0,1000,20,0,20); @@ -411,6 +417,26 @@ bool NeutronMultiplicity::InitialiseHistograms(){ h_neutrons_energy_fv_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); h_neutrons_energy_fv_zoom->GetYaxis()->SetTitle("Number of neutrons"); + h_neutrons_energy_fv_down->SetStats(0); + h_neutrons_energy_fv_down->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv_down->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv_cyl->SetStats(0); + h_neutrons_energy_fv_cyl->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv_cyl->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_q2->SetStats(0); + h_neutrons_q2->GetXaxis()->SetTitle("Q^{2} [(GeV/c)^{2}]"); + h_neutrons_q2->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_q2_fv->SetStats(0); + h_neutrons_q2_fv->GetXaxis()->SetTitle("Q^{2} [(GeV/c)^{2}]"); + h_neutrons_q2_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_q2_fv_down->SetStats(0); + h_neutrons_q2_fv_down->GetXaxis()->SetTitle("Q^{2} [(GeV/c)^{2}]"); + h_neutrons_q2_fv_down->GetYaxis()->SetTitle("Number of neutrons"); + h_neutrons_costheta->SetStats(0); h_neutrons_costheta->GetXaxis()->SetTitle("cos(#theta)"); h_neutrons_costheta->GetYaxis()->SetTitle("Number of neutrons"); @@ -610,6 +636,7 @@ bool NeutronMultiplicity::FillHistograms(){ h_neutrons_mrdstop->Fill(NumberNeutrons); h_neutrons_energy->Fill(SimpleRecoEnergy,NumberNeutrons); h_neutrons_energy_zoom->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_q2->Fill(SimpleRecoQ2/1.e6,NumberNeutrons); h_neutrons_costheta->Fill(SimpleRecoCosTheta,NumberNeutrons); h_neutrons_pT->Fill(SimpleRecoPt,NumberNeutrons); h_muon_energy->Fill(SimpleRecoEnergy); @@ -634,6 +661,7 @@ bool NeutronMultiplicity::FillHistograms(){ h_muon_costheta_fv->Fill(SimpleRecoCosTheta); h_neutrons_energy_fv->Fill(SimpleRecoEnergy,NumberNeutrons); h_neutrons_energy_fv_zoom->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_q2_fv->Fill(SimpleRecoQ2/1.e6,NumberNeutrons); h_neutrons_costheta_fv->Fill(SimpleRecoCosTheta,NumberNeutrons); h_neutrons_pT_fv->Fill(SimpleRecoPt,NumberNeutrons); h_neutrons_mrdstop_fv->Fill(NumberNeutrons); @@ -652,12 +680,22 @@ bool NeutronMultiplicity::FillHistograms(){ h_pmtvolneutrons_pT_fv->Fill(SimpleRecoPt,true_NCapturesPMTVol); } } + std::cout << " NM [debug] DownstreamFV/FullCylFV: " << DownstreamFV << "/" << FullCylFV << std::endl; + if (DownstreamFV == 1) + { + h_neutrons_energy_fv_down->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_q2_fv_down->Fill(SimpleRecoQ2/1.e6,NumberNeutrons); + } + if (FullCylFV == 1) h_neutrons_energy_fv_cyl->Fill(SimpleRecoEnergy,NumberNeutrons); + h_muon_vtx_x->Fill(SimpleRecoVtx.X()); h_muon_vtx_y->Fill(SimpleRecoVtx.Y()); h_muon_vtx_z->Fill(SimpleRecoVtx.Z()); - h_muon_vtx_yz->Fill(SimpleRecoVtx.Z()-1.681,SimpleRecoVtx.Y()-0.144); - h_muon_vtx_xz->Fill(SimpleRecoVtx.Z()-1.681,SimpleRecoVtx.X()); + //h_muon_vtx_yz->Fill(SimpleRecoVtx.Z()-1.681,SimpleRecoVtx.Y()-0.144); + //h_muon_vtx_xz->Fill(SimpleRecoVtx.Z()-1.681,SimpleRecoVtx.X()); + h_muon_vtx_yz->Fill(SimpleRecoVtx.Z(),SimpleRecoVtx.Y()); + h_muon_vtx_xz->Fill(SimpleRecoVtx.Z(),SimpleRecoVtx.X()); reco_VtxX = SimpleRecoVtx.X(); reco_VtxY = SimpleRecoVtx.Y(); @@ -751,6 +789,10 @@ bool NeutronMultiplicity::SaveBoostStore(){ store_neutronmult->Set("NeutronEffMap",neutron_eff_map); store_neutronmult->Set("PMTMRDCoinc",passPMTMRDCoincCut); store_neutronmult->Set("NumMRDTracks",numtracksinev); + store_neutronmult->Set("DownstreamFV",DownstreamFV); + store_neutronmult->Set("FullCylFV",FullCylFV); + store_neutronmult->Set("SimpleRecoNeutrinoEnergy",SimpleRecoNeutrinoEnergy); + store_neutronmult->Set("SimpleRecoQ2",SimpleRecoQ2); if (isMC){ store_neutronmult->Set("NeutrinoEnergy",true_Enu); @@ -829,6 +871,10 @@ bool NeutronMultiplicity::ReadBoostStore(){ read_neutronmult->Get("NeutronEffMap",neutron_eff_map); read_neutronmult->Get("PMTMRDCoinc",passPMTMRDCoincCut); read_neutronmult->Get("NumMRDTracks",numtracksinev); + read_neutronmult->Get("DownstreamFV",DownstreamFV); + read_neutronmult->Get("FullCylFV",FullCylFV); + read_neutronmult->Get("SimpleRecoNeutrinoEnergy",SimpleRecoNeutrinoEnergy); + read_neutronmult->Get("SimpleRecoQ2",SimpleRecoQ2); m_data->Stores["ANNIEEvent"]->Set("RunNumber",RunNumber); m_data->Stores["ANNIEEvent"]->Set("EventNumber",EventNumber); @@ -854,6 +900,10 @@ bool NeutronMultiplicity::ReadBoostStore(){ m_data->Stores["RecoEvent"]->Set("NeutronEffMap",neutron_eff_map); m_data->Stores.at("RecoEvent")->Set("PMTMRDCoinc",passPMTMRDCoincCut); m_data->Stores["MRDTracks"]->Set("NumMrdTracks",numtracksinev); + m_data->Stores["RecoEvent"]->Set("DownstreamFV",DownstreamFV); + m_data->Stores["RecoEvent"]->Set("FullCylFV",FullCylFV); + m_data->Stores["RecoEvent"]->Set("SimpleRecoNeutrinoEnergy",SimpleRecoNeutrinoEnergy); + m_data->Stores["RecoEvent"]->Set("SimpleRecoQ2",SimpleRecoQ2); if (isMC){ read_neutronmult->Get("NeutrinoEnergy",true_Enu); @@ -973,6 +1023,15 @@ bool NeutronMultiplicity::GetParticleInformation(){ bool get_simple_mrdstop = m_data->Stores["RecoEvent"]->Get("SimpleRecoMRDStop",SimpleRecoMRDStop); if (!get_simple_mrdstop) Log("NeutronMultiplicity tool: No SimpleRecoMRDStop in RecoEvent!",v_error,verbosity); + bool get_simple_fvregion = m_data->Stores["RecoEvent"]->Get("DownstreamFV",DownstreamFV); + if (!get_simple_fvregion) Log("NeutronMultiplicity tool: No DownstreamFV in RecoEvent!",v_error,verbosity); + get_simple_fvregion = m_data->Stores["RecoEvent"]->Get("FullCylFV",FullCylFV); + if (!get_simple_fvregion) Log("NeutronMultiplicity tool: No FullCylFV in RecoEvent!",v_error,verbosity); + bool get_simple_nuenergy = m_data->Stores["RecoEvent"]->Get("SimpleRecoNeutrinoEnergy",SimpleRecoNeutrinoEnergy); + if (!get_simple_nuenergy) Log("NeutronMultiplicity tool: No SimpleRecoNeutrinoEnergy in RecoEvent!",v_error,verbosity); + bool get_simple_q2 = m_data->Stores["RecoEvent"]->Get("SimpleRecoQ2",SimpleRecoQ2); + if (!get_simple_q2) Log("NeutronMultiplicity tool: No SimpleRecoQ2 in RecoEvent!",v_error,verbosity); + bool get_pmtmrdcoinc = m_data->Stores.at("RecoEvent")->Get("PMTMRDCoinc",passPMTMRDCoincCut); if (!get_pmtmrdcoinc) Log("NeutronMultiplicity tool: No PMTMRDCoinc in RecoEvent!",v_error,verbosity); @@ -1006,7 +1065,7 @@ bool NeutronMultiplicity::GetMCTruthInformation(){ bool return_value = true; //Get information from GENIE store - bool get_neutrino_energy = m_data->Stores["GenieInfo"]->Get("NeutrinoEnergy",true_Enu); +/* bool get_neutrino_energy = m_data->Stores["GenieInfo"]->Get("NeutrinoEnergy",true_Enu); if (!get_neutrino_energy) Log("NeutronMultiplicity tool: No NeutrinoEnergy In GenieInfo!",v_error,verbosity); true_Enu *= 1000; //convert to MeV for consistency bool get_q2 = m_data->Stores["GenieInfo"]->Get("EventQ2",true_Q2); @@ -1041,7 +1100,7 @@ bool NeutronMultiplicity::GetMCTruthInformation(){ bool get_p = m_data->Stores["GenieInfo"]->Get("NumFSProtons",true_PrimProt); if (!get_p) Log("NeutronMultiplicity tool: No NumFSProtons In GenieInfo!",v_error,verbosity); - return_value = (get_neutrino_energy && get_q2 && get_cc && get_qel && get_res && get_dis && get_coh && get_mec && get_n && get_p); + return_value = (get_neutrino_energy && get_q2 && get_cc && get_qel && get_res && get_dis && get_coh && get_mec && get_n && get_p);*/ //Get information from RecoEvent store RecoVertex* TrueVtx = nullptr; auto get_muonMC = m_data->Stores.at("RecoEvent")->Get("TrueVertex",TrueVtx); @@ -1141,6 +1200,11 @@ bool NeutronMultiplicity::GetMCTruthInformation(){ bool NeutronMultiplicity::ResetVariables(){ + DownstreamFV = -9999; + FullCylFV = -9999; + SimpleRecoNeutrinoEnergy = -9999; + SimpleRecoQ2 = -9999; + SimpleRecoFlag = -9999; SimpleRecoVtx = Position(-9999,-9999,-9999); SimpleRecoStopVtx = Position(-9999,-9999,-9999); diff --git a/UserTools/NeutronMultiplicity/NeutronMultiplicity.h b/UserTools/NeutronMultiplicity/NeutronMultiplicity.h index 93392784b..b77f5aa31 100644 --- a/UserTools/NeutronMultiplicity/NeutronMultiplicity.h +++ b/UserTools/NeutronMultiplicity/NeutronMultiplicity.h @@ -78,6 +78,10 @@ class NeutronMultiplicity: public Tool { std::vector input_filenames_; //Reconstruction variables + int DownstreamFV; + int FullCylFV; + double SimpleRecoNeutrinoEnergy; + double SimpleRecoQ2; int SimpleRecoFlag; Position SimpleRecoVtx; Position SimpleRecoStopVtx; @@ -124,8 +128,13 @@ class NeutronMultiplicity: public Tool { TH1F *h_neutrons_mrdstop_fv = nullptr; TH2F *h_neutrons_energy = nullptr; TH2F *h_neutrons_energy_fv = nullptr; + TH2F *h_neutrons_energy_fv_down = nullptr; + TH2F *h_neutrons_energy_fv_cyl = nullptr; TH2F *h_neutrons_energy_zoom = nullptr; TH2F *h_neutrons_energy_fv_zoom = nullptr; + TH2F *h_neutrons_q2 = nullptr; + TH2F *h_neutrons_q2_fv = nullptr; + TH2F *h_neutrons_q2_fv_down = nullptr; TH2F *h_primneutrons_energy = nullptr; TH2F *h_primneutrons_energy_fv = nullptr; TH2F *h_primneutrons_energy_zoom = nullptr; diff --git a/UserTools/PMTDataDecoder/PMTDataDecoder.cpp b/UserTools/PMTDataDecoder/PMTDataDecoder.cpp index ee4629f5b..c40a14428 100644 --- a/UserTools/PMTDataDecoder/PMTDataDecoder.cpp +++ b/UserTools/PMTDataDecoder/PMTDataDecoder.cpp @@ -46,6 +46,13 @@ bool PMTDataDecoder::Initialise(std::string configfile, DataModel &data){ m_data->CStore.Set("FIFOError1",fifo1); m_data->CStore.Set("FIFOError2",fifo2); + saveRWMRaw = true; + saveBRFRaw = true; + m_variables.Get("saveRWMRaw",saveRWMRaw); + m_variables.Get("saveBRFRaw",saveBRFRaw); + RWMRawWaveforms = new std::map>; + BRFRawWaveforms = new std::map>; + std::cout << "PMTDataDecoder Tool: Initialized successfully" << std::endl; return true; } @@ -305,6 +312,75 @@ bool PMTDataDecoder::Execute(){ m_data->CStore.Set("FIFOPMTWaves",FIFOPMTWaves); m_data->CStore.Set("TimestampsFromTheFuture",TimestampsFromTheFuture); + // loop the FinishedPMTWaves, for each timestamp, put the RWM and BRF waveform to RWMRawWaveforms and BRFRawWaveforms + if(saveBRFRaw || saveRWMRaw) + { + for (std::map, std::vector>>::iterator it = FinishedPMTWaves->begin(); it != FinishedPMTWaves->end(); it++) + { + uint64_t timestamp = it->first; + std::map, std::vector> afinishedPMTWaves = FinishedPMTWaves->at(timestamp); + for (std::pair, std::vector> apair : afinishedPMTWaves) + { + int CardID = apair.first.at(0); + int ChannelID = apair.first.at(1); + int SlotNum = CardID % 100; + int CrateNum = CardID / 1000; + unsigned int uCrateNum = (unsigned int)CrateNum; + 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(RunNumber >= 5870) + { + // 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); + //Check the size of the WaveBank to see if things are bloating Log("PMTDataDecoder Tool: Size of WaveBank (# waveforms partially built): " + to_string(WaveBank.size()),v_message, verbosity); diff --git a/UserTools/PMTDataDecoder/PMTDataDecoder.h b/UserTools/PMTDataDecoder/PMTDataDecoder.h index 0e3274a57..8972b3950 100644 --- a/UserTools/PMTDataDecoder/PMTDataDecoder.h +++ b/UserTools/PMTDataDecoder/PMTDataDecoder.h @@ -132,6 +132,12 @@ 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/PMTWaveformSim/PMTWaveformSim.cpp b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp new file mode 100644 index 000000000..0f1a4f804 --- /dev/null +++ b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp @@ -0,0 +1,568 @@ +#include +#include +#include + +// ANNIE includes +#include "ANNIEconstants.h" +#include "PMTWaveformSim.h" + +// ROOT includes +#include "TGraph.h" + +PMTWaveformSim::PMTWaveformSim():Tool(){} + + +bool PMTWaveformSim::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 + ///////////////////////////////////////////////////////////////// + + // get config variables + bool gotVerbosity = m_variables.Get("verbosity", verbosity); + if (!gotVerbosity) verbosity = 1; + + bool gotPMTParamFile = m_variables.Get("PMTParameterFile", fPMTParameterFile); + if (!gotPMTParamFile) { + logmessage = "PMTWaveformSim: No PMTParameterFile specified! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + if (!LoadPMTParameters()) + return false; + + bool got_sigmamap = m_variables.Get("useTimeSmearing", fuseTimeSmearing); + if (!got_sigmamap) { + logmessage = "PMTWaveformSim: No useTimeSmearing specified! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + bool gotPrewindow = m_variables.Get("Prewindow", fPrewindow); + if (!gotPrewindow) { + logmessage = "PMTWaveformSim: Prewindow not defined. Using default of 10."; + Log(logmessage, v_warning, verbosity); + fPrewindow = 10; + } + + bool gotReadoutWindow = m_variables.Get("ReadoutWindow", fReadoutWindow); + if (!gotReadoutWindow) { + logmessage = "PMTWaveformSim: ReadoutWindow not defined. Using default of 35."; + Log(logmessage, v_warning, verbosity); + fReadoutWindow = 35; + } + + bool gotT0Offset = m_variables.Get("T0Offset", fT0Offset); + if (!gotT0Offset) { + logmessage = "PMTWaveformSim: T0Offset not defined. Using default of 25."; + Log(logmessage, v_warning, verbosity); + fT0Offset = 25; + } + + bool gotShiftTimes = m_variables.Get("TimeShift", fTimeShift); + if (!gotShiftTimes) { + logmessage = "PMTWaveformSim: TimeShift not defined. Using default of 0."; + Log(logmessage, v_warning, verbosity); + fTimeShift = 0.0; + } else { + logmessage = "PMTWaveformSim: TimeShift = " + std::to_string(fTimeShift) + "ns will be applied to ALL MCHits."; + Log(logmessage, v_warning, verbosity); + } + + bool gotDebug = m_variables.Get("MakeDebugFile", fDebug); + if (!gotDebug) fDebug = 0; + if (fDebug) + fOutFile = new TFile("PMTWaveforms.root", "RECREATE"); + + bool gotGeometry = m_data->Stores.at("ANNIEEvent")->Header->Get("AnnieGeometry", fGeo); + if(!gotGeometry){ + logmessage = "PMTWaveformSim: Error retrieving Geometry from ANNIEEvent! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // random seed is grabbed from the system clock + fRandom.SetSeed(0); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::Execute() +{ + int load_status = LoadFromStores(); + + if (load_status == 0) return false; + + // The container for the data that we'll put into the ANNIEEvent + std::map> > RawADCDataMC; + std::map> > CalADCDataMC; + + + // If MCHits is empty (load_status == 2), create one minimal baseline waveform so that the hit finder doesn't freak out + // while keeping the rest of the machinery the same + if (load_status == 2) { + logmessage = "PMTWaveformSim: Creating single minimal baseline waveform (No MCHits)..."; + Log(logmessage, v_message, verbosity); + + // we can put the dummy baseline in a dead PMT channel so it won't be integrated + unsigned long dummy_chankey = 333; // PMT ID 333 is dead + + // create a short baseline waveform (~50ns) so that the hit finder will be satisfied + int num_samples = 25; // 50ns + double noiseSigma = fRandom.Gaus(1, 0.01); // set the noise to basically 0 + int baseline = fRandom.Uniform(300, 350); + + std::vector rawSamples; + std::vector calSamples; + + for (int i = 0; i < num_samples; i++) { + double noise = fRandom.Gaus(0, noiseSigma); + int sample = std::round(noise + baseline); + sample = (sample > 4095) ? 4095 : ((sample < 0) ? 0 : sample); // shouldn't matter + + rawSamples.push_back(sample); + calSamples.push_back((sample - baseline) * ADC_TO_VOLT); + } + + std::vector> rawWaveforms; + std::vector> calWaveforms; + + rawWaveforms.emplace_back(0, rawSamples); + calWaveforms.emplace_back(0, calSamples, baseline, noiseSigma); + + RawADCDataMC.emplace(dummy_chankey, rawWaveforms); + CalADCDataMC.emplace(dummy_chankey, calWaveforms); + + } + + // normal use case (no blank MCHits) + for (auto mcHitsIt : *fMCHits) { // Loop over the hit PMTs + int PMTID = mcHitsIt.first; + + std::vector mcHits = mcHitsIt.second; + + // Generate waveform samples from the MC hits + // samples from hits that are close in time will be added together + // key is hit time in clock ticks, value is amplitude + std::map sample_map; + for (const auto& mcHit : mcHits) {// Loop through each MCHit in the vector + + // skip negative hit times, what does that even mean if we're not using the smeared digit time? + // skip hit times past 70 us since that's our longest readout + if (mcHit.GetTime() < 0) continue; + if (mcHit.GetTime() > 70000) continue; + + // Grab the hit time (also converted to clock ticks) and the charge + double hit_t0 = mcHit.GetTime() + fTimeShift; + double hit_charge = mcHit.GetCharge(); + + logmessage = "PMTWaveformSim:\n hit charge = " + std::to_string(hit_charge) + " p.e., hit time = " + std::to_string(hit_t0) + " for PMTID " + std::to_string(PMTID); + Log(logmessage, v_message, verbosity); + + // before "digitizing", add smearing based on the uncertainty extracted in the laser analysis + if (fuseTimeSmearing) { + double timesmear = TimeSmearing(PMTID); + hit_t0 += timesmear; + } + + // now convert to clock ticks + uint16_t t0_ticks = uint16_t(hit_t0 / NS_PER_ADC_SAMPLE); + + // Set the readout window in clock ticks, but don't allow negative times + uint16_t start_clocktick = (t0_ticks > fPrewindow)? t0_ticks - fPrewindow : 0; + uint16_t end_clocktick = start_clocktick + fReadoutWindow; + + // Randomly Sample the PMT parameters for each MCHit + SampleFitParameters(PMTID); + + // loop over clock ticks + for (uint16_t clocktick = start_clocktick; clocktick <= end_clocktick; clocktick += 1) { + uint16_t sample = CustomLogNormalPulse(hit_t0, clocktick, hit_charge); + + std::stringstream logmessage; + logmessage << " --> clocktick = " << clocktick << ", sample = " << sample; + Log(logmessage.str(), v_message, verbosity); + + // check if this hit time has been recorded + // either set it or add to it + if (sample_map.find(clocktick) == sample_map.end()) + sample_map[clocktick] = sample; + else + sample_map[clocktick] += sample; + }// end loop over clock ticks + }// end loop over mcHits + + // If there are no samples for this PMT then no need to do the rest + if (sample_map.empty()) continue; + + + // Set the noise envelope and baseline for this PMT + // The noise std dev appears to be normally distributed around 1 with sigma 0.25 + // TODO: set accurate baseline and noise profiles for all PMTs individually (noise should be fine, baselines will vary) + double noiseSigma = fRandom.Gaus(1, 0.25); + int basline = fRandom.Uniform(300, 350); + + // convert the sample map into a vector of Waveforms and put them into the container + std::vector> rawWaveforms; + std::vector> calWaveforms; + ConvertMapToWaveforms(sample_map, rawWaveforms, calWaveforms, noiseSigma, basline); + + RawADCDataMC.emplace(PMTID, rawWaveforms); + CalADCDataMC.emplace(PMTID, calWaveforms); + }// end loop over PMTs + + + // Publish the waveforms to the ANNIEEvent store if we have them + m_data->Stores.at("ANNIEEvent")->Set("RawADCDataMC", RawADCDataMC); + m_data->Stores.at("ANNIEEvent")->Set("CalibratedADCData", CalADCDataMC); + + if (fDebug) + FillDebugGraphs(RawADCDataMC); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::Finalise() +{ + if (fDebug) + fOutFile->Close(); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::LoadPMTParameters() +{ + + std::ifstream infile(fPMTParameterFile); + if (!infile.is_open()) { + logmessage = "PMTWaveformSim: Error opening CSV file: "; + logmessage += fPMTParameterFile + "!"; + Log(logmessage, v_error, verbosity); + return false; + } + + if (fuseTimeSmearing) { + // load timing offsets from the laser calibration to use as our timing uncertainty / smearing + bool got_offset = m_data->CStore.Get("ChannelNumToTankPMTTimingSigmaMap",ChannelKeyToTimingSigmaMap); + if (!got_offset) { + logmessage = "PMTWaveformSim: Error retrieving PMT timing uncertainty... double check LoadGeometry maybe?"; + Log(logmessage, v_error, verbosity); + return false; + } + } + + int pmtid; + // Stored fit parameters. + // p0, p1, and p2 are the mean values of the lognorm + // T1 and T2 are the reflection spacings + // r1 and r2 are the reflection amplitudes (relative to the main peak amplitude) + // the uncertainties (u*) are the sq(diagonal elements) of the fitted covariance matrix + double p0, p1, p2, T1, T2, R1, R2, + up0, up1, up2, uT1, uT2, uR1, uR2; + + std::string comma; + std::string line; + while (std::getline(infile, line)) { + if (infile.fail()) { + logmessage = "PMTWaveformSim: Error using CSV file: "; + logmessage += fPMTParameterFile + "!"; + Log(logmessage, v_error, verbosity); + + return false; + } + + // Skip the header line + if (line.find("PMT") != std::string::npos) continue; + + // Skip any commented lines + if(line.rfind("#",0) != std::string::npos) continue; + + // Turn the line into a stringstream to extract the values + std::stringstream ss(line); + ss >> pmtid >> comma >> p0 >> comma >> p1 >> comma >> p2 >> comma >> T1 >> comma >> T2 >> comma >> R1 >> comma >> R2 >> comma + >> up0 >> comma >> up1 >> comma >> up2 >> comma >> uT1 >> comma >> uT2 >> comma >> uR1 >> comma >> uR2; + + fPMTParamMap[pmtid] = {p0, p1, p2, T1, T2, R1, R2, up0, up1, up2, uT1, uT2, uR1, uR2}; + + logmessage = "PMTWaveformSim: Loaded parameters for PMTID " + std::to_string(pmtid) + ": "; + logmessage += "p0 = " + std::to_string(p0); + logmessage += " p1 = " + std::to_string(p1); + logmessage += " p2 = " + std::to_string(p2); + logmessage += " T1 = " + std::to_string(T1); + logmessage += " T2 = " + std::to_string(T2); + logmessage += " R1 = " + std::to_string(R1); + logmessage += " R2 = " + std::to_string(R2); + logmessage += " uncertainty_p0 = " + std::to_string(p0); + logmessage += " uncertainty_p1 = " + std::to_string(p1); + logmessage += " uncertainty_p2 = " + std::to_string(p2); + logmessage += " uncertainty_T1 = " + std::to_string(T1); + logmessage += " uncertainty_T2 = " + std::to_string(T2); + logmessage += " uncertainty_R1 = " + std::to_string(R1); + logmessage += " uncertainty_R2 = " + std::to_string(R2); + Log(logmessage, v_message, verbosity); + } + + infile.close(); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::SampleFitParameters(int pmtid) +{ + PMTFitParams pmtParams; + if (fPMTParamMap.find(pmtid) != fPMTParamMap.end()) { + pmtParams = fPMTParamMap[pmtid]; + } else { + logmessage = "PMTWaveformSim: PMTParameters not found for " + std::to_string(pmtid); + logmessage += ", using defaults (exemplary fit: PMT 403 Hamamatsu): p0 = 16.876, p1 = 65.448, p2 = 0.032, T1 = 6.593, T2 = 6.975, r1 = 0.174, r2 = 0.049"; + Log(logmessage, v_warning, verbosity); + + // TODO make this a random sample as well + // TODO make the default the parameters of the *total* fit + fP0 = 16.876; + fP1 = 65.448; + fP2 = 0.032; + fT1 = 6.593; + fT2 = 6.975; + fR1 = 0.174; + fR2 = 0.049; + + return true; + } + + // First sample a Gaussian with mean 0 and deviation 1 + double rr0 = fRandom.Gaus(); // p0 + double rr1 = fRandom.Gaus(); // p1 + double rr2 = fRandom.Gaus(); // p2 + + // Randomly sample parameters with their associated uncertainties + fP0 = rr0*pmtParams.up0 + pmtParams.p0; + fP1 = rr1*pmtParams.up1 + pmtParams.p1; + fP2 = rr2*pmtParams.up2 + pmtParams.p2; + + // for the reflection coefficients, we know they must be positive (or else its nonsense) + double rr3, rr4, rr5, rr6; + do { + rr3 = fRandom.Gaus(); // T1 + rr4 = fRandom.Gaus(); // T2 + rr5 = fRandom.Gaus(); // r1 + rr6 = fRandom.Gaus(); // r2 + + fT1 = rr3*pmtParams.uT1 + pmtParams.T1; + fT2 = rr4*pmtParams.uT2 + pmtParams.T2; + fR1 = rr5*pmtParams.uR1 + pmtParams.R1; + fR2 = rr6*pmtParams.uR2 + pmtParams.R2; + + if (fT1 < 0.0 || fT2 < 0.0 || fR1 < 0.0 || fR2 < 0.0) { + std::stringstream debug_msg_random; + debug_msg_random << "PMTWaveformSim: Resampling due to negative value(s): " + << "fT1 = " << fT1 << ", " + << "fT2 = " << fT2 << ", " + << "fR1 = " << fR1 << ", " + << "fR2 = " << fR2 << std::endl; + Log(debug_msg_random.str(), v_warning, verbosity); + } + + } while (fT1 < 0.0 || fT2 < 0.0 || fR1 < 0.0 || fR2 < 0.0); + + + std::stringstream debug_msg; + debug_msg << "PMTWaveformSim::SampleFitParameters final sampled parameters:" + << "\n random p0 = " << fP0 + << "\n random p1 = " << fP1 + << "\n random p2 = " << fP2 + << "\n random T1 = " << fT1 + << "\n random T2 = " << fT2 + << "\n random R1 = " << fR1 + << "\n random R2 = " << fR2; + Log(debug_msg.str(), v_warning, verbosity); + + return true; +} + +//------------------------------------------------------------------------------ +uint16_t PMTWaveformSim::CustomLogNormalPulse(double hit_t0, uint16_t clocktick, double hit_charge) +{ + //p0*exp( -0.5 * (log(x/p1)/p2)^2) (main peak) + sum_{i = 1}^{3}[(pi*p0)*exp( -0.5 * (log(x - (i * Ti)/p1)/p2)^2)] (3 reflections) + + // The fit was performed in time units of ns, but we pass samples in clock ticks + double x = (clocktick + fT0Offset) * NS_PER_ADC_SAMPLE - hit_t0; + + // debug + double logarg_main = x / fP1; + double logarg_r1 = (x - fT1) / fP1; + double logarg_r2 = (x - 2*fT2) / fP1; + std::stringstream debug_msg; + debug_msg << "PMTWaveformSim::CustomLogNormalPulse debug:" + << "\n clocktick = " << clocktick + << "\n hit_t0 = " << hit_t0 + << "\n x = " << x + << "\n logarg_main = " << logarg_main + << "\n logarg_r1 = " << logarg_r1 + << "\n logarg_r2 = " << logarg_r2 + << "\n fP0 = " << fP0 + << ", fP1 = " << fP1 + << ", fP2 = " << fP2 + << ", fT1 = " << fT1 + << ", fT2 = " << fT2 + << ", fR1 = " << fR1 + << ", fR2 = " << fR2 + << ", hit_charge = " << hit_charge; + Log(debug_msg.str(), v_warning, verbosity); + + // main peak parameters + double numerator = log(x/fP1); + numerator = numerator * numerator; + double denom = fP2 * fP2; // main peak shape + width is used for all reflection peaks; only calculate once + double amplitude = fP0 * exp(-0.5 * numerator/denom) * hit_charge; + + // reflection 1 parameters + double numerator_r1 = log((x - fT1)/fP1); + numerator_r1 = numerator_r1 * numerator_r1; + amplitude += (fP0 * fR1) * exp(-0.5 * numerator_r1/denom) * hit_charge; + + // reflection 2 parameters + double numerator_r2 = log((x - (2*fT2))/fP1); + numerator_r2 = numerator_r2 * numerator_r2; + amplitude += (fP0 * fR2) * exp(-0.5 * numerator_r2/denom) * hit_charge; + + // Clip at 4095 and digitize to an integer + return uint16_t((amplitude > 4095) ? 4095 : amplitude); +} + +//------------------------------------------------------------------------------ +void PMTWaveformSim::ConvertMapToWaveforms(const std::map &sample_map, + std::vector> &rawWaveforms, + std::vector> &calWaveforms, + double noiseSigma, int baseline) +{ + // Clear the output waveforms just in case + rawWaveforms.clear(); + calWaveforms.clear(); + + // All MC has extended readout, but it's time consuming to draw 35000 noise samples + // Instead, only sample up to the maximum tick time. Then start with all baseline and + // add noise only to relevant ticks. The intermediate space between pulses will have no noise + + uint16_t maxTick = sample_map.rbegin()->first; + std::vector rawSamples(maxTick+1, baseline); + std::vector calSamples(maxTick+1, 0); + for (auto sample_pair : sample_map) { + uint16_t tick = sample_pair.first; + + // Generate noise for each sample based on the std dev of the noise envelope + double noise = fRandom.Gaus(0, noiseSigma); + int sample = std::round(noise + baseline); + + sample += sample_pair.second; + + rawSamples[tick] = (sample > 4095) ? 4095 : sample; + calSamples[tick] = (rawSamples[tick] - baseline) * ADC_TO_VOLT; + } + + // The start time in data is a trigger timestamp. Don't have that for MC so just set to 0. + rawWaveforms.emplace_back(0, rawSamples); + calWaveforms.emplace_back(0, calSamples, baseline, noiseSigma); +} + +//------------------------------------------------------------------------------ +int PMTWaveformSim::LoadFromStores() +{ + bool goodAnnieEvent = m_data->Stores.count("ANNIEEvent"); + if (!goodAnnieEvent) { + logmessage = "PMTWaveformSim: no ANNIEEvent store!"; + Log(logmessage, v_error, verbosity); + return 0; + } + + bool goodMCHits = m_data->Stores.at("ANNIEEvent")->Get("MCHits", fMCHits); + if (!goodMCHits) { + logmessage = "PMTWaveformSim: no MCHits in the ANNIEEvent! "; + Log(logmessage, v_error, verbosity); + return 0; + } + + if (fMCHits->empty()) { + logmessage = "PMTWaveformSim: The MCHits map is empty! Will fill a single PMT with a minimal waveform."; + Log(logmessage, v_warning, verbosity); + return 2; + } + + + return 1; +} + +//------------------------------------------------------------------------------ +void PMTWaveformSim::FillDebugGraphs(const std::map> > &RawADCDataMC) +{ + for (auto itpair : RawADCDataMC) { + std::string chanString = std::to_string(itpair.first); + + // Get/make the directory for this PMT + TDirectory* dir = fOutFile->GetDirectory(chanString.c_str()); + if (!dir) + dir = fOutFile->mkdir(chanString.c_str()); + + // Hop into that directory and save the graph + dir->cd(); + + // loop over waveforms and make graphs + for (uint wfIdx = 0; wfIdx < itpair.second.size(); ++wfIdx) { + auto waveform = itpair.second.at(wfIdx); + + uint32_t evtNum = 0; + m_data->Stores.at("ANNIEEvent")->Get("EventNumber",evtNum); + std::string grName = ("wf_" + std::to_string(evtNum) + "_" + std::to_string(wfIdx)); + + // Make the graph + std::vector samples = waveform.Samples(); + TGraph grTemp = TGraph(); + double sampleX = waveform.GetStartTime(); + for(auto sample : samples) { + grTemp.AddPoint(sampleX, sample); + ++sampleX; + } + + grTemp.Write(grName.c_str()); + }// end loop over waveforms + }// end loop over PMTs +} + +double PMTWaveformSim::TimeSmearing(int pmtid) +{ + // fetch uncertainty using PMT id + auto it = ChannelKeyToTimingSigmaMap->find(pmtid); + double timing_sigma; + if (it != ChannelKeyToTimingSigmaMap->end()) { + timing_sigma = it->second; + if (verbosity > v_debug) { + std::cout << "PMTWaveformSim: Found timing uncertainty for PMT " << pmtid + << " -> " << timing_sigma << " ns" << std::endl; + } + } else { + timing_sigma = 1.0; // default to 1 ns if not found + if (verbosity > v_error) { + std::cout << "PMTWaveformSim: Didn't find timing uncertainty for PMT " << pmtid + << ", setting timing uncertainty to " << timing_sigma << " ns" + << std::endl; + } + } + + // apply time smearing by sampling normal centered at 0 with std = timing_sigma + double time_smearing = fRandom.Gaus(0, timing_sigma); + return time_smearing; +} + + + + + diff --git a/UserTools/PMTWaveformSim/PMTWaveformSim.h b/UserTools/PMTWaveformSim/PMTWaveformSim.h new file mode 100644 index 000000000..8ca705ae1 --- /dev/null +++ b/UserTools/PMTWaveformSim/PMTWaveformSim.h @@ -0,0 +1,93 @@ +#ifndef PMTWaveformSim_H +#define PMTWaveformSim_H + +#include +#include + +// ANNIE includes +#include "Tool.h" +#include "CalibratedADCWaveform.h" +#include "Waveform.h" + +// ROOT includes +#include "TFile.h" +#include "TRandom3.h" + +struct PMTFitParams +{ + double p0, p1, p2, T1, T2, R1, R2; + double up0, up1, up2, uT1, uT2, uR1, uR2; +}; + + +/** + * \class PMTWaveformSim + * + * 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: A.Sutton, S.Doran, and D. Ajana $ +* $Date: 2024/11/05 10:44:00 $ +* Contact: doran@iastate.edu +*/ +class PMTWaveformSim: public Tool { + + + public: + + PMTWaveformSim(); ///< 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. + int LoadFromStores(); ///< Fetch all necessary info from the CStore + + bool LoadPMTParameters(); ///< load in: 1. lognorm fit information from the csv file and 2. PMT timing uncertainties from laser analysis + bool SampleFitParameters(int pmtid); ///< sample fit parameters in a way that preserves covariance + uint16_t CustomLogNormalPulse(double hit_t0, uint16_t t0_clocktick, double hit_charge); //< construct simulated ADC pulses using sampled fit values + void ConvertMapToWaveforms(const std::map &sample_map, ///< construct a waveform with the simulated pulse + baseline modulation, to feed into the PhaseIIADCHitFinder + std::vector> &rawWaveforms, + std::vector> &calWaveforms, + double noiseSigma, int baseline); + + void FillDebugGraphs(const std::map> > &RawADCDataMC); ///< debugging + double TimeSmearing(int pmtid); ///< prior to sampling the fits, we can add realistic time smearing (instead of relying on WCSim's time smearing) to the MCHit (true) time + + private: + + // To load from the ANNIEEvent + std::map> *fMCHits = nullptr; + + Geometry *fGeo = nullptr; + + // Config variables + uint16_t fPrewindow; // number of clock ticks before the MC hit time to begin sampling the fit function + uint16_t fReadoutWindow; // number of clock ticks around the MC hit time over which waveforms are sampled + int fT0Offset; // a timing offset (in clock ticks) that can be used to align the pulse start time (can be positive or negative) + bool fuseTimeSmearing; // whether to implement time smearing based on the uncertainties extracted from the PMT laser timing analysis + // (this should be used in place of the standard WCSim time smearing) + double fTimeShift; // [ns] to shift MC hit times by - if generating WCSim particles, there is often a pileup at t = 0. When doing the hit integration, + // this can artificially shorten the "pre"-pulse integration (doesn't typically happen in data). + + std::string fPMTParameterFile; + + TRandom3 fRandom; + + std::map fPMTParamMap; + double fP0, fP1, fP2; // main peak parameters + double fT1, fT2, fR1, fR2; // reflection amplitudes and time spacings + + // timing uncertainty map + std::map* ChannelKeyToTimingSigmaMap; + + bool fDebug; + TFile *fOutFile; + + int verbosity; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; +}; + + +#endif diff --git a/UserTools/PMTWaveformSim/README.md b/UserTools/PMTWaveformSim/README.md new file mode 100644 index 000000000..09dd5b692 --- /dev/null +++ b/UserTools/PMTWaveformSim/README.md @@ -0,0 +1,40 @@ +# PMTWaveformSim + +PMTWaveformSim generates PMT waveforms based on the simulated PMT hits. For each MCHit a lognorm waveform is sampled based on fit parameters extracted from SPE waveforms in data. The fit functions are taken from Daya Bay and are used to model a main peak and two reflections. The fit parameters are sampled using the associated fit errors, and captures the random behavior of a PMT's response. A full extended readout window (70 us) is sampled and waveforms from overlapping hits are added. A random baseline between 300 and 350 ADC is added. Random noise is applied, where the noise sigma is sampled from a gaussian with mean 1 and std dev of 0.25. The baseline and noise envelope values are hardcoded at the moment. Finally, any ADC counts above 4095 are clipped to mimic saturation. The resulting MC waveform hits look like Data hits, and can be passed to tools downstream as if they are Data hits (so long as the configuration is set for those tools). + +The implementation of this tool and details on the waveform simulation can be found here: https://annie-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=5962&filename=MC%20Tuning%20and%20Validation%20_%20March%202025%20Collab%20Meeting%20_%20Steven%20Doran.pdf&version=1 + +Details on the fits used can be found here: https://github.com/S81D/PMTPulseFit + +## Data + +**RawADCDataMC** `std::map> >` +* The raw simulated waveforms. The key is PMT channel number, then inner vector should always have size == 1 + +**CalibratedADCData** `std::map> >` +* The "calibrated" simulated waveforms. The baseline and sigma are the true, randomly-generated values. The key is PMT channel number, then inner vector should always have size == 1 + + +## Configuration + +`PMTWaveformSim` uses a fit file with SPE fits extracted from the data for each PMT. Any toolchain using this tool must have a `PMTWaveformLognormFit.csv` file in that toolchain directory. + +``` +verbosity 0 +PMTParameterFile configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv # file containing the fit parameters and uncertainties +useTimeSmearing 0 # instead of the default WCSim time smearing, add in realistic time smearing based on the PMT laser analysis +Prewindow 80 # number of clock ticks before the MC hit time to begin sampling the fit function +ReadoutWindow 200 # number of clock ticks around the MC hit time over which waveforms are sampled +T0Offset 25 # A timing offset (in clock ticks) that can be used to vary the pulse start times + # (it is primarily used to ensure the lognorm fits on the main peak avoid NaNs when sampling the fit params) + # (The T0offset set to 25 shifts the sampling to avoid fit blowups, then the code shifts it back by 25. 25 is therefore the "default" and is recommended.) +TimeShift 0 # This is an artificial time shift to the MC Hits [ns] + # (as WCSim simulates particles from t0 = 0, this can be used as a toggle on the "trigger time") +MakeDebugFile 0 # Produce a root file containing all the simulated waveforms +``` + +## Other notes +#### CAUTION: In line 90, the RNG seed is set in Initialization based on the clock time. If any other downstream tools are also setting a random seed, there may be unexpected behavior as a result of this tool. + +For events with no MCHits (and hence no waveforms to simulate) a "dummy" waveform is simulated in one of the dead PMT channels (333). The dummy waveform is very short (50ns) and samples from a noise distribution lower than normal, as to not have any hits register in the hit finder (the hit finder will skip dead PMTs anyways). Passing at least one waveform to the hit finding tools prevents crashing. **IF** that PMT is ever repaired or comes back online, please move this dummy channel to a different offline channel. + diff --git a/UserTools/ParseDataMonitoring/ParseDataMonitoring.cpp b/UserTools/ParseDataMonitoring/ParseDataMonitoring.cpp index 9859502b0..3032dc86c 100644 --- a/UserTools/ParseDataMonitoring/ParseDataMonitoring.cpp +++ b/UserTools/ParseDataMonitoring/ParseDataMonitoring.cpp @@ -2,6 +2,11 @@ ParseDataMonitoring::ParseDataMonitoring():Tool(){} +namespace { +const unsigned int NUM_CH = 30; +const unsigned int NUM_SAMP = 256; +const unsigned int NUM_PSEC = 5; +} bool ParseDataMonitoring::Initialise(std::string configfile, DataModel &data){ diff --git a/UserTools/ParseDataMonitoring/ParseDataMonitoring.h b/UserTools/ParseDataMonitoring/ParseDataMonitoring.h index 46214bd2a..282e18f09 100644 --- a/UserTools/ParseDataMonitoring/ParseDataMonitoring.h +++ b/UserTools/ParseDataMonitoring/ParseDataMonitoring.h @@ -10,10 +10,6 @@ #include "PsecData.h" -#define NUM_CH 30 -#define NUM_SAMP 256 -#define NUM_PSEC 5 - using namespace std; /** * * \class ParseDataMonitoring 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 a7a4563ca..c77ee2543 100755 --- a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp +++ b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp @@ -12,17 +12,18 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat m_data = &data; // Load the default threshold settings for finding pulses - verbosity = 3; + verbosity = 0; use_led_waveforms = false; pulse_finding_approach = "threshold"; adc_threshold_db = "none"; - default_adc_threshold = 5; + default_adc_threshold = 7; threshold_type = "relative"; - pulse_window_type = "fixed"; + pulse_window_type = "Fixed_2023_Gains"; pulse_window_start_shift = -3; pulse_window_end_shift = 25; adc_window_db = "none"; //Used when pulse_finding_approach="fixed_windows" eventbuilding_mode = false; + mc_waveforms = false; //Load any configurables set in the config file m_variables.Get("verbosity",verbosity); @@ -36,6 +37,7 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat m_variables.Get("PulseWindowEnd", pulse_window_end_shift); m_variables.Get("WindowIntegrationDB", adc_window_db); m_variables.Get("EventBuilding",eventbuilding_mode); + m_variables.Get("MCWaveforms",mc_waveforms); if ((pulse_window_start_shift > 0) || (pulse_window_end_shift) < 0){ Log("PhaseIIADCHitFinder Tool: WARNING... trigger threshold crossing will not be inside pulse window. Threshold" @@ -65,12 +67,21 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat eventbuilding_mode = false; } + if (mc_waveforms && (eventbuilding_mode || use_led_waveforms)) { + Log("PhaseIIADCCalibrator: Cannot use MCWaveforms in EventBuilding mode or while using LED waveforms. Aborting!", v_error, verbosity); + return false; + } + //Set in CStore for tools to know and log this later m_data->CStore.Set("ADCThreshold",default_adc_threshold); // Get the Auxiliary channel types; identifies which channels are SiPM channels 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); + //Recreate maps that were deleted with ANNIEEvent->Delete() ANNIEEventBuilder tool hit_map = new std::map>; aux_hit_map = new std::map>; @@ -126,6 +137,11 @@ bool PhaseIIADCHitFinder::Execute() { } else { got_raw_data = annie_event->Get("RawADCData", raw_waveform_map); got_rawaux_data = annie_event->Get("RawADCAuxData", raw_aux_waveform_map); + + if (mc_waveforms) { + got_raw_data = annie_event->Get("RawADCDataMC", raw_waveform_map); + }// end if mc_waveforms + } // Check for problems if ( !got_raw_data ) { @@ -133,12 +149,12 @@ bool PhaseIIADCHitFinder::Execute() { verbosity); return false; } - if ( !got_rawaux_data ) { + if ( !got_rawaux_data && !(use_led_waveforms || mc_waveforms)) { Log("Error: The PhaseIIADCHitFinder tool could not find the RawADCAuxData entry", v_error, verbosity); return false; } - else if ( raw_waveform_map.empty() ) { + else if ( raw_waveform_map.empty() && !mc_waveforms ) { Log("Error: The PhaseIIADCHitFinder tool found an empty RawADCData entry", v_error, verbosity); return false; @@ -162,12 +178,12 @@ bool PhaseIIADCHitFinder::Execute() { " entry", v_error, verbosity); return false; } - if ( !got_calibratedaux_data ) { + if ( !got_calibratedaux_data && !(use_led_waveforms || mc_waveforms)) { Log("Error: The PhaseIIADCHitFinder tool could not find the CalibratedADCAuxData" " entry", v_error, verbosity); return false; } - else if ( calibrated_waveform_map.empty() ) { + else if ( calibrated_waveform_map.empty() && !mc_waveforms ) { Log("Error: The PhaseIIADCHitFinder tool found an empty CalibratedADCData entry", v_error, verbosity); return false; @@ -663,6 +679,10 @@ std::vector PhaseIIADCHitFinder::find_pulses_bywindow( double charge = 0.; unsigned long raw_area = 0; // ADC * samples + unsigned short baseline_plus_one_sigma = static_cast( + std::round( calibrated_minibuffer_data.GetBaseline() + + calibrated_minibuffer_data.GetSigmaBaseline() )); + if(MaxHeightPulseOnly){ // From that peak sample, sum up to either side until finding a // sample that's 10% of the max height @@ -672,23 +692,57 @@ std::vector PhaseIIADCHitFinder::find_pulses_bywindow( size_t pulsewinright = peak_sample + 1; bool integrated_leftward = false; bool integrated_rightward = false; + + size_t extra_pulsewinleft = 0; + bool extra_winleft = false; + size_t extra_pulsewinright = 0; + bool extra_winright = false; + while (!integrated_leftward && peak_sample!=wmin){ double sample_height = calibrated_minibuffer_data.GetSample(pulsewinleft); - if (sample_height > (0.1 * calibrated_amplitude) && (pulsewinleft>wmin)){ + double raw_sample_height = raw_minibuffer_data.GetSample(pulsewinleft); + + if (raw_sample_height <= (baseline_plus_one_sigma)) extra_winleft = true; + + if (pulsewinleft<=wmin) {integrated_leftward = true;} + + else if (raw_sample_height > (baseline_plus_one_sigma) && (pulsewinleft>wmin) && !extra_winleft ){ raw_area += raw_minibuffer_data.GetSample(pulsewinleft); charge += sample_height; pulsewinleft-=1; } - else integrated_leftward = true; + + else if (extra_winleft && pulsewinleft>wmin) { + raw_area += raw_minibuffer_data.GetSample(pulsewinleft); + charge += sample_height; + pulsewinleft-=1; + extra_pulsewinleft += 1; + if(extra_pulsewinleft == 5) integrated_leftward = true; + } + } while (!integrated_rightward && peak_sample!=wmax){ double sample_height = calibrated_minibuffer_data.GetSample(pulsewinright); - if (sample_height > (0.1 * calibrated_amplitude) && (pulsewinright < wmax)){ + double raw_sample_height = raw_minibuffer_data.GetSample(pulsewinright); + + if (raw_sample_height <= (baseline_plus_one_sigma)) extra_winright = true; + + if (pulsewinright>=wmax) {integrated_rightward = true;} + + else if (raw_sample_height > (baseline_plus_one_sigma) && (pulsewinright PhaseIIADCHitFinder::find_pulses_bywindow( // Convert the pulse integral to nC charge *= NS_PER_ADC_SAMPLE / ADC_IMPEDANCE; + // PMT Timing offsets + double timing_offset=0.0; + std::map::const_iterator it = ChannelKeyToTimingOffsetMap.find(channel_key); + if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available + timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); + } else { + if(verbosity>2 && !mc_waveforms){ + 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) + std::vector trace_x; + std::vector trace_y; + + double pulse_start_time = wmin * NS_PER_ADC_SAMPLE; + double pulse_baseline = calibrated_minibuffer_data.GetBaseline(); + + for (size_t p = wmin; p <= wmax; ++p) { + double ns_time = p * NS_PER_ADC_SAMPLE; + double val_adc = raw_minibuffer_data.GetSample(p); + trace_x.push_back(ns_time - pulse_start_time); + trace_y.push_back(val_adc - pulse_baseline); + } // Store the freshly made pulse in the vector of found pulses pulses.emplace_back(channel_key, - ( wmin * NS_PER_SAMPLE ), - peak_sample * NS_PER_SAMPLE, + ( wmin * NS_PER_ADC_SAMPLE )-timing_offset, + (peak_sample * NS_PER_ADC_SAMPLE)-timing_offset, calibrated_minibuffer_data.GetBaseline(), calibrated_minibuffer_data.GetSigmaBaseline(), - raw_area, max_ADC, calibrated_amplitude, charge); + raw_area, max_ADC, calibrated_amplitude, charge, + trace_x, trace_y); } return pulses; } +// ****************************************************************** +// "PulseFindingApproach" default for EventBuilding std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( const Waveform& raw_minibuffer_data, const CalibratedADCWaveform& calibrated_minibuffer_data, @@ -805,15 +886,240 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( // Convert the pulse integral to nC charge *= NS_PER_ADC_SAMPLE / ADC_IMPEDANCE; + // PMT Timing offsets + double timing_offset=0.0; + std::map::const_iterator it = ChannelKeyToTimingOffsetMap.find(channel_key); + 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... 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) + 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(); + + for (size_t p = pulse_start_sample; p <= pulse_end_sample; ++p) { + double ns_time = p * NS_PER_ADC_SAMPLE; + double val_adc = raw_minibuffer_data.GetSample(p); + trace_x.push_back(ns_time - pulse_start_time); + 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_SAMPLE ), - peak_sample * NS_PER_SAMPLE, + ( pulse_start_sample * NS_PER_ADC_SAMPLE )-timing_offset, + (peak_sample * NS_PER_ADC_SAMPLE)-timing_offset, calibrated_minibuffer_data.GetBaseline(), calibrated_minibuffer_data.GetSigmaBaseline(), - raw_area, max_ADC, calibrated_amplitude, charge); + raw_area, max_ADC, calibrated_amplitude, charge, + trace_x, trace_y); } - + + + // ****************************************************************** + // Fixed integration window defined relative to *baseline* threshold crossings + // "PulseWindowType" default for EventBuilding (to match the 2023 gains calibration integration approach) + } else if(pulse_window_type == "Fixed_2023_Gains"){ + + // 2023 Gains integration approach (same as 'full_window_maxpeak' PulseFindingApproach, but we require pulse threshold finding) + // * pulse is defined as any instance of sample above the ADC threshold + // * pulse start defined as 5 samples to the left from where the pulse emerges from the baseline + // * pulse end defined as 5 samples to the right from where the pulse returns to the baseline + + 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 + 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; + + // 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 << "Pulse found is VERY EARLY in the minibuffer (< 5 samples)... assigning pulse start as 0" << std::endl; + pulse_start_sample = 0; + } + + else { + size_t pulsewinleft = s; + + // determine start of pulse by walking back from the threshold crossing point until we dip below baseline, then take 5 samples before as the pulse start + while (pulsewinleft > 0) { + double raw_sample_height = raw_minibuffer_data.GetSample(pulsewinleft); + if (raw_sample_height <= baseline_plus_one_sigma) { + + if (pulsewinleft >= 5) { // avoid underflow + pulse_start_sample = pulsewinleft - 5; // pulse start = baseline crossing - 5 samples + } + + else { + 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; + } + + break; + } + pulsewinleft--; + } + + // 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 << "Baseline crossing was not found... assigning pulse start as 0" << std::endl; + } + pulse_start_sample = 0; + } + } + + // once we reach the baseline again (right side of the pulse), we determine the pulse stop (5 samples after baseline + sigma crossing) + // or in case we've reached the end of the minibuffer, force pulse to end + } else if ( in_pulse && ((raw_minibuffer_data.GetSample(s) < baseline_plus_one_sigma) || (s == num_samples - 1)) ) { + in_pulse = false; + + if (s == num_samples - 1) { + 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 << "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. + unsigned long raw_area = 0; // ADC * samples + unsigned short max_ADC = std::numeric_limits::lowest(); + size_t peak_sample = BOGUS_INT; + for (size_t p = pulse_start_sample; p <= pulse_end_sample; ++p) { + raw_area += raw_minibuffer_data.GetSample(p); + if (max_ADC < raw_minibuffer_data.GetSample(p)) { + max_ADC = raw_minibuffer_data.GetSample(p); + peak_sample = p; + } + } + // The amplitude of the pulse (V) + double calibrated_amplitude + = calibrated_minibuffer_data.GetSample(peak_sample); + + // Calculated the charge detected in this pulse (nC) + // using the calibrated waveform + double charge = 0.; + // Integrate the calibrated pulse (to get a quantity in V * samples) + for (size_t p = pulse_start_sample; p <= pulse_end_sample; ++p) { + charge += calibrated_minibuffer_data.GetSample(p); + } + + // Convert the pulse integral to nC + // FIXME: We need a static database with each PMT's impedance + charge *= NS_PER_ADC_SAMPLE / ADC_IMPEDANCE; + // TODO: consider adding code to merge pulses if they occur + // very close together (i.e. if the end of one is just a few samples away + // from the start of another) + + // PMT Timing offsets + double timing_offset=0.0; + std::map::const_iterator it = ChannelKeyToTimingOffsetMap.find(channel_key); + if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available + timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); + } else { + 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; + } + } + + // New approach to hit timing to avoid 2ns bins - 50% threshold above baseline + // Look for where the ADC value crosses 50% of the maximum, assign hit time + // TODO: consider using an approach recommended by Bob: get time at 50%, get time at 20%, draw straight line in between and find time to zero threshold + const double threshold_percentage = 0.5; + unsigned short threshold_value = ((max_ADC - adc_threshold) * threshold_percentage) + adc_threshold; + double hit_time = peak_sample; + bool hit_time_found = false; + + // Find the first sample where the ADC value is above 50% + for (size_t p = peak_sample; p > pulse_start_sample; --p) { + if (raw_minibuffer_data.GetSample(p) < threshold_value) { + hit_time = p; + hit_time_found = true; + break; + } + } + + // 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 (hit_time > pulse_start_sample && hit_time < pulse_end_sample) { + double x1 = hit_time; + double x2 = hit_time + 1.0; + unsigned short y1 = raw_minibuffer_data.GetSample(static_cast(x1)); + unsigned short y2 = raw_minibuffer_data.GetSample(static_cast(x2)); + hit_time = x1 + (threshold_value - y1) * (x2 - x1) / (y2 - y1); // linear interpolation + } + } + + // 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(); + + for (size_t p = pulse_start_sample; p <= pulse_end_sample; ++p) { + double ns_time = p * NS_PER_ADC_SAMPLE; + double val_adc = raw_minibuffer_data.GetSample(p); + trace_x.push_back(ns_time - pulse_start_time); + trace_y.push_back(val_adc - pulse_baseline); + } + + 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, + ( hit_time * NS_PER_ADC_SAMPLE )-timing_offset, // interpolated hit time + calibrated_minibuffer_data.GetBaseline(), + calibrated_minibuffer_data.GetSigmaBaseline(), + raw_area, max_ADC, calibrated_amplitude, charge, + trace_x, trace_y); + } + } + + + // ****************************************************************** // 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; @@ -868,18 +1174,107 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( // very close together (i.e. if the end of one is just a few samples away // from the start of another) + // PMT Timing offsets + double timing_offset=0.0; + std::map::const_iterator it = ChannelKeyToTimingOffsetMap.find(channel_key); + 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... setting this channel's offset to 0ns" << channel_key << std::endl; + } + } + + // New approach to hit timing to avoid 2ns bins - 50% threshold above baseline + // Look for where the ADC value crosses 50% of the maximum, assign hit time + // TODO: consider using an approach recommended by Bob: get time at 50%, get time at 20%, draw straight line in between and find time to zero threshold + const double threshold_percentage = 0.5; + unsigned short threshold_value = ((max_ADC - adc_threshold) * threshold_percentage) + adc_threshold; + double hit_time = peak_sample; + bool hit_time_found = false; + + // Find the first sample where the ADC value is above 50% + for (size_t p = peak_sample; p > pulse_start_sample; --p) { + if (raw_minibuffer_data.GetSample(p) < threshold_value) { + hit_time = p; + hit_time_found = true; + break; + } + } + + // Perform simple linear interpolation to find exact crossing point + if (hit_time_found) { + if(verbosity>4) 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; + unsigned short y1 = raw_minibuffer_data.GetSample(static_cast(x1)); + unsigned short y2 = raw_minibuffer_data.GetSample(static_cast(x2)); + hit_time = x1 + (threshold_value - y1) * (x2 - x1) / (y2 - y1); // linear interpolation + } + } + + 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(); + + for (size_t p = pulse_start_sample; p <= pulse_end_sample; ++p) { + double ns_time = p * NS_PER_ADC_SAMPLE; + double val_adc = raw_minibuffer_data.GetSample(p); + trace_x.push_back(ns_time - pulse_start_time); + 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, - ( pulse_start_sample * NS_PER_ADC_SAMPLE ), - peak_sample * NS_PER_ADC_SAMPLE, + ( pulse_start_sample * NS_PER_ADC_SAMPLE )-timing_offset, + (hit_time * NS_PER_ADC_SAMPLE)-timing_offset, // interpolated hit time calibrated_minibuffer_data.GetBaseline(), calibrated_minibuffer_data.GetSigmaBaseline(), - raw_area, max_ADC, calibrated_amplitude, charge); + raw_area, max_ADC, calibrated_amplitude, charge, + trace_x, trace_y); } } } else { if(verbosity > v_error){ - std::cout << "PhaseIIADCHitFinder Tool error: Pulse window type not recognized. Please pick fixed or dynamic" << std::endl; + std::cout << "PhaseIIADCHitFinder Tool error: Pulse window type not recognized. Please pick fixed, dynamic, or Fixed_2023_Gains" << std::endl; } } if(verbosity > v_debug) std::cout << "Number of pulses in channels pulse vector: " << pulses.size() << std::endl; diff --git a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h index d7af819c0..ef3c10907 100755 --- a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h +++ b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h @@ -59,7 +59,9 @@ class PhaseIIADCHitFinder : public Tool { std::map channel_threshold_map; std::map>> channel_window_map; bool eventbuilding_mode; - + bool mc_waveforms; + + std::map ChannelKeyToTimingOffsetMap; std::map* AuxChannelNumToTypeMap; diff --git a/UserTools/PhaseIIADCHitFinder/README.md b/UserTools/PhaseIIADCHitFinder/README.md index c17f2ce82..0e8de25b2 100755 --- a/UserTools/PhaseIIADCHitFinder/README.md +++ b/UserTools/PhaseIIADCHitFinder/README.md @@ -1,10 +1,36 @@ # PhaseIIADCHitFinder -PhaseIIADCHitFinder +Hit finding tool for the tank PMTs. The configurable settings and types of pulse integration are listed below, but the main feature of the tool is to identify pulses via: +- With a threshold-style approach (default - used in the EventBuilder and in the MC waveform workflow) +- Search for the maximum peak within the entire buffer (used for Gains calibration with LED data) +- Within a fixed, pre-defined window (used for assessing the pedestal / (dark) noise rates or other relevant analyses) ## Data -Describe any data formats PhaseIIADCHitFinder creates, destroys, changes, or analyzes. E.G. +After identifying a pulse and obtaining the integrated charge [nQ], the pulse timing [ns], and other features of the identified "hit", the tool will populate the ADCPulse class (DataModel/ADCPulse), storing: +- `int` TubeID (PMT channel ID) +- `double` start_time (Returns the start time (ns) of the pulse relative to the start of its minibuffer) +- `double` peak_time (Returns the peak time (ns) of the pulse relative to the start of its minibuffer) +- `double` baseline (Returns the approximate baseline (ADC) used to calibrate the pulse) +- `double` sigma_baseline (Returns the approximate error on the baseline (ADC) used to calibrate the pulse) +- `unsigned long` area (Returns the area (ADC * samples) of the uncalibrated pulse) +- `unsigned short` raw_amplitude (Returns the amplitude (ADC) of the uncalibrated pulse) +- `double` calibrated_amplitude (eturns the amplitude (V) of the calibrated (baseline-subtracted) pulse) +- `double` charge (Returns the charge (nC) of the calibrated (baseline-subtracted) pulse) +- `const std::vector&` trace_x (Returns the x [ns] points of the "found" pulse (baseline-subtracted and relative to pulse start point)) +- `const std::vector&` trace_y (Returns the y [ADC] points of the "found" pulse (baseline-subtracted and relative to pulse start point)) + +into: `std::map>` RecoADCHits + +It will then store the hit charge [nQ] and the hit time [ns] to the store via: `std::map>*` Hits + +The tool will set additional objects to the store: +- ADCThreshold (Threshold used to identify pulses) +- InProgressHits, InProgressRecoADCHits, InProgressHitsAux, InProgressRecoADCHitsAux, NewHitsData (for book-keeping in the event building mode) + +Lastly, for the auxillary channels, it will store the ADCPulse and Hit instead to: +- `std::map>` RecoADCAuxHits +- `std::map>*` AuxHits ## Configuration @@ -16,54 +42,61 @@ UseLEDWaveforms [int]: Specifies whether hits and pulses are found using the 1=Use LED window waveforms, 0 = Use full waveforms. +MCWaveforms [int]: Whether the `PMTWaveformSim` MC waveform generator is being used for MC Hits. + +EventBuilding [int]: Whether this tool is being used in the event building toolchain. + ###### PULSE FINDING TECHNIQUES ######### PulseFindingApproach [string]: String that defines what algorithm is used to find pulses. Possible options: - "threshold": Search for an ADC sample to cross some defined threshold. Threshold + - "threshold": (DEFAULT for event building and MC waveforms) Search for an ADC sample to cross some defined threshold. Threshold is manipulable using DefaultADCThreshold and DefaultThresholdType config variables. - "fixed_window": Fixed windows defined in the WindowIntegrationDB text file are + - "fixed_window": Fixed windows defined in the WindowIntegrationDB text file are treated entirely as pulses. - "full_window": Every waveform is integrated completely and background-subtracted + - "full_window": Every waveform is integrated completely and background-subtracted to form a single pulse object. - "full_window_maxpeak": The maximum peak anywhere in the window is taken as the pulse. + - "full_window_maxpeak": The maximum peak anywhere in the window is taken as the pulse. the pulse is integrated to either side of the max until dropping to - < 10% of the max peak amplitude, then background-subtracted. + < 10% of the max peak amplitude, then background-subtracted. This is + used in the LED analysis (use with find_pulses_bywindow) - "signal_window_maxpeak": The maximum peak anywhere beyond the baseline estimation window + - "signal_window_maxpeak": The maximum peak anywhere beyond the baseline estimation window is taken as the pulse. the pulse is integrated to either side of the max until dropping to < 10% of the max peak amplitude, then background-subtracted. - "NNLS": Uses the NNLS algorithm that will be applied to LAPPD hit reconstruction. + - "NNLS": Uses the NNLS algorithm that will be applied to LAPPD hit reconstruction. Not yet implemented. ###### "threshold" setting configurables ######## -DefaultADCThreshold [int]: Defines the default threshold to be used for any PMT +- DefaultADCThreshold [int]: Defines the default threshold to be used for any PMT that does not have a channel_key, threshold value defined in the ADCThresholdDB file. -DefaultThresholdType [string]: Marks whether the given threshold values in the DB value are +- DefaultThresholdType [string]: Marks whether the given threshold values in the DB value are relative to the calibrated baseline ("relative"), or absolute ADC counts ("absolute"). -PulseWindowType [string]: If using "threshold" on pulse finding approach, this toggle defines - how the pulse windows in a waveform are found. Either fixed window ("fixed") or - the pulse windows are defined by crossing and un-crossing threshold ("dynamic"). +- PulseWindowType [string]: If using "threshold" on pulse finding approach, this toggle defines + how the pulse windows in a waveform are found. There are three options: fixed window ("fixed"), + dynamic window where the pulse windows are defined by crossing and un-crossing threshold ("dynamic"), + and ("Fixed_2023_Gains") which implements the same integration window used in the 2023 Gains calibration + where the pulse windows are defined by crossing and un-crossing the baseline. -PulseWindowStart [int]: Start of pulse window relative to when adc trigger threshold +- PulseWindowStart [int]: Start of pulse window relative to when adc trigger threshold was crossed. Only used when PulseFindingApproach==threshold and PulseWindowType==fixed. Unit is ADC samples. -PulseWindowEnd [int]: End of pulse window relative to when adc trigger threshold +- PulseWindowEnd [int]: End of pulse window relative to when adc trigger threshold was crossed. Only used when PulseFindingApproach==threshold and PulseWindowType==fixed. Unit is ADC samples. -ADCThresholdDB [string]: Absolute path to a CSV file where each line is the pair +- ADCThresholdDB [string]: Absolute path to a CSV file where each line is the pair channel_key (int), threshold (int). For any channel_key,threshold pair defined in the config file, these thresholds will be used in place of the default ADC threshold. Thresholds define the ADC threshold for each PMT used when pulse-finding. @@ -75,5 +108,103 @@ WindowIntegrationDB [string]: Absolute path to a CSV file where each line has th A channel can be given multiple integration windows. Windows are in ADC samples. A single pulse will be calculated for each integration window defined. + +## Example of working configurations +##### EventBuilding ##### ``` +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 +MCWaveforms 0 ``` + +##### PrintADCData (obtaining raw traces for pulse analysis) ##### +``` +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 0 +MCWaveforms 0 +``` + +##### MC ##### +``` +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 0 +MCWaveforms 1 +``` + +##### Gains ##### +``` +verbosity 0 + +UseLEDWaveforms 1 + +PulseFindingApproach full_window_maxpeak + +EventBuilding 0 +MCWaveforms 0 +``` + +## Tools needed to run this tool successfully +All working configurations must include at minimum the following tools: +``` +LoadGeometry +PhaseIIADCCalibrator +PhaseIIADCHitFinder +``` + +This is executed either: +1. Over RAWData as part of the event building procedure +2. Over ProcessedData that contains the raw waveforms instead of the extracted hits information (no hit finding was ran during the event building to purposely give you the raw waveforms) +3. On MC waveforms generated by the `PMTWaveformSim` tool to give you data-like MC hits + +In all three cases additional tools are needed. + +For 1. (RAWData for event building): +``` +LoadGeometry +LoadRawData (EventBuilder or DataDecoder) or EBLoadRaw (EventBuilderV2) +PMTDataDecoder +TriggerDataDecoder +PhaseIIADCCalibrator +PhaseIIADCHitFinder +``` + +For 2. (ProcessedData with raw waveforms): +``` +LoadGeometry +LoadANNIEEvent +PhaseIIADCCalibrator +PhaseIIADCHitFinder +``` + +For 3. (MC waveforms): +``` +LoadGeometry +LoadWCSim +PMTWaveformSim +PhaseIIADCHitFinder +``` + diff --git a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp index 8022719e9..9d0e8295f 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp @@ -13,23 +13,38 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ ///////////////////////////////////////////////////////////////// hasGenie = false; + hasBNBtimingMC = false; + MCWaveform = false; + ApplyDeadMask = false; m_variables.Get("verbose", verbosity); m_variables.Get("IsData",isData); + m_variables.Get("PMTWaveformSim",MCWaveform); + m_variables.Get("ApplyDeadMask",ApplyDeadMask); m_variables.Get("HasGenie",hasGenie); + m_variables.Get("HasBNBtimingMC",hasBNBtimingMC); m_variables.Get("TankHitInfo_fill", TankHitInfo_fill); m_variables.Get("MRDHitInfo_fill", MRDHitInfo_fill); m_variables.Get("fillCleanEventsOnly", fillCleanEventsOnly); m_variables.Get("MCTruth_fill", MCTruth_fill); m_variables.Get("MRDReco_fill", MRDReco_fill); m_variables.Get("TankReco_fill", TankReco_fill); + m_variables.Get("Reweight_fill", Reweight_fill); m_variables.Get("RecoDebug_fill", RecoDebug_fill); + 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); m_variables.Get("MRDClusterProcessing",MRDClusterProcessing); m_variables.Get("TriggerProcessing",TriggerProcessing); + + m_variables.Get("Digit_fill",Digit_fill); + + m_variables.Get("MuonFitter_fill", MuonFitter_fill); std::string output_filename; m_variables.Get("OutputFile", output_filename); @@ -101,6 +116,60 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITankClusterTree->Branch("SiPM1NPulses",&fSiPM1NPulses,"SiPM1NPulses/I"); fPhaseIITankClusterTree->Branch("SiPM2NPulses",&fSiPM2NPulses,"SiPM2NPulses/I"); } + if(LAPPDData_fill) + { + 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); + } + } + //MuonFitter reco track length, vtx, energy; juju + if (MuonFitter_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"); + } } if(MRDClusterProcessing){ @@ -156,6 +225,50 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIIMRDClusterTree->Branch("MRDStop",&fMRDStop); 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){ @@ -164,6 +277,19 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITrigTree->Branch("subrunNumber",&fSubrunNumber,"subrunNumber/I"); fPhaseIITrigTree->Branch("runType",&fRunType,"runType/I"); fPhaseIITrigTree->Branch("startTime",&fStartTime_Tree,"startTime/l"); + + + //DIGITS + if(Digit_fill){ + fPhaseIITrigTree->Branch("digitX",&fdigitX); + fPhaseIITrigTree->Branch("digitY",&fdigitY); + fPhaseIITrigTree->Branch("digitZ",&fdigitZ); + fPhaseIITrigTree->Branch("digitT",&fdigitT); + fPhaseIITrigTree->Branch("NDigitsPMTs",&fNDigitsPMTs); + fPhaseIITrigTree->Branch("NDigitsLAPPDs",&fNDigitsLAPPDs); + + } + //DIGITS //Some lower level information to save fPhaseIITrigTree->Branch("eventNumber",&fEventNumber,"eventNumber/I"); @@ -260,7 +386,37 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITrigTree->Branch("recoVtxFOM",&fRecoVtxFOM,"recoVtxFOM/D"); fPhaseIITrigTree->Branch("recoStatus",&fRecoStatus,"recoStatus/I"); } - + + //Michael's Simple Reconstruction + if(SimpleReco_fill){ + fPhaseIITrigTree->Branch("simpleRecoFlag",&fSimpleFlag,"simpleRecoFlag/I"); + fPhaseIITrigTree->Branch("simpleRecoEnergy",&fSimpleEnergy,"simpleRecoEnergy/D"); + fPhaseIITrigTree->Branch("simpleRecoVtxX",&fSimpleVtxX,"simpleRecoVtxX/D"); + fPhaseIITrigTree->Branch("simpleRecoVtxY",&fSimpleVtxY,"simpleRecoVtxY/D"); + fPhaseIITrigTree->Branch("simpleRecoVtxZ",&fSimpleVtxZ,"simpleRecoVtxZ/D"); + fPhaseIITrigTree->Branch("simpleRecoStopVtxX",&fSimpleStopVtxX,"simpleRecoStopVtxX/D"); + fPhaseIITrigTree->Branch("simpleRecoStopVtxY",&fSimpleStopVtxY,"simpleRecoStopVtxY/D"); + fPhaseIITrigTree->Branch("simpleRecoStopVtxZ",&fSimpleStopVtxZ,"simpleRecoStopVtxZ/D"); + fPhaseIITrigTree->Branch("simpleRecoCosTheta",&fSimpleCosTheta,"simpleRecoCosTheta/D"); + fPhaseIITrigTree->Branch("simpleRecoPt",&fSimplePt,"simpleRecoPt/D"); + fPhaseIITrigTree->Branch("simpleRecoFV",&fSimpleFV,"simpleRecoFV/I"); + fPhaseIITrigTree->Branch("simpleRecoMrdEnergyLoss",&fSimpleMrdEnergyLoss,"simpleRecoMrdEnergyLoss/D"); + fPhaseIITrigTree->Branch("simpleRecoTrackLengthInMRD",&fSimpleTrackLengthInMRD,"simpleRecoTrackLengthInMRD/D"); + fPhaseIITrigTree->Branch("simpleRecoMRDStartX",&fSimpleMRDStartX,"simpleRecoMRDStartX/D"); + fPhaseIITrigTree->Branch("simpleRecoMRDStartY",&fSimpleMRDStartY,"simpleRecoMRDStartY/D"); + fPhaseIITrigTree->Branch("simpleRecoMRDStartZ",&fSimpleMRDStartZ,"simpleRecoMRDStartZ/D"); + fPhaseIITrigTree->Branch("simpleRecoMRDStopX",&fSimpleMRDStopX,"simpleRecoMRDStopX/D"); + fPhaseIITrigTree->Branch("simpleRecoMRDStopY",&fSimpleMRDStopY,"simpleRecoMRDStopY/D"); + fPhaseIITrigTree->Branch("simpleRecoMRDStopZ",&fSimpleMRDStopZ,"simpleRecoMRDStopZ/D"); + fPhaseIITrigTree->Branch("simpleRecoTrackLengthInTank",&fSimpleTrackLengthInTank,"simpleRecoTrackLengthInTank/D"); + } + + //Ring Counting + if(RingCounting_fill){ + fPhaseIITrigTree->Branch("RCSRPred",&fRCSRPred,"RCSRPred/D"); + fPhaseIITrigTree->Branch("RCMRPred",&fRCMRPred,"RCMRPred/D"); + } + //MC truth information for muons //Output to tree when MCTruth_fill = 1 in config if (MCTruth_fill){ @@ -305,6 +461,7 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITrigTree->Branch("trueNeutCapE",&fTrueNeutCapE); fPhaseIITrigTree->Branch("trueNeutCapGammaE",&fTrueNeutCapGammaE); fPhaseIITrigTree->Branch("trueNeutrinoEnergy",&fTrueNeutrinoEnergy,"trueNeutrinoEnergy/D"); + fPhaseIITrigTree->Branch("trueNuPDG",&fTrueNuPDG,"trueNuPDG/I"); fPhaseIITrigTree->Branch("trueNeutrinoMomentum_X",&fTrueNeutrinoMomentum_X,"trueNeutrinoMomentum_X/D"); fPhaseIITrigTree->Branch("trueNeutrinoMomentum_Y",&fTrueNeutrinoMomentum_Y,"trueNeutrinoMomentum_Y/D"); fPhaseIITrigTree->Branch("trueNeutrinoMomentum_Z",&fTrueNeutrinoMomentum_Z,"trueNeutrinoMomentum_Z/D"); @@ -341,6 +498,58 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITrigTree->Branch("trueKPlusCher",&fTrueKPlusCher,"trueKPlusCher/I"); fPhaseIITrigTree->Branch("trueKMinus",&fTrueKMinus,"trueKMinus/I"); fPhaseIITrigTree->Branch("trueKMinusCher",&fTrueKMinusCher,"trueKMinusCher/I"); + fPhaseIITrigTree->Branch("trueBJx",&fTrueBJx,"trueBJx/D"); + fPhaseIITrigTree->Branch("truey",&fTruey,"truey/D"); + fPhaseIITrigTree->Branch("trueq0",&fTrueq0,"trueq0/D"); + fPhaseIITrigTree->Branch("trueq3",&fTrueq3,"trueq3/D"); + fPhaseIITrigTree->Branch("trueTargetZ",&fTrueTarget,"trueTargetZ/I"); + fPhaseIITrigTree->Branch("trueW2",&fTrueW2,"trueW2/D"); + } + + if (Reweight_fill){ + fPhaseIITrigTree->Branch("XSecWeights",&fxsec_weights); + fPhaseIITrigTree->Branch("FluxWeights",&fflux_weights); + fPhaseIITrigTree->Branch("weight_All0_UBGenie",&fAll0); + fPhaseIITrigTree->Branch("weight_All1_UBGenie",&fAll1); + fPhaseIITrigTree->Branch("weight_All2_UBGenie",&fAll2); + fPhaseIITrigTree->Branch("weight_All3_UBGenie",&fAll3); + fPhaseIITrigTree->Branch("weight_All4_UBGenie",&fAll4); + fPhaseIITrigTree->Branch("weight_All5_UBGenie",&fAll5); + fPhaseIITrigTree->Branch("weight_AxFFCCQEshape_UBGenie",&fAxFFCCQEshape); + fPhaseIITrigTree->Branch("weight_DecayAngMEC_UBGenie",&fDecayAngMEC); + fPhaseIITrigTree->Branch("weight_NormCCCOH_UBGenie",&fNormCCCOH); + fPhaseIITrigTree->Branch("weight_Norm_NCCOH_UBGenie",&fNorm_NCCOH); + fPhaseIITrigTree->Branch("weight_RPA_CCQE_UBGenie",&fRPA_CCQE); + fPhaseIITrigTree->Branch("weight_RootinoFix_UBGenie",&fRootinoFix); + fPhaseIITrigTree->Branch("weight_ThetaDelta2NRad_UBGenie",&fThetaDelta2NRad); + fPhaseIITrigTree->Branch("weight_Theta_Delta2Npi_UBGenie",&fTheta_Delta2Npi); + fPhaseIITrigTree->Branch("weight_TunedCentralValue_UBGenie",&fTunedCentralValue); + fPhaseIITrigTree->Branch("weight_VecFFCCQEshape_UBGenie",&fVecFFCCQEshape); + fPhaseIITrigTree->Branch("weight_XSecShape_CCMEC_UBGenie",&fXSecShape_CCMEC); + fPhaseIITrigTree->Branch("weight_horncurrent_FluxUnisim",&fhorncurrent); + fPhaseIITrigTree->Branch("weight_expskin_FluxUnisim",&fexpskin); + fPhaseIITrigTree->Branch("weight_piplus_PrimaryHadronSWCentralSplineVariation",&fpiplus); + fPhaseIITrigTree->Branch("weight_piminus_PrimaryHadronSWCentralSplineVariation",&fpiminus); + fPhaseIITrigTree->Branch("weight_kplus_PrimaryHadronFeynmanScaling",&fkplus); + fPhaseIITrigTree->Branch("weight_kzero_PrimaryHadronSanfordWang",&fkzero); + fPhaseIITrigTree->Branch("weight_kminus_PrimaryHadronNormalization",&fkminus); + fPhaseIITrigTree->Branch("weight_pioninexsec_FluxUnisim",&fpioninexsec); + fPhaseIITrigTree->Branch("weight_pionqexsec_FluxUnisim",&fpionqexsec); + fPhaseIITrigTree->Branch("weight_piontotxsec_FluxUnisim",&fpiontotxsec); + fPhaseIITrigTree->Branch("weight_nucleoninexsec_FluxUnisim",&fnucleoninexsec); + fPhaseIITrigTree->Branch("weight_nucleonqexsec_FluxUnisim",&fnucleonqexsec); + fPhaseIITrigTree->Branch("weight_nucleontotxsec_FluxUnisim",&fnucleontotxsec); + } + + //MuonFitter reco track length, vtx, energy; juju + if (MuonFitter_fill) + { + fPhaseIITrigTree->Branch("recoMuonVtxX", &fRecoMuonVtxX, "recoMuonVtxX/D"); + fPhaseIITrigTree->Branch("recoMuonVtxY", &fRecoMuonVtxY, "recoMuonVtxY/D"); + fPhaseIITrigTree->Branch("recoMuonVtxZ", &fRecoMuonVtxZ, "recoMuonVtxZ/D"); + fPhaseIITrigTree->Branch("recoTankTrack", &fRecoTankTrack, "recoTankTrack/D"); + fPhaseIITrigTree->Branch("recoMuonKE", &fRecoMuonKE, "recoMuonKE/D"); + fPhaseIITrigTree->Branch("numMrdLayers", &fNumMrdLayers, "numMrdLayers/I"); } // Reconstructed variables from each step in Muon Reco Analysis @@ -390,6 +599,48 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITrigTree->Branch("deltaAzimuth",&fDeltaAzimuth,"deltaAzimuth/D"); 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; @@ -399,10 +650,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: "<Stores.at("ANNIEEvent")->Get("ClusterMap",m_all_clusters); @@ -434,12 +705,20 @@ bool PhaseIITreeMaker::Execute(){ return false; } } else { + if (MCWaveform){ + get_clusters = m_data->CStore.Get("ClusterMap",m_all_clusters); + if(!get_clusters){ + std::cout << "PhaseIITreeMaker tool: MCWaveform --> no clusters found!" << std::endl; + return false; + } + } else { get_clusters = m_data->CStore.Get("ClusterMapMC",m_all_clusters_MC); if (!get_clusters){ std::cout <<"PhaseIITreeMaker 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 <<"PhaseIITreeMaker tool: No cluster detkeys found!" << std::endl; @@ -449,29 +728,51 @@ bool PhaseIITreeMaker::Execute(){ 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(); + if (isData) { + cluster_size = (int) m_all_clusters->size(); + } else { + if (MCWaveform) { + 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 (isData) { + it_cluster_pair = (*m_all_clusters).begin(); + } else { + if (MCWaveform) { + it_cluster_pair = (*m_all_clusters).begin(); + } else { + it_cluster_pair_mc = (*m_all_clusters_MC).begin(); + } + } + if (cluster_size == 0) loop_map = false; while (loop_map){ //for (std::pair>&& cluster_pair : *m_all_clusters) { Log("PhaseIITreeMaker Tool: Resetting variables prior to getting run level info",v_debug,verbosity); this->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); + + uint64_t primaryTrigTime = 0; + m_data->Stores.at("ANNIEEvent")->Get("PrimaryTriggerTime", primaryTrigTime); - fStartTime_Tree = (ULong64_t) fStartTime; + fStartTime_Tree = (ULong64_t) primaryTrigTime; // ANNIE Event number m_data->Stores.at("ANNIEEvent")->Get("EventTimeTank",fEventTimeTank); fEventTimeTank_Tree = (ULong64_t) fEventTimeTank; @@ -481,10 +782,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); @@ -549,6 +859,19 @@ bool PhaseIITreeMaker::Execute(){ if(verbosity>3) Log("PhaseIITreeMaker Tool: No cluster classifiers. Continuing tree",v_debug,verbosity); } } else { + if (MCWaveform){ + std::vector cluster_hits = it_cluster_pair->second; + fClusterTime = it_cluster_pair->first; + if(TankHitInfo_fill){ + Log("PhaseIITreeMaker Tool: Loading tank cluster hits into cluster tree",v_debug,verbosity); + this->LoadTankClusterHits(cluster_hits); + } + + bool good_class = this->LoadTankClusterClassifiers(it_cluster_pair->first); + if(!good_class){ + if(verbosity>3) Log("PhaseIITreeMaker Tool: No cluster classifiers. Continuing tree",v_debug,verbosity); + } + } else { std::vector cluster_hits = it_cluster_pair_mc->second; fClusterTime = it_cluster_pair_mc->first; std::vector cluster_detkeys = m_all_clusters_detkeys->at(it_cluster_pair_mc->first); @@ -560,21 +883,48 @@ bool PhaseIITreeMaker::Execute(){ if(!good_class){ if(verbosity>3) Log("PhaseIITreeMaker Tool: No cluster classifiers. Continuing tree",v_debug,verbosity); } + bool good_bunch = this->LoadBNBtimingMC(it_cluster_pair_mc->first); + if(!good_bunch){ + if(verbosity>v_debug) Log("PhaseIITreeMaker Tool: No BNB timing (MC). Continuing tree",v_debug,verbosity); + } + } } if(SiPMPulseInfo_fill) this->LoadSiPMHits(); + 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); + } fPhaseIITankClusterTree->Fill(); cluster_num += 1; - if (isData){ - it_cluster_pair++; - if (it_cluster_pair == (*m_all_clusters).end()) loop_map = false; + 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; - } + if (MCWaveform) { + 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; + } + } + } + } } - + if(MRDClusterProcessing){ Log("PhaseIITreeMaker Tool: Beginning MRD cluster processing",v_debug,verbosity); @@ -614,10 +964,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); @@ -690,12 +1050,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; @@ -710,6 +1075,7 @@ bool PhaseIITreeMaker::Execute(){ fNumClusterTracks = this->LoadMRDTrackReco(i); //Get the track info } + if (LAPPDData_fill) this->LoadLAPPDData(); fPhaseIIMRDClusterTree->Fill(); cluster_num += 1; @@ -718,14 +1084,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); @@ -738,11 +1108,20 @@ bool PhaseIITreeMaker::Execute(){ m_data->Stores.at("ANNIEEvent")->Get("TriggerWord",trigword_temp); fTriggerword = int(trigword_temp); m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); - BeamStatus beamstat; - m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); - if (beamstat.ok()) fBeamok = 1; - else fBeamok = 0; - fPot = beamstat.pot(); + 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); @@ -758,6 +1137,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); @@ -765,12 +1145,41 @@ bool PhaseIITreeMaker::Execute(){ // Read hits and load into ntuple if(TankHitInfo_fill){ - this->LoadAllTankHits(isData); + this->LoadAllTankHits(isData, MCWaveform); } if(SiPMPulseInfo_fill) this->LoadSiPMHits(); if(MRDHitInfo_fill) this->LoadAllMRDHits(isData); - + + //DIGITS + if(Digit_fill) this->LoadDigitHits(); + //DIGITS + /* + if(Digit_fill){ + // get digits from RecoDigit store + std::vector* digitList; + auto get_digits=m_data->Stores.at("RecoEvent")->Get("RecoDigit", digitList); + if(not get_digits){ + Log("PhaseIITreeMaker Tool: Failed to retrieve the RecoDigit from RecoEvent Store!",v_error,verbosity); + return false; + } + // Extract the PMT & LAPPD digit information + // =============================== + int totalPMTs =0; // number of digits from PMT hits in the event + int totalLAPPDs = 0; // number of digits from LAPPD hits in the event + //loop through all digits + for(RecoDigit &adigit : *digitList){ + digitX.push_back(adigit.GetPosition().X()); + digitY.push_back(adigit.GetPosition().Y()); + digitZ.push_back(adigit.GetPosition().Z()); + digitT.push_back(adigit.GetCalTime()); + if(adigit.GetDigitType()==0){totalPMTs+=1;} //when the digit type is zero we have a PMT digit + else{totalLAPPDs+=1;}// when it is 1 we have LAPPD + } + Log("PhaseIITreeMaker Tool: Got "+to_string(totalPMTs)+" PMT digits; "+to_string(digitT.size()) +" total digits so far",v_debug,verbosity); + Log("PhaseIITreeMaker Tool: Got "+to_string(totalLAPPDs)+" LAPPD digits; "+to_string(digitT.size()) +" total digits",v_debug,verbosity); + } +*/ if(MRDReco_fill){ fNumClusterTracks=0; @@ -782,6 +1191,12 @@ bool PhaseIITreeMaker::Execute(){ for(int i=0; i < (int) MrdTimeClusters.size(); i++) fNumClusterTracks += this->LoadMRDTrackReco(i); } + if(SimpleReco_fill) this->FillSimpleRecoInfo(); + + if(RingCounting_fill) this->FillRingCountingInfo(); + + if(Reweight_fill) this->FillWeightInfo(); + bool got_reco = false; if(TankReco_fill) got_reco = this->FillTankRecoInfo(); @@ -794,6 +1209,20 @@ bool PhaseIITreeMaker::Execute(){ // FIll tree with all reconstruction information if (RecoDebug_fill) this->FillRecoDebugInfo(); + if (LAPPDData_fill) this->LoadLAPPDData(); + + 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); + } + fPhaseIITrigTree->Fill(); } return true; @@ -817,6 +1246,8 @@ void PhaseIITreeMaker::ResetVariables() { fEventNumber = -9999; fEventTimeTank_Tree = 9999; fNHits = -9999; + fNDigitsPMTs = 0; + fNDigitsLAPPDs = 0; fVetoHit = -9999; fEventTimeMRD_Tree = 9999; fTriggerword = -1; @@ -837,6 +1268,10 @@ void PhaseIITreeMaker::ResetVariables() { fSiPMNum.clear(); } + if(hasBNBtimingMC){ + fbunchTimes = -9999; + } + if(TankClusterProcessing){ fClusterMaxPE = -9999; fClusterChargePointX = -9999; @@ -881,6 +1316,7 @@ void PhaseIITreeMaker::ResetVariables() { fTrueNeutCapE->clear(); fTrueNeutCapGammaE->clear(); fTrueNeutrinoEnergy = -9999; + fTrueNuPDG = -9999; fTrueNeutrinoMomentum_X = -9999; fTrueNeutrinoMomentum_Y = -9999; fTrueNeutrinoMomentum_Z = -9999; @@ -917,6 +1353,45 @@ void PhaseIITreeMaker::ResetVariables() { fTrueKPlusCher = -9999; fTrueKMinus = -9999; fTrueKMinusCher = -9999; + fTrueW2 = -9999; + fTrueBJx = -9999; + fTruey = -9999; + fTrueTarget = -9999; + fTrueq0 = -9999; + fTrueq3 = -9999; + } + + if (Reweight_fill){ + fAll0.clear(); + fAll1.clear(); + fAll2.clear(); + fAll3.clear(); + fAll4.clear(); + fAll5.clear(); + fAxFFCCQEshape.clear(); + fDecayAngMEC.clear(); + fNormCCCOH.clear(); + fNorm_NCCOH.clear(); + fRPA_CCQE.clear(); + fRootinoFix.clear(); + fThetaDelta2NRad.clear(); + fTheta_Delta2Npi.clear(); + fTunedCentralValue.clear(); + fVecFFCCQEshape.clear(); + fXSecShape_CCMEC.clear(); + fpiplus.clear(); + fpiminus.clear(); + fkplus.clear(); + fkzero.clear(); + fkminus.clear(); + fhorncurrent.clear(); + fpioninexsec.clear(); + fpionqexsec.clear(); + fpiontotxsec.clear(); + fexpskin.clear(); + fnucleoninexsec.clear(); + fnucleonqexsec.clear(); + fnucleontotxsec.clear(); } if (RecoDebug_fill){ @@ -996,7 +1471,32 @@ void PhaseIITreeMaker::ResetVariables() { fMRDStop.clear(); fMRDThrough.clear(); } - + if(SimpleReco_fill){ + fSimpleFlag = -9999; + fSimpleEnergy = -9999; + fSimpleVtxX = -9999; + fSimpleVtxY = -9999; + fSimpleVtxZ = -9999; + fSimpleStopVtxX = -9999; + fSimpleStopVtxY = -9999; + fSimpleStopVtxZ = -9999; + fSimpleCosTheta = -9999; + fSimplePt = -9999; + fSimpleFV = -9999; + fSimpleMrdEnergyLoss = -9999; + fSimpleTrackLengthInMRD = -9999; + fSimpleTrackLengthInTank = -9999; + fSimpleMRDStartX = -9999; + fSimpleMRDStartY = -9999; + fSimpleMRDStartZ = -9999; + fSimpleMRDStopX = -9999; + fSimpleMRDStopY = -9999; + fSimpleMRDStopZ = -9999; + } + if(RingCounting_fill){ + fRCSRPred = -9999; + fRCMRPred = -9999; + } if(TankHitInfo_fill){ fIsFiltered.clear(); fHitX.clear(); @@ -1023,6 +1523,79 @@ void PhaseIITreeMaker::ResetVariables() { fDeltaZenith = -9999; fDeltaAngle = -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(); + + } + + //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; + } } bool PhaseIITreeMaker::LoadTankClusterClassifiers(double cluster_time){ @@ -1047,6 +1620,18 @@ bool PhaseIITreeMaker::LoadTankClusterClassifiers(double cluster_time){ return good_classifiers; } +bool PhaseIITreeMaker::LoadBNBtimingMC(double cluster_time){ + Log("PhaseITreeMaker tool: Getting BNB timing (MC)", v_debug, verbosity); + bool got_bnb_times = m_data->Stores.at("ANNIEEvent")->Get("bunchTimes", bunchTimes); + if(!got_bnb_times){ + Log("PhaseITreeMaker tool: BNB timing (MC) not found!", v_debug, verbosity); + } else { + Log("PhaseITreeMaker tool: Setting fbunchTimes variables", v_debug, verbosity); + fbunchTimes = bunchTimes.at(cluster_time); + } + return got_bnb_times; +} + void PhaseIITreeMaker::LoadTankClusterHits(std::vector cluster_hits){ Position detector_center=geom->GetTankCentre(); double tank_center_x = detector_center.X(); @@ -1058,9 +1643,12 @@ void PhaseIITreeMaker::LoadTankClusterHits(std::vector cluster_hits){ fClusterHits = 0; for (int i = 0; i<(int)cluster_hits.size(); i++){ int channel_key = cluster_hits.at(i).GetTubeId(); + Detector* this_detector = geom->ChannelToDetector(channel_key); + if (ApplyDeadMask && this_detector->GetStatus() == detectorstatus::OFF) { + continue; + } 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(); @@ -1104,9 +1692,12 @@ void PhaseIITreeMaker::LoadTankClusterHitsMC(std::vector cluster_hits, st int wcsimid = channelkey_to_pmtid.at(utubeid); unsigned long detkey_data = pmtid_to_channelkey[wcsimid]; int channel_key_data = (int) detkey_data; + Detector* this_detector = geom->ChannelToDetector(tubeid); + if (ApplyDeadMask && this_detector->GetStatus() == detectorstatus::OFF) { + continue; + } 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(); @@ -1248,6 +1839,34 @@ void PhaseIITreeMaker::LoadAllMRDHits(bool IsData){ return; } + +//DIGITS +void PhaseIITreeMaker::LoadDigitHits(){ + // get digits from RecoDigit store + std::vector* digitList; + bool get_digits=false; + get_digits=m_data->Stores.at("RecoEvent")->Get("RecoDigit", digitList); + if(!get_digits){ + Log("PhaseIITreeMaker Tool: Failed to retrieve the RecoDigit from RecoEvent Store!",v_error,verbosity); + return; + } + // Extract the PMT & LAPPD digit information + // =============================== + //loop through all digits + for(RecoDigit &adigit : *digitList){ + fdigitX.push_back(adigit.GetPosition().X()); + fdigitY.push_back(adigit.GetPosition().Y()); + fdigitZ.push_back(adigit.GetPosition().Z()); + fdigitT.push_back(adigit.GetCalTime()); + if(adigit.GetDigitType()==0){fNDigitsPMTs+=1;} //when the digit type is zero we have a PMT digit + else{fNDigitsLAPPDs+=1;}// when it is 1 we have LAPPD + } + Log("PhaseIITreeMaker Tool: Got "+to_string(fNDigitsPMTs)+" PMT digits; "+to_string(fdigitT.size()) +" total digits so far",v_debug,verbosity); + Log("PhaseIITreeMaker Tool: Got "+to_string(fNDigitsLAPPDs)+" LAPPD digits; "+to_string(fdigitT.size()) +" total digits",v_debug,verbosity); + return; +} +//DIGITS + int PhaseIITreeMaker::LoadMRDTrackReco(int SubEventID) { //Check for valid track criteria m_data->Stores["MRDTracks"]->Get("MRDTracks",theMrdTracks); @@ -1317,95 +1936,109 @@ int PhaseIITreeMaker::LoadMRDTrackReco(int SubEventID) { return NumClusterTracks; } -void PhaseIITreeMaker::LoadAllTankHits(bool IsData) { - 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){ - //for(std::pair>&& apair : *Hits){ - 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]; +void PhaseIITreeMaker::LoadAllTankHits(bool isData, bool MCWaveform) { + std::map>* Hits = nullptr; + std::map>* MCHits = nullptr; + bool got_hits = false; + + if (isData) { + got_hits = m_data->Stores["ANNIEEvent"]->Get("Hits", Hits); + } else { + if (MCWaveform) { + got_hits = m_data->Stores["ANNIEEvent"]->Get("Hits", Hits); + } else { + got_hits = m_data->Stores["ANNIEEvent"]->Get("MCHits", MCHits); + } } - 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); - fHitType.push_back(RecoDigit::PMT8inch); // 0 For PMTs + + 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; + + bool loop_tank = true; + int hits_size = (isData || MCWaveform) ? Hits->size() : MCHits->size(); + if (hits_size == 0) loop_tank = false; + + auto it_tank_data = (isData || MCWaveform) ? Hits->begin() : std::map>::iterator(); + auto it_tank_mc = (!isData && !MCWaveform) ? MCHits->begin() : std::map>::iterator(); + + while (loop_tank) { + unsigned long channel_key = (isData || MCWaveform) ? it_tank_data->first : 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 && !MCWaveform) { + int wcsimid = channelkey_to_pmtid.at(channel_key); + channel_key_data = pmtid_to_channelkey[wcsimid]; } - } 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); - fHitType.push_back(RecoDigit::PMT8inch); // 0 For PMTs + + bool SPE_available = false; + + if (ApplyDeadMask && this_detector->GetStatus() == detectorstatus::OFF) { + goto skip_channel; // do not save the hits information for a Dead PMT (if the mask is on), jump to skip_channel + } + + SPE_available = (isData || MCWaveform) ? + (ChannelKeyToSPEMap.find(channel_key) != ChannelKeyToSPEMap.end()) : + (ChannelKeyToSPEMap.find(channel_key_data) != ChannelKeyToSPEMap.end()); + + if (SPE_available) { + if (isData || MCWaveform) { + 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); + fHitType.push_back(RecoDigit::PMT8inch); + } + } 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); + fHitType.push_back(RecoDigit::PMT8inch); + } + } + } + + skip_channel: // skip the block above if the PMT is dead, advance the iterator + if (isData || MCWaveform) { + 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; } - } - } - 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; + return; } bool PhaseIITreeMaker::FillTankRecoInfo() { @@ -1449,6 +2082,75 @@ bool PhaseIITreeMaker::FillTankRecoInfo() { return got_reco_info; } +void PhaseIITreeMaker::FillRingCountingInfo() { + auto* reco_event = m_data->Stores["RecoEvent"]; + if (!reco_event) { + Log("Error: The PhaseIITreeMaker tool could not find the RecoEvent Store", v_error, verbosity); + } + double RCSRPred; + double RCMRPred; + auto get_sr = m_data->Stores["RecoEvent"]->Get("RingCountingSRPrediction",RCSRPred); + auto get_mr = m_data->Stores["RecoEvent"]->Get("RingCountingMRPrediction",RCMRPred); + + if(get_sr && get_mr){ + fRCSRPred = RCSRPred; + fRCMRPred = RCMRPred; + } + else Log("Error: PhaseIITreeMaker tool could not find RingCountingPrediction from RecoEvent Store", v_error, verbosity); + return; +} + +void PhaseIITreeMaker::FillSimpleRecoInfo() { + auto* reco_event = m_data->Stores["RecoEvent"]; + if (!reco_event) { + Log("Error: The PhaseITreeMaker tool could not find the RecoEvent Store", v_error, verbosity); + } + int SimpleRecoFlag; + bool SimpleRecoFV; + double SimpleRecoEnergy, SimpleRecoCosTheta, SimpleRecoPt, SimpleRecoMrdEnergyLoss, SimpleRecoTrackLengthInMRD; + double SimpleRecoTrackLengthInTank; + Position SimpleRecoVtx; + Position SimpleRecoStopVtx; + Position SimpleRecoMRDStart; + Position SimpleRecoMRDStop; + auto get_flag = m_data->Stores["RecoEvent"]->Get("SimpleRecoFlag",SimpleRecoFlag); + auto get_energy = m_data->Stores["RecoEvent"]->Get("SimpleRecoEnergy",SimpleRecoEnergy); + auto get_vtx = m_data->Stores["RecoEvent"]->Get("SimpleRecoVtx",SimpleRecoVtx); + auto get_stopvtx = m_data->Stores["RecoEvent"]->Get("SimpleRecoStopVtx",SimpleRecoStopVtx); + auto get_cos = m_data->Stores["RecoEvent"]->Get("SimpleRecoCosTheta",SimpleRecoCosTheta); + auto get_pt = m_data->Stores["RecoEvent"]->Get("SimpleRecoPt",SimpleRecoPt); + auto get_fv = m_data->Stores["RecoEvent"]->Get("SimpleRecoFV",SimpleRecoFV); + auto get_mrdenergy = m_data->Stores["RecoEvent"]->Get("SimpleRecoMrdEnergyLoss",SimpleRecoMrdEnergyLoss); + auto get_mrdtrack = m_data->Stores["RecoEvent"]->Get("SimpleRecoTrackLengthInMRD",SimpleRecoTrackLengthInMRD); + auto get_tanktrack = m_data->Stores["RecoEvent"]->Get("SimpleRecoTrackLengthInTank",SimpleRecoTrackLengthInTank); + auto get_mrdstart = m_data->Stores["RecoEvent"]->Get("SimpleRecoMRDStart",SimpleRecoMRDStart); + auto get_mrdstop = m_data->Stores["RecoEvent"]->Get("SimpleRecoMRDStop",SimpleRecoMRDStop); + + if(get_flag && get_energy && get_vtx && get_stopvtx && get_cos && get_pt && get_fv && get_mrdenergy && get_mrdtrack && get_mrdstart && get_mrdstop){ + fSimpleFlag = SimpleRecoFlag; + fSimpleEnergy = SimpleRecoEnergy; + fSimpleVtxX = SimpleRecoVtx.X(); + fSimpleVtxY = SimpleRecoVtx.Y(); + fSimpleVtxZ = SimpleRecoVtx.Z(); + fSimpleStopVtxX = SimpleRecoStopVtx.X(); + fSimpleStopVtxY = SimpleRecoStopVtx.Y(); + fSimpleStopVtxZ = SimpleRecoStopVtx.Z(); + fSimpleCosTheta = SimpleRecoCosTheta; + fSimplePt = SimpleRecoPt; + fSimpleFV = (SimpleRecoFV)? 1 : 0; + fSimpleMrdEnergyLoss = SimpleRecoMrdEnergyLoss; + fSimpleTrackLengthInMRD = SimpleRecoTrackLengthInMRD; + fSimpleTrackLengthInTank = SimpleRecoTrackLengthInTank; + fSimpleMRDStartX = SimpleRecoMRDStart.X(); + fSimpleMRDStartY = SimpleRecoMRDStart.Y(); + fSimpleMRDStartZ = SimpleRecoMRDStart.Z(); + fSimpleMRDStopX = SimpleRecoMRDStop.X(); + fSimpleMRDStopY = SimpleRecoMRDStop.Y(); + fSimpleMRDStopZ = SimpleRecoMRDStop.Z(); + } + return; +} + void PhaseIITreeMaker::FillRecoDebugInfo() { // Read Seed candidates std::vector* seedvtxlist = 0; @@ -1674,6 +2376,9 @@ bool PhaseIITreeMaker::FillMCTruthInfo() { bool TrueCC, TrueNC, TrueQEL, TrueDIS, TrueCOH, TrueMEC, TrueRES; int fsNeutrons, fsProtons, fsPi0, fsPiPlus, fsPiPlusCher, fsPiMinus, fsPiMinusCher; int fsKPlus, fsKPlusCher, fsKMinus, fsKMinusCher, TrueNuPDG, TrueFSLeptonPdg; + int TrueTarget; + double TrueW2, TrueBJx, Truey, Trueq0, Trueq3; + double TrueNuIntxVtxDisToEdge; Position TrueFSLeptonVtx; Direction TrueFSLeptonMomentum; Direction TrueNeutrinoMomentum; @@ -1708,12 +2413,20 @@ bool PhaseIITreeMaker::FillMCTruthInfo() { 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); + bool get_w = m_data->Stores["GenieInfo"]->Get("EventW2",TrueW2); + bool get_bjx = m_data->Stores["GenieInfo"]->Get("EventBjx",TrueBJx); + bool get_y = m_data->Stores["GenieInfo"]->Get("Eventy",Truey); + bool get_targetZ = m_data->Stores["GenieInfo"]->Get("TargetZ",TrueTarget); + bool get_q0 = m_data->Stores["GenieInfo"]->Get("Eventq0",Trueq0); + bool get_q3 = m_data->Stores["GenieInfo"]->Get("Eventq3",Trueq3); + bool get_nu_pdg = m_data->Stores["GenieInfo"]->Get("NeutrinoPDG",TrueNuPDG); std::cout <<"get_neutrino_energy: "<Stores.at("ANNIEEvent")->Get("xsec_weights",fxsec_weights); + bool get_flux_weights = m_data->Stores.at("ANNIEEvent")->Get("flux_weights",fflux_weights); + if (get_xsec_weights && get_flux_weights){ + fAll0 = fxsec_weights["All0"]; + fAll1 = fxsec_weights["All1"]; + fAll2 = fxsec_weights["All2"]; + fAll3 = fxsec_weights["All3"]; + fAll4 = fxsec_weights["All4"]; + fAll5 = fxsec_weights["All5"]; + fAxFFCCQEshape = fxsec_weights["AxFFCCQEshape"]; + fDecayAngMEC = fxsec_weights["DecayAngMEC"]; + fNormCCCOH = fxsec_weights["NormCCCOH"]; + fNorm_NCCOH = fxsec_weights["Norm_NCCOH"]; + fRPA_CCQE = fxsec_weights["RPA_CCQE"]; + fRootinoFix = fxsec_weights["RootinoFix"]; + fThetaDelta2NRad = fxsec_weights["ThetaDelta2NRad"]; + fTheta_Delta2Npi = fxsec_weights["Theta_Delta2Npi"]; + fTunedCentralValue = fxsec_weights["TunedCentralValue"]; + fVecFFCCQEshape = fxsec_weights["VecFFCCQEshape"]; + fXSecShape_CCMEC = fxsec_weights["XSecShape_CCMEC"]; + fhorncurrent = fflux_weights["horncurrent_FluxUnisim"]; + fexpskin = fflux_weights["expskin_FluxUnisim"]; + fpiplus = fflux_weights["piplus_PrimaryHadronSWCentralSplineVariation"]; + fpiminus = fflux_weights["piminus_PrimaryHadronSWCentralSplineVariation"]; + fkplus = fflux_weights["kplus_PrimaryHadronFeynmanScaling"]; + fkzero = fflux_weights["kzero_PrimaryHadronSanfordWang"]; + fkminus = fflux_weights["kminus_PrimaryHadronNormalization"]; + fpioninexsec = fflux_weights["pioninexsec_FluxUnisim"]; + fpionqexsec = fflux_weights["pionqexsec_FluxUnisim"]; + fpiontotxsec = fflux_weights["piontotxsec_FluxUnisim"]; + fnucleoninexsec = fflux_weights["nucleoninexsec_FluxUnisim"]; + fnucleonqexsec = fflux_weights["nucleonqexsec_FluxUnisim"]; + fnucleontotxsec = fflux_weights["nucleontotxsec_FluxUnisim"]; + } +} + void PhaseIITreeMaker::FillTruthRecoDiffInfo(bool successful_mcload,bool successful_recoload) { if (!successful_mcload || !successful_recoload) { Log("PhaseIITreeMaker Tool: Error loading True Muon Vertex or Extended Vertex information. Continuing to build remaining tree",v_message,verbosity); @@ -1805,3 +2561,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 1bb0f9789..3153ee0b3 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h @@ -21,6 +21,33 @@ #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" +#include "CLHEP/Random/JamesRandom.h" +#include "Framework/Conventions/KineVar.h" +#include "Framework/EventGen/EventRecord.h" +#include "Framework/Interaction/Interaction.h" +#include "Framework/Interaction/Kinematics.h" +//#include "Framework/Messenger/Messenger.h" +#include "Framework/Utils/AppInit.h" +#include +#include +#include // neut reaction codes +#include +#include +#include +#include +#include +#include +#include +#include +#include "TChain.h" +#include "TVector3.h" +#include "TLorentzVector.h" class PhaseIITreeMaker: public Tool { @@ -41,21 +68,34 @@ class PhaseIITreeMaker: public Tool { int LoadMRDTrackReco(int SubEventNumber); void LoadAllMRDHits(bool IsData); void FillRecoDebugInfo(); + void FillSimpleRecoInfo(); + void FillRingCountingInfo(); + void FillWeightInfo(); void FillTruthRecoDiffInfo(bool got_mc, bool got_reco); + void LoadDigitHits(); /// \brief Summary of Reconstructed vertex void RecoSummary(); void LoadTankClusterHits(std::vector cluster_hits); void LoadTankClusterHitsMC(std::vector cluster_hits,std::vector cluster_detkeys); bool LoadTankClusterClassifiers(double cluster_time); - void LoadAllTankHits(bool IsData); + bool LoadBNBtimingMC(double cluster_time); + void LoadAllTankHits(bool IsData, bool MCWaveform); void LoadSiPMHits(); + void LoadLAPPDData(); + void FillLAPPDData(); + + void FillLAPPDHit(); + void FillLAPPDPulse(); private: //General variables bool isData; + bool MCWaveform; + bool ApplyDeadMask; bool hasGenie; + bool hasBNBtimingMC; std::map* AuxChannelNumToTypeMap; std::map ChannelKeyToSPEMap; @@ -112,7 +152,7 @@ class PhaseIITreeMaker: public Tool { std::vector fSiPMHitT; std::vector fSiPMHitAmplitude; std::vector fSiPMNum; - // Digits + // Digits (Hits) int fNHits = 0; std::vector fIsFiltered; std::vector fHitX; @@ -125,6 +165,15 @@ class PhaseIITreeMaker: public Tool { std::vector fHitDetID; std::vector fHitChankey; std::vector fHitChankeyMC; + + //Digits + int fNDigitsPMTs = 0; + int fNDigitsLAPPDs = 0; + std::vector fdigitX; + std::vector fdigitY; + std::vector fdigitZ; + std::vector fdigitT; + // MRD hit info int fVetoHit; @@ -168,6 +217,10 @@ class PhaseIITreeMaker: public Tool { std::vector fADCWaveformChankeys; std::vector fADCWaveformSamples; + // ************** MC BNB Spill Structure ************* // + std::map bunchTimes; + double fbunchTimes; + // ************ Muon reconstruction level information ******** // std::string MRDTriggertype; std::vector* theMrdTracks; // the reconstructed tracks @@ -226,8 +279,43 @@ class PhaseIITreeMaker: public Tool { std::vector* fTrueNeutCapGammaE = nullptr; int fTrueMultiRing; + //Weights + std::map> fxsec_weights; + std::map> fflux_weights; + std::vector fAll0; + std::vector fAll1; + std::vector fAll2; + std::vector fAll3; + std::vector fAll4; + std::vector fAll5; + std::vector fAxFFCCQEshape; + std::vector fDecayAngMEC; + std::vector fNormCCCOH; + std::vector fNorm_NCCOH; + std::vector fRPA_CCQE; + std::vector fRootinoFix; + std::vector fThetaDelta2NRad; + std::vector fTheta_Delta2Npi; + std::vector fTunedCentralValue; + std::vector fVecFFCCQEshape; + std::vector fXSecShape_CCMEC; + std::vector fpiplus; + std::vector fpiminus; + std::vector fkplus; + std::vector fkzero; + std::vector fkminus; + std::vector fhorncurrent; + std::vector fpioninexsec; + std::vector fpionqexsec; + std::vector fpiontotxsec; + std::vector fexpskin; + std::vector fnucleoninexsec; + std::vector fnucleonqexsec; + std::vector fnucleontotxsec; + //Genie information for event double fTrueNeutrinoEnergy; + int fTrueNuPDG; double fTrueNeutrinoMomentum_X; double fTrueNeutrinoMomentum_Y; double fTrueNeutrinoMomentum_Z; @@ -246,6 +334,12 @@ class PhaseIITreeMaker: public Tool { int fTrueFSLPdg; double fTrueFSLEnergy; double fTrueQ2; + double fTrueW2; + double fTrueBJx; + double fTruey; + double fTrueq0; + double fTrueq3; + int fTrueTarget; int fTrueCC; int fTrueNC; int fTrueQEL; @@ -306,7 +400,33 @@ class PhaseIITreeMaker: public Tool { double fPointVtxDirZ; double fPointVtxFOM; int fPointVtxStatus; + + // Simple Reco + int fSimpleFlag; + double fSimpleEnergy; + double fSimpleVtxX; + double fSimpleVtxY; + double fSimpleVtxZ; + double fSimpleStopVtxX; + double fSimpleStopVtxY; + double fSimpleStopVtxZ; + double fSimpleCosTheta; + double fSimplePt; + int fSimpleFV; + double fSimpleMrdEnergyLoss; + double fSimpleTrackLengthInMRD; + double fSimpleTrackLengthInTank; + double fSimpleMRDStartX; + double fSimpleMRDStartY; + double fSimpleMRDStartZ; + double fSimpleMRDStopX; + double fSimpleMRDStopY; + double fSimpleMRDStopZ; + // Ring Counting + double fRCSRPred; + double fRCMRPred; + // Extended Vertex double fRecoVtxX; double fRecoVtxY; @@ -332,6 +452,13 @@ class PhaseIITreeMaker: public Tool { double fDeltaZenith; double fDeltaAngle; + // MuonFitter vertex + double fRecoMuonVtxX; + double fRecoMuonVtxY; + double fRecoMuonVtxZ; + double fRecoTankTrack; + double fRecoMuonKE; + int fNumMrdLayers; /// \brief Integer that determines the level of logging to perform int verbosity = 0; @@ -352,9 +479,76 @@ class PhaseIITreeMaker: public Tool { bool MCTruth_fill = 0; //Output the MC truth information bool TankReco_fill = 0; bool MRDReco_fill = 0; + bool Reweight_fill = 0; + bool SimpleReco_fill = 0; + bool RingCounting_fill = 0; 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; + + // 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; + + bool Digit_fill = 0; + bool MuonFitter_fill = 0; }; diff --git a/UserTools/PhaseIITreeMaker/README.md b/UserTools/PhaseIITreeMaker/README.md index 7c6a588f9..f153d6456 100644 --- a/UserTools/PhaseIITreeMaker/README.md +++ b/UserTools/PhaseIITreeMaker/README.md @@ -18,39 +18,56 @@ verbose (1 or 0) Defines the level of verbosity for outputs of PhaseIITreeMaker algorithm. OutputFile TestFile.ntuple.root -ClusterProcessing 1 -Process cluster-level trees. Each ntuple entry contains all the PMT hits observed +Output filename + +TankClusterProcessing 1 +Process PMT cluster-level trees. Each ntuple entry contains all the PMT hits observed in a cluster (as defined in the ClusterFinder tool) as well as cluster classifiers (as defined in the ClusterClassifiers tool), along with other general information -(run/subrun number, nhits, SiPM hits, trigger time). +(run/subrun number, nhits, SiPM hits, trigger time). + +MRDClusterProcessing 1 +Process MRD cluster-level trees. Each ntuple entry contains all the MRD hits observed +in a cluster (as defined in the TimeClustering tool), along with other general information +(run/subrun number, nhits, trigger time). TriggerProcessing 1 Process trigger-level trees. Each ntuple entry contains all PMT hits observed for a given trigger, along with other general information (run/subrun number, -nhits,trigger time). +nhits,trigger time,beam parameters). +TankHitInfo_fill 1 +Fill in PMT hit information for all hits (Time,Charge,PE,Position). -HitInfo_fill 1 -Fill in hit information for all hits (Time,Charge,PE,Position). - +MRDHitInfo_fill 1 +Fill in MRD hit information for all hits (Time,Channel ID). SiPMPulseInfo_fill 1 Fill in SiPM pulse information (charge/time/SiPM number). +MRDReco_fill 0 +Fill in track reconstruction parameters defined by the FindMRDTracks tool. + fillCleanEventsOnly (1 or 0) Only fill tree with events that pass the event selection defined in the EventSelector tool. - Reco_fill 0 Fill in final reconstruction parameters estimated using the Tank Reconstruction algorithms. - MCTruth_fill (1 or 0) Input will determine if Truth information from files given is saved to the reco tree. Will output to tree if 1. +Reweight_fill (1 or 0) +Input will determine if reweights from flux and xsec will be saved to tree. +Will output to tree if 1. + +SimpleReco_fill (1 or 0) +Input will determine if info from SimpleReconstruction will be saved to reco +tree. Will output to tree if 1. + muonTruthRecoDiff_fill (1 or 0) Input determines if the difference in truth and reco information is saved to the reco tree. Will output to tree if 1. @@ -61,4 +78,23 @@ reconstruction chain are saved to the tree. Values include seeds from SeedVtxFi fits from PointPosFinder, and FOMs for likelihood fits at each reconstruction step. Will output to tree if 1. +IsData (1 or 0) +Whether the data we are processing is real (Hits) or MC (MCHits). + +ApplyDeadMask (1 or 0) +Whether to include faulty/dead PMTs that may be in the ProcessedData + +PMTWaveformSim (1 or 0) +PMTWaveformSim tool constructs waveforms from MC hits and performs hit finding just like in the data. +If enabled, IsData should also be 0 to signal it is MC. + +HasGenie (1 or 0) +Input determines whether GENIE-level information is loaded by the LoadGENIEEvent tool. + +HasBNBtimingMC (1 or 0) +Input determines whether cluster times (MC) are spill-corrected to produce a BNB-realistic timing structure. +Must have HasGenie 1 and TankClusterProcessing 1 enabled. +(as defined in the AssignBunchTimingMC tool). + ``` + diff --git a/UserTools/PlotWaveforms/Makefile b/UserTools/PlotWaveforms/Makefile index 77048d9c4..4243d55da 100755 --- a/UserTools/PlotWaveforms/Makefile +++ b/UserTools/PlotWaveforms/Makefile @@ -1,3 +1,5 @@ +.NOTPARALLEL: dict.cc + ifndef CXXFLAGS CXXFLAGS = -std=c++1y -O3 endif @@ -14,7 +16,7 @@ ifneq ($(MAKECMDGOALS),clean) CXX = g++ CXXFLAGS += -Wall -Wextra -Wpedantic CXXFLAGS += -Werror -Wno-error=unused-parameter -Wcast-align - + # Add extra compiler flags for recognized compilers (currently just gcc # and clang) CXXVERSION = $(shell $(CXX) --version) @@ -22,7 +24,7 @@ ifneq ($(MAKECMDGOALS),clean) ifneq (,$(findstring clang,$(CXXVERSION))) # clang $(info Compiling using version $(COMPILER_VERSION) of clang) - + # The ROOT headers trigger clang's no-keyword-macro warning, so disable it. CXXFLAGS += -Wno-keyword-macro else @@ -43,7 +45,7 @@ ifneq ($(MAKECMDGOALS),clean) endif endif endif - + ROOTCONFIG := $(shell command -v root-config 2> /dev/null) # prefer rootcling as the dictionary generator executable name, but use # rootcint if you can't find it @@ -52,7 +54,7 @@ ifneq ($(MAKECMDGOALS),clean) ROOTCLING := $(shell command -v rootcint 2> /dev/null) endif ROOT := $(shell command -v root 2> /dev/null) - + ifndef ROOTCONFIG $(error Could not find a valid ROOT installation.) else @@ -69,26 +71,35 @@ ifneq ($(MAKECMDGOALS),clean) endif -dictionary: viewer_linkdef.hh +dict.cc: viewer_linkdef.hh RawViewer.h @echo "making $@" $(RM) dict.* dict*.pcm - $(ROOTCLING) -f dict.cc -c -I ../recoANNIE -I ../../DataModel $(BoostInclude) RawViewer.h viewer_linkdef.hh + MAKEFLAGS= $(ROOTCLING) -f dict.cc -c -I ../../DataModel $(BoostInclude) RawViewer.h viewer_linkdef.hh + +# dict.cc: viewer_linkdef.hh RawViewer.h +# @echo "making $@" +# $(RM) dict.* dict*.pcm +# $(ROOTCLING) -f dict.cc -c -I ../../DataModel $(BoostInclude) RawViewer.h viewer_linkdef.hh -dict.o: dictionary dict.cc +dict.o: dict.cc @echo "making $@" - @cp ../recoANNIE/*.h ../../DataModel/ANNIEconstants.h ../../include/ + @cp ../../DataModel/ANNIEconstants.h ../../DataModel/Constants.h ../../DataModel/RawReader.h ../../DataModel/RawReadout.h ../../DataModel/RawChannel.h ../../DataModel/RawCard.h ../../DataModel/RawTrigData.h ../../include/ $(CXX) $(CXXFLAGS) -fPIC -o $@ -I../../include -L../lib $(ROOT_CXXFLAGS) \ $(ROOT_LDFLAGS) $(BoostInclude) $(BoostLib) -c dict.cc %.o: %.cc @echo "making $@" - $(CXX) $(ROOT_CXXFLAGS) $(CXXFLAGS) -fPIC -I../../include -I ../recoANNIE -I../../DataModel $(BoostInclude) $(BoostLib) -o $@ -c $^ + $(CXX) $(ROOT_CXXFLAGS) $(CXXFLAGS) -fPIC -I../../include -I../../DataModel $(BoostInclude) $(BoostLib) -o $@ -c $^ + +../../DataModel/%.o: ../../DataModel/%.cpp + $(CXX) $(ROOT_CXXFLAGS) $(CXXFLAGS) -fPIC -I../../include -I../../DataModel $(BoostInclude) $(BoostLib) -o $@ -c $^ -libRawViewer.so: dict.o RawViewer.o +libRawViewer.so: dict.o RawViewer.o ../../DataModel/RawReader.o ../../DataModel/RawReadout.o ../../DataModel/RawChannel.o ../../DataModel/RawCard.o ../../DataModel/RawTrigData.o ../../DataModel/RawReader.h ../../DataModel/RawReadout.h ../../DataModel/RawChannel.h ../../DataModel/RawCard.h ../../DataModel/RawTrigData.h ../../DataModel/Constants.h @echo "making $@" $(CXX) $(CXXFLAGS) -fPIC --shared -L../lib -I../../include \ - $(ROOT_CXXFLAGS) $(ROOT_LDFLAGS) \ + $(BoostInclude) $(BoostLib) $(ROOT_CXXFLAGS) $(ROOT_LDFLAGS) \ -Wl,-rpath -Wl,$(libdir):$(shell pwd) dict.o RawViewer.o \ + ../../DataModel/RawReader.o ../../DataModel/RawReadout.o ../../DataModel/RawChannel.o ../../DataModel/RawCard.o ../../DataModel/RawTrigData.o \ -o $@ .INTERMEDIATE: dict.o RawViewer.o dict.cc diff --git a/UserTools/PlotsTrackLengthAndEnergy/PlotsTrackLengthAndEnergy.cpp b/UserTools/PlotsTrackLengthAndEnergy/PlotsTrackLengthAndEnergy.cpp index a8b33ab95..fe934abc8 100644 --- a/UserTools/PlotsTrackLengthAndEnergy/PlotsTrackLengthAndEnergy.cpp +++ b/UserTools/PlotsTrackLengthAndEnergy/PlotsTrackLengthAndEnergy.cpp @@ -40,6 +40,7 @@ bool PlotsTrackLengthAndEnergy::Execute(){ TCanvas c2("c2","c2",1280,1024); TCanvas c3("c3","c3",1280,1024); TCanvas c4("c4","c4",1280,1024); + TCanvas c5("c5","c5",1280,1024); TH2D lengthhist("True_RecoLength", "; MC Track Length [cm]; Reconstructed Track Length [cm]", 50, 0, 400., 50, 0., 400.); TH2D energyhist("True_Reco_Energy", "; E_{MC} [MeV]; E_{reco} [MeV]", 100, 0, 2000., 100, 0., 2000.); @@ -47,9 +48,10 @@ bool PlotsTrackLengthAndEnergy::Execute(){ TH1D lengthresol2("wlambda_max", "Length Resolution", 80, 0, 400); TH1D energyresol1("MC Energy", "Energy Resolution", 100, 0, 2000); TH1D energyresol2("BDT Energy", "Energy Resolution", 100, 0, 2000); + TH1D deltaenergy("Relative Error", "Energy Relative Error %;#DeltaE/E (%)", 100, 0, 0); for(int i=0; i + +#include "ANNIEconstants.h" +#include "PrintADCTraces.h" + +#include "TGraph.h" + +PrintADCTraces::PrintADCTraces():Tool(){} + +// Tool will loop over hits, extract ADC traces from the RecoADCData, and output those traces to a root file + +// output root file structure +// ROOT file: +// ├── chankey/ # directory for each PMT channel +// ├── 332/ +// │ ├── wf1 TGraph # for each pulse, a TGraph +// │ └── wf2 TGraph +// ├── 463/ +// │ ├── wf1 TGraph +// │ └── ... +// └── 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] + + +bool PrintADCTraces::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + // get config variables + + bool gotVerbosity = m_variables.Get("verbosity", verbosity); + if (!gotVerbosity) verbosity = 1; + + // range of hit charges to save + gotPEmin = m_variables.Get("hitPE_min", fhitPEmin); + if (!gotPEmin) { + logmessage = "PrintADCTraces: hitPE_min not defined. No selection will be imposed."; + Log(logmessage, v_error, verbosity); + } + gotPEmax = m_variables.Get("hitPE_max", fhitPEmax); + if (!gotPEmax) { + logmessage = "PrintADCTraces: hitPE_max not defined. No selection will be imposed."; + Log(logmessage, v_error, verbosity); + } + + // save only hit times in a certain range (useful for laser peak or beam spill) + gotTmin = m_variables.Get("hitT_min", fhitTmin); + if (!gotTmin) { + logmessage = "PrintADCTraces: hitT_min not defined. No selection will be imposed."; + Log(logmessage, v_error, verbosity); + } + gotTmax = m_variables.Get("hitT_max", fhitTmax); + if (!gotTmax) { + logmessage = "PrintADCTraces: hitT_max not defined. No selection will be imposed."; + Log(logmessage, v_error, verbosity); + } + + // maximum number of total traces saved - this could explode depending on how many events we run over + bool gotMaxTraces = m_variables.Get("MaxTraces", fMaxTraces); + if (!gotMaxTraces) { + logmessage = "PrintADCTraces: MaxTraces not defined. Using default of 10000."; + Log(logmessage, v_error, verbosity); + fMaxTraces = 10000; + } + + // per individual channel, how many traces do you want? + bool gotMaxTracesPerChan = m_variables.Get("MaxTracesPerChannel", fMaxTracesPerChan); + if (!gotMaxTracesPerChan) { + logmessage = "PrintADCTraces: MaxTracesPerChannel not defined. Setting no limit on traces per channel, will default to filling according to MaxTraces argument."; + Log(logmessage, v_error, verbosity); + fMaxTracesPerChan = 0; + } + + // name of the output root file containing trace data + bool gotOutputFilename = m_variables.Get("OutputFilename", filename); + if (!gotOutputFilename) { + logmessage = "PrintADCTraces: OutputFilename not defined. Setting output file name to: 'ADCTraces.root'"; + Log(logmessage, v_error, verbosity); + filename = "ADCTraces.root"; + } + + // set up output file + fOutFile = new TFile(filename.c_str(), "RECREATE"); + + // 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; +} + +//------------------------------------------------------------------------------ +bool PrintADCTraces::Execute() +{ + Log("PrintADCTraces: Execute()", v_debug, verbosity); + + // *********************************** + // load stores + + bool goodAnnieEvent = m_data->Stores.count("ANNIEEvent"); + if (!goodAnnieEvent) { + logmessage = "PrintADCTraces: no ANNIEEvent store! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // need this for the nQ -> PE conversion + bool gotSPEmap = m_data->CStore.Get("ChannelNumToTankPMTSPEChargeMap",fChannelKeyToSPEMap); + if (!gotSPEmap) { + logmessage = "PrintADCTraces: could not find ChannelNumToTankPMTSPEChargeMap! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // ADCPulse class information (contains the traces) + bool got_recoadc = m_data->Stores["ANNIEEvent"]->Get("RecoADCData",fRecoADCData); + if (!got_recoadc) { + logmessage = "PrintADCTraces: could not find RecoADCData! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // TGraph title will be ____ + int fRunNumber = 9999; + int fPartFileNumber = 9999; + uint64_t fWaveformTime = 0; + + bool gotRunNumber = m_data->Stores["ANNIEEvent"]->Get("RunNumber", fRunNumber); + bool gotPartFile = m_data->Stores["ANNIEEvent"]->Get("PartNumber", fPartFileNumber); + bool gotTimestamp = m_data->Stores["ANNIEEvent"]->Get("EventTimeTank", fWaveformTime); + + if (!gotPartFile || !gotTimestamp || !gotRunNumber) { + logmessage = "PrintADCTraces: Error retrieving "; + if (!gotRunNumber) logmessage += "RunNumber "; + if (!gotPartFile) logmessage += "PartNumber "; + if (!gotTimestamp) logmessage += "EventTimeTank "; + logmessage += "from ANNIEEvent! Setting default (nonsense) values."; + Log(logmessage, v_error, verbosity); + } + + // *********************************** + // write out ADC traces + + fOutFile->cd(); // go to root of output file + + // loop through RecoADCData and fill the graphs with the ADC traces + for (auto& chan_pair : fRecoADCData) { + unsigned long chankey = chan_pair.first; + auto& minibuffers = chan_pair.second; + + int& chanGraphCount = graphsPerChannel[chankey]; + + // make/get directory + std::string chanStr = std::to_string(chankey); + TDirectory* dir = fOutFile->GetDirectory(chanStr.c_str()); + if (!dir) dir = fOutFile->mkdir(chanStr.c_str()); + dir->cd(); + + for (size_t mb_i = 0; mb_i < minibuffers.size(); ++mb_i) { + + // if the max trace limit is reached, stop looping over the minibuffers + if ((fMaxTraces != 0 && totalGraphs >= fMaxTraces) || + (fMaxTracesPerChan != 0 && chanGraphCount >= fMaxTracesPerChan)) { + break; + } + + const auto& pulsevec = minibuffers.at(mb_i); + + 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] + + // need to convert from nQ -> PE using SPE conversion map + auto spe_it = fChannelKeyToSPEMap.find(chankey); + double hitPE = -9999; + if (spe_it != fChannelKeyToSPEMap.end() && spe_it->second > 0) { + hitPE = hitQ / spe_it->second; + } else { + logmessage = "PrintADCTraces: Missing or invalid SPE value for channel " + std::to_string(chankey) + + ". Cannot convert to PE. Using placeholder -9999."; + Log(logmessage, v_warning, verbosity); + } + + // apply hitT and hitPE cuts (skip pulse if it doesn't pass) + bool passTime = (!gotTmin || hitT >= fhitTmin) && (!gotTmax || hitT <= fhitTmax); + bool passPE = (!gotPEmin || hitPE >= fhitPEmin) && (!gotPEmax || hitPE <= fhitPEmax); + if (!passTime || !passPE) continue; + + // construct TGraph title: ____ + std::stringstream grTitle; + grTitle << fRunNumber << "_" << fPartFileNumber << "_" << fWaveformTime + << "_" << std::fixed << std::setprecision(2) << hitT + << "_" << std::fixed << std::setprecision(2) << hitPE; + + // grab trace + const auto& xpts = pulse.GetTraceXPoints(); + const auto& ypts = pulse.GetTraceYPoints(); + + 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()); + gr.SetTitle(grTitle.str().c_str()); + gr.Write(); + + // write to summary TTree + fchan = chankey; + frun = fRunNumber; + feventTime = fWaveformTime; + fhitT = hitT; + fhitPE = hitPE; + fhitBaseline = hitBaseline; + fhitNoise = hitNoise; + fTraceSummaryTree->Fill(); + + ++totalGraphs; + ++chanGraphCount; + } + } + } + + logmessage = "PrintADCTraces: Total graphs written this event: " + std::to_string(totalGraphs); + Log(logmessage, v_debug, verbosity); + + return true; +} + +//------------------------------------------------------------------------------ +bool PrintADCTraces::Finalise() +{ + if (fOutFile) { + + if (fTraceSummaryTree) { // write summary to root file + fOutFile->cd(); + fTraceSummaryTree->Write(); + fTraceSummaryTree = nullptr; + } + + fOutFile->cd(); + fOutFile->Write(); // write all contents to file + fOutFile->Close(); // close the ROOT file + delete fOutFile; // clean up the pointer + fOutFile = nullptr; + } + + Log("PrintADCTraces: Finished and closed output ROOT file.", v_debug, verbosity); + + logmessage = "PrintADCTraces: Total graphs written across all events: " + std::to_string(totalGraphs); + Log(logmessage, v_debug, verbosity); + for (const auto& entry : graphsPerChannel) { + logmessage = " Channel " + std::to_string(entry.first) + + " → " + std::to_string(entry.second) + " graphs"; + Log(logmessage, v_debug, verbosity); + } + + return true; +} + +//------------------------------------------------------------------------------ + +// done diff --git a/UserTools/PrintADCTraces/PrintADCTraces.h b/UserTools/PrintADCTraces/PrintADCTraces.h new file mode 100644 index 000000000..b2319d7d1 --- /dev/null +++ b/UserTools/PrintADCTraces/PrintADCTraces.h @@ -0,0 +1,71 @@ +#ifndef PrintADCTraces_H +#define PrintADCTraces_H + +#include "Tool.h" +#include "TFile.h" +#include "TTree.h" +#include "TGraph.h" +#include "ADCPulse.h" +#include "Hit.h" + +/** + * \class PrintADCTraces + * + * \brief Tool to extract and store ADC traces in TGraphs + * + * $Author: S. Doran $ + * $Date: Apr 2025 $ + * Contact: doran@iastate.edu + */ +class PrintADCTraces: public Tool { + + + public: + + PrintADCTraces(); ///< 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: + + TFile* fOutFile = nullptr; // output root file + TTree* fTraceSummaryTree = nullptr; // summary TTree in root file + int fchan, frun; // branches in summary TTree + uint64_t feventTime; + float fhitT, fhitPE; + float fhitBaseline, fhitNoise; + + int totalGraphs = 0; // keep track how many TGraphs were written + std::map graphsPerChannel; + + float fhitTmin = 0; // config parameters + float fhitTmax = 0; + float fhitPEmin = 0; + float fhitPEmax = 0; + int fMaxTraces = 0; + int fMaxTracesPerChan = 0; + std::string filename; + + bool gotTmin = false; + bool gotTmax = false; + bool gotPEmin = false; + bool gotPEmax = false; + + // maps to Store objects + std::map>> fRecoADCData; + std::map fChannelKeyToSPEMap; + + int verbosity; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; +}; + + +#endif + + + diff --git a/UserTools/PrintADCTraces/README.md b/UserTools/PrintADCTraces/README.md new file mode 100644 index 000000000..583ce8b0b --- /dev/null +++ b/UserTools/PrintADCTraces/README.md @@ -0,0 +1,72 @@ +# 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. + +## Output rootfile + +`PrintADCTraces` produces a root file containing directories for each PMT channel - within each channel will be TGraphs for each ADC trace: + +``` +// ROOT file: +// ├── chankey/ # directory for each PMT channel +// ├── 332/ +// │ ├── wf1 TGraph # for each pulse, a TGraph +// │ └── wf2 TGraph +// ├── 463/ +// │ ├── wf1 TGraph +// │ └── ... +// └── 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] +``` + +where the TGraph name is given by: ```____``` + + +## Configuration +``` +# PrintADCTraces Config File + +verbosity 0 + +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 + # omitting both of these will not impose a time selection + +MaxTraces 10000 # maximum number of traces to include in the root file (default is 10,000 if not set by user) + # if set to '0', no limit will be imposed + +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 +``` + +## Example toolchain +``` +LoadANNIEEvent +LoadGeometry +ClusterFinder (only if you are using the clustered hits) +PrintADCTraces +``` + +## Additional information +- ADC traces will be in ADC (y) vs time [ns] (x). All pulse times will be relative (and zeroed) to the start time of the pulse. All pulse amplitudes (y) are baseline-subtracted. This way its easier to compare. You can cross reference the pulse features with the title (which contains the charge and time of the pulse) to determine more information. +- This tool is similar to `PrintADCData`, but instead of printing out all raw PMT waveforms, it only prints out the found pulse traces (and provides more identifying / filtering information based on charge / time). +- Runtime is ~30s for 10 part files (about the same whether or not `ClusterFinder` is included). +- Filesize for the output root file is ~0.05MB per waveform per channel. If including 100 waveforms per PMT channel(`MaxTracesPerChannel 100`) the filesize is ~5MB, if 1000 the filesize is ~50MB. diff --git a/UserTools/PrintANNIEEvent/PrintANNIEEvent.cpp b/UserTools/PrintANNIEEvent/PrintANNIEEvent.cpp index e80661db3..16e49b726 100644 --- a/UserTools/PrintANNIEEvent/PrintANNIEEvent.cpp +++ b/UserTools/PrintANNIEEvent/PrintANNIEEvent.cpp @@ -301,13 +301,45 @@ bool PrintANNIEEvent::Execute(){ cout <<"RecoADCPulses : {"<= v_debug) { + std::cout << "PrintDQ: Executing tool..." << std::endl; + } + + ResetVariables(); + if (verbosity >= v_debug) { + std::cout << "PrintDQ: Succesfully reset variables" << std::endl; + } + + if (!LoadStores()) // Load info from store + return false; + if (verbosity >= v_debug) { + std::cout << "PrintDQ: Store info loading successful" << std::endl; + } + + if (!GrabVariables()) // Assign variable information for more complex objects + return false; + if (verbosity >= v_debug) { + std::cout << "PrintDQ: Tricky variables assigned successfully" << std::endl; + } + + FindCounts(); + if (verbosity >= v_debug) { + std::cout << "PrintDQ: Succesfully found counts for that ANNIEEvent" << std::endl; + } + + return true; + +} + + +//------------------------------------------------------------------------------ + +bool PrintDQ::Finalise() +{ + + if (verbosity >= v_debug) { + std::cout << "PrintDQ: Calculating rates" << std::endl; + } + + // calculate rates + float_t events_per_cluster = totalclusters / totalevents; + float_t ext_rate_1 = totalext_rate_1 * 100 / totalevents; + float_t ext_rate_2 = totalext_rate_2 * 100 / totalevents; + float_t okay_beam = totalokay_beam * 100 / totalevents; + float_t has_track = totalhas_track * 100 / totalevents; + float_t has_lappd = totalhas_lappd * 100 / totalevents; + float_t has_BRF = totalhas_BRF * 100 / totalevents; + float_t timezero = totaltimezero * 100 / totalevents; + float_t tmrd_coinc = totaltmrd_coinc * 100 / totalevents; + float_t veto_hit = totalveto_hit * 100 / totalevents; + float_t veto_tmrd_coinc = totalveto_tmrd_coinc * 100 / totalevents; + float_t clusters_in_spill = totalclusters_in_spill * 100 / totalclusters; + float_t clusters_in_prompt = totalclusters_in_prompt * 100 / totalclusters; + float_t clusters_in_ext = totalclusters_in_ext * 100 / totalclusters; + + if (verbosity >= v_debug) { + std::cout << "PrintDQ: Calculating errors" << std::endl; + } + + // and errors + float_t er_events_per_cluster = CalculateStatError(totalclusters, totalevents) / 100; // clusters per event is a true rate, not a % + float_t er_ext_rate_1 = CalculateStatError(totalext_rate_1, totalevents); + float_t er_ext_rate_2 = CalculateStatError(totalext_rate_2, totalevents); + float_t er_okay_beam = CalculateStatError(totalokay_beam, totalevents); + float_t er_has_lappd = CalculateStatError(totalhas_lappd, totalevents); + float_t er_has_BRF = CalculateStatError(totalhas_BRF, totalevents); + float_t er_timezero = CalculateStatError(totaltimezero, totalevents); + float_t er_tmrd_coinc = CalculateStatError(totaltmrd_coinc, totalevents); + float_t er_veto_hit = CalculateStatError(totalveto_hit, totalevents); + float_t er_veto_tmrd_coinc = CalculateStatError(totalveto_tmrd_coinc, totalevents); + float_t er_has_track = CalculateStatError(totalhas_track, totalevents); + float_t er_clusters_in_spill = CalculateStatError(totalclusters_in_spill, totalclusters); + float_t er_clusters_in_prompt = CalculateStatError(totalclusters_in_prompt, totalclusters); + float_t er_clusters_in_ext = CalculateStatError(totalclusters_in_ext, totalclusters); + + // output + std::cout << "" << std::endl; + std::cout << "" << std::endl; + std::cout << "**************************************" << std::endl; + std::cout << "Run " << fRunNumber << std::endl; + std::cout << "**************************************" << std::endl; + std::cout << "" << std::endl; + std::cout << "total events: " << totalevents << std::endl; + std::cout << "has LAPPD data: " << totalhas_lappd << " (" << has_lappd << "% +/- " << er_has_lappd << "%)" << std::endl; + std::cout << "has BRF fit: " << totalhas_BRF << " (" << has_BRF << "% +/- " << er_has_BRF << "%)" << std::endl; + std::cout << "eventTimeTank = 0: " << totaltimezero << " (" << timezero << "% +/- " << er_timezero << "%)" << std::endl; + std::cout << "beam_ok: " << totalokay_beam << " (" << okay_beam << "% +/- " << er_okay_beam << "%)" << std::endl; + std::cout << "total clusters: " << totalclusters << " (" << events_per_cluster << " +/- " << er_events_per_cluster << ")" << std::endl; + std::cout << "prompt clusters: " << totalclusters_in_prompt << " (" << clusters_in_prompt << "% +/- " << er_clusters_in_prompt << "%)" << std::endl; + std::cout << "spill clusters: " << totalclusters_in_spill << " (" << clusters_in_spill << "% +/- " << er_clusters_in_spill << "%)" << std::endl; + std::cout << "ext clusters: " << totalclusters_in_ext << " (" << clusters_in_ext << "% +/- " << er_clusters_in_ext << "%)" << std::endl; + std::cout << "extended (CC): " << totalext_rate_1 << " (" << ext_rate_1 << "% +/- " << er_ext_rate_1 << "%)" << std::endl; + std::cout << "extended (NC): " << totalext_rate_2 << " (" << ext_rate_2 << "% +/- " << er_ext_rate_2 << "%)" << std::endl; + std::cout << "Tank+MRD coinc: " << totaltmrd_coinc << " (" << tmrd_coinc << "% +/- " << er_tmrd_coinc << "%)" << std::endl; + std::cout << "1 MRD track: " << totalhas_track << " (" << has_track << "% +/- " << er_has_track << "%)" << std::endl; + std::cout << "Tank+Veto coinc: " << totalveto_hit << " (" << veto_hit << "% +/- " << er_veto_hit << "%)" << std::endl; + std::cout << "Tank+MRD+Veto coinc: " << totalveto_tmrd_coinc << " (" << veto_tmrd_coinc << "% +/- " << er_veto_tmrd_coinc << "%)" << std::endl; + std::cout << "" << std::endl; + std::cout << "" << std::endl; + + // write metrics to .csv file + std::ofstream csv_file("R" + std::to_string(fRunNumber) + "_PrintDQ.csv"); + + if (!csv_file.is_open()) { + Log("PrintDQ Error: Unable to open CSV file for writing", v_error, verbosity); + return false; + } + + csv_file << "Metric,Counts,Rate (%),Rate Error (+/- %)\n"; + WritetoCSV(csv_file, "Total Events", totalevents, 0.0, 0.0); // no corresponding rate for total events + WritetoCSV(csv_file, "Has LAPPD Data", totalhas_lappd, has_lappd, er_has_lappd); + WritetoCSV(csv_file, "Has BRF Fit", totalhas_BRF, has_BRF, er_has_BRF); + WritetoCSV(csv_file, "EventTimeTank = 0", totaltimezero, timezero, er_timezero); + WritetoCSV(csv_file, "Beam OK", totalokay_beam, okay_beam, er_okay_beam); + WritetoCSV(csv_file, "Total Clusters (rate given as clusters / event)", totalclusters, events_per_cluster, er_events_per_cluster); + WritetoCSV(csv_file, "Prompt Clusters", totalclusters_in_prompt, clusters_in_prompt, er_clusters_in_prompt); + WritetoCSV(csv_file, "Spill Clusters", totalclusters_in_spill, clusters_in_spill, er_clusters_in_spill); + WritetoCSV(csv_file, "Ext Clusters", totalclusters_in_ext, clusters_in_ext, er_clusters_in_ext); + WritetoCSV(csv_file, "Extended (CC)", totalext_rate_1, ext_rate_1, er_ext_rate_1); + WritetoCSV(csv_file, "Extended (NC)", totalext_rate_2, ext_rate_2, er_ext_rate_2); + WritetoCSV(csv_file, "Tank+MRD Coinc", totaltmrd_coinc, tmrd_coinc, er_tmrd_coinc); + WritetoCSV(csv_file, "1 MRD Track", totalhas_track, has_track, er_has_track); + WritetoCSV(csv_file, "Tank+Veto Coinc", totalveto_hit, veto_hit, er_veto_hit); + WritetoCSV(csv_file, "Tank+MRD+Veto Coinc", totalveto_tmrd_coinc, veto_tmrd_coinc, er_veto_tmrd_coinc); + + csv_file.close(); + + std::cout << "Run metrics written to " << "R" + std::to_string(fRunNumber) + "_PrintDQ.csv" << std::endl; + std::cout << "" << std::endl; + + return true; +} + +//------------------------------------------------------------------------------ + +void PrintDQ::FindCounts() { + + // total beam triggers (UBT only) + int trigger_index = -1; // Default to -1 if not found + if (!fGroupedTriggerWord.empty()) { + for (size_t k = 0; k < fGroupedTriggerWord.size(); k++) { + if ((fGroupedTriggerWord)[k] == 14) { + trigger_index = static_cast(k); + break; + } + } + } + + if (trigger_index != -1) { // There is a beam trigger + Log("PrintDQ: We found an undelayed beam trigger!", v_debug, verbosity); + + totalevents++; + + + if (fBeamok == 1) { + totalokay_beam++; // all subsequent rates are based on the number of "good" beam triggers + Log("PrintDQ: beam_ok = 1 for this event", v_debug, verbosity); + } + + + // events with eventTimeTank == 0 (weird issue where ADV waveforms don't get timestamps) + if (fEventTimeTank == 0){ + totaltimezero++; + Log("PrintDQ: eventTimeTank = 0 for this event", v_debug, verbosity); + } + + + // Extended readout rates (1 = charge-based, 2 = forced, random) + if (fExtended == 1){ + totalext_rate_1++; + Log("PrintDQ: ext = 1 for this event", v_debug, verbosity); + } + if (fExtended == 2){ + totalext_rate_2++; + Log("PrintDQ: ext = 2 for this event", v_debug, verbosity); + } + + + // Does the event have LAPPDs? + if (fHasLAPPD == 1) { + totalhas_lappd++; + Log("PrintDQ: ext = 2 for this event", v_debug, verbosity); + } + + + // coincidences + if (fNoVeto == 0) { + totalveto_hit++; // opposite logic to NoVeto + Log("PrintDQ: Tank+Veto coincidence for this event", v_debug, verbosity); + } + if (fPMTMRDCoinc == 1) { + totaltmrd_coinc++; // Tank + MRD + if (fNoVeto == 0) { + totalveto_tmrd_coinc++; // Veto + Tank + MRD + Log("PrintDQ: Tank+Veto+MRD coincidence for this event", v_debug, verbosity); + } + // find MRD tracks + // Search through the MRD cluster array to see if any of them had a single track. If thats the case (and there was TankMRDCoinc), we can say there was a track + if (std::find(fNumClusterTracks.begin(), fNumClusterTracks.end(), 1) != fNumClusterTracks.end()) { + totalhas_track++; + Log("PrintDQ: Tank+MRD coincidence + 1 MRD Track for this event", v_debug, verbosity); + } + } + + + // Does the event have a usable BRF signal (+ fit) + if (fBRFFirstPeakFit != 0) { + totalhas_BRF++; + Log("PrintDQ: BRF fit found for this event", v_debug, verbosity); + } + + + // find total number of clusters, and how many of the prompt clusters are in the beam spill + Log("*************** Looking at clusters *****************", v_debug, verbosity); + for (size_t j = 0; j < fClusterTime.size(); j++) { // loop over all clusters + Log("######################################################", v_debug, verbosity); + + totalclusters++; + + std::ostringstream ct_message; + ct_message << "PrintDQ: PMT Cluster found, with time " << fClusterTime.at(j) << " ns"; + Log(ct_message.str(), v_debug, verbosity); + + if (fClusterTime[j] < 2000) { // cluster is in prompt window + totalclusters_in_prompt++; + Log("PrintDQ: cluster is in the prompt window (<2us)", v_debug, verbosity); + + if (fClusterTime[j] > 190 && fClusterTime[j] < 1750) { // based on expected beam spill structure from data + totalclusters_in_spill++; + Log("PrintDQ: cluster is in the beam spill (190:1750ns)", v_debug, verbosity); + } + } + else { + totalclusters_in_ext++; // clusters in the ext window + + Log("PrintDQ: cluster is in the ext window (>2us)", v_debug, verbosity); + } + } + Log("*****************************************************", v_debug, verbosity); + + } + +} + + +//------------------------------------------------------------------------------ + +float PrintDQ::CalculateStatError(float numerator, float denominator) { + + // return 0 if denom/numerator = 0 to avoid errors + if (denominator == 0 || numerator == 0) { + return 0; + } + + // Calculate stat error: sqrt( (dN/N)^2 + (dD/D)^2 ) * (N/D), where N/D is the rate + float relative_error_numerator = sqrt(numerator) / numerator; + float relative_error_denominator = sqrt(denominator) / denominator; + float total_relative_error = sqrt((relative_error_numerator * relative_error_numerator) + + (relative_error_denominator * relative_error_denominator)); + + // The error in the ratio is: ratio * total_relative_error + float ratio = 100 * numerator / denominator; // (needs to be multiplied by 100 as we are expressing them as %'s) + return ratio * total_relative_error; +} + + +//------------------------------------------------------------------------------ + +bool PrintDQ::LoadStores() +{ + // grab necessary information from Stores, and calculate other necessary parameters + + bool get_run = m_data->Stores["ANNIEEvent"]->Get("RunNumber", fRunNumber); + if (!get_run) { + Log("PrintDQ: RunNumber not found in the ANNIEEvent!", v_debug, verbosity); + } + + bool get_ext = m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); + if (!get_ext) { + Log("PrintDQ: no Extended Variable in the ANNIEEvent!", v_debug, verbosity); + } + + bool get_ETT = m_data->Stores["ANNIEEvent"]->Get("EventTimeTank", fEventTimeTank); + if (!get_ETT) { + Log("PrintDQ: no EventTimeTank in the ANNIEEvent!", v_debug, verbosity); + } + + bool get_veto = m_data->Stores["RecoEvent"]->Get("NoVeto", fNoVeto); + if (!get_veto) { + Log("PrintDQ: NoVeto not present in the RecoEvent! Are you sure you ran the EventSelector tool?", v_debug, verbosity); + } + + bool get_coinc = m_data->Stores["RecoEvent"]->Get("PMTMRDCoinc", fPMTMRDCoinc); + if (!get_coinc) { + Log("PrintDQ: PMTMRDCoinc not present in the RecoEvent! Are you sure you ran the EventSelector tool?", v_debug, verbosity); + } + + bool get_lappd = m_data->Stores["ANNIEEvent"]->Get("DataStreams", fDataStreams); + if (!get_lappd) { + Log("PrintDQ: DataStreams (used for hasLAPPD) not present in the ANNIEEvent!", v_debug, verbosity); + } + + bool get_BRF = m_data->Stores["ANNIEEvent"]->Get("BRFFirstPeakFit", fBRFFirstPeakFit); + if (!get_BRF) { + Log("PrintDQ: BRFFirstPeakFit not present in the ANNIEEvent! Are you sure you ran the FitRWMWaveform tool?", v_debug, verbosity); + } + + bool get_beam = m_data->Stores["ANNIEEvent"]->Get("beam_good", fBeamok); + if (!get_beam) { + Log("PrintDQ: no beam_good in the ANNIEEvent!", v_debug, verbosity); + } + + // Grouped Triggers + bool get_GT = m_data->Stores["ANNIEEvent"]->Get("GroupedTrigger", fGroupedTrigger); + if (!get_GT) { + Log("PrintDQ: no GroupedTrigger in the ANNIEEvent!", v_debug, verbosity); + } + + // PMT clusters (need the ClusterFinder tool) + bool get_Clusters = m_data->CStore.Get("ClusterMap", fClusterMap); + if (!get_Clusters) { + Log("PrintDQ: no ClusterMap in the CStore! Did you run the ClusterFinder tool?", v_debug, verbosity); + } + + // MRD Tracks (TimeClustering and FindMRDTracks tools) + bool get_mrdclusters = m_data->CStore.Get("MrdTimeClusters", fMrdTimeClusters); + if (!get_mrdclusters) { + Log("PrintDQ: No MRD clusters found! Did you run the TimeClustering tool?", v_debug, verbosity); + } + + return true; + +} + + +//------------------------------------------------------------------------------ + +void PrintDQ::ResetVariables() { + + // initialize to 0; if we dont find them in the Store, we want their counts to be 0 + fRunNumber = 0; + fExtended = 0; + fEventTimeTank = 0; + fNoVeto = 0; + fPMTMRDCoinc = 0; + fHasLAPPD = 0; + fBRFFirstPeakFit = 0; + fBeamok = 0; + + fClusterTime.clear(); + fGroupedTrigger.clear(); + fGroupedTriggerTime.clear(); + fGroupedTriggerWord.clear(); + fNumClusterTracks.clear(); + fDataStreams.clear(); + +} + + +//------------------------------------------------------------------------------ + +bool PrintDQ::GrabVariables() { + + // HasLAPPD + Log("PrintDQ: Seeing if DataStreams has LAPPDs", v_debug, verbosity); + if (fDataStreams["LAPPD"] == 1) + fHasLAPPD = 1; + else + fHasLAPPD = 0; + + // load grouped trigger info + Log("PrintDQ: Accessing GroupedTriggers", v_debug, verbosity); + for (std::map::iterator it = fGroupedTrigger.begin(); it != fGroupedTrigger.end(); ++it) + { + uint64_t key = it->first; + uint32_t value = it->second; + + fGroupedTriggerTime.push_back(key); + fGroupedTriggerWord.push_back(value); + } + + // load cluster time info + Log("PrintDQ: Accessing pairs in the cluster map", v_debug, verbosity); + for (std::pair>&& apair : *fClusterMap) { + double thisClusterTime = apair.first; // grab avg hit time of the cluster (clusterTime) + fClusterTime.push_back(thisClusterTime); + } + + // load MRD clusters and tracks + Log("PrintDQ: Accessing MRD Clusters", v_debug, verbosity); + int SubEventID; + for (int i = 0; i < (int)fMrdTimeClusters.size(); i++) { + + SubEventID = i; + + // Check for valid Track criteria + bool get_tracks = m_data->Stores["MRDTracks"]->Get("MRDTracks", ftheMrdTracks); + bool get_numtracks = m_data->Stores["MRDTracks"]->Get("NumMrdTracks", fnumtracksinev); + + int NumClusterTracks = 0; + Log("PrintDQ: Finding MRD Tracks", v_debug, verbosity); + for (int tracki = 0; tracki < fnumtracksinev; tracki++) { + + NumClusterTracks += 1; + BoostStore *thisTrackAsBoostStore = &(ftheMrdTracks->at(tracki)); + int TrackEventID = -1; + thisTrackAsBoostStore->Get("MrdSubEventID", TrackEventID); + if (TrackEventID != SubEventID) + continue; + + // If we're here, this track is associated with this cluster + + NumClusterTracks += 1; + } + + // get the track info + int ThisMRDClusterTrackNum = NumClusterTracks; + fNumClusterTracks.push_back(ThisMRDClusterTrackNum); + + } + + return true; +} + + +//------------------------------------------------------------------------------ + +void PrintDQ::WritetoCSV(std::ofstream& file, const std::string& metric, int count, float percentage, float error) { + file << metric << "," << count << "," << percentage << "," << error << "\n"; +} + + +// ************************************************************************* // + +// done diff --git a/UserTools/PrintDQ/PrintDQ.h b/UserTools/PrintDQ/PrintDQ.h new file mode 100644 index 000000000..a57c66fab --- /dev/null +++ b/UserTools/PrintDQ/PrintDQ.h @@ -0,0 +1,90 @@ +#ifndef PrintDQ_H +#define PrintDQ_H + +#include +#include + +#include "Tool.h" +#include "Hit.h" + + +/** + * \class PrintDQ + * + * A tool to print out statistics about processed runs for better Data Quality monitoring +* +* $Author: S.Doran $ +* $Date: 2024/10/17 $ +* Contact: doran@iastate.edu +*/ +class PrintDQ: public Tool { + + public: + + PrintDQ(); ///< 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 LoadStores(); ///< Loads all relevant information from the store and some other parameters, away from the Execute function + void ResetVariables(); ///< Clearing maps and resetting variables + bool GrabVariables(); ///< Assign values to tricky variables (clusterTime, Grouped Triggers, MRD Tracks) + void FindCounts(); ///< Loop over extracted event information and count them up + float CalculateStatError(float numerator, float denominator); ///< Statistical error calculation for the rates + void WritetoCSV(std::ofstream& file, const std::string& metric, + int count, float percentage, float error); ///< Write each row of metrics to a .csv file + + private: + + std::map> *fClusterMap = nullptr; ///< All clusters + std::vector> fMrdTimeClusters; ///< All MRD clusters + std::vector *ftheMrdTracks; ///< the reconstructed MRD tracks + std::map fDataStreams; ///< Tank, MRD, LAPPD data streams + std::map fGroupedTrigger; ///< collection of triggers for a single event + vector fGroupedTriggerTime; ///< corresponding timestamp for each trigger + vector fGroupedTriggerWord; ///< corresponding trigger number for each trigger + vector fClusterTime; ///< PMT cluster times + std::vector fNumClusterTracks; ///< MRD Tracks corresponding to MRD clusters (NumClusterTracks) + + int fRunNumber; ///< run number (tool assumes you're running over 1 run at a time) + int fExtended; ///< extended window trigger (0 = none, 1 = charge-based, 2 = forced) + ULong64_t fEventTimeTank; ///< ADC waveform timestamp + bool fNoVeto; ///< was the veto hit in coincidence with tank PMT activity? (NoVeto = 1 is no coincidence activity) + bool fPMTMRDCoinc; ///< was there an MRD cluster in coincidence with tank PMT activity? + double fBRFFirstPeakFit; ///< first peak of the BRF waveform, Gaussian fit + int fBeamok; ///< beam "ok" condition: (0.5e12 < pot < 8e12), (172 < horn val < 176), (downstream/upstream toroids within 5%) + int fnumtracksinev; ///< number of MRD tracks found in the event + int fHasLAPPD; ///< whether DataStreams contains LAPPDs + + /// *** description of print output from the tool *** + // counts across all events /// total counts (% / rate) --> other variables expressed as out of "total events" are out of "total events with undelayed beam triggers" + float_t totalclusters; ///< total clusters (clusters per event; not a %) + float_t totalevents; ///< total events with an undelayed beam trigger (no rate/%) + float_t totalclusters_in_prompt; ///< total clusters in prompt window (% out of total clusters) + float_t totalclusters_in_ext; ///< total clusters in ext window (% out of total clusters) + float_t totalclusters_in_spill; ///< total clusters in spill (190:1750ns) (% out of total clusters) + float_t totalext_rate_1; ///< total extended windows (CC, charge based) (% out of total events) + float_t totalext_rate_2; ///< total extended windows (NC, forced readout) (% out of total events) + float_t totalokay_beam; ///< total events with "beam_ok" condition (% out of total events) + float_t totaltmrd_coinc; ///< total events with PMT+MRD coincidence (% out of total events) + float_t totalveto_hit; ///< total events with PMR+Veto coicidence (% out of total events) + float_t totalveto_tmrd_coinc; ///< total events with PMT+MRD+Veto coincidence (% out of total events) + float_t totalhas_track; ///< total events with at least one instance of a single MRD track for a given MRD cluster (% out of total events) + float_t totalhas_lappd; ///< total events with LAPPD data present in the data stream (% out of total events) + float_t totalhas_BRF; ///< total events with a fit to the BRF waveform (% out of total events) + float_t totaltimezero; ///< total events with no timestamp for the ADC waveforms (% out of total events) + + + + /// \brief verbosity levels: if 'verbosity' < this level, the message type will be logged. + int verbosity; + int v_error=0; // STOP THE SHOW + int v_warning=1; // this and below the show will go on + int v_message=2; + int v_debug=3; + std::string logmessage; + +}; + + +#endif \ No newline at end of file diff --git a/UserTools/PrintDQ/README.md b/UserTools/PrintDQ/README.md new file mode 100644 index 000000000..b1d9a809f --- /dev/null +++ b/UserTools/PrintDQ/README.md @@ -0,0 +1,64 @@ +# PrintDQ + +`PrintDQ` is a quick, easy to use data quality (DQ) tool that prints out run statistics. It's to be used over the beam ProcessedData created by the event building toolchain. This tool works by loading in `ANNIEEvent`, `RecoEvent`, `ClusterMap`, and `MrdTimeClusters` information, counting and calculating rates based on how many events fit various selection criteria. `PrintDQ` accesses PMT/MRD clusters, MRD tracks, and BRF fitting results, so it is necessary to run the following tools beforehand to ensure it executes properly: + +- `LoadANNIEEvent` +- `LoadGeometry` +- `TimeClustering` +- `FindMRDTracks` +- `ClusterFinder` +- `ClusterClassifiers` +- `EventSelector` +- `FitRWMWaveform` (new, PR #289) + +## Data + +`PrintDQ` prints out the run statistics and does not add anything to the Store. It also populates a .csv file with the same statistics (`R_PrintDQ.csv`). Here's an example of the print output from the tool: +``` +************************************** +Run 4314 +************************************** + +total events: 6336 +has LAPPD data: 121 (1.90972% +/- 0.175261%) +has BRF fit: 6324 (99.8106% +/- 1.77415%) +eventTimeTank = 0: 29 (0.457702% +/- 0.0851874%) +beam_ok: 5018 (79.1982% +/- 1.49664%) +total clusters: 279 (0.0440341 +/- 0.00269367) +prompt clusters: 273 (97.8495% +/- 8.32999%) +spill clusters: 236 (84.5878% +/- 7.48089%) +ext clusters: 6 (2.15054% +/- 0.887344%) +extended (CC): 0 (0% +/- 0%) +extended (NC): 31 (0.489268% +/- 0.0880898%) +Tank+MRD coinc: 14 (0.22096% +/- 0.0591191%) +1 MRD track: 5 (0.0789141% +/- 0.0353054%) +Tank+Veto coinc: 30 (0.473485% +/- 0.0866505%) +Tank+MRD+Veto coinc: 4 (0.0631313% +/- 0.0315756%) +``` + +- `total events` = total events with an undelayed beam trigger (14) +- `has LAPPD data` = events where the Data Steams contains LAPPDs (% given out of total undelayed beam trigger events) +- `has BRF fit` = events where the BRF auxiliary waveform was successfully fit (% given out of total undelayed beam trigger events) +- `eventTimeTank` = events that have no timestamps for their ADC waveform for some reason (% given out of total undelayed beam trigger events) +- `beam_ok` = events with "good" beam conditions, as extracted by the BeamFetcherV2 tool (% given out of total undelayed beam trigger events). Good beam conditions are defined as: (0.5e12 < pot < 8e12), (172 < horn val < 176), (downstream/upstream toroids within 5%) +- `total clusters` = total number of clusters found in the events with an undelayed beam trigger (rate given as clusters per event) +- `prompt clusters` = total number of clusters found in the prompt 2us window (% given out of the total number of clusters) +- `spill clusters` = total number of clusters found in the beam spill: 190:1750ns (% given out of the total number of clusters) +- `ext clusters` = total number of clusters found in the extended window: >2us (% given out of the total number of clusters) +- `extended (CC)` = total number of events with an extended window, CC/charge-based readout (% given out of total undelayed beam trigger events) +- `extended (NC)` = total number of events with an extended window, NC/random/forced readout (% given out of total undelayed beam trigger events) +- `Tank+MRD coinc` = total number of events with Tank + MRD coincidence (% given out of total undelayed beam trigger events) - coincidence defined in the `EventSelector` tool. +- `1 MRD Track` = total events with at least one instance of a single MRD track for a given MRD cluster (% given out of total undelayed beam trigger events) +- `Tank+Veto coinc` = total number of events with Tank + Veto coincidence (% given out of total undelayed beam trigger events) - coincidence defined in the `EventSelector` tool. +- `Tank+MRD+Veto coinc` = total number of events with Tank + MRD + Veto coincidence (% given out of total undelayed beam trigger events) - coincidences defined in the `EventSelector` tool. + +## Configuration +``` +# PrintDQ Config File + +verbosity 0 +``` + +## Additional information + +This tool is meant for quick feedback on beam runs. Various statistics will be blank/missing if ran over source runs (but the tool should still work). The `LoadANNIEEvent` tool (to be run beforehand) loads in the ProcessedData via a `my_inputs.txt` file - make sure to populate this list with a single run's worth of part files. The tool is intended to be used over just one run at a time to provide an accurate snapshot of the run's conditions. This tool within a suitable toolchain may take several minutes depending on how many part files are present in the run (and on verbosity levels). diff --git a/UserTools/ProcessedLAPPDFilter/ProcessedLAPPDFilter.cpp b/UserTools/ProcessedLAPPDFilter/ProcessedLAPPDFilter.cpp new file mode 100644 index 000000000..8fb4ff3e0 --- /dev/null +++ b/UserTools/ProcessedLAPPDFilter/ProcessedLAPPDFilter.cpp @@ -0,0 +1,703 @@ +#include "ProcessedLAPPDFilter.h" + +ProcessedLAPPDFilter::ProcessedLAPPDFilter() : Tool() {} + +bool ProcessedLAPPDFilter::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 + ///////////////////////////////////////////////////////////////// + + FilterVerbosity = 0; + m_variables.Get("FilterVerbosity", FilterVerbosity); + requirePulsedAmp = 15; + m_variables.Get("requirePulsedAmp", requirePulsedAmp); + requirePulsedStripNumber = 7; + m_variables.Get("requirePulsedStripNumber", requirePulsedStripNumber); + + saveAllLAPPDEvents = false; + m_variables.Get("saveAllLAPPDEvents", saveAllLAPPDEvents); + savePMTClusterEvents = false; + m_variables.Get("savePMTClusterEvents", savePMTClusterEvents); + + MRDDataName = "FilteredMRDData"; + MRDNoVetoDataName = "FilteredMRDNoVetoData"; + m_variables.Get("MRDDataName", MRDDataName); + m_variables.Get("MRDNoVetoDataName", MRDNoVetoDataName); + + AllLAPPDDataName = "FilteredAllLAPPDData"; + m_variables.Get("AllLAPPDDataName", AllLAPPDDataName); + PMTClusterDataName = "FilteredPMTClusterData"; + m_variables.Get("PMTClusterDataName", PMTClusterDataName); + + filterType = "MRDtrack"; // MRDtrack and pmt cluster + // filterType = "PMTCluster"; // pmt cluster only + m_variables.Get("filterType", filterType); + + RequireNoVeto = false; + m_variables.Get("RequireNoVeto", RequireNoVeto); + RequireCherenkovCover = false; + m_variables.Get("RequireCherenkovCover", RequireCherenkovCover); + + FilteredMRD = new BoostStore(false, 2); // all events with MRD in it //if gotEventMRD = true; + FilteredMRDNoVeto = new BoostStore(false, 2); // all events with MRD but no veto// if gotEventMRD && gotEventMRDNoVeto = true + FilteredAllLAPPD = new BoostStore(false, 2); // all events with LAPPD data + FilteredPMTCluster = new BoostStore(false, 2); // all events with PMT cluster + + gotEventMRD = false; + gotEventMRDNoVeto = false; + gotEventPMTCluster = false; + + EventPMTClusterNumber = 0; + EventMRDNumber = 0; + EventMRDNoVetoNumber = 0; + CurrentExeNumber = 0; + pairedEventNumber = 0; + PsecDataNumber = 0; + PMTClusterEventNum = 0; + + passCutEventNumber = 0; + + return true; +} + +bool ProcessedLAPPDFilter::Execute() +{ + + uint64_t ETT = 0; + bool gotETT = m_data->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/ReweightEventsGenie/README.md b/UserTools/ReweightEventsGenie/README.md deleted file mode 100644 index 4f7e02ef0..000000000 --- a/UserTools/ReweightEventsGenie/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# ReweightEventsGenie - -ReweightEventsGenie - -## Data - -Describe any data formats ReweightEventsGenie creates, destroys, changes, or analyzes. E.G. - -**flux_weights** `map>` -* Beam flux weight systematics - -**xsec_weights** `map>` -* Cross section weight systematics - -**MCisCC** `bool` -* Truth. Is the event CC? - -**MCQsquared** `double` -* True momentum transfer squared - -**MCNuPx** `double` -**MCNuPy** `double` -**MCNuPz** `double` -**MCNuE** `double` -**MCNuPDG** `int` -* True neutrino momentum, energy, and PDG - -**MCTgtPx** `double` -**MCTgtPy** `double` -**MCTgtPz** `double` -**MCTgtE** `double` -**MCTgtPDG** `int` -**MCTgtisP** `bool` -**MCTgtisN** `bool` -* True target momentum, energy, PDG, and is the target a proton or neutron - -**MCFSLPx** `double` -**MCFSLPy** `double` -**MCFSLPz** `double` -**MCFSLE** `double` -**MCFSLm** `double` -* True final state lepton momentum, energy, and mass - -**MC0pi0** `bool` -* Truth. There are no neutral charged pions in this event. - -**MC0piPMgt160** `bool` -* Truth. There are no charged pions above Cherenkov threshold in this event. - - - -## Configuration - -Describe any configuration variables for ReweightEventsGenie. - -``` -param1 key1:value1|key2:value2|key3:value3 -``` diff --git a/UserTools/ReweightEventsGenie/ReweightEventsGenie.cpp b/UserTools/ReweightEventsGenie/ReweightEventsGenie.cpp deleted file mode 100644 index 0d5be4f29..000000000 --- a/UserTools/ReweightEventsGenie/ReweightEventsGenie.cpp +++ /dev/null @@ -1,863 +0,0 @@ -#include "ReweightEventsGenie.h" -#include "GenieInfo.h" -#include "TMap.h" -#include "TArrayF.h" -#include "TString.h" - - -#define LOADED_GENIE 1 - -/** - * \class ReweightEventsGenie - * Loads GENIE events and handles event weights for flux and cross section systematics studies - * -* Ported in parts from LoadGenieEvent -* $Author: B.Richards -* $Date: 2019/05/28 10:44:00 -* Contact: b.richards@qmul.ac.uk -* -* UBGenieWeightCalc.cxx -* Ported from larsim back to uboonecode on Mar 13 2020 -* by Steven Gardiner -* Heavily rewritten on Dec 9 2019 -* by Steven Gardiner -* Updated by Marco Del Tutto on Feb 18 2017 -* Ported from uboonecode to larsim on Feb 14 2017 -* by Marco Del Tutto -* -* Ported and updated to ANNIE ToolChain Framework -* $Author: James Minock -* $Date: 2023/02/09 -* Contact: jmm1018@physics.rutgers.edu - -*/ -ReweightEventsGenie::ReweightEventsGenie():Tool(){} - -bool ReweightEventsGenie::Initialise(std::string configfile, DataModel &data){ -//#if LOADED_GENIE==1 - /////////////////// Useful header /////////////////////// - if(configfile!="") m_variables.Initialise(configfile); // loading config file - //m_variables.Print(); - m_data= &data; //assigning transient data pointer - ///////////////////////////////////////////////////////////////// - m_variables.Get("verbosity",verbosity); - m_variables.Get("FluxVersion",fluxver); // flux version: 0=rhatcher files, 1=zarko files(gsimple) - m_variables.Get("FromWCSim",fromwcsim); - m_variables.Get("OnGrid",on_grid); - m_variables.Get("genie_module_label",fGenieModuleWeight); - - // Open the GHEP files - /////////////////////// - std::cout << "Tool ReweightEventsGenie: Opening TChain" << std::endl; - - int annieeventexists = m_data->Stores.count("ANNIEEvent"); - if(annieeventexists==0) m_data->Stores["ANNIEEvent"] = new BoostStore(false,2); - - //opens dummy file to initialize GENIE - flux = new TChain("gtree"); - int dummy_check = flux->Add("./UserTools/ReweightEventsGenie/beamData/gntp.dummy.ghep.root"); - if(dummy_check == 0){ throw std::invalid_argument("ERROR: cannot find gntp.dummy.ghep.root"); } - SetBranchAddresses(); - - if(!fromwcsim){ - m_variables.Get("FileDir",filedir); - m_variables.Get("FilePattern",filepattern); - m_variables.Get("OutputDir",outdir); - m_variables.Get("OutputFile",outpattern); - std::string inputfiles = filedir+"/"+filepattern; - if(on_grid) inputfiles = filepattern; - tchainentrynum=0; - flux = new TChain("gtree"); - int numbytes = flux->Add(inputfiles.c_str()); - std::cout << "Tool ReweightEventsGenie: Read " << to_string(numbytes) << " bytes loading TChain " << inputfiles << std::endl; - std::cout << "Tool ReweightEventsGenie: Genie TChain has " << to_string(flux->GetEntries()) << " entries" << std::endl; - SetBranchAddresses(); - } - - m_variables.Get("weight_functions_genie",weight_options); - m_variables.Get("weight_functions_flux",fweight_options); - std::string central_values; - m_variables.Get("genie_central_values",central_values); - - //parse and tokenize array of strings that list weights - std::stringstream weights_in(weight_options); - std::stringstream fweights_in(fweight_options); - std::string temp; - while (weights_in.good()){ - std::getline(weights_in, temp, ','); - weight_names.push_back(temp); - } - while (fweights_in.good()){ - std::getline(fweights_in, temp, ','); - fweight_names.push_back(temp); - } - - //Parse Genie central values configuration - std::stringstream CV_in(central_values); - std::string temp_token; - float val; - vector CV_knob_names; - vector CV_knob_value; - while (CV_in.good()){ - std::getline(CV_in, temp, '|'); - std::stringstream token_in(temp); - while (token_in.good()){ - std::getline(token_in, temp_token, ':'); - CV_knob_names.push_back(temp_token); - std::getline(token_in, temp_token, ':'); - std::stringstream to_val(temp_token); - to_val >> val; - CV_knob_value.push_back(val); - } - } - // Map to store the CV knob settings - std::map< genie::rew::GSyst_t, float > gsyst_to_cv_map; - genie::rew::GSyst_t temp_knob; - for (unsigned int i = 0; i < CV_knob_names.size(); i++ ) { - if ( valid_knob_name(CV_knob_names[i], temp_knob) ) { - if ( gsyst_to_cv_map.count( temp_knob ) ) { - std::cout << "ERROR: Duplicate central values were configured for the " << CV_knob_names[i] << " GENIE knob."; - } - gsyst_to_cv_map[ temp_knob ] = CV_knob_value[i]; - } - } - - reweightVector.resize(weight_names.size()); - - //intitalize variables for Genie weight configurations - std::string parameter, tokens, keys, values; - std::string temp_pars, temp_sigs, temp_mins, temp_maxs; - float sig; - vector str_par; - vector str_sig; - vector str_min; - vector str_max; - //Get each parameter - for(unsigned int i = 0; i < weight_names.size(); i++){ - evwgh::xsecconfig xs_configs; - m_variables.Get(weight_names[i],parameter); - //Separate key-value pairs from each other - std::stringstream param_in(parameter); - while (param_in.good()){ - std::getline(param_in, tokens, '|'); - //Separate and save values from keys - std::stringstream pair_in(tokens); - while (pair_in.good()){ - std::getline(pair_in, keys, ':'); - std::getline(pair_in, values, ':'); - if(keys == "parameter_list"){ - values.erase(0,1);//strip out brackets - values.erase(values.size()-1); - std::stringstream pars_in(values); - while(pars_in.good()){ - std::getline(pars_in, temp_pars, ',');//separate tokens - temp_pars.erase(0,1);//strip out quotations - temp_pars.erase(temp_pars.size()-1); - xs_configs.parameter_list.push_back(temp_pars); - } - } - else if(keys == "parameter_sigma"){ - values.erase(0,1);//strip out brackets - values.erase(values.size()-1); - std::stringstream sigs_in(values); - while(sigs_in.good()){ - std::getline(sigs_in, temp_sigs, ',');//separate tokens - std::stringstream to_float(temp_sigs); - to_float >> sig; - xs_configs.parameter_sigma.push_back(sig); - } - } - else if(keys == "parameter_min"){ - values.erase(0,1);//strip out brackets - values.erase(values.size()-1); - std::stringstream mins_in(values); - while(mins_in.good()){ - std::getline(mins_in, temp_mins, ',');//separate tokens - std::stringstream to_float(temp_mins); - to_float >> sig; - xs_configs.parameter_min.push_back(sig); - } - } - else if(keys == "parameter_max"){ - values.erase(0,1);//strip out brackets - values.erase(values.size()-1); - std::stringstream maxs_in(values); - while(maxs_in.good()){ - std::getline(maxs_in, temp_maxs, ',');//separate tokens - std::stringstream to_float(temp_maxs); - to_float >> sig; - xs_configs.parameter_max.push_back(sig); - } - } - else if(keys == "type") xs_configs.type = values; - else if(keys == "mode") xs_configs.mode = values; - else if(keys == "random_seed"){ - std::stringstream to_int(values); - int rand; - to_int >> rand; - xs_configs.random_seed = rand; - } - else if(keys == "number_of_multisims"){ - std::stringstream to_int(values); - int nom; - to_int >> nom; - xs_configs.number_of_multisims = nom; - } - } - } - - vector< genie::rew::GSyst_t > knobs_to_use; - for ( const auto& knob_name : xs_configs.parameter_list ) { - if ( valid_knob_name(knob_name, temp_knob) ) knobs_to_use.push_back( temp_knob ); - } - - // We need to add all of the tuned CV knobs to the list when configuring - // the weight calculators and checking for incompatibilities. Maybe all of - // the systematic variation knobs are fine to use together, but they also - // need to be compatible with the tuned CV. To perform the check, copy the - // list of systematic variation knobs to use and add all the CV knobs that - // aren't already present. - std::vector< genie::rew::GSyst_t > all_knobs_vec = knobs_to_use; - for ( const auto& pair : gsyst_to_cv_map ) { - genie::rew::GSyst_t cv_knob = pair.first; - auto begin = all_knobs_vec.cbegin(); - auto end = all_knobs_vec.cend(); - if ( !std::count(begin, end, cv_knob) ) all_knobs_vec.push_back( cv_knob ); - } - - // Check that the enabled knobs (both systematic variations and knobs used - // for the CV tune) are all compatible with each other. The std::map - // returned by this function call provides information needed to fine-tune - // the configuration of the GENIE weight calculators. - std::map< std::string, int > modes_to_use = this->CheckForIncompatibleSystematics( all_knobs_vec ); - - //check for same number of parameters as sigmas ========================= - - if(xs_configs.mode == "pm1sigma" || xs_configs.mode == "minmax") xs_configs.number_of_multisims = 2; - else if(xs_configs.mode == "central_value") xs_configs.number_of_multisims = 1; - - CLHEP::HepJamesRandom engine(xs_configs.random_seed); - - reweightVector[i].resize(xs_configs.number_of_multisims); - - // Set up the weight calculators for each universe - for ( auto& rwght : reweightVector[i] ) { - this->SetupWeightCalculators( rwght, modes_to_use ); - } - - //prepare sigmas - size_t num_usable_knobs = knobs_to_use.size(); - std::vector< std::vector > reweightingSigmas( num_usable_knobs ); - - for ( size_t k = 0; k < num_usable_knobs; ++k ) { - reweightingSigmas[k].resize( xs_configs.number_of_multisims ); - genie::rew::GSyst_t current_knob = knobs_to_use.at( k ); - for ( size_t u = 0; u < xs_configs.number_of_multisims; ++u ) { - if (xs_configs.mode == "multisim") { - reweightingSigmas[k][u] = xs_configs.parameter_sigma[k] * CLHEP::RandGaussQ::shoot(&engine, 0., 1.); - } - else if (xs_configs.mode == "pm1sigma") { - reweightingSigmas[k][u] = ( u == 0 ? 1. : -1. ); // u == 0 => 1; u == 1 => -1 if pm1sigma is specified - } - else if (xs_configs.mode == "minmax") { - reweightingSigmas[k][u] = ( u == 0 ? xs_configs.parameter_max.at(k) : xs_configs.parameter_min.at(k) ); // u == 0 => max; u == 1 => min if minmax is specified - } - else if (xs_configs.mode == "central_value") { - reweightingSigmas[k][u] = 0.; // we'll correct for a modified CV below if needed - } - else { - reweightingSigmas[k][u] = xs_configs.parameter_sigma[k]; - } - std::cout << "Set sigma for the " << genie::rew::GSyst::AsString( current_knob ) << " knob in universe #" << u << ". sigma = " << reweightingSigmas[k][u] << std::endl; - // Add an offset if the central value for the current knob has been - // configured (and is thus probably nonzero). Ignore this for minmax mode - // (the limits should be chosen to respect a modified central value) - if (xs_configs.mode != "minmax") { - auto iter = gsyst_to_cv_map.find( current_knob ); - if ( iter != gsyst_to_cv_map.end() ) { - reweightingSigmas[k][u] += iter->second; - std::cout << "CV offset added to the " << genie::rew::GSyst::AsString( current_knob ) << " knob. New sigma for universe #" << u << " is " << reweightingSigmas[k][u] << std::endl; - } - } - } - } - - // Set of FHiCL weight calculator labels for which the tuned CV will be - // ignored. If the name of the weight calculator doesn't appear in this set, - // then variation weights will be thrown around the tuned CV. - std::set< std::string > CALC_NAMES_THAT_IGNORE_TUNED_CV = { "RootinoFix" }; - - // Don't adjust knobs to reflect the tuned CV if this weight calculator - // should ignore those (as determined by whether it has one of the special - // FHiCL names) - if ( !CALC_NAMES_THAT_IGNORE_TUNED_CV.count(weight_names[i]) ) { - // Add tuned CV knobs which have not been tweaked, and set them to their - // modified central values. This ensures that weights are always thrown - // around the modified CV. - for ( const auto& pair : gsyst_to_cv_map ) { - genie::rew::GSyst_t cv_knob = pair.first; - float cv_value = pair.second; - // If the current tuned CV knob is not present in the list of tweaked - // knobs, then add it to the list with its tuned central value - if ( !std::count(knobs_to_use.cbegin(), knobs_to_use.cend(), cv_knob) ) { - ++num_usable_knobs; - knobs_to_use.push_back( cv_knob ); - // The tuned CV knob will take the same value in every universe - reweightingSigmas.emplace_back(std::vector(xs_configs.number_of_multisims, cv_value) ); - } - } - } - - // TODO: deal with parameters that have a priori bounds (e.g., FFCCQEVec, - // which can vary on the interval [0,1]) - // Set up the knob values for each universe - for ( size_t u = 0; u < reweightVector[i].size(); ++u ) { - auto& rwght = reweightVector[i].at( u ); - genie::rew::GSystSet& syst = rwght.Systematics(); - for ( unsigned int k = 0; k < knobs_to_use.size(); ++k ) { - genie::rew::GSyst_t knob = knobs_to_use.at( k ); - float twk_dial_value = reweightingSigmas.at( k ).at( u ); - syst.Set( knob, twk_dial_value ); - } // loop over tweaked knobs - rwght.Reconfigure(); - rwght.Print(); - } // loop over universes - } -//------------------------------------------------------------------------------------- - //intitalize variables for flux weight configuration - std::string flux_function = ""; - tokens = ""; - keys = ""; - values = ""; - sig = 0.0; - //Get each parameter - for(unsigned int i = 0; i < fweight_names.size(); i++){ - m_variables.Get(fweight_names[i],flux_function); - evwgh::fluxconfig temp_configs; - temp_configs.title = fweight_names[i]; - //Separate key-value pairs from each other - std::stringstream param_in(flux_function); - while (param_in.good()){ - std::getline(param_in, tokens, '|'); - //Separate and save values from keys - std::stringstream pair_in(tokens); - while (pair_in.good()){ - std::getline(pair_in, keys, ':'); - std::getline(pair_in, values, ':'); - if(keys == "type") temp_configs.type = values; - else if(keys == "CentralValue_hist_file"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.CentralValue_hist_file = values; - } - else if(keys == "PositiveSystematicVariation_hist_file"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.PositiveSystematicVariation_hist_file = values; - } - else if(keys == "NegativeSystematicVariation_hist_file"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.NegativeSystematicVariation_hist_file = values; - } - else if(keys == "cv_hist_file"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.cv_hist_file = values; - } - else if(keys == "rw_hist_file"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.rw_hist_file = values; - } - else if(keys == "ExternalData"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.ExternalData = values; - } - else if(keys == "ExternalFit"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.ExternalFit = values; - } - else if(keys == "parameter_list"){ - //strip out brackets - values.erase(0,1); - values.erase(values.size()-1); - std::string temp_pars; - std::stringstream pars_in(values); - while(pars_in.good()){ - std::getline(pars_in, temp_pars, ','); - //strip out quotations - temp_pars.erase(0,1); - temp_pars.erase(temp_pars.size()-1); - temp_configs.parameter_list.push_back(temp_pars); - } - } - else if(keys == "weight_calculator"){ - values.erase(0,1); - values.erase(values.size()-1); - temp_configs.weight_calculator = values; - } - else if(keys == "mode") temp_configs.mode = values; - else if(keys == "random_seed"){ - std::stringstream to_int(values); - int rand; - to_int >> rand; - temp_configs.random_seed = rand; - } - else if(keys == "number_of_multisims"){ - std::stringstream to_int(values); - int nom; - to_int >> nom; - temp_configs.number_of_multisims = nom; - } - else if(keys == "scale_factor_pos"){ - std::stringstream to_double(values); - double sfp; - to_double >> sfp; - temp_configs.scale_factor_pos= sfp; - } - else if(keys == "scale_factor_neg"){ - std::stringstream to_double(values); - double sfn; - to_double >> sfn; - temp_configs.scale_factor_neg = sfn; - } - else if(keys == "parameter_sigma"){ - std::stringstream to_int(values); - int ps; - to_int >> ps; - temp_configs.parameter_sigma = ps; - } - else if(keys == "scale_factor"){ - std::stringstream to_int(values); - int sf; - to_int >> sf; - temp_configs.scale_factor = sf; - } - else if(keys == "PrimaryHadronGeantCode"){ - if(temp_configs.type == "PrimaryHadronSanfordWang"){ - //strip out brackets - values.erase(0,1); - values.erase(values.size()-1); - std::string temp_pars; - std::stringstream pars_in(values); - while(pars_in.good()){ - std::getline(pars_in, temp_pars, ','); - //strip out quotations - temp_pars.erase(0,1); - temp_pars.erase(temp_pars.size()-1); - temp_configs.parameter_list.push_back(temp_pars); - } - } - else{ - std::stringstream to_int(values); - int phgc; - to_int >> phgc; - temp_configs.PrimaryHadronGeantCode = phgc;//array for Sanford Wang - } - } - else if(keys == "use_MiniBooNE_random_numbers"){ - temp_configs.use_MiniBooNE_random_numbers = (values == "false") ? false : true; - } - } - } - fconfig_funcs.push_back(temp_configs); - } - //put in Weight Manager - wm.Configure(fconfig_funcs); - return true; -} - - -bool ReweightEventsGenie::Execute(){ - if(fromwcsim){ - // retrieve the genie file and entry number from the LoadWCSim tool - std::string inputfiles; - get_ok = m_data->CStore.Get("GenieFile",inputfiles); - if(!get_ok){ - std::cout << "Tool ReweightEventsGenie: Failed to find GenieFile in CStore" << std::endl; - return false; - } - get_ok = m_data->CStore.Get("GenieEntry",tchainentrynum); - if(!get_ok){ - std::cout << "Tool ReweightEventsGenie: Failed to find GenieEntry in CStore" << std::endl; - return false; - } - std::string curfname = ((curf) ? curf->GetName() : ""); - // check if this is a new file - if(inputfiles!=curfname){ - // we need to load the new file - if(flux) flux->ResetBranchAddresses(); - if(curf) curf->Close(); - std::cout << "Tool ReweightEventsGenie: Loading new file " << inputfiles << std::endl; - curf=TFile::Open(inputfiles.c_str()); - flux=(TChain*)curf->Get("gtree"); - SetBranchAddresses(); - } - } - std::cout << "Tool ReweightEventsGenie: Loading tchain entry " << to_string(tchainentrynum) << std::endl; - local_entry = flux->LoadTree(tchainentrynum); - std::cout << "Tool ReweightEventsGenie: localentry is " << to_string(local_entry) << std::endl; - if((local_entry<0) || (local_entry!=tchainentrynum)){ - std::cout << "Tool ReweightEventsGenie: Reached end of file, returning" << std::endl; - m_data->vars.Set("StopLoop",1); - return true; - } - flux->GetEntry(local_entry); - curf = flux->GetCurrentFile(); - geniehdr=dynamic_cast (curf->Get("header")); //used to get run number - if(curf!=curflast || curflast==nullptr){ - TString curftstring = curf->GetName(); - currentfilestring = std::string(curftstring.Data()); - curflast=curf; - std::cout << "Tool ReweightEventsGenie: Opening new file \"" << currentfilestring << "\"" << std::endl; - } - tchainentrynum++; - - // Expand out the neutrino event and flux info - // ======================================================= - // header only contains the event number - genie::NtpMCRecHeader hdr = genieintx->hdr; - unsigned int genie_event_num = hdr.ievent; - // ======== flux info ======== - evwgh::event e; - e.entryno = gsimplenumientry->entryno; - e.run = gsimplenumientry->run; - double energy = gsimpleentry->E; - e.nenergyn = energy; - e.nenergyf = energy; - e.evtno = gsimplenumientry->evtno; - e.ntype = gsimpleentry->pdg; - - e.tpx=gsimplenumientry->tpx; - e.tpy=gsimplenumientry->tpy; - e.tpz=gsimplenumientry->tpz; - e.tptype=gsimplenumientry->tptype; - - e.vx = gsimplenumientry->vx; - e.vy = gsimplenumientry->vy; - e.vz = gsimplenumientry->vz; - e.pdpx = gsimplenumientry->pdpx; - e.pdpy = gsimplenumientry->pdpy; - e.pdpz = gsimplenumientry->pdpz; - - double apppz = gsimplenumientry->pppz; - e.ppdxdz = (gsimplenumientry->pppx)/apppz; - e.ppdydz = (gsimplenumientry->pppy)/apppz; - e.pppz = apppz; - e.ppmedium = gsimplenumientry->ppmedium; - e.ptype = gsimplenumientry->ptype; - - e.nimpwt = gsimpleentry->wgt; - - //Fill Ndecay (check parent type, neutrino type and if it is a 2 or 3 body decay) - e.ndecay = gsimplenumientry->ndecay; - - //Run flux reweighting - evwgh::MCEventWeight wght=wm.Run(e,0); - - // all neutrino intx details are in the event record - genie::EventRecord* gevtRec = genieintx->event; - - // neutrino interaction info - genie::Interaction* genieint = gevtRec->Summary(); - - //assume 1 neutrino per event, no pile-up - std::vector> weights(weight_names.size()); - - for(unsigned int i = 0; i < weight_names.size(); i++){ - unsigned int num_knobs = reweightVector[i].size(); - double nuE = genieint->InitState().ProbeE(genie::kRfLab); - - genie::Kinematics* kine_ptr = genieint->KinePtr(); - // Final lepton mass - double ml = genieint->FSPrimLepton()->Mass(); - // Final lepton 4-momentum - const TLorentzVector& p4l = kine_ptr->FSLeptonP4(); - // Final lepton kinetic energy - double Tl = p4l.E() - ml; - // Final lepton scattering cosine - double ctl = p4l.CosTheta(); - - kine_ptr->SetKV( kKVTl, Tl ); - kine_ptr->SetKV( kKVctl, ctl ); - - double lep_px = p4l.Px(); - double lep_py = p4l.Py(); - double lep_pz = p4l.Pz(); - - TIter partitr(gevtRec); - genie::GHepParticle *part = 0; - bool isCC = true; - bool has0pi0 = true; - bool has0piPMgt160 = true; - - if(genieint->ProcInfo().IsWeakNC()) isCC = false; - - // Pion flags - while((part = dynamic_cast(partitr.Next()))){ - int piPDG = part->Pdg(); - if(piPDG == 111) has0pi0 = false; - if(std::abs(piPDG) == 211) { - double piPx = part->Px(); - double piPy = part->Py(); - double piPz = part->Pz(); - if(std::sqrt(std::pow(piPx,2)+std::pow(piPy,2)+std::pow(piPz,2)) > 0.160) has0piPMgt160 = false; - } - } - - // All right, the event record is fully ready. Now ask the GReWeight - // objects to compute the weights. - weights[i].resize( num_knobs ); - for (unsigned int k = 0; k < num_knobs; ++k ) { - weights[i][k] = reweightVector[i].at(k).CalcWeight( *gevtRec ); - } - - m_data->Stores.at("ANNIEEvent")->Set("flux_weights",wght.fWeight); - m_data->Stores.at("ANNIEEvent")->Set("xsec_weights",weights); - m_data->Stores.at("ANNIEEvent")->Set("MCisCC",isCC); - m_data->Stores.at("ANNIEEvent")->Set("MCQsquared",genieint->KinePtr()->Q2()); - m_data->Stores.at("ANNIEEvent")->Set("MCNuPx",genieint->InitState().GetProbeP4()->Px()); - m_data->Stores.at("ANNIEEvent")->Set("MCNuPy",genieint->InitState().GetProbeP4()->Py()); - m_data->Stores.at("ANNIEEvent")->Set("MCNuPz",genieint->InitState().GetProbeP4()->Pz()); - m_data->Stores.at("ANNIEEvent")->Set("MCNuE",nuE); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtPx",genieint->InitState().GetTgtP4()->Px()); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtPy",genieint->InitState().GetTgtP4()->Py()); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtPz",genieint->InitState().GetTgtP4()->Pz()); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtE",genieint->InitState().GetTgtP4()->E()); - m_data->Stores.at("ANNIEEvent")->Set("MCNuPDG",genieint->InitState().ProbePdg()); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtPDG",genieint->InitState().TgtPdg()); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtisP",genieint->InitState().TgtPtr()->IsProton()); - m_data->Stores.at("ANNIEEvent")->Set("MCTgtisN",genieint->InitState().TgtPtr()->IsNeutron()); - m_data->Stores.at("ANNIEEvent")->Set("MCFSLm",ml); - m_data->Stores.at("ANNIEEvent")->Set("MCFSLPx",lep_px); - m_data->Stores.at("ANNIEEvent")->Set("MCFSLPy",lep_py); - m_data->Stores.at("ANNIEEvent")->Set("MCFSLPz",lep_pz); - m_data->Stores.at("ANNIEEvent")->Set("MCFSLE",p4l.E()); - m_data->Stores.at("ANNIEEvent")->Set("MC0pi0",has0pi0); - m_data->Stores.at("ANNIEEvent")->Set("MC0piPMgt160",has0piPMgt160); - - } - - std::cout << "Tool ReweightEventsGenie: Clearing genieintx" << std::endl; - genieintx->Clear(); // REQUIRED TO PREVENT MEMORY LEAK - - return true; -} - - -bool ReweightEventsGenie::Finalise(){ - std::cout << "Completed reweighting" << std::endl; - return true; -} - -void ReweightEventsGenie::SetBranchAddresses(){ - std::cout << "Tool ReweightEventsGenie: Setting branch addresses" << std::endl; - // neutrino event information - flux->SetBranchAddress("gmcrec",&genieintx); - flux->GetBranch("gmcrec")->SetAutoDelete(kTRUE); - - // input (BNB intx) event information - if(fluxver==0){ // rhatcher files - flux->SetBranchAddress("flux",&gnumipassthruentry); - flux->GetBranch("flux")->SetAutoDelete(kTRUE); - } else if(fluxver==1){ // zarko files -// flux->Print(); - flux->SetBranchAddress("numi",&gsimplenumientry); - flux->GetBranch("numi")->SetAutoDelete(kTRUE); - flux->SetBranchAddress("simple",&gsimpleentry); - flux->GetBranch("simple")->SetAutoDelete(kTRUE); - flux->SetBranchAddress("aux",&gsimpleauxinfo); - flux->GetBranch("aux")->SetAutoDelete(kTRUE); - } else { - flux->Print(); - } -} - -bool ReweightEventsGenie::valid_knob_name( const std::string& knob_name, genie::rew::GSyst_t& knob ) { - std::set< genie::rew::GSyst_t > UNIMPLEMENTED_GENIE_KNOBS = { - kXSecTwkDial_RnubarnuCC, // tweak the ratio of \sigma(\bar\nu CC) / \sigma(\nu CC) - kXSecTwkDial_NormCCQEenu, // tweak CCQE normalization (maintains dependence on neutrino energy) - kXSecTwkDial_NormDISCC, // tweak the inclusive DIS CC normalization - kXSecTwkDial_DISNuclMod // unclear intent, does anyone else know? - S. Gardiner - }; - knob = genie::rew::GSyst::FromString( knob_name ); - if ( knob != kNullSystematic && knob != kNTwkDials ) { - if ( UNIMPLEMENTED_GENIE_KNOBS.count(knob) ) { - return false; - } - } - else { - return false; - } - return true; -} - -void ReweightEventsGenie::SetupWeightCalculators(genie::rew::GReWeight& rw, const std::map& modes_to_use){ - // Based on the list from the GENIE command-line tool grwght1p - - rw.AdoptWghtCalc( "xsec_ncel", new GReWeightNuXSecNCEL ); - rw.AdoptWghtCalc( "xsec_ccqe", new GReWeightNuXSecCCQE ); - rw.AdoptWghtCalc( "xsec_ccqe_axial", new GReWeightNuXSecCCQEaxial ); - rw.AdoptWghtCalc( "xsec_ccqe_vec", new GReWeightNuXSecCCQEvec ); - rw.AdoptWghtCalc( "xsec_ccres", new GReWeightNuXSecCCRES ); - rw.AdoptWghtCalc( "xsec_ncres", new GReWeightNuXSecNCRES ); - rw.AdoptWghtCalc( "xsec_nonresbkg", new GReWeightNonResonanceBkg ); - rw.AdoptWghtCalc( "xsec_coh", new GReWeightNuXSecCOH ); - rw.AdoptWghtCalc( "xsec_dis", new GReWeightNuXSecDIS ); - rw.AdoptWghtCalc( "nuclear_qe", new GReWeightFGM ); - rw.AdoptWghtCalc( "hadro_res_decay", new GReWeightResonanceDecay ); - rw.AdoptWghtCalc( "hadro_fzone", new GReWeightFZone ); - rw.AdoptWghtCalc( "hadro_intranuke", new GReWeightINuke ); - rw.AdoptWghtCalc( "hadro_agky", new GReWeightAGKY ); - rw.AdoptWghtCalc( "xsec_nc", new GReWeightNuXSecNC ); - rw.AdoptWghtCalc( "res_dk", new GReWeightResonanceDecay ); - rw.AdoptWghtCalc( "xsec_empmec", new GReWeightXSecEmpiricalMEC); - // GReWeightDISNuclMod::CalcWeight() is not implemented, so we won't - // bother to use it here. - S. Gardiner, 9 Dec 2019 - //rw.AdoptWghtCalc( "nuclear_dis", new GReWeightDISNuclMod ); - // Set the modes for the weight calculators that need them to be specified - //UBoone Patch - rw.AdoptWghtCalc( "xsec_mec", new GReWeightXSecMEC ); - rw.AdoptWghtCalc( "deltarad_angle", new GReWeightDeltaradAngle ); - rw.AdoptWghtCalc( "xsec_coh_ub", new GReWeightNuXSecCOHuB ); - rw.AdoptWghtCalc( "res_bug_fix", new GReWeightRESBugFix ); - - for ( const auto& pair : modes_to_use ) { - std::string calc_name = pair.first; - int mode = pair.second; - genie::rew::GReWeightI* calc = rw.WghtCalc( calc_name ); - // The GReWeightI base class doesn't have a SetMode(int) function, - // so we'll just try dynamic casting until we get the right one. - // If none work, then throw an exception. - // TODO: Add a virtual function GReWeightI::SetMode( int ) in GENIE's - // Reweight framework. Then we can avoid the hacky dynamic casts here. - auto* calc_ccqe = dynamic_cast< genie::rew::GReWeightNuXSecCCQE* >( calc ); - auto* calc_ccres = dynamic_cast< genie::rew::GReWeightNuXSecCCRES* >( calc ); - auto* calc_ncres = dynamic_cast< genie::rew::GReWeightNuXSecNCRES* >( calc ); - auto* calc_dis = dynamic_cast< genie::rew::GReWeightNuXSecDIS* >( calc ); - if ( calc_ccqe ) calc_ccqe->SetMode( mode ); - else if ( calc_ccres ) calc_ccres->SetMode( mode ); - else if ( calc_ncres ) calc_ncres->SetMode( mode ); - else if ( calc_dis ) calc_dis->SetMode( mode ); - } -} - -std::map< std::string, int > ReweightEventsGenie::CheckForIncompatibleSystematics(const std::vector& knob_vec){ - std::map< std::string, int > modes_to_use; - std::map< std::string, std::map > > INCOMPATIBLE_GENIE_KNOBS = { - // CCQE (genie::rew::GReWeightNuXSecCCQE) - { "xsec_ccqe", { - { genie::rew::GReWeightNuXSecCCQE::kModeNormAndMaShape, - { - // Norm + shape - kXSecTwkDial_NormCCQE, // tweak CCQE normalization (energy independent) - kXSecTwkDial_MaCCQEshape, // tweak Ma CCQE, affects dsigma(CCQE)/dQ2 in shape only (normalized to constant integral) - kXSecTwkDial_E0CCQEshape // tweak E0 CCQE RunningMA, affects dsigma(CCQE)/dQ2 in shape only (normalized to constant integral) - } - }, - { genie::rew::GReWeightNuXSecCCQE::kModeMa, - { - // Ma - kXSecTwkDial_MaCCQE, // tweak Ma CCQE, affects dsigma(CCQE)/dQ2 both in shape and normalization - kXSecTwkDial_E0CCQE, // tweak E0 CCQE RunningMA, affects dsigma(CCQE)/dQ2 both in shape and normalization - } - }, - { genie::rew::GReWeightNuXSecCCQE::kModeZExp, - { - // Z-expansion - kXSecTwkDial_ZNormCCQE, // tweak Z-expansion CCQE normalization (energy independent) - kXSecTwkDial_ZExpA1CCQE, // tweak Z-expansion coefficient 1, affects dsigma(CCQE)/dQ2 both in shape and normalization - kXSecTwkDial_ZExpA2CCQE, // tweak Z-expansion coefficient 2, affects dsigma(CCQE)/dQ2 both in shape and normalization - kXSecTwkDial_ZExpA3CCQE, // tweak Z-expansion coefficient 3, affects dsigma(CCQE)/dQ2 both in shape and normalization - kXSecTwkDial_ZExpA4CCQE // tweak Z-expansion coefficient 4, affects dsigma(CCQE)/dQ2 both in shape and normalization - } - }, - } }, - - // CCRES (genie::rew::GReWeightNuXSecCCRES) - { "xsec_ccres", { - { genie::rew::GReWeightNuXSecCCRES::kModeNormAndMaMvShape, - { - // Norm + shape - kXSecTwkDial_NormCCRES, /// tweak CCRES normalization - kXSecTwkDial_MaCCRESshape, /// tweak Ma CCRES, affects d2sigma(CCRES)/dWdQ2 in shape only (normalized to constant integral) - kXSecTwkDial_MvCCRESshape /// tweak Mv CCRES, affects d2sigma(CCRES)/dWdQ2 in shape only (normalized to constant integral) - } - }, - { genie::rew::GReWeightNuXSecCCRES::kModeMaMv, - { - // Ma + Mv - kXSecTwkDial_MaCCRES, // tweak Ma CCRES, affects d2sigma(CCRES)/dWdQ2 both in shape and normalization - kXSecTwkDial_MvCCRES // tweak Mv CCRES, affects d2sigma(CCRES)/dWdQ2 both in shape and normalization - } - } - } }, - - // NCRES (genie::rew::GReWeightNuXSecNCRES) - { "xsec_ncres", { - { genie::rew::GReWeightNuXSecNCRES::kModeNormAndMaMvShape, - { - // Norm + shape - kXSecTwkDial_NormNCRES, /// tweak NCRES normalization - kXSecTwkDial_MaNCRESshape, /// tweak Ma NCRES, affects d2sigma(NCRES)/dWdQ2 in shape only (normalized to constant integral) - kXSecTwkDial_MvNCRESshape /// tweak Mv NCRES, affects d2sigma(NCRES)/dWdQ2 in shape only (normalized to constant integral) - } - }, - { genie::rew::GReWeightNuXSecNCRES::kModeMaMv, - { - // Ma + Mv - kXSecTwkDial_MaNCRES, // tweak Ma NCRES, affects d2sigma(NCRES)/dWdQ2 both in shape and normalization - kXSecTwkDial_MvNCRES // tweak Mv NCRES, affects d2sigma(NCRES)/dWdQ2 both in shape and normalization - } - } - } }, - - // DIS (genie::rew::GReWeightNuXSecDIS) - { "xsec_dis", { - { genie::rew::GReWeightNuXSecDIS::kModeABCV12u, - { - kXSecTwkDial_AhtBY, // tweak the Bodek-Yang model parameter A_{ht} - incl. both shape and normalization effect - kXSecTwkDial_BhtBY, // tweak the Bodek-Yang model parameter B_{ht} - incl. both shape and normalization effect - kXSecTwkDial_CV1uBY, // tweak the Bodek-Yang model parameter CV1u - incl. both shape and normalization effect - kXSecTwkDial_CV2uBY // tweak the Bodek-Yang model parameter CV2u - incl. both shape and normalization effect - } - }, - { genie::rew::GReWeightNuXSecDIS::kModeABCV12uShape, - { - kXSecTwkDial_AhtBYshape, // tweak the Bodek-Yang model parameter A_{ht} - shape only effect to d2sigma(DIS)/dxdy - kXSecTwkDial_BhtBYshape, // tweak the Bodek-Yang model parameter B_{ht} - shape only effect to d2sigma(DIS)/dxdy - kXSecTwkDial_CV1uBYshape, // tweak the Bodek-Yang model parameter CV1u - shape only effect to d2sigma(DIS)/dxdy - kXSecTwkDial_CV2uBYshape // tweak the Bodek-Yang model parameter CV2u - shape only effect to d2sigma(DIS)/dxdy - } - } - } } - }; - for ( const auto& knob : knob_vec ) { - for ( const auto& pair1 : INCOMPATIBLE_GENIE_KNOBS ) { - std::string calc_name = pair1.first; - const auto& mode_map = pair1.second; - for ( const auto& pair2 : mode_map ) { - int mode = pair2.first; - std::set knob_set = pair2.second; - if ( knob_set.count(knob) ) { - auto search = modes_to_use.find( calc_name ); - if ( search != modes_to_use.end() ) { - if ( search->second != mode ) { - auto knob_str = genie::rew::GSyst::AsString( knob ); - std::cout << "ERROR: The GENIE knob " << knob_str << " is incompatible with others that are already configured" << std::endl; - } - } - else modes_to_use[ calc_name ] = mode; - } - } - } - } - return modes_to_use; -} - - - - diff --git a/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE.root b/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE.root deleted file mode 100644 index 35089b648..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE_KPlus_withoutSciBooNE.root b/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE_KPlus_withoutSciBooNE.root deleted file mode 100644 index 823b3b608..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE_KPlus_withoutSciBooNE.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root b/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root deleted file mode 100644 index 2f84b95e1..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/expskin_nrtd1000_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/expskin_nrtd1000_flux.root deleted file mode 100644 index 3b7d84d20..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/expskin_nrtd1000_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root deleted file mode 100644 index e044c9033..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_horn173ka_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_horn173ka_rgen610.6_flux.root deleted file mode 100644 index c3fb781f5..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_horn173ka_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_horn175ka_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_horn175ka_rgen610.6_flux.root deleted file mode 100644 index e7f90b1be..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_horn175ka_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleoninexsec_down_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleoninexsec_down_rgen610.6_flux.root deleted file mode 100644 index 49f9c222b..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleoninexsec_down_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleoninexsec_up_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleoninexsec_up_rgen610.6_flux.root deleted file mode 100644 index 02e895384..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleoninexsec_up_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleonqexsec_down_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleonqexsec_down_rgen610.6_flux.root deleted file mode 100644 index 9842c719f..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleonqexsec_down_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleonqexsec_up_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleonqexsec_up_rgen610.6_flux.root deleted file mode 100644 index 203be2759..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleonqexsec_up_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleontotxsec_down_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleontotxsec_down_rgen610.6_flux.root deleted file mode 100644 index 57793d343..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleontotxsec_down_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleontotxsec_up_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleontotxsec_up_rgen610.6_flux.root deleted file mode 100644 index 7320bdc54..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_nucleontotxsec_up_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pioninexsec_down_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pioninexsec_down_rgen610.6_flux.root deleted file mode 100644 index f271c0ce0..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pioninexsec_down_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pioninexsec_up_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pioninexsec_up_rgen610.6_flux.root deleted file mode 100644 index 455a03b67..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pioninexsec_up_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pionqexsec_down_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pionqexsec_down_rgen610.6_flux.root deleted file mode 100644 index 2229046af..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pionqexsec_down_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pionqexsec_up_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pionqexsec_up_rgen610.6_flux.root deleted file mode 100644 index 8584ee46e..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_pionqexsec_up_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_piontotxsec_down_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_piontotxsec_down_rgen610.6_flux.root deleted file mode 100644 index c098bd5b3..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_piontotxsec_down_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_piontotxsec_up_rgen610.6_flux.root b/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_piontotxsec_up_rgen610.6_flux.root deleted file mode 100644 index 3717bb77d..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/UnisimHists/may06_piontotxsec_up_rgen610.6_flux.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/bnbcorrection/bnb_newflux_volAVTPC.root b/UserTools/ReweightEventsGenie/beamData/bnbcorrection/bnb_newflux_volAVTPC.root deleted file mode 100644 index e51595b02..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/bnbcorrection/bnb_newflux_volAVTPC.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/bnbcorrection/bnb_oldflux_volAVTPC.root b/UserTools/ReweightEventsGenie/beamData/bnbcorrection/bnb_oldflux_volAVTPC.root deleted file mode 100644 index d10f9b90e..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/bnbcorrection/bnb_oldflux_volAVTPC.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/beamData/gntp.dummy.ghep.root b/UserTools/ReweightEventsGenie/beamData/gntp.dummy.ghep.root deleted file mode 100644 index f3027506d..000000000 Binary files a/UserTools/ReweightEventsGenie/beamData/gntp.dummy.ghep.root and /dev/null differ diff --git a/UserTools/ReweightEventsGenie/FluxHistWeightCalc.cpp b/UserTools/ReweightFlux/FluxHistWeightCalc.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/FluxHistWeightCalc.cpp rename to UserTools/ReweightFlux/FluxHistWeightCalc.cpp diff --git a/UserTools/ReweightEventsGenie/FluxUnisimWeightCalc.cpp b/UserTools/ReweightFlux/FluxUnisimWeightCalc.cpp similarity index 99% rename from UserTools/ReweightEventsGenie/FluxUnisimWeightCalc.cpp rename to UserTools/ReweightFlux/FluxUnisimWeightCalc.cpp index d08328a0c..8eb47e99b 100644 --- a/UserTools/ReweightEventsGenie/FluxUnisimWeightCalc.cpp +++ b/UserTools/ReweightFlux/FluxUnisimWeightCalc.cpp @@ -119,9 +119,9 @@ namespace evwgh { for (int intyp=0;intyp<4;intyp++) { for (int ibin=0;ibin<200;ibin++) { //Grab events from ibin+1 - fCV[iptyp][intyp][ibin]=(dynamic_cast (fcv.Get(Form("h5%d%d",ptype[iptyp],ntype[intyp]))))->GetBinContent(ibin+1); - fRWpos[iptyp][intyp][ibin]=(dynamic_cast (frwpos.Get(Form("h5%d%d",ptype[iptyp],ntype[intyp]))))->GetBinContent(ibin+1); - fRWneg[iptyp][intyp][ibin]=(dynamic_cast (frwneg.Get(Form("h5%d%d",ptype[iptyp],ntype[intyp]))))->GetBinContent(ibin+1); + fCV[iptyp][intyp][ibin]=(dynamic_cast (fcv.Get(Form("h5%d%d",ptype[iptyp],ntype[intyp]))))->GetBinContent(ibin+1); + fRWpos[iptyp][intyp][ibin]=(dynamic_cast (frwpos.Get(Form("h5%d%d",ptype[iptyp],ntype[intyp]))))->GetBinContent(ibin+1); + fRWneg[iptyp][intyp][ibin]=(dynamic_cast (frwneg.Get(Form("h5%d%d",ptype[iptyp],ntype[intyp]))))->GetBinContent(ibin+1); }// energy bin }// type of neutrinos diff --git a/UserTools/ReweightEventsGenie/MCEventWeight.h b/UserTools/ReweightFlux/MCEventWeight.h similarity index 89% rename from UserTools/ReweightEventsGenie/MCEventWeight.h rename to UserTools/ReweightFlux/MCEventWeight.h index ad2f32a8d..2be5e7b07 100644 --- a/UserTools/ReweightEventsGenie/MCEventWeight.h +++ b/UserTools/ReweightFlux/MCEventWeight.h @@ -1,5 +1,5 @@ -#ifndef _MCEVENTWEIGHT_H_ -#define _MCEVENTWEIGHT_H_ +#ifndef _MCFLUXEVENTWEIGHT_H_ +#define _MCFLUXEVENTWEIGHT_H_ #include #include @@ -10,7 +10,7 @@ namespace evwgh { std::map > fWeight; }; - struct xsecconfig{ +/* struct xsecconfig{ std::string title = ""; std::string type = ""; int random_seed = 0; @@ -21,7 +21,7 @@ namespace evwgh { std::string mode = ""; int number_of_multisims = 0; }; - +*/ struct fluxconfig{ std::string title = ""; std::string type = ""; @@ -57,7 +57,6 @@ namespace evwgh { double vy; double vz; int tptype; - //int tgptype; int ptype; int ntype; double nimpwt; @@ -71,12 +70,6 @@ namespace evwgh { double ppdxdz; double ppdydz; double pppz; - //double muparpx; - //double muparpy; - //double muparpz; - //double mupare; - //double necm; - //int tgen; }; } -#endif //_MCEVENTWEIGHT_H_ +#endif //_MCFLUXEVENTWEIGHT_H_ diff --git a/UserTools/ReweightEventsGenie/PrimaryHadronFeynmanScalingWeightCalc.cpp b/UserTools/ReweightFlux/PrimaryHadronFeynmanScalingWeightCalc.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/PrimaryHadronFeynmanScalingWeightCalc.cpp rename to UserTools/ReweightFlux/PrimaryHadronFeynmanScalingWeightCalc.cpp diff --git a/UserTools/ReweightEventsGenie/PrimaryHadronNormalizationWeightCalc.cpp b/UserTools/ReweightFlux/PrimaryHadronNormalizationWeightCalc.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/PrimaryHadronNormalizationWeightCalc.cpp rename to UserTools/ReweightFlux/PrimaryHadronNormalizationWeightCalc.cpp diff --git a/UserTools/ReweightEventsGenie/PrimaryHadronSWCentralSplineVariationWeightCalc.cpp b/UserTools/ReweightFlux/PrimaryHadronSWCentralSplineVariationWeightCalc.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/PrimaryHadronSWCentralSplineVariationWeightCalc.cpp rename to UserTools/ReweightFlux/PrimaryHadronSWCentralSplineVariationWeightCalc.cpp diff --git a/UserTools/ReweightEventsGenie/PrimaryHadronSanfordWangWeightCalc.cpp b/UserTools/ReweightFlux/PrimaryHadronSanfordWangWeightCalc.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/PrimaryHadronSanfordWangWeightCalc.cpp rename to UserTools/ReweightFlux/PrimaryHadronSanfordWangWeightCalc.cpp diff --git a/UserTools/ReweightFlux/README.md b/UserTools/ReweightFlux/README.md new file mode 100644 index 000000000..09134485c --- /dev/null +++ b/UserTools/ReweightFlux/README.md @@ -0,0 +1,20 @@ +# ReweightFlux + +ReweightFlux +To be ran following LoadReweightGenieEvent Tool in ToolChain + +## Data + +Describe any data formats ReweightFlux creates, destroys, changes, or analyzes. E.G. + +**flux_weights** `map>` +* Beam flux weight systematics + + +## Configuration + +Describe any configuration variables for ReweightFlux. + +``` +param1 key1:value1|key2:value2|key3:value3 +``` diff --git a/UserTools/ReweightFlux/ReweightFlux.cpp b/UserTools/ReweightFlux/ReweightFlux.cpp new file mode 100644 index 000000000..5d56ca74b --- /dev/null +++ b/UserTools/ReweightFlux/ReweightFlux.cpp @@ -0,0 +1,255 @@ +#include "ReweightFlux.h" + +ReweightFlux::ReweightFlux():Tool(){} + + +bool ReweightFlux::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("Verbosity",verbosity); + m_variables.Get("weight_functions_flux",weight_options); + + //parse and tokenize array of strings that list weights + std::stringstream weights_in(weight_options); + std::string temp; + while (weights_in.good()){ + std::getline(weights_in, temp, ','); + fweight_names.push_back(temp); + } + + +//------------------------------------------------------------------------------------- + //intitalize variables for flux weight configuration + std::string flux_function = ""; + std::string tokens = ""; + std::string keys = ""; + std::string values = ""; + //Get each parameter + for(unsigned int i = 0; i < fweight_names.size(); i++){ + m_variables.Get(fweight_names[i],flux_function); + evwgh::fluxconfig temp_configs; + temp_configs.title = fweight_names[i]; + //Separate key-value pairs from each other + std::stringstream param_in(flux_function); + while (param_in.good()){ + std::getline(param_in, tokens, '|'); + //Separate and save values from keys + std::stringstream pair_in(tokens); + while (pair_in.good()){ + std::getline(pair_in, keys, ':'); + std::getline(pair_in, values, ':'); + if(keys == "type") temp_configs.type = values; + else if(keys == "CentralValue_hist_file"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.CentralValue_hist_file = values; + } + else if(keys == "PositiveSystematicVariation_hist_file"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.PositiveSystematicVariation_hist_file = values; + } + else if(keys == "NegativeSystematicVariation_hist_file"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.NegativeSystematicVariation_hist_file = values; + } + else if(keys == "cv_hist_file"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.cv_hist_file = values; + } + else if(keys == "rw_hist_file"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.rw_hist_file = values; + } + else if(keys == "ExternalData"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.ExternalData = values; + } + else if(keys == "ExternalFit"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.ExternalFit = values; + } + else if(keys == "parameter_list"){ + //strip out brackets + values.erase(0,1); + values.erase(values.size()-1); + std::string temp_pars; + std::stringstream pars_in(values); + while(pars_in.good()){ + std::getline(pars_in, temp_pars, ','); + //strip out quotations + temp_pars.erase(0,1); + temp_pars.erase(temp_pars.size()-1); + temp_configs.parameter_list.push_back(temp_pars); + } + } + else if(keys == "weight_calculator"){ + values.erase(0,1); + values.erase(values.size()-1); + temp_configs.weight_calculator = values; + } + else if(keys == "mode") temp_configs.mode = values; + else if(keys == "random_seed"){ + std::stringstream to_int(values); + int rand; + to_int >> rand; + temp_configs.random_seed = rand; + } + else if(keys == "number_of_multisims"){ + std::stringstream to_int(values); + int nom; + to_int >> nom; + temp_configs.number_of_multisims = nom; + } + else if(keys == "scale_factor_pos"){ + std::stringstream to_double(values); + double sfp; + to_double >> sfp; + temp_configs.scale_factor_pos= sfp; + } + else if(keys == "scale_factor_neg"){ + std::stringstream to_double(values); + double sfn; + to_double >> sfn; + temp_configs.scale_factor_neg = sfn; + } + else if(keys == "parameter_sigma"){ + std::stringstream to_int(values); + int ps; + to_int >> ps; + temp_configs.parameter_sigma = ps; + } + else if(keys == "scale_factor"){ + std::stringstream to_int(values); + int sf; + to_int >> sf; + temp_configs.scale_factor = sf; + } + else if(keys == "PrimaryHadronGeantCode"){ + if(temp_configs.type == "PrimaryHadronSanfordWang"){ + //strip out brackets + values.erase(0,1); + values.erase(values.size()-1); + std::string temp_pars; + std::stringstream pars_in(values); + while(pars_in.good()){ + std::getline(pars_in, temp_pars, ','); + //strip out quotations + temp_pars.erase(0,1); + temp_pars.erase(temp_pars.size()-1); + temp_configs.parameter_list.push_back(temp_pars); + } + } + else{ + std::stringstream to_int(values); + int phgc; + to_int >> phgc; + temp_configs.PrimaryHadronGeantCode = phgc;//array for Sanford Wang + } + } + else if(keys == "use_MiniBooNE_random_numbers"){ + temp_configs.use_MiniBooNE_random_numbers = (values == "false") ? false : true; + } + } + } + fconfig_funcs.push_back(temp_configs); + } + //put in Weight Manager + wm.Configure(fconfig_funcs); + + return true; +} + + +bool ReweightFlux::Execute(){ + // Get the flux info + // ======================================================= + + int parentpdg, parentdecaymode, parentprodmedium, parentpdgattgtexit; + float parentdecayvtx_x, parentdecayvtx_y, parentdecayvtx_z; + float parentdecaymom_x, parentdecaymom_y, parentdecaymom_z; + float parentprodmom_x, parentprodmom_y, parentprodmom_z; + float parenttgtexitmom_x, parenttgtexitmom_y, parenttgtexitmom_z; + int fluxrun, fluxentryno, fluxevtno, fluxntype; + double fluxnimpwt, fluxnenergyn, fluxnenergyf; + + bool get_pdg = m_data->Stores["GenieInfo"]->Get("ParentPdg",parentpdg); + bool get_decay_mode = m_data->Stores["GenieInfo"]->Get("ParentDecayMode",parentdecaymode); + bool get_decay_vx = m_data->Stores["GenieInfo"]->Get("ParentDecayVtx_X",parentdecayvtx_x); + bool get_decay_vy = m_data->Stores["GenieInfo"]->Get("ParentDecayVtx_Y",parentdecayvtx_y); + bool get_decay_vz = m_data->Stores["GenieInfo"]->Get("ParentDecayVtx_Z",parentdecayvtx_z); + bool get_decay_px = m_data->Stores["GenieInfo"]->Get("ParentDecayMom_X",parentdecaymom_x); + bool get_decay_py = m_data->Stores["GenieInfo"]->Get("ParentDecayMom_Y",parentdecaymom_y); + bool get_decay_pz = m_data->Stores["GenieInfo"]->Get("ParentDecayMom_Z",parentdecaymom_z); + bool get_prod_px = m_data->Stores["GenieInfo"]->Get("ParentProdMom_X",parentprodmom_x); + bool get_prod_py = m_data->Stores["GenieInfo"]->Get("ParentProdMom_Y",parentprodmom_y); + bool get_prod_pz = m_data->Stores["GenieInfo"]->Get("ParentProdMom_Z",parentprodmom_z); + bool get_medium = m_data->Stores["GenieInfo"]->Get("ParentProdMedium",parentprodmedium); + bool get_tgt_pdg = m_data->Stores["GenieInfo"]->Get("ParentPdgAtTgtExit",parentpdgattgtexit); + bool get_tgt_px = m_data->Stores["GenieInfo"]->Get("ParentTgtExitMom_X",parenttgtexitmom_x); + bool get_tgt_py = m_data->Stores["GenieInfo"]->Get("ParentTgtExitMom_Y",parenttgtexitmom_y); + bool get_tgt_pz = m_data->Stores["GenieInfo"]->Get("ParentTgtExitMom_Z",parenttgtexitmom_z); + bool get_entryno = m_data->Stores["GenieInfo"]->Get("ParentEntryNo",fluxentryno); + bool get_run = m_data->Stores["GenieInfo"]->Get("ParentRunNo",fluxrun); + bool get_energyn = m_data->Stores["GenieInfo"]->Get("ParentNEnergyN",fluxnenergyn); + bool get_energyf = m_data->Stores["GenieInfo"]->Get("ParentNEnergyF",fluxnenergyf); + bool get_evtno = m_data->Stores["GenieInfo"]->Get("ParentEventNo",fluxevtno); + bool get_ntype = m_data->Stores["GenieInfo"]->Get("ParentNType",fluxntype); + bool get_wgt = m_data->Stores["GenieInfo"]->Get("ParentWgt",fluxnimpwt); + + + // ======== flux info ======== + evwgh::event e; + e.entryno = fluxentryno; + e.run = fluxrun; + e.nenergyn = fluxnenergyn; + e.nenergyf = fluxnenergyf; + e.evtno = fluxevtno; + e.ntype = fluxntype; + + e.tpx=parenttgtexitmom_x; + e.tpy=parenttgtexitmom_y; + e.tpz=parenttgtexitmom_z; + e.tptype=parentpdgattgtexit; + + e.vx = parentdecayvtx_x; + e.vy = parentdecayvtx_y; + e.vz = parentdecayvtx_z; + e.pdpx = parentdecaymom_x; + e.pdpy = parentdecaymom_y; + e.pdpz = parentdecaymom_z; + + e.ppdxdz = parentprodmom_x; + e.ppdydz = parentprodmom_y; + e.pppz = parentprodmom_z; + e.ppmedium = parentprodmedium; + e.ptype = parentpdg; + + e.nimpwt = fluxnimpwt; + + //Fill Ndecay (check parent type, neutrino type and if it is a 2 or 3 body decay) + e.ndecay = parentdecaymode; + + //Run flux reweighting + evwgh::MCEventWeight wght=wm.Run(e,0); + + m_data->Stores.at("ANNIEEvent")->Set("flux_weights",wght.fWeight); + + return true; +} + + +bool ReweightFlux::Finalise(){ + if(verbosity > 0) std::cout << "Completed Flux Reweighting" << std::endl; + return true; +} diff --git a/UserTools/ReweightEventsGenie/ReweightEventsGenie.h b/UserTools/ReweightFlux/ReweightFlux.h similarity index 62% rename from UserTools/ReweightEventsGenie/ReweightEventsGenie.h rename to UserTools/ReweightFlux/ReweightFlux.h index 88f361902..4c8fe9557 100644 --- a/UserTools/ReweightEventsGenie/ReweightEventsGenie.h +++ b/UserTools/ReweightFlux/ReweightFlux.h @@ -1,5 +1,5 @@ -#ifndef ReweightEventsGenie_H -#define ReweightEventsGenie_H +#ifndef ReweightFlux_H +#define ReweightFlux_H #include #include @@ -13,7 +13,7 @@ #include #include "Tool.h" -#include "GenieInfo.h" +/*#include "GenieInfo.h" #include "CLHEP/Random/RandGaussQ.h" #include "CLHEP/Random/JamesRandom.h" #include "Framework/Conventions/KineVar.h" @@ -32,9 +32,10 @@ #include #include #include +*/ #include -#include "RwFramework/GSystSet.h" +/*#include "RwFramework/GSystSet.h" #include "RwFramework/GSyst.h" #include "RwFramework/GReWeight.h" #include "RwCalculators/GReWeightNuXSecNCEL.h" @@ -73,6 +74,7 @@ #include #include #include +*/ #include "TChain.h" #include "TFile.h" #include "TTree.h" @@ -83,33 +85,26 @@ #include "MCEventWeight.h" #include "WeightManager.h" -#define LOADED_GENIE 1 + /** - * \class ReweightEventsGenie + * \class ReweightFlux * -* Ported in parts from LoadGenieEvent -* $Author: B.Richards -* $Date: 2019/05/28 10:44:00 -* Contact: b.richards@qmul.ac.uk + * 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. * -* Updated -* $Author: James Minock -* $Date: 2023/02/09 -* Contact: jmm1018@physics.rutgers.edu +* $Author: B.Richards $ +* $Date: 2019/05/28 10:44:00 $ +* Contact: b.richards@qmul.ac.uk */ - -class ReweightEventsGenie: public Tool { +class ReweightFlux: public Tool { public: - ReweightEventsGenie(); ///< Simple constructor + + ReweightFlux(); ///< 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 valid_knob_name( const std::string& knob_name, genie::rew::GSyst_t& knob ); - std::map< std::string, int > CheckForIncompatibleSystematics(const std::vector& knob_vec); - void SetupWeightCalculators(genie::rew::GReWeight& rw, const std::map& modes_to_use); // verbosity levels: if 'verbosity' < this level, the message type will be logged. int verbosity; @@ -120,53 +115,15 @@ class ReweightEventsGenie: public Tool { std::string logmessage; int get_ok; + private: //Configuration variables std::string weight_options; - std::string fweight_options; - std::string sample; - std::string fGenieModuleWeight; - vector weight_names; vector fweight_names; vector fconfig_funcs; evwgh::WeightManager wm; - vector> reweightVector; - int flx_run; - unsigned int flx_evt; - - // function to load the branch addresses - void SetBranchAddresses(); - - // function to fill the info into the handy genieinfostruct - void GetGenieEntryInfo(genie::EventRecord* gevtRec, genie::Interaction* genieint, - GenieInfo& thegenieinfo, bool printneutrinoevent=false); - - BoostStore* geniestore = nullptr; - int fluxstage; - std::string filedir, filepattern, outdir, outpattern, fluxdir, fluxfile; - bool loadwcsimsource; - TChain* flux = nullptr; - TFile* curf = nullptr; // keep track of file changes - TFile* curflast = nullptr; - genie::NtpMCEventRecord* genieintx = nullptr; // = new genie::NtpMCEventRecord; - genie::NtpMCTreeHeader* geniehdr = nullptr; - // for fluxver 0 files - genie::flux::GNuMIFluxPassThroughInfo* gnumipassthruentry = nullptr; - // for fluxver 1 files - genie::flux::GSimpleNtpEntry* gsimpleentry = nullptr; - genie::flux::GSimpleNtpAux* gsimpleauxinfo = nullptr; - genie::flux::GSimpleNtpNuMI* gsimplenumientry = nullptr; - - // genie file variables - int fluxver; // 0 = old flux, 1 = new flux - std::string currentfilestring; - long local_entry=0; // - int tchainentrynum=0; // - int tchainentrynum_fw=0; - bool fromwcsim; - bool on_grid; }; diff --git a/UserTools/ReweightEventsGenie/WeightCalc.cpp b/UserTools/ReweightFlux/WeightCalc.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/WeightCalc.cpp rename to UserTools/ReweightFlux/WeightCalc.cpp diff --git a/UserTools/ReweightEventsGenie/WeightCalc.h b/UserTools/ReweightFlux/WeightCalc.h similarity index 100% rename from UserTools/ReweightEventsGenie/WeightCalc.h rename to UserTools/ReweightFlux/WeightCalc.h diff --git a/UserTools/ReweightEventsGenie/WeightCalcCreator.cpp b/UserTools/ReweightFlux/WeightCalcCreator.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/WeightCalcCreator.cpp rename to UserTools/ReweightFlux/WeightCalcCreator.cpp diff --git a/UserTools/ReweightEventsGenie/WeightCalcCreator.h b/UserTools/ReweightFlux/WeightCalcCreator.h similarity index 100% rename from UserTools/ReweightEventsGenie/WeightCalcCreator.h rename to UserTools/ReweightFlux/WeightCalcCreator.h diff --git a/UserTools/ReweightEventsGenie/WeightCalcFactory.cpp b/UserTools/ReweightFlux/WeightCalcFactory.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/WeightCalcFactory.cpp rename to UserTools/ReweightFlux/WeightCalcFactory.cpp diff --git a/UserTools/ReweightEventsGenie/WeightCalcFactory.h b/UserTools/ReweightFlux/WeightCalcFactory.h similarity index 100% rename from UserTools/ReweightEventsGenie/WeightCalcFactory.h rename to UserTools/ReweightFlux/WeightCalcFactory.h diff --git a/UserTools/ReweightEventsGenie/WeightManager.cpp b/UserTools/ReweightFlux/WeightManager.cpp similarity index 100% rename from UserTools/ReweightEventsGenie/WeightManager.cpp rename to UserTools/ReweightFlux/WeightManager.cpp diff --git a/UserTools/ReweightEventsGenie/WeightManager.h b/UserTools/ReweightFlux/WeightManager.h similarity index 100% rename from UserTools/ReweightEventsGenie/WeightManager.h rename to UserTools/ReweightFlux/WeightManager.h diff --git a/UserTools/ReweightEventsGenie/Weight_t.h b/UserTools/ReweightFlux/Weight_t.h similarity index 100% rename from UserTools/ReweightEventsGenie/Weight_t.h rename to UserTools/ReweightFlux/Weight_t.h diff --git a/UserTools/RingCounting/README.md b/UserTools/RingCounting/README.md index 8a2377936..22fff5bfd 100644 --- a/UserTools/RingCounting/README.md +++ b/UserTools/RingCounting/README.md @@ -47,10 +47,12 @@ FinaliseFunction Finalise verbose 1 -load_from_file 0 # If set to 1, load CNNImage formatted csv files -files_to_load configfiles/RingCounting/files_to_load.txt # txt file containing files to load in case load_from_file == 1 -version 1_0_0 # Model version -model_path /annie/app/users/dschmid/RingCountingStore/models/ # Model path -pmt_mask november_22 # Masked PMTs (name of hard-coded set of PMTs to ignore) -save_to RC_output.csv # Prediction output file, used if load_from_file == 1 +load_from_csv 0 # If set to 1, load CNNImage-formatted csv files +save_to_csv 0 # If set to 1, save predictions to csv files +save_to RC_output.csv # Prediction output file, used if load_from_csv and + # save_to_csv are both true. +files_to_load configfiles/RingCounting/files_to_load.txt # txt file containing files to load in case load_from_file == 1 +version 1_0_0 # Model version +model_path /exp/annie/app/users/dschmid/RingCountingStore/models/ # Model path +pmt_mask november_22 # Masked PMTs (name of hard-coded set of PMTs to ignore) ``` diff --git a/UserTools/RingCounting/RingCounting.py b/UserTools/RingCounting/RingCounting.py index 032c21d04..32ed3aa59 100644 --- a/UserTools/RingCounting/RingCounting.py +++ b/UserTools/RingCounting/RingCounting.py @@ -15,26 +15,36 @@ # Daniel Tobias Schmid, Feb. 2023, dschmid@fnal.gov / d.schmid@students.uni-mainz.de # -------------------------------------------------------------------------------------------------------------------- # -# The Cherenkov-ring-counting tool is used to classify events as single- or multi-ring by analyzing PMT hit maps loaded -# from a CSV file of CNNImage displays. It uses a keras based neural network. To use this tool in a ToolChain, users +# The Cherenkov-ring-counting tool is used to classify events as single- or multi-ring by analyzing 10x16 PMT hit maps. +# Data is loaded from a CSV file of CNNImage displays, or using the CNNImage tool can be created with data provided +# by other tools. It uses a keras/tf based Convolutional Neural Network. To use this tool in a ToolChain, users # must populate the the corresponding "/configfiles/YourToolChain/RingCountingConfig" file with the following # information: -# (Square brackets imply a variable in the config file) -# 1. The path to a file containing a list of files of the PMT data to be used.Must be in CNNImage format. +# (Square brackets are a variable in the config file) +# 1. The path to a file containing a list of files of the PMT data to be used, if data is to be loaded from a csv +# file. Must be in CNNImage format. # -> defined by setting [[files_to_load]] -# 2. The model version +# 2. Whether to load from a csv file or use a previous ToolChain to process/load processed data/MC +# -> defined by setting [[load_from_csv]] +# 3. Whether to save to a csv file when previously loading data from a csv file (both have to be 1) +# -> defined by setting [[save_to_csv]] +# 4. The model version # -> defined by setting [[version]] -# Check the documentation! -# 3. The model directory path (not including the model's filename, but including last slash) +# 5. The model directory path (not including the model's filename, but including last slash) # -> defined by setting [[model_path]] -# 4. Which PMT mask to use (some PMTs have been turned off in the training); check documentation for which model +# 6. Which PMT mask to use (some PMTs have been turned off in the training); check documentation for which model # requires what mask. # -> defined by setting [[pmt_mask]] -# 5. Where to save the predictions. +# 7. Where to save the predictions, when save_to_csv == true # -> defined by setting [[save_to]] # An example config file can also be found in in the RingCountingStore/documentation/ folders mentioned below. # -# Documentation on the tool, model versions and performance can be found in (anniegpvm-machine): +# +# When using on the grid, make sure to only use onsite computing resources. TensorFlow is not supported at all offsite +# facilities (July 2024). Also make sure to send the model to the grid, bundled with your process. +# +# +# Documentation of the tool, model versions and performance can(will) be found at (anniegpvm-machine): # /pnfs/annie/persistent/users/dschmid/RingCountingStore/documentation/ **TODO** # All models are located in (anniegpvm-machine): # /pnfs/annie/persistent/users/dschmid/RingCountingStore/models/ @@ -72,7 +82,8 @@ class RingCounting(Tool, RingCountingGlobals): # ---------------------------------------------------------------------------------------------------- # Config stuff - load_from_file = std.string() # if 1, load a CNNImage formatted csv file instead of using the tool chain + load_from_csv = std.string() # if 1, load 1 or more CNNImage formatted csv file instead of using toolchain + save_to_csv = std.string() # if 1, save as a csv file in format MR prediction, SR prediction files_to_load = std.string() # List of files to be loaded (must be in CNNImage format, # load_from_file has to be true) version = std.string() # Model version @@ -102,8 +113,10 @@ def Initialise(self): # Config area self.m_variables.Get("files_to_load", self.files_to_load) self.files_to_load = str(self.files_to_load) # cast to str since std.string =/= str - self.m_variables.Get("load_from_file", self.load_from_file) - self.load_from_file = "1" == str(self.load_from_file) + self.m_variables.Get("load_from_csv", self.load_from_csv) + self.load_from_csv = "1" == str(self.load_from_csv) + self.m_variables.Get("save_to_csv", self.save_to_csv) + self.save_to_csv = "1" == str(self.save_to_csv) self.m_variables.Get("version", self.version) self.m_variables.Get("model_path", self.model_path) self.m_variables.Get("pmt_mask", self.pmt_mask) @@ -113,7 +126,7 @@ def Initialise(self): # ---------------------------------------------------------------------------------------------------- # Loading data - if self.load_from_file: + if self.load_from_csv: self.load_data() else: self.m_log.Log(__file__ + " Not loading data from csv file.", self.v_message, self.m_verbosity) @@ -133,7 +146,7 @@ def Execute(self): self.mask_pmts() self.predict() - if not self.load_from_file: + if not self.load_from_csv: predicted_sr = float(self.predicted[0][1]) predicted_mr = float(self.predicted[0][0]) @@ -147,7 +160,9 @@ def Execute(self): def Finalise(self): """ Finalise the tool by saving the predictions. """ self.m_log.Log(__file__ + " Finalising", self.v_debug, self.m_verbosity) - if self.load_from_file: + if self.save_to_csv and self.load_from_csv: + # TODO: ToolChain -> save to csv + # Can currently only do csv -> csv or ToolChain -> BoostStore. self.save_data() return 1 @@ -202,7 +217,7 @@ def mask_pmts(self): """ Mask PMTs to 0. The PMTs to be masked is given as a list of indices, defined by setting [[pmt_mask]]. For further details check the RingCountingGlobals class. """ - if self.load_from_file: + if self.load_from_csv: for event in self.cnn_image_pmt: np.put(event, self.pmt_mask, 0, mode='raise') else: @@ -214,7 +229,7 @@ def load_model(self): def get_next_event(self): """ Get the next event from the BoostStore. """ - if self.load_from_file: + if self.load_from_csv: return reco_event_bs = self.m_data.Stores.at("RecoEvent") @@ -236,12 +251,12 @@ def get_next_event(self): def predict(self): """ - Classify events in single- and multi-ring events using a keras model. Save a list of 2-dimensional predictions + Classify events in single- and multi-ring events using a keras model. Store a list of 2-dimensional predictions (same order as input) to self.predicted. Predictions are given as [MR prediction, SR prediction]. """ 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/SimpleReconstruction/SimpleReconstruction.cpp b/UserTools/SimpleReconstruction/SimpleReconstruction.cpp index a512f4afe..b6b850a11 100644 --- a/UserTools/SimpleReconstruction/SimpleReconstruction.cpp +++ b/UserTools/SimpleReconstruction/SimpleReconstruction.cpp @@ -52,6 +52,7 @@ bool SimpleReconstruction::Execute(){ m_data->Stores["RecoEvent"]->Set("SimpleRecoTrackLengthInMRD",SimpleRecoTrackLengthInMRD); m_data->Stores["RecoEvent"]->Set("SimpleRecoMRDStart",SimpleRecoMRDStart); m_data->Stores["RecoEvent"]->Set("SimpleRecoMRDStop",SimpleRecoMRDStop); + m_data->Stores["RecoEvent"]->Set("SimpleRecoTrackLengthInTank",SimpleRecoTrackLengthInTank); //Fill Particles object with muon if (reco_possible){ @@ -113,6 +114,7 @@ void SimpleReconstruction::SetDefaultValues(){ SimpleRecoFV = false; SimpleRecoMrdEnergyLoss = -9999; SimpleRecoTrackLengthInMRD = -9999; + SimpleRecoTrackLengthInTank = -9999; SimpleRecoMRDStart.SetX(-9999); SimpleRecoMRDStart.SetY(-9999); SimpleRecoMRDStart.SetZ(-9999); @@ -380,6 +382,8 @@ bool SimpleReconstruction::SimpleVertexReconstruction(){ SimpleRecoVtx.SetY(reco_vtx_y); SimpleRecoVtx.SetZ(reco_vtx_z); + SimpleRecoTrackLengthInTank = sqrt((max_pe/9/2./100.*dirx)*(max_pe/9/2./100.*dirx) + (max_pe/9/2./100.*diry)*(max_pe/9/2./100.*diry) + (max_pe/9/2./100.*dirz)*(max_pe/9/2./100.*dirz)); + Log("SimpleEnergyReconstruction: Reconstructed interaction vertex: ("+std::to_string(SimpleRecoVtx.X())+","+std::to_string(SimpleRecoVtx.Y())+","+std::to_string(SimpleRecoVtx.Z())+")",v_message,verbosity); //Check if vertex is in Fiducial Volume diff --git a/UserTools/SimpleReconstruction/SimpleReconstruction.h b/UserTools/SimpleReconstruction/SimpleReconstruction.h index c26c9aa5b..e4ce5fb31 100644 --- a/UserTools/SimpleReconstruction/SimpleReconstruction.h +++ b/UserTools/SimpleReconstruction/SimpleReconstruction.h @@ -47,6 +47,7 @@ class SimpleReconstruction: public Tool { bool SimpleRecoFV; double SimpleRecoMrdEnergyLoss; double SimpleRecoTrackLengthInMRD; + double SimpleRecoTrackLengthInTank; Position SimpleRecoMRDStart; Position SimpleRecoMRDStop; diff --git a/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp b/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp index 56dae396a..f571b2e69 100644 --- a/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp +++ b/UserTools/TriggerDataDecoder/TriggerDataDecoder.cpp @@ -60,11 +60,17 @@ bool TriggerDataDecoder::Initialise(std::string configfile, DataModel &data){ bool TriggerDataDecoder::Execute(){ if (mode == "EventBuilding"){ + + processed_sources.clear(); + processed_ns.clear(); + 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; + } return true; } //Clear decoding maps if a new run/subrun is encountered @@ -98,7 +104,7 @@ bool TriggerDataDecoder::Execute(){ } bool new_ts_available = false; std::vector aTimeStampData = Tdata->TimeStampData; - std::cout <<"aTimeStampData.size(): "<0) std::cout <<"aTimeStampData.size(): "<v_debug) std::cout<<"TriggerDataDecoder Tool: Loading next TrigData from entry's index " << i <AddWord(aTimeStampData.at(i)); @@ -208,6 +214,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; } @@ -293,6 +315,7 @@ void TriggerDataDecoder::CheckForRunChange() std::stringstream ss_trig_overlap; ss_trig_overlap << "TrigOverlap_R"<`. + +The toolchain runs quickly (few seconds per part file), but when running over 20 part files as mentioned above the root file quickly explodes in size. For 20 part files, the root file size is ~700 MB. Until the tool is adjusted, the current solution is to use a bash script to run the toolchain in 20 part file chunks, then offload the root files from `/exp/annie/app/users/` to `scratch/` or `persistent/` to avoid overloading your app area. + +You can run this bash script via: `sh generate_AmBe_waveforms.sh `. Please make the appropriate changes to the bash file prior to running it (like user name, ToolAnalysis directory path, etc...). diff --git a/configfiles/AmBeWaveform/ToolChainConfig b/configfiles/AmBeWaveform/ToolChainConfig new file mode 100644 index 000000000..4e80a3628 --- /dev/null +++ b/configfiles/AmBeWaveform/ToolChainConfig @@ -0,0 +1,22 @@ +#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/AmBeWaveform/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 diff --git a/configfiles/AmBeWaveform/ToolsConfig b/configfiles/AmBeWaveform/ToolsConfig new file mode 100644 index 000000000..586f4776f --- /dev/null +++ b/configfiles/AmBeWaveform/ToolsConfig @@ -0,0 +1,4 @@ +myLoadANNIEEvent LoadANNIEEvent ./configfiles/AmBeWaveform/LoadANNIEEventConfig +myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +myFitRWMWaveform FitRWMWaveform ./configfiles/AmBeWaveform/FitRWMWaveformConfig + diff --git a/configfiles/AmBeWaveform/create_my_inputs.sh b/configfiles/AmBeWaveform/create_my_inputs.sh new file mode 100644 index 000000000..5f1c9f950 --- /dev/null +++ b/configfiles/AmBeWaveform/create_my_inputs.sh @@ -0,0 +1,20 @@ +#!/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/processed_EBV2/R${run}/" + +find "$processed_dir" -type f -name "Processed*" | sort -t'/' -k2V > "$output_file" + +echo "done" + diff --git a/configfiles/AmBeWaveform/generate_AmBe_waveforms.sh b/configfiles/AmBeWaveform/generate_AmBe_waveforms.sh new file mode 100644 index 000000000..7fc689e71 --- /dev/null +++ b/configfiles/AmBeWaveform/generate_AmBe_waveforms.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# Author: Steven Doran + +echo "" +echo "Please make sure you have done the following: + + - Using the following toolchain: + * LoadANNIEEvent + * LoadGeometry + * FitRWMWaveform + + - Enable 'printToRootFile 1' in the FitRWMWaveform tool + - Per 20 part files, ensure 'maxPrintNumber 20000' (you can expect ~15,000 waveforms per 20 part files) + + - Set the correct configurations in this script: + * pro_dir (processed files directory) + * step_size (number of files to execute per toolchain execution) + * user (name of present user) + * TA_folder (name of ToolAnalysis directory) + * toolchain (name of toolchain to be executed) + * offload (scratch or persistent area where you can copy large root files to - /exp/annie/app/ only allocates ~50 GB of space) + + - Have a temporary tmp/ folder bind mounted for singularity in your /exp/annie/app/user// area + * example: singularity shell -B/pnfs:/pnfs,/exp/annie/app/users/$user/temp_directory:/tmp, ... + +" +sleep 5 + +# Check if the user provided a run argument +if [[ -z "$1" ]]; then + echo "" + echo "##############################" + echo "Error: No run number provided." + echo "Usage: $0 " + echo "" + exit 1 +fi + + +# +# +# +# ********************************************************************* # +run=$1 + +pro_dir="/pnfs/annie/persistent/processed/processed_EBV2/R${run}/" +step_size=20 + +user="" + +TA_folder="ToolAnalysis/" +toolchain="AmBeWaveform" + +offload="/pnfs/annie/scratch/users/${user}/AmBe_dump/" + +# ********************************************************************* # +# +# +# + + +echo "" +echo "Generating AmBe waveforms for Run ${run}..." +echo "" +echo "User set to $user" +echo "" + +# Check if the run was processed +if [[ ! -d "$pro_dir" ]]; then + echo "Error: Directory $pro_dir does not exist." + echo "" + exit 1 +fi + +# Get the list of raw files and count them +pro_files=($(ls "$pro_dir" | grep "^ProcessedData_PMT_R${run}S0p")) +num_pro_files=${#pro_files[@]} + +if (( num_pro_files <= step_size )); then + start_indices=("0") + end_indices=($(($num_pro_files - 1))) +else + start_indices=("0") + end_indices=() + + for (( i=step_size; i> "$my_files" + done + + cp $my_files /exp/annie/app/users/$user/$TA_folder/configfiles/$toolchain/. + + echo "" + cat /exp/annie/app/users/$user/$TA_folder/configfiles/$toolchain/$my_files + echo "" + echo "" + echo "" + + sleep 3 + + # Enter the Singularity environment and execute commands + singularity shell -B/pnfs:/pnfs,/exp/annie/app/users/$user/temp_directory:/tmp,/exp/annie/data:/exp/annie/data,/exp/annie/app:/exp/annie/app /cvmfs/singularity.opensciencegrid.org/anniesoft/toolanalysis:latest << EOF + + cd /exp/annie/app/users/$user/$TA_folder + + source Setup.sh + + ./Analyse ./configfiles/$toolchain/ToolChainConfig + + exit + +EOF + + echo "" + ls -lrth /exp/annie/app/users/$user/$TA_folder + echo "" + + # copy large root files from /annie/app area to some persistent or scratch area + mkdir -p $offload/$run + + # setup transfer + source /cvmfs/fermilab.opensciencegrid.org/products/common/etc/setup + setup ifdhc v2_5_4 + + echo "" + echo "Copying ProcessedData Files..." + echo "" + + ifdh cp /exp/annie/app/users/$user/$TA_folder/RWMBRFWaveforms.root $offload/$run/AmBeWaveforms_${run}_p${p_start}_p${p_end}.root + sleep 1 + rm -rf /exp/annie/app/users/$user/$TA_folder/RWMBRFWaveforms.root + + ls -lrth $offload/$run + echo "" + + sleep 5 + + +echo "" +echo "done" +echo "" + +done diff --git a/configfiles/AmBeWaveform/my_inputs.txt b/configfiles/AmBeWaveform/my_inputs.txt new file mode 100644 index 000000000..ff48013ec --- /dev/null +++ b/configfiles/AmBeWaveform/my_inputs.txt @@ -0,0 +1,3 @@ +/pnfs/annie/persistent/processed/processed_EBV2/R4499/ProcessedData_PMT_R4499S0p0 +/pnfs/annie/persistent/processed/processed_EBV2/R4499/ProcessedData_PMT_R4499S0p1 +/pnfs/annie/persistent/processed/processed_EBV2/R4499/ProcessedData_PMT_R4499S0p2 diff --git a/configfiles/BeamClusterAnalysis/ANNIEEventTreeMakerConfig b/configfiles/BeamClusterAnalysis/ANNIEEventTreeMakerConfig new file mode 100644 index 000000000..8084b3635 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/ANNIEEventTreeMakerConfig @@ -0,0 +1,32 @@ +ANNIEEventTreeMakerVerbosity 0 + +fillAllTriggers 1 +fill_singleTrigger 0 +fillLAPPDEventsOnly 0 +TankCluster_fill 1 +cluster_TankHitInfo_fill 1 + +TankReco_fill 0 + +OutputFile ANNIETree.root +TankClusterProcessing 1 +MRDClusterProcessing 1 +TriggerProcessing 1 +TankHitInfo_fill 1 +MRDHitInfo_fill 1 +MRDReco_fill 1 +SiPMPulseInfo_fill 0 +fillCleanEventsOnly 0 +MCTruth_fill 0 +Reco_fill 1 +RecoDebug_fill 0 +muonTruthRecoDiff_fill 0 +isData 1 +HasGenie 0 +RingCounting_fill 1 + +LAPPDData_fill 1 +LAPPDReco_fill 1 +RWMBRF_fill 1 +LAPPD_PPS_fill 1 +LAPPD_Waveform_fill 0 diff --git a/configfiles/BeamClusterAnalysis/CNNImageConfig b/configfiles/BeamClusterAnalysis/CNNImageConfig new file mode 100644 index 000000000..c4048f220 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/CNNImageConfig @@ -0,0 +1,17 @@ +# 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 + +IsData 1 diff --git a/configfiles/BeamClusterAnalysis/ChannelSPEGains2023.csv b/configfiles/BeamClusterAnalysis/ChannelSPEGains2023.csv new file mode 100644 index 000000000..b65b82d52 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/ChannelSPEGains2023.csv @@ -0,0 +1,122 @@ +332 0.001345 +334 0.001421 +335 0.001375 +336 0.001222 +338 0.001387 +339 0.001038 +340 0.001248 +341 0.001543 +343 0.000267 +344 0.001334 +347 0.001570 +348 0.001478 +350 0.001290 +351 0.001455 +353 0.000380 +354 0.001767 +355 0.001198 +356 0.000478 +357 0.001922 +358 0.000923 +359 0.000281 +360 0.001380 +361 0.000748 +362 0.001344 +363 0.001367 +364 0.001223 +365 0.001003 +366 0.000631 +367 0.001649 +368 0.001776 +369 0.000722 +370 0.001148 +371 0.001657 +372 0.001653 +373 0.001443 +374 0.001435 +375 0.001382 +376 0.001476 +377 0.001466 +378 0.001382 +379 0.001521 +380 0.001265 +381 0.001465 +382 0.001248 +383 0.001465 +384 0.001618 +385 0.001540 +386 0.001438 +387 0.001528 +388 0.001353 +389 0.001616 +390 0.001268 +391 0.001271 +392 0.001406 +393 0.001628 +394 0.001487 +395 0.001701 +396 0.001678 +397 0.001547 +398 0.001368 +399 0.001428 +400 0.001328 +401 0.001480 +402 0.001311 +403 0.001130 +404 0.001569 +405 0.000906 +406 0.001542 +407 0.001491 +408 0.001396 +409 0.001414 +410 0.001386 +411 0.001278 +412 0.001401 +413 0.001499 +414 0.001488 +415 0.001217 +416 0.0 +417 0.001468 +418 0.001457 +419 0.001248 +420 0.001744 +421 0.001398 +422 0.001409 +423 0.001324 +424 0.001548 +425 0.001455 +426 0.001274 +427 0.001316 +428 0.001420 +429 0.001338 +430 0.001515 +432 0.001307 +433 0.001279 +434 0.001357 +435 0.001416 +436 0.001345 +437 0.001448 +438 0.001350 +439 0.001398 +440 0.001487 +441 0.001459 +442 0.001291 +443 0.001236 +446 0.001495 +447 0.001373 +448 0.001353 +449 0.001375 +450 0.001321 +451 0.001302 +452 0.001618 +453 0.001466 +454 0.001241 +455 0.001388 +456 0.001535 +457 0.001650 +458 0.001478 +459 0.001360 +460 0.001463 +461 0.001375 +462 0.001420 +463 0.001396 diff --git a/configfiles/BeamClusterAnalysis/ClusterClassifiersConfig b/configfiles/BeamClusterAnalysis/ClusterClassifiersConfig index 199d3866f..752200268 100644 --- a/configfiles/BeamClusterAnalysis/ClusterClassifiersConfig +++ b/configfiles/BeamClusterAnalysis/ClusterClassifiersConfig @@ -1 +1 @@ -verbosity 2 +verbosity 0 diff --git a/configfiles/BeamClusterAnalysis/ClusterFinderConfig b/configfiles/BeamClusterAnalysis/ClusterFinderConfig index 337d7fc2e..95d8b6d0f 100644 --- a/configfiles/BeamClusterAnalysis/ClusterFinderConfig +++ b/configfiles/BeamClusterAnalysis/ClusterFinderConfig @@ -3,10 +3,11 @@ 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 100 # in ns, size of the window used to "clusterize" +ClusterFindingWindow 40 # in ns, size of the window used to "clusterize" AcqTimeWindow 70000 # in ns, size of the acquisition window -ClusterIntegrationWindow 100 # in ns, all hits with +/- 1/2 of this window are considered in the cluster +ClusterIntegrationWindow 40 # 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? ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat +MC_pulse_width 10 # 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/BeamClusterAnalysis/ClusterFinderConfig_default b/configfiles/BeamClusterAnalysis/ClusterFinderConfig_default new file mode 100644 index 000000000..337d7fc2e --- /dev/null +++ b/configfiles/BeamClusterAnalysis/ClusterFinderConfig_default @@ -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 100 # in ns, size of the window used to "clusterize" +AcqTimeWindow 70000 # in ns, size of the acquisition window +ClusterIntegrationWindow 100 # 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? +ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat diff --git a/configfiles/BeamClusterAnalysis/DigitBuilderConfig b/configfiles/BeamClusterAnalysis/DigitBuilderConfig new file mode 100644 index 000000000..81127ff34 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/DigitBuilderConfig @@ -0,0 +1,15 @@ +# DigitBuilder config file + +verbosity 0 +ParametricModel 1 +#Reading in MC files +IsMC 0 +# 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 + +ChankeyToPMTIDMap ./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt +SinglePEGains ./configfiles/BeamClusterAnalysis/ChannelSPEGains2023.csv + diff --git a/configfiles/BeamClusterAnalysis/EventSelectorConfig b/configfiles/BeamClusterAnalysis/EventSelectorConfig index 73250c81d..a711f08bf 100644 --- a/configfiles/BeamClusterAnalysis/EventSelectorConfig +++ b/configfiles/BeamClusterAnalysis/EventSelectorConfig @@ -19,7 +19,7 @@ RecoFVCut 0 NHitCut 0 NHitmin 4 #Minimum number of hit digits PMTMRDCoincCut 0 -PMTMRDOffset 745 +PMTMRDOffset 755 PromptTrigOnly 0 TriggerWord -1 SaveStatusToStore 1 diff --git a/configfiles/BeamClusterAnalysis/FitRWMWaveformConfig b/configfiles/BeamClusterAnalysis/FitRWMWaveformConfig new file mode 100644 index 000000000..0a724adf4 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/FitRWMWaveformConfig @@ -0,0 +1,4 @@ +verbosityFitRWMWaveform 1 +printToRootFile 1 + + diff --git a/configfiles/BeamClusterAnalysis/LoadANNIEEventConfig b/configfiles/BeamClusterAnalysis/LoadANNIEEventConfig index a26db8731..73ea107d7 100644 --- a/configfiles/BeamClusterAnalysis/LoadANNIEEventConfig +++ b/configfiles/BeamClusterAnalysis/LoadANNIEEventConfig @@ -1,4 +1,4 @@ -verbose 0 +verbose 1 FileForListOfInputs ./configfiles/BeamClusterAnalysis/my_inputs.txt EventOffset 0 GlobalEvNr 1 diff --git a/configfiles/BeamClusterAnalysis/PhaseIITreeMakerConfig b/configfiles/BeamClusterAnalysis/PhaseIITreeMakerConfig index eee2e9cb4..991caba81 100644 --- a/configfiles/BeamClusterAnalysis/PhaseIITreeMakerConfig +++ b/configfiles/BeamClusterAnalysis/PhaseIITreeMakerConfig @@ -1,6 +1,6 @@ verbose 0 -OutputFile BeamRun_R2573_AllTriggers.ntuple.root +OutputFile BeamRunTree.root TankClusterProcessing 1 MRDClusterProcessing 1 TriggerProcessing 1 @@ -10,8 +10,11 @@ MRDReco_fill 1 SiPMPulseInfo_fill 0 fillCleanEventsOnly 1 MCTruth_fill 0 -Reco_fill 0 +Reco_fill 1 RecoDebug_fill 0 muonTruthRecoDiff_fill 0 IsData 1 HasGenie 0 + +LAPPDData_fill 1 +LAPPDReco_fill 1 diff --git a/configfiles/BeamClusterAnalysis/RingCountingConfig b/configfiles/BeamClusterAnalysis/RingCountingConfig new file mode 100644 index 000000000..4bd2ac8a6 --- /dev/null +++ b/configfiles/BeamClusterAnalysis/RingCountingConfig @@ -0,0 +1,25 @@ +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/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/AssignBunchTimingMCConfig b/configfiles/BeamClusterAnalysisMC/AssignBunchTimingMCConfig new file mode 100644 index 000000000..8bebe310a --- /dev/null +++ b/configfiles/BeamClusterAnalysisMC/AssignBunchTimingMCConfig @@ -0,0 +1,14 @@ +# AssignBunchTimingMC Config File + +verbosity 0 + +# BNB properties taken from: MicroBooNE https://doi.org/10.1103/PhysRevD.108.052010 +bunchwidth 1.308 # BNB instrinic bunch spread [ns] +bunchinterval 18.936 # BNB bunch spacings [ns] +bunchcount 81 # number of BNB bunches per spill + +BRFfituncertainty 1.809 # jitter in our beam signals / BRF fitting uncertainty [ns] + +sampletype 0 # Tank (0) or World (1) genie samples you are running over +prompttriggertime 1 # WCSim prompt trigger settings: (0 = default, t0 = 0 when a particle enters the volume) + # (1 = modified, t0 = 0 when the neutrino beam dump begins) 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 59ef4564a..7908df285 100644 --- a/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig +++ b/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig @@ -3,10 +3,10 @@ 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 100 # 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 100 # 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? -ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat +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/DeadPMTIDs_p2v7.txt b/configfiles/BeamClusterAnalysisMC/DeadPMTIDs_p2v7.txt index a5e258dad..4ce119098 100644 --- a/configfiles/BeamClusterAnalysisMC/DeadPMTIDs_p2v7.txt +++ b/configfiles/BeamClusterAnalysisMC/DeadPMTIDs_p2v7.txt @@ -1,4 +1,5 @@ 2 +6 11 14 15 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 6e22a33ba..4da19c900 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig @@ -1,11 +1,24 @@ -verbosity 2 -FluxVersion 0 # use 0 to load genie files based on bnb_annie_0000.root etc files - # use 1 to load files based on beammc_annie_0000.root etc files -#FileDir NA # specify "NA" for newer files: full path is saved in WCSim -FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 -#FileDir /pnfs/annie/persistent/users/moflaher/genie/BNB_World_10k_11-03-18_gsimpleflux -FilePattern gntp.197.ghep.root -#FilePattern LoadWCSimTool ## use this pattern to load corresponding genie info with the LoadWCSimTool - ## N.B: FileDir must still be specified for now! (WCSim files do not record their directory) -ManualFileMatching 0 -EventOffset 0 +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) + # use 1 to load files based on beammc_annie_0000.root etc files (generated by Zarko, gsimple flux format) + # - All GENIE (and WCSim) files generated by James uses gsimple (1) format + +# 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/simulations/genie3/G1810a0211a/standard/tank + +# Name of GENIE file to open +FilePattern gntp.99.ghep.root # gntp.[run_number].ghep.root +#FilePattern LoadWCSimTool # special option to load GENIE events corresponding to WCSim events + +# Option to match GENIE events to WCSim events without using file path saved in WCSim file +ManualFileMatching 1 # 0 (false) - no manual matching, 1 (true) - uses FileDir and info from WCSim file name to find GENIE files/events - strongly recommended to use (1)! (as of Aug 2023) + +# Number of events in the WCSim file (used for offsetting the GENIE file event when used in conjunction with ManualFileMatching) +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 diff --git a/configfiles/BeamClusterAnalysisMC/LoadGeometryConfig b/configfiles/BeamClusterAnalysisMC/LoadGeometryConfig index 894092ba3..c64227136 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadGeometryConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadGeometryConfig @@ -4,5 +4,5 @@ FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv LAPPDGeoFile ./configfiles/LoadGeometry/LAPPDGeometry.csv TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv -TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains2023.csv AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv diff --git a/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig b/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig index defd4639b..717035a0c 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig @@ -1,13 +1,13 @@ #LoadWCSim 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_0.1.9.root -#InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_ambe_port5_z0_5000_0.root -InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/pmt-files/wcsim_beam_gst_1079_0_0.9000.root -#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/pmt-files/wcsim_beam_gst_1079_9_0.9009.root -#InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_michel_1000_0.root -#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_throughgoing/wcsim_throughgoing_muon_R2614_0.0.root +# 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/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 29999cdee..f6407f1a5 100644 --- a/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig +++ b/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig @@ -1,6 +1,7 @@ verbose 5 -OutputFile MCBeam_Gst_new_Run9000_NoSplitSubTriggers.ntuple.root +OutputFile MCBeam_Gst_G1810a0211a_ntuple.root + TankClusterProcessing 1 MRDClusterProcessing 1 TriggerProcessing 1 @@ -11,7 +12,11 @@ SiPMPulseInfo_fill 0 fillCleanEventsOnly 0 MCTruth_fill 1 Reco_fill 0 +TankReco_fill 0 RecoDebug_fill 0 +SimpleReco_fill 0 +Reweight_fill 0 muonTruthRecoDiff_fill 0 IsData 0 -HasGenie 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 55400ce09..1d60f1abb 100644 --- a/configfiles/BeamClusterAnalysisMC/ToolsConfig +++ b/configfiles/BeamClusterAnalysisMC/ToolsConfig @@ -4,9 +4,16 @@ 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 +myCNNImage CNNImage ./configfiles/BeamClusterAnalysisMC/CNNImageConfig +myRingCounting PythonScript configfiles/BeamClusterAnalysisMC/RingCountingConfig +myANNIEEventTreeMaker ANNIEEventTreeMaker ./configfiles/BeamClusterAnalysisMC/ANNIEEventTreeMakerConfig +myAssignBunchTimingMC AssignBunchTimingMC ./configfiles/BeamClusterAnalysisMC/AssignBunchTimingMCConfig myPhaseIITreeMaker PhaseIITreeMaker ./configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig 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/BeamFetcherV2Config b/configfiles/BeamFetcherV2/BeamFetcherV2Config new file mode 100644 index 000000000..b49564534 --- /dev/null +++ b/configfiles/BeamFetcherV2/BeamFetcherV2Config @@ -0,0 +1,8 @@ +# BeamFetcher config file +verbose 5 +DevicesFile ./configfiles/BeamFetcherV2/devices.txt # File containing one device per line or a bundle +IsBundle 1 # bool stating whether DevicesFile contains bundles or individual devices +FetchFromTimes 0 # bool defining how to grab the data (from input times (1) or trigger(0)) +TimeChunkStepInMilliseconds 3600000 # one hour +SaveROOT 1 # bool, do you want to write a ROOT file with the timestamps and devices? +DeleteCTCData 1 diff --git a/configfiles/BeamFetcherV2/CreateMyList.sh b/configfiles/BeamFetcherV2/CreateMyList.sh new file mode 100644 index 000000000..4ccfef7cc --- /dev/null +++ b/configfiles/BeamFetcherV2/CreateMyList.sh @@ -0,0 +1,19 @@ +if [ "$#" -ne 1 ]; then + echo "Usage: ./CreateMyList.sh RUN" + echo "Specified input variable must contain the run number" + exit 1 +fi + +RUN=$1 +DIR=/pnfs/annie/persistent/raw/raw/ + +NUMFILES=$(ls -1q ${DIR}${RUN}/RAWDataR${RUN}* | wc -l) + +echo "NUMBER OF FILES IN ${DIR}${RUN}: ${NUMFILES}" + +rm my_files.txt + +for p in $(seq 0 $(($NUMFILES -1 ))) +do + echo "${DIR}${RUN}/RAWDataR${RUN}S0p${p}" >> my_files.txt +done diff --git a/configfiles/BeamFetcherV2/DefaultTriggerMask.txt b/configfiles/BeamFetcherV2/DefaultTriggerMask.txt new file mode 100644 index 000000000..05f190104 --- /dev/null +++ b/configfiles/BeamFetcherV2/DefaultTriggerMask.txt @@ -0,0 +1,3 @@ +#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 +14 diff --git a/configfiles/BeamFetcherV2/LoadRawDataConfig b/configfiles/BeamFetcherV2/LoadRawDataConfig new file mode 100644 index 000000000..cff346d06 --- /dev/null +++ b/configfiles/BeamFetcherV2/LoadRawDataConfig @@ -0,0 +1,8 @@ +verbosity 11 +BuildType CTC +Mode FileList +InputFile ./configfiles/BeamFetcherV2/my_files.txt +DummyRunInfo 1 +StoreTrigOverlap 0 +ReadTrigOverlap 0 +StoreRawData 0 diff --git a/configfiles/BeamFetcherV2/README.md b/configfiles/BeamFetcherV2/README.md new file mode 100644 index 000000000..e334f5143 --- /dev/null +++ b/configfiles/BeamFetcherV2/README.md @@ -0,0 +1,3 @@ +See the BeamFetcherV2 tool for description/usage. + +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/ReweightEventsGenie/ToolChainConfig b/configfiles/BeamFetcherV2/ToolChainConfig similarity index 89% rename from configfiles/ReweightEventsGenie/ToolChainConfig rename to configfiles/BeamFetcherV2/ToolChainConfig index 9f1962a53..32618da66 100644 --- a/configfiles/ReweightEventsGenie/ToolChainConfig +++ b/configfiles/BeamFetcherV2/ToolChainConfig @@ -18,7 +18,7 @@ service_publish_sec -1 service_kick_sec -1 ##### Tools To Add ##### -Tools_File configfiles/ReweightEventsGenie/ToolsConfig ## list of tools to run and their config files +Tools_File configfiles/BeamFetcherV2/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 diff --git a/configfiles/BeamFetcherV2/ToolsConfig b/configfiles/BeamFetcherV2/ToolsConfig new file mode 100644 index 000000000..2141e92ed --- /dev/null +++ b/configfiles/BeamFetcherV2/ToolsConfig @@ -0,0 +1,4 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +LoadRawData LoadRawData ./configfiles/BeamFetcherV2/LoadRawDataConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/BeamFetcherV2/TriggerDataDecoderConfig +BeamFetcherV2 BeamFetcherV2 ./configfiles/BeamFetcherV2/BeamFetcherV2Config diff --git a/configfiles/BeamFetcherV2/TriggerDataDecoderConfig b/configfiles/BeamFetcherV2/TriggerDataDecoderConfig new file mode 100644 index 000000000..843bb5357 --- /dev/null +++ b/configfiles/BeamFetcherV2/TriggerDataDecoderConfig @@ -0,0 +1,4 @@ +verbosity 0 +TriggerMaskFile ./configfiles/BeamFetcherV2/DefaultTriggerMask.txt +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/BeamFetcherV2/devices.txt b/configfiles/BeamFetcherV2/devices.txt new file mode 100644 index 000000000..0bf9117bd --- /dev/null +++ b/configfiles/BeamFetcherV2/devices.txt @@ -0,0 +1 @@ +BoosterNeutrinoBeam_read diff --git a/configfiles/BeamFetcherV2/my_files.txt b/configfiles/BeamFetcherV2/my_files.txt new file mode 100644 index 000000000..509031822 --- /dev/null +++ b/configfiles/BeamFetcherV2/my_files.txt @@ -0,0 +1,4 @@ +/pnfs/annie/persistent/raw/raw/4774/RAWDataR4774S0p1 +/pnfs/annie/persistent/raw/raw/4774/RAWDataR4774S0p2 +/pnfs/annie/persistent/raw/raw/4774/RAWDataR4774S0p3 +/pnfs/annie/persistent/raw/raw/4774/RAWDataR4774S0p4 diff --git a/configfiles/CC_MC_RECO_ntuple/AssignBunchTimingMCConfig b/configfiles/CC_MC_RECO_ntuple/AssignBunchTimingMCConfig new file mode 100644 index 000000000..3fd95b480 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/AssignBunchTimingMCConfig @@ -0,0 +1,14 @@ +# AssignBunchTimingMC Config File + +verbosity 0 + +# BNB properties taken from: MicroBooNE https://doi.org/10.1103/PhysRevD.108.052010 +bunchwidth 1.308 # BNB instrinic bunch spread [ns] +bunchinterval 18.936 # BNB bunch spacings [ns] +bunchcount 81 # number of BNB bunches per spill + +BRFfituncertainty 1.809 # jitter in our beam signals / BRF fitting uncertainty [ns] + +sampletype 0 # Tank (0) or World (1) genie samples you are running over +prompttriggertime 1 # WCSim prompt trigger settings: (0 = default, t0 = 0 when a particle enters the volume) + # (1 = modified, t0 = 0 when the neutrino beam dump begins) diff --git a/configfiles/CC_MC_RECO_ntuple/CNNImageConfig b/configfiles/CC_MC_RECO_ntuple/CNNImageConfig new file mode 100644 index 000000000..e6e997fa5 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/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/CC_MC_RECO_ntuple/ClusterClassifiersConfig b/configfiles/CC_MC_RECO_ntuple/ClusterClassifiersConfig new file mode 100644 index 000000000..948ed3354 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/ClusterClassifiersConfig @@ -0,0 +1,3 @@ +#ClusterClassifiers Config file +verbosity 0 +IsData 0 diff --git a/configfiles/CC_MC_RECO_ntuple/ClusterFinderConfig b/configfiles/CC_MC_RECO_ntuple/ClusterFinderConfig new file mode 100644 index 000000000..90934ea38 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/ClusterFinderConfig @@ -0,0 +1,12 @@ +# ClusterFinder Config File + +verbosity 0 +HitStore MCHits #Either MCHits or Hits (accessed in ANNIEEvent store) +OutputFile mc_clusters.root +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 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/CC_MC_RECO_ntuple/DigitBuilderConfig b/configfiles/CC_MC_RECO_ntuple/DigitBuilderConfig new file mode 100644 index 000000000..989becdc6 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/DigitBuilderConfig @@ -0,0 +1,8 @@ +# DigitBuilder config file + +verbosity 0 +isMC 1 +ParametricModel 1 +PhotoDetectorConfiguration All +LAPPDIDFile ./configfiles/VertexReco/PhaseIIRecoTruth/LAPPDIDs.txt +DigitChargeThr 10 diff --git a/configfiles/CC_MC_RECO_ntuple/EventSelectorConfig b/configfiles/CC_MC_RECO_ntuple/EventSelectorConfig new file mode 100644 index 000000000..913100d0d --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/EventSelectorConfig @@ -0,0 +1,26 @@ +# EventSelector config file + +verbosity 0 +MRDRecoCut 0 +MCFVCut 0 +MCPMTVolCut 0 +MCMRDCut 0 +MCPiKCut 0 +MCIsMuonCut 0 +MCIsElectronCut 0 +MCIsSingleRingCut 0 +MCIsMultiRingCut 0 +MCProjectedMRDHit 0 +MCEnergyCut 0 +Emin 0 +Emax 5000 +NHitCut 0 +NHitmin 4 +PromptTrigOnly 0 +RecoFVCut 0 +RecoPMTVolCut 0 +PMTMRDCoincCut 0 +PMTMRDOffset 10 +TriggerWord 5 +SaveStatusToStore 1 +IsMC 1 diff --git a/configfiles/CC_MC_RECO_ntuple/FindMrdTracksConfig b/configfiles/CC_MC_RECO_ntuple/FindMrdTracksConfig new file mode 100644 index 000000000..d78ed9b58 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/FindMrdTracksConfig @@ -0,0 +1,12 @@ +# FindMrdTracks Config File +# all variables retrieved with m_variables.Get() must be defined here! + +verbosity 0 +IsData 0 +OutputDirectory . +OutputFile mrdtrackfile # the output file built will be '/...root' +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/CC_MC_RECO_ntuple/LAPPDIDs.txt b/configfiles/CC_MC_RECO_ntuple/LAPPDIDs.txt new file mode 100644 index 000000000..776b28912 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/LAPPDIDs.txt @@ -0,0 +1,5 @@ +11 +13 +14 +15 +17 diff --git a/configfiles/ReweightEventsGenie/LoadGenieEventConfig b/configfiles/CC_MC_RECO_ntuple/LoadGenieEventConfig similarity index 81% rename from configfiles/ReweightEventsGenie/LoadGenieEventConfig rename to configfiles/CC_MC_RECO_ntuple/LoadGenieEventConfig index 7047236c7..1dcc71d18 100644 --- a/configfiles/ReweightEventsGenie/LoadGenieEventConfig +++ b/configfiles/CC_MC_RECO_ntuple/LoadGenieEventConfig @@ -1,12 +1,12 @@ -verbosity 100 +verbosity 0 FluxVersion 1 # use 0 to load genie files based on bnb_annie_0000.root etc files # use 1 to load files based on beammc_annie_0000.root etc files -FileDir NA # specify "NA" for newer files: full path is saved in WCSim +#FileDir NA # specify "NA" for newer files: full path is saved in WCSim #FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 #FileDir /pnfs/annie/persistent/users/moflaher/genie/BNB_World_10k_11-03-18_gsimpleflux #FileDir /pnfs/annie/persistent/simulations/genie3/G1810a0211a/standard/tank -#FileDir . ## Use with grid -#FilePattern gntp.*.ghep.root ## for specifying specific files to load +FileDir . ## Use with grid +#FilePattern gntp.0.ghep.root ## for specifying specific files to load FilePattern LoadWCSimTool ## use this pattern to load corresponding genie info with the LoadWCSimTool ## N.B: FileDir must still be specified for now! ManualFileMatching 0 ## to manually match GENIE event to corresponding WCSim event diff --git a/configfiles/CC_MC_RECO_ntuple/LoadReweightGenieEventConfig b/configfiles/CC_MC_RECO_ntuple/LoadReweightGenieEventConfig new file mode 100644 index 000000000..87bfab4fb --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/LoadReweightGenieEventConfig @@ -0,0 +1,71 @@ +# Reweightable GENIE cross section and beam flux model uncertainties +# Revised 19 Feb 2025 +# +# Maintainer:James Minock + +verbosity 0 +FluxVersion 1 # use 0 to load genie files based on bnb_annie_0000.root etc files + # use 1 to load files based on beammc_annie_0000.root etc files +#FileDir NA # specify "NA" for newer files: full path is saved in WCSim +#FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 +#FileDir /pnfs/annie/persistent/users/moflaher/genie/BNB_World_10k_11-03-18_gsimpleflux +#FileDir /pnfs/annie/persistent/simulations/genie3/G1810a0211a/standard/tank +FileDir . ## Use with grid +#FilePattern gntp.0.ghep.root ## for specifying specific files to load +FilePattern LoadWCSimTool ## use this pattern to load corresponding genie info with the LoadWCSimTool + ## N.B: FileDir must still be specified for now! +ManualFileMatching 0 ## to manually match GENIE event to corresponding WCSim event +FileEvents 1000 ## number of events in the WCSim file + ## 500 for Marcus files + ## 1000 for James files + +########################### REWEIGHT ################################### +genie_module_label generator + +genie_central_values MaCCQE:4.9778|RPA_CCQE:0.151|NormCCMEC:1.31189|XSecShape_CCMEC:1.0 + +weight_functions_xsec All0,All1,All2,All3,All4,All5,AxFFCCQEshape,DecayAngMEC,NormCCCOH,Norm_NCCOH,RPA_CCQE,RootinoFix,ThetaDelta2NRad,Theta_Delta2Npi,TunedCentralValue,VecFFCCQEshape,XSecShape_CCMEC + + # INDIVIDUAL WEIGHT CALCULATORS + # Thse use "minmax" mode and represent a variation between two extremes. The + # recommended uncertainty is the full spread between them. + +genie_qema type:Genie|random_seed:15|parameter_list:["QEMA"]|parameter_sigma:[1]|mode:multisim|number_of_multisims:10 + +RPA_CCQE type:UBGenie|random_seed:2|parameter_list:["RPA_CCQE"]|parameter_sigma:[0.4]|parameter_min:[-0.249]|parameter_max:[0.551]|mode:minmax|number_of_multisims:2 + +XSecShape_CCMEC type:UBGenie|random_seed:4|parameter_list:["XSecShape_CCMEC"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + +AxFFCCQEshape type:UBGenie|random_seed:5|parameter_list:["AxFFCCQEshape"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + +VecFFCCQEshape type:UBGenie|random_seed:6|parameter_list:["VecFFCCQEshape"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + +DecayAngMEC type:UBGenie|random_seed:7|parameter_list:["DecayAngMEC"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + +Theta_Delta2Npi type:UBGenie|random_seed:53|parameter_list:["Theta_Delta2Npi"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + + # New angular distribution variation for radiative Delta decays +ThetaDelta2NRad type:UBGenie|random_seed:54|parameter_list:["ThetaDelta2Rad"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + + # Unisim variation of CC COH normalization (still finalizing approach) +NormCCCOH type:UBGenie|random_seed:56|parameter_list:["NormCCCOH"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + + # Unisim variation of NC COH normalization (still finalizing approach) +NormNCCOH type:UBGenie|random_seed:57|parameter_list:["NormNCCOH"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 + +TunedCentralValue type:UBGenie|random_seed:99|parameter_list:["MaCCQE","RPA_CCQE","NormCCMEC","XSecShape_CCMEC"]|parameter_sigma:[1,1,1,1]|mode:central_value|number_of_multisims:1 + +RootinoFix type:UBGenie|random_seed:101|parameter_list:["RESRootino"]|parameter_sigma:[1]|mode:multisim|number_of_multisims:1 + + # ALL OTHER RECOMMENDED SYSTEMATIC VARIATIONS THROWN TOGETHER +All0 type:UBGenie|random_seed:100|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 + +All1 type:UBGenie|random_seed:1101|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 + +All2 type:UBGenie|random_seed:1102|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 + +All3 type:UBGenie|random_seed:1103|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 + +All4 type:UBGenie|random_seed:1104|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 + +All5 type:UBGenie|random_seed:1105|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 diff --git a/configfiles/CC_MC_RECO_ntuple/LoadWCSimConfig b/configfiles/CC_MC_RECO_ntuple/LoadWCSimConfig new file mode 100644 index 000000000..69362e3a2 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/LoadWCSimConfig @@ -0,0 +1,22 @@ +#LoadWCSim Config File +# all variables retrieved with m_variables.Get() must be defined here! +verbose 1 + +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_24-09-17_BNB_Water_10k_22-05-17/wcsim_0.49......19.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_03-05-17_rhatcher/wcsim_0.49......00.root ## first of the DOE proposal files +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_3-12-18_ANNIEp2v6_BNB_Water_10k_22-05-17/wcsim_0.49......19.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.49......19.root +#InputFile ./25_04_19_wcsim_0.49......19.root + +#InputFile /annie/app/users/jminock/ToolAnalysis/wcsim_0.root +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beamlike/wcsim_beamlike_muon_0.100.root +#InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/pmt/wcsim_0.0.0.root +InputFile ./wcsim_0.0.0.root +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/pmt-files/wcsim_beam_gst_1060_91_0.7091.root + +WCSimVersion 3 ## should reflect the WCSim version of the files being loaded +HistoricTriggeroffset 0 ## time offset of digits relative to the trigger +UseDigitSmearedTime 1 ## whether to use smeared digit time (T), or true time of first photon (F) +LappdNumStrips 56 ## num channels to construct from each LAPPD +LappdStripLength 100 ## relative x position of each LAPPD strip, for dual-sided readout [mm] +LappdStripSeparation 10 ## stripline separation, for calculating relative y position of each LAPPD strip [mm] diff --git a/configfiles/CC_MC_RECO_ntuple/LoadWCSimLAPPDConfig b/configfiles/CC_MC_RECO_ntuple/LoadWCSimLAPPDConfig new file mode 100644 index 000000000..6b42bbb28 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/LoadWCSimLAPPDConfig @@ -0,0 +1,14 @@ +#LoadWCSimLAPPD Config File +# all variables retrieved with m_variables.Get() must be defined here! +verbose 0 + +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_24-09-17_BNB_Water_10k_22-05-17/wcsim_lappd_0.49......19.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_03-05-17_rhatcher/wcsim_lappd_0.49......00.root ## first of the DOE proposal files +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beamlike/wcsim_beamlike_muon_lappd_0.100.root +#InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/lappd/wcsim_lappd_0.0.0.root +InputFile ./wcsim_lappd_0.0.0.root +#InputFile /annie/app/users/jminock/ToolAnalysis/wcsim_lappd_0.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/CC_MC_RECO_ntuple/MCParticlePropertiesConfig b/configfiles/CC_MC_RECO_ntuple/MCParticlePropertiesConfig new file mode 100644 index 000000000..019526011 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/MCParticlePropertiesConfig @@ -0,0 +1,3 @@ +# MCParticleProperties configuration file + +verbosity 0 diff --git a/configfiles/CC_MC_RECO_ntuple/MCRecoEventLoaderConfig b/configfiles/CC_MC_RECO_ntuple/MCRecoEventLoaderConfig new file mode 100644 index 000000000..e65013140 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/MCRecoEventLoaderConfig @@ -0,0 +1,10 @@ +# MCRecoEventLoader config file + +verbosity 0 +GetPionKaonInfo 1 +GetNRings 1 +ParticleID 13 +DoParticleSelection 0 +xshift 0.0 +yshift 14.46469 +zshift -168.1 diff --git a/configfiles/CC_MC_RECO_ntuple/MRD_Chankey_WCSimID.dat b/configfiles/CC_MC_RECO_ntuple/MRD_Chankey_WCSimID.dat new file mode 100644 index 000000000..32c665110 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/MRD_Chankey_WCSimID.dat @@ -0,0 +1,306 @@ +26 1 +27 3 +28 5 +29 7 +30 9 +31 11 +32 13 +33 15 +34 17 +35 19 +36 21 +37 23 +38 25 +39 0 +40 2 +41 4 +42 6 +43 8 +44 10 +45 12 +46 14 +47 16 +48 18 +49 20 +50 22 +51 24 +52 27 +53 29 +54 31 +55 33 +56 35 +57 37 +58 39 +59 41 +60 43 +61 45 +62 47 +63 49 +64 51 +65 53 +66 55 +67 26 +68 28 +69 30 +70 32 +71 34 +72 36 +73 38 +74 40 +75 42 +76 44 +77 46 +78 48 +79 50 +80 52 +81 54 +82 57 +83 59 +84 61 +85 63 +86 65 +87 67 +88 69 +89 71 +90 73 +91 75 +92 77 +93 79 +94 81 +95 56 +96 58 +97 60 +98 62 +99 64 +100 66 +101 68 +102 70 +103 72 +104 74 +105 76 +106 78 +107 80 +108 83 +109 85 +110 87 +111 89 +112 91 +113 93 +114 95 +115 97 +116 99 +117 101 +118 103 +119 105 +120 107 +121 109 +122 111 +123 113 +124 115 +125 82 +126 84 +127 86 +128 88 +129 90 +130 92 +131 94 +132 96 +133 98 +134 100 +135 102 +136 104 +137 106 +138 108 +139 110 +140 112 +141 114 +142 117 +143 119 +144 121 +145 123 +146 125 +147 127 +148 129 +149 131 +150 133 +151 135 +152 137 +153 139 +154 141 +155 116 +156 118 +157 120 +158 122 +159 124 +160 126 +161 128 +162 130 +163 132 +164 134 +165 136 +166 138 +167 140 +168 143 +169 145 +170 147 +171 149 +172 151 +173 153 +174 155 +175 157 +176 159 +177 161 +178 163 +179 165 +180 167 +181 142 +182 144 +183 146 +184 148 +185 150 +186 152 +187 154 +188 156 +189 158 +190 160 +191 162 +192 164 +193 166 +194 169 +195 171 +196 173 +197 175 +198 177 +199 179 +200 181 +201 183 +202 185 +203 187 +204 189 +205 191 +206 193 +207 168 +208 170 +209 172 +210 174 +211 176 +212 178 +213 180 +214 182 +215 184 +216 186 +217 188 +218 190 +219 192 +220 195 +221 197 +222 199 +223 201 +224 203 +225 205 +226 207 +227 209 +228 211 +229 213 +230 215 +231 217 +232 219 +233 221 +234 223 +235 194 +236 196 +237 198 +238 200 +239 202 +240 204 +241 206 +242 208 +243 210 +244 212 +245 214 +246 216 +247 218 +248 220 +249 222 +250 225 +251 227 +252 229 +253 231 +254 233 +255 235 +256 237 +257 239 +258 241 +259 243 +260 245 +261 247 +262 249 +263 224 +264 226 +265 228 +266 230 +267 232 +268 234 +269 236 +270 238 +271 240 +272 242 +273 244 +274 246 +275 248 +276 251 +277 253 +278 255 +279 257 +280 259 +281 261 +282 263 +283 265 +284 267 +285 269 +286 271 +287 273 +288 275 +289 277 +290 279 +291 250 +292 252 +293 254 +294 256 +295 258 +296 260 +297 262 +298 264 +299 266 +300 268 +301 270 +302 272 +303 274 +304 276 +305 278 +306 281 +307 283 +308 285 +309 287 +310 289 +311 291 +312 293 +313 295 +314 297 +315 299 +316 301 +317 303 +318 305 +319 280 +320 282 +321 284 +322 286 +323 288 +324 290 +325 292 +326 294 +327 296 +328 298 +329 300 +330 302 +331 304 diff --git a/configfiles/CC_MC_RECO_ntuple/MuonFitterConfig b/configfiles/CC_MC_RECO_ntuple/MuonFitterConfig new file mode 100644 index 000000000..69465ed64 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/MuonFitterConfig @@ -0,0 +1,33 @@ +verbosity 0 + +OutputFile MC_MuonFitter_Reco_2998.root +IsData 0 # 1:is data, not MC; 0:not data, is MC +LuxArea 506.7 # 10-inch R7081 Hamamatsu +EtelArea 613.1 # 11-inch D784UKFLB ETEL +HamamatsuArea 324.3 # 8-inch R5912-100 Hamamatsu +WatchboyArea 506.7 # 10-inch R7081 Hamamatsu +WatchmanArea 506.7 # 10-inch R7081-100 Hamamatsu +PMTMRDOffset 0 # delay btwn tank and MRD PMTs +StepSizeAi 15 # some distance muon travels [cm] +InsideAngle 1. # degrees added to Cherenkov angle for hits to be considered inside cone +OutsideAngle 9. # degrees added to Cherenkov angle for hits to be considered outside cone +PMTChargeThreshold 2 # minimum amount of charge seen by PMT +EtaThreshold 500 # threshold to find best vertex +DisplayTruth 0 # display truth information in graphs (only in MC) +RecoMode 0 # run tool after fitting tank track +AiEtaFile ev_ai_eta_R0.0.txt +#TankTrackFitFile /exp/annie/app/users/jhe/MyToolAnalysis_MFer/fitbyeye_wcsim_2000-2999_RNN_240525v1.txt +#TankTrackFitFile fitbyeye_wcsim_2000-2999_RNN_240525v1.txt +TankTrackFitFile tanktrackfitfile_r0.0_RNN.txt + +UseNumLayers 1 # Updates reco track length in MRD using number of layers +UsePCA 0 # Updates reco track length in MRD using number of layers and PCA-reconstructed track angle (set UseNumLayers 1) +UseConnDots 0 # Updates reco track length in MRD by connecting the MRD hits +UseELoss 0 # Use official ANNIE MRD energyLoss as starting MRD energy +UseSimpleEReco 0 # Just add ANNIE MRD energyLoss (set UseELoss 1); no updating dEdx +RecoEnergyShift 0 # Shift reco muon energy + +Plot3D 0 # 0:no plot; 1:yes plot +Draw3DFMV 0 +Draw3DMRD 0 +SaveHistograms 0 # 0:no; 1:yes diff --git a/configfiles/CC_MC_RECO_ntuple/MuonFitterREADME.md b/configfiles/CC_MC_RECO_ntuple/MuonFitterREADME.md new file mode 100644 index 000000000..a8f65763b --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/MuonFitterREADME.md @@ -0,0 +1,50 @@ +#MuonFitter Config + +*********************** +#Description +********************** + +Date created: 2024-10-02 +The MuonFitter toolchain makes an attempt to fit muons using hit information. + +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. + +MuonFitter has 2 functionalities. The first functionality is pre-reconstruction. It takes input information and outputs a text file providing information to be fitted. This text file is used in a script to generate an additional text file that contains the fitted information. + +The second functionality is reconstruction. It takes both text files and reconstructs the vertex based on the fitted paths. + +Therefore, in order to properly use this Tool in a ToolChain: The ToolChain must be ran twice on the same set of data. Instructions are below. + +************************ +#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. + + +To generate a model, run the following scripts in order: + +1. Data_prepare.py + +2. RNN_train.py + +WARNING: currently, Data_prepare.py requires input files that do not exist on the ANNIE gpvms. These scripts were created and used to create models outside of the ANNIE gpvms and ToolAnalysis container. These scripts are to be considered DEPRECATED until further notice. + +Please update any paths such that all files and models are available or copy all model files to configfiles/MuonFitter/RNNFit directory. All model files are currently located at /pnfs/annie/persistent/simulations/models/MuonFitter/ + +To run the Tool: + +1. First, run in "RecoMode 0". This will generate a file: ev_ai_eta_R{RUN}.txt with a {RUN} number corresponding to the WCSim run number. You do not need any Tools further along the ToolChain for this step. This text file is all you need. + +2. Second, run "python3 Fit_data.py ev_ai_eta_R{RUN}.txt". This will apply the fitting and generate another textfile to be ran in ToolAnalysis: tanktrackfitfile_r{RUN}_RNN.txt. ALSO: please update any paths such that all files and models are available. + +3. Finally, run in "RecoMode 1". This is running the ToolChain for real. Please set the paths for the ev_ai_eta_R{RUN}.txt and tanktrackfitfile_r{RUN}_RNN.txt accordingly so they can be read in with the corresponding data file. See the README.md in UserTools/MuonFitter/ for short descriptions of information saved to the DataModel and how to access them. diff --git a/configfiles/CC_MC_RECO_ntuple/PhaseIITreeMakerConfig b/configfiles/CC_MC_RECO_ntuple/PhaseIITreeMakerConfig new file mode 100644 index 000000000..271e31814 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/PhaseIITreeMakerConfig @@ -0,0 +1,24 @@ +verbose 0 + +IsData 0 +HasGenie 1 +RecoDebug_fill 1 +MCTruth_fill 1 +muonTruthRecoDiff_fill 0 +pionKaonCount_fill 0 +TankHitInfo_fill 0 +MRDHitInfo 0 +fillCleanEventsOnly 0 +MRDReco_fill 1 +TankReco_fill 1 +SimpleReco_fill 1 +RingCounting_fill 1 +Reweight_fill 1 +MuonFitter_fill 1 +HasBNBtimingMC 1 +TankClusterProcessing 1 +MRDClusterProcessing 1 +TriggerProcessing 1 + +OutputFile PhaseIITree_0.0.0.root +#NumEventsWritten 2000 diff --git a/configfiles/CC_MC_RECO_ntuple/README.md b/configfiles/CC_MC_RECO_ntuple/README.md new file mode 100644 index 000000000..fbbf4e112 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/README.md @@ -0,0 +1,70 @@ +# Configure files + +*********************** +#Description +********************** + +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 + +Values that contain multiple variables are separated by "|" into separate tokens +These tokens are broken up into "key:value" pairs +Syntax matters. Follow example in ReweightEventsGenieConfig + +Note: Only one value is permitted per name and they are stored in a string stream and template cast back to the type given. + +************************ +#Summary +************************ + +Tools that load information from files +----------------------- +LoadGeometry +LoadWCSim +LoadWCSimLAPPD +LoadGenieEvent - do not include this Tool if reweighting +----------------------- + +Tools that perform reweighting (optional) +----------------------- +LoadReweightGenieEvent - this Tool REPLACES LoadGenieEvent +ReweightFlux +----------------------- + +Tools that process signals and truth information +----------------------- +MCParticleProperties +MCRecoEventLoader +TimeClustering +FindMrdTracks +ClusterFinder +ClusterClassifiers +DigitBuilder +EventSelector +----------------------- + +Tool performs reconstruction +----------------------- +RingCounting +MuonFitter - this Tool REPLACES SimpleReconstruction +SimpleReconstruction +----------------------- + +Tool saves information to ntuple +----------------------- +PhaseIITreeMaker +----------------------- + diff --git a/configfiles/CC_MC_RECO_ntuple/ReweightFluxConfig b/configfiles/CC_MC_RECO_ntuple/ReweightFluxConfig new file mode 100644 index 000000000..3ac305287 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/ReweightFluxConfig @@ -0,0 +1,45 @@ +verbosity 0 +OnGrid 0 + +# Reweightable beam flux model uncertainties +# Revised 27 June 2024 +# +# Maintainer:James Minock + + + #Full set of well-formed Beam Uncertainties for use with post-MCC8 Flux +weight_functions_flux piplus,piminus,kplus,kzero,kminus,horncurrent,pioninexsec,nucleontotxsec,nucleonqexsec,nucleoninexsec,pionqexsec,piontotxsec,expskin +#weight_functions_flux piplus2 + + +# FLUX CONFIGS +piplus2 type:PrimaryHadronSWCentralSplineVariation|random_seed:2|parameter_list:["piplus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:10|PrimaryHadronGeantCode:211|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root"|ExternalFit:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false + + +horncurrent type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_horn175ka_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_horn173ka_flux.root"|parameter_list:["horncurrent"]|random_seed:7|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +pioninexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_pioninexsec_up_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_pioninexsec_down_flux.root"|parameter_list:["pioninexsec"]|random_seed:8|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +nucleontotxsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_nucleontotxsec_up_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_nucleontotxsec_down_flux.root"|parameter_list:["nucleontotxsec"]|random_seed:9|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +nucleonqexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_nucleonqexsec_up_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_nucleonqexsec_down_flux.root"|parameter_list:["nucleonqexse"]|random_seed:10|scale_factor_pos:0.333|scale_factor_neg:0.573|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +nucleoninexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_nucleoninexsec_up_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_nucleoninexsec_down_flux.root"|parameter_list:["nucleoninexsec"]|random_seed:11|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +pionqexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_pionqexsec_up_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_pionqexsec_down_flux.root"|parameter_list:["pionqexsec"]|random_seed:12|scale_factor_pos:0.292|scale_factor_neg:0.585|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +piontotxsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_piontotxsec_up_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_piontotxsec_down_flux.root"|parameter_list:["piontotxsec"]|random_seed:13|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +expskin type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/july24_baseline_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/july24_expskin_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/july24_expskin_flux.root"|parameter_list:["expskin"]|random_seed:14|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false + +bnbcorrection type:FluxHist|cv_hist_file:"beamData/bnbcorrection/bnb_oldflux_volAVTPC.root"|rw_hist_file:"beamData/bnbcorrection/bnb_newflux_volAVTPC.root"|random_seed:985|mode:reweight|number_of_multisims:1000 + +piplus type:PrimaryHadronSWCentralSplineVariation|random_seed:2|parameter_list:["piplus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:211|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root"|ExternalFit:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false + +piminus type:PrimaryHadronSWCentralSplineVariation|random_seed:3|parameter_list:["piminus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:-211|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root"|ExternalFit:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false + +kplus type:PrimaryHadronFeynmanScaling|random_seed:4|parameter_sigma:1|mode:multisim|number_of_multisims:1000|PrimaryHadronGeantCode:321|weight_calculator:"MicroBooNE"|parameter_list:["kplus"]|scale_factor:1|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false + +kzero type:PrimaryHadronSanfordWang|random_seed:5|parameter_list:["kzero"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:[130,310,311]|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false + +kminus type:PrimaryHadronNormalization|random_seed:6|parameter_list:["kminus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:-321|weight_calculator:"MiniBooNE"|use_MiniBooNE_random_numbers:false diff --git a/configfiles/CC_MC_RECO_ntuple/RingCountingConfig b/configfiles/CC_MC_RECO_ntuple/RingCountingConfig new file mode 100644 index 000000000..36c0c9cf8 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/RingCountingConfig @@ -0,0 +1,22 @@ +PythonScript RingCounting + +InitialiseFunction Initialise +ExecuteFunction Execute +FinaliseFunction Finalise + +verbose 1 + +# analysis specific settings +# +# Define file containing (multiple) filepath(s) to be loaded +load_from_csv 0 +save_to_csv 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/ +# Masked PMTs (to 0) config -> check documentation +pmt_mask november_22 +# Output file +save_to RC_output.csv diff --git a/configfiles/CC_MC_RECO_ntuple/SimpleReconstructionConfig b/configfiles/CC_MC_RECO_ntuple/SimpleReconstructionConfig new file mode 100644 index 000000000..121a74589 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/SimpleReconstructionConfig @@ -0,0 +1,3 @@ +# SimpleReconstruction config file + +verbosity 0 diff --git a/configfiles/CC_MC_RECO_ntuple/TimeClusteringConfig b/configfiles/CC_MC_RECO_ntuple/TimeClusteringConfig new file mode 100644 index 000000000..4a968f850 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/TimeClusteringConfig @@ -0,0 +1,12 @@ +#TimeClustering Config File + +verbosity 0 +IsData 0 +MinDigitsForTrack 4 +MaxMrdSubEventDuration 30 # [ns] if all hits are within this period, just make one subevent +MinSubeventTimeSep 30 # [ns] gaps of at leas this long delimit subevents +MakeMrdDigitTimePlot 0 # draw a 1D histogram of times to check subevent splitting is suitble +MakeSingleEventPlots 0 +LaunchTApplication 0 +MapChankey_WCSimID ./configfiles/CC_MC_RECO_ntuple/MRD_Chankey_WCSimID.dat +OutputROOTFile test.root diff --git a/configfiles/CC_MC_RECO_ntuple/ToolChainConfig b/configfiles/CC_MC_RECO_ntuple/ToolChainConfig new file mode 100644 index 000000000..6c75b4148 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/ToolChainConfig @@ -0,0 +1,26 @@ +#ToolChain dynamic setup file + +##### Runtime Parameters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandled errors only, 2= exit on unhandled errors and handled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails +remote_port 24002 +IO_Threads 1 ## Number of threads for network traffic (~ 1/Gbps) + +###### 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/CC_MC_RECO_ntuple/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/CC_MC_RECO_ntuple/ToolsConfig b/configfiles/CC_MC_RECO_ntuple/ToolsConfig new file mode 100644 index 000000000..d4e47f5f7 --- /dev/null +++ b/configfiles/CC_MC_RECO_ntuple/ToolsConfig @@ -0,0 +1,24 @@ +myLoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig +myLoadWCSim LoadWCSim configfiles/CC_MC_RECO_ntuple/LoadWCSimConfig +myLoadWCSimLAPPD LoadWCSimLAPPD configfiles/CC_MC_RECO_ntuple/LoadWCSimLAPPDConfig +#myLoadGenieEvent LoadGenieEvent configfiles/CC_MC_RECO_ntuple/LoadGenieEventConfig +myLoadReweightGenieEvent LoadReweightGenieEvent configfiles/CC_MC_RECO_ntuple/LoadReweightGenieEventConfig +myReweightFlux ReweightFlux configfiles/CC_MC_RECO_ntuple/ReweightFluxConfig +myMCParticleProperties MCParticleProperties configfiles/CC_MC_RECO_ntuple/MCParticlePropertiesConfig +myMCRecoEventLoader MCRecoEventLoader configfiles/CC_MC_RECO_ntuple/MCRecoEventLoaderConfig +myTimeClustering TimeClustering configfiles/CC_MC_RECO_ntuple/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/CC_MC_RECO_ntuple/FindMrdTracksConfig +myClusterFinder ClusterFinder configfiles/CC_MC_RECO_ntuple/ClusterFinderConfig +myClusterClassifiers ClusterClassifiers configfiles/CC_MC_RECO_ntuple/ClusterClassifiersConfig +myDigitBuilder DigitBuilder configfiles/CC_MC_RECO_ntuple/DigitBuilderConfig +myEventSelector EventSelector configfiles/CC_MC_RECO_ntuple/EventSelectorConfig +myCNNImage CNNImage ./configfiles/CC_MC_RECO_ntuple/CNNImageConfig +myRingCounting PythonScript configfiles/CC_MC_RECO_ntuple/RingCountingConfig +#myVtxSeedGenerator VtxSeedGenerator +#myVtxSeedFineGrid VtxSeedFineGrid +#myVtxExtendedVertexFinder VtxExtendedVertexFinder +#mySimpleReconstruction SimpleReconstruction configfiles/CC_MC_RECO_ntuple/SimpleReconstructionConfig +myMuonFitter MuonFitter configfiles/CC_MC_RECO_ntuple/MuonFitterConfig +myAssignBunchTimingMC AssignBunchTimingMC ./configfiles/CC_MC_RECO_ntuple/AssignBunchTimingMCConfig +myPhaseIITreeMaker PhaseIITreeMaker configfiles/CC_MC_RECO_ntuple/PhaseIITreeMakerConfig + diff --git a/configfiles/ClusterFinder/ClusterFinderConfig b/configfiles/ClusterFinder/ClusterFinderConfig index 1b1fb60b7..d4fcab139 100644 --- a/configfiles/ClusterFinder/ClusterFinderConfig +++ b/configfiles/ClusterFinder/ClusterFinderConfig @@ -1,10 +1,12 @@ # ClusterFinder Config File +verbosity 0 HitStore Hits #Either MCHits or Hits (accessed in ANNIEEvent store) OutputFile Run1415S0_AllPMTs_ClusterFinder #Output root prefix name for the current run -ClusterFindingWindow 50 # in ns, size of the window used to "clusterize" -AcqTimeWindow 4000 # in ns, size of the acquisition window -ClusterIntegrationWindow 50 # 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 +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 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 #2D charge-vs-time plot to be drawn? +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/ClusterSearcher/ClusterSearcher2Config b/configfiles/ClusterSearcher/ClusterSearcher2Config new file mode 100755 index 000000000..20af28b1b --- /dev/null +++ b/configfiles/ClusterSearcher/ClusterSearcher2Config @@ -0,0 +1,22 @@ +# ClusterSearcher2 config file + +verbosity 5 +ClusterMode 2 #searching track-like clusters +Config 3 #config type: 1 = pulse height cut, 2 = +neighbour cut, 3 = +cluster cut +IsMC 1 +PmtMinPulseHeight 20 #minimum pulse height +PmtNeighbourRadius 600 #digit neighbouring distance [cm] +PmtMinNeighbourDigits 2 #minimum neighbour digits +PmtClusterRadius 600 #digit clustering distance [cm] +PmtTimeWindowN 100 #neighbouring time window [ns] +PmtTimeWindowC 100 #clustering time window [ns] +PmtMinHitsPerCluster 1 #number of hits per cluster +LappdMinPulseHeight 0 #minimum pulse height +LappdNeighbourRadius 250 #digit neighbouring distance [cm] +LappdMinNeighbourDigits 20 #minimum neighbour digits +LappdClusterRadius 250 #digit clustering distance [cm] +LappdTimeWindowN 1 #neighbouring time window [ns] +LappdTimeWindowC 1 #clustering time window [ns] +LappdMinHitsPerCluster 5 #number of digits per cluster +#MinClusterDigits 50 #minimum clustered digits (LAPPD+PMT) +MinClusterDigits 1 #minimum clustered digits (PMT-only) diff --git a/configfiles/ClusterSearcher/ClusterSearcherConfig b/configfiles/ClusterSearcher/ClusterSearcherConfig new file mode 100755 index 000000000..22020dbbf --- /dev/null +++ b/configfiles/ClusterSearcher/ClusterSearcherConfig @@ -0,0 +1,22 @@ +# ClusterSearcher config file + +verbosity 5 +ClusterMode 1 #searching track-like clusters +Config 3 #config type: 1 = pulse height cut, 2 = +neighbour cut, 3 = +cluster cut +IsMC 1 +PmtMinPulseHeight 20 #minimum pulse height +PmtNeighbourRadius 60 #digit neighbouring distance [cm] +PmtMinNeighbourDigits 2 #minimum neighbour digits +PmtClusterRadius 60 #digit clustering distance [cm] +PmtTimeWindowN 10 #neighbouring time window [ns] +PmtTimeWindowC 100 #clustering time window [ns] +PmtMinHitsPerCluster 4 #number of hits per cluster +LappdMinPulseHeight 0 #minimum pulse height +LappdNeighbourRadius 25 #digit neighbouring distance [cm] +LappdMinNeighbourDigits 20 #minimum neighbour digits +LappdClusterRadius 25 #digit clustering distance [cm] +LappdTimeWindowN 1 #neighbouring time window [ns] +LappdTimeWindowC 1 #clustering time window [ns] +LappdMinHitsPerCluster 5 #number of digits per cluster +#MinClusterDigits 50 #minimum clustered digits (LAPPD+PMT) +MinClusterDigits 4 #minimum clustered digits (PMT-only) diff --git a/configfiles/ClusterSearcher/DigitBuilderConfig b/configfiles/ClusterSearcher/DigitBuilderConfig new file mode 100755 index 000000000..a2aac4e86 --- /dev/null +++ b/configfiles/ClusterSearcher/DigitBuilderConfig @@ -0,0 +1,12 @@ +# DigitBuilder config file + +verbosity 5 +ParametricModel 1 +#Reading in MC files +IsMC 1 +DigitChargeThr 20 #need to change the name +# 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/PhaseIIRecoFirinne/LAPPDIDs.txt +StripHit 0 diff --git a/configfiles/ClusterSearcher/EventSelectorConfig b/configfiles/ClusterSearcher/EventSelectorConfig new file mode 100755 index 000000000..b87dc8504 --- /dev/null +++ b/configfiles/ClusterSearcher/EventSelectorConfig @@ -0,0 +1,17 @@ +# EventSelector config file + +verbosity 0 +MCPMTVolCut 0 +MCFVCut 1 +MCMRDCut 1 +MCPiKCut 0 +MCIsMuonCut 1 +MRDRecoCut 0 +RecoPMTVolCut 0 +RecoFVCut 0 +MCIsSingleRingCut 0 +NHitCut 1 +LAPPDMult 0 +TriggerWord 0 +PromptTrigOnly 0 +SaveStatusToStore 1 diff --git a/configfiles/ClusterSearcher/LoadGenieEventConfig b/configfiles/ClusterSearcher/LoadGenieEventConfig new file mode 100644 index 000000000..bdeb21864 --- /dev/null +++ b/configfiles/ClusterSearcher/LoadGenieEventConfig @@ -0,0 +1,12 @@ +verbosity 0 +FluxVersion 1 # use 0 to load genie files based on bnb_annie_0000.root etc files + # use 1 to load files based on beammc_annie_0000.root etc files +#FileDir NA # specify "NA" for newer files: full path is saved in WCSim +#FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 +#FileDir /pnfs/annie/persistent/users/moflaher/genie/BNB_World_10k_11-03-18_gsimpleflux +FileDir /Data/Neutronsim +FilePattern gntp.1078.ghep.root +#FilePattern LoadWCSimTool ## use this pattern to load corresponding genie info with the LoadWCSimTool + ## N.B: FileDir must still be specified for now! (WCSim files do not record their directory) +ManualFileMatching 0 +EventOffset 0 #9900 diff --git a/configfiles/ClusterSearcher/LoadGeometryConfig b/configfiles/ClusterSearcher/LoadGeometryConfig new file mode 100644 index 000000000..3d8ce96bc --- /dev/null +++ b/configfiles/ClusterSearcher/LoadGeometryConfig @@ -0,0 +1,9 @@ +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry_09_29_20.csv +#FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LoadGeometry/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv diff --git a/configfiles/ClusterSearcher/LoadWCSimConfig b/configfiles/ClusterSearcher/LoadWCSimConfig new file mode 100644 index 000000000..9bd2001a0 --- /dev/null +++ b/configfiles/ClusterSearcher/LoadWCSimConfig @@ -0,0 +1,17 @@ +#LoadWCSim Config File +# all variables retrieved with m_variables.Get() must be defined here! +verbose 0 + +#InputFile /Data/Ambesim/pmt/*.root +#InputFile /Data/HighEnergy/wcsim-thousand-high_0.root +InputFile /Data/0824Beamsim/pmt/*.root + +WCSimVersion 3 ## should reflect the WCSim version of the files being loaded +HistoricTriggeroffset 0 ## time offset of digits relative to the trigger +UseDigitSmearedTime 1 ## whether to use smeared digit time (T), or true time of first photon (F) +LappdNumStrips 60 ## num channels to construct from each LAPPD +LappdStripLength 100 ## relative x position of each LAPPD strip, for dual-sided readout [mm] +LappdStripSeparation 10 ## stripline separation, for calculating relative y position of each LAPPD strip [mm] +PMTMask configfiles/BeamClusterAnalysisMC/DeadPMTIDs_p2v7.txt ## Which PMTs should be masked out? / are dead? +ChankeyToPMTIDMap ./configfiles/BeamClusterAnalysisMC/Chankey_WCSimID_v7.txt +SplitSubTriggers 0 # should subtriggers be loaded in separate Execute steps? diff --git a/configfiles/ClusterSearcher/LoadWCSimLAPPDConfig b/configfiles/ClusterSearcher/LoadWCSimLAPPDConfig new file mode 100644 index 000000000..f39db46d8 --- /dev/null +++ b/configfiles/ClusterSearcher/LoadWCSimLAPPDConfig @@ -0,0 +1,11 @@ +#LoadWCSimLAPPD Config File +# all variables retrieved with m_variables.Get() must be defined here! +verbose 1 + +#InputFile /Data/Ambesim/lappd/*.root +#InputFile /Data/HighEnergy/wcsim-thousand-high_lappd_0.root +InputFile /Data/0824Beamsim/lappd/*.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/ClusterSearcher/MCParticlePropertiesConfig b/configfiles/ClusterSearcher/MCParticlePropertiesConfig new file mode 100644 index 000000000..714c40f32 --- /dev/null +++ b/configfiles/ClusterSearcher/MCParticlePropertiesConfig @@ -0,0 +1,3 @@ +# MCParticleProperties configuration file + +verbosity 5 diff --git a/configfiles/ClusterSearcher/MCRecoEventLoaderConfig b/configfiles/ClusterSearcher/MCRecoEventLoaderConfig new file mode 100644 index 000000000..cba5524e7 --- /dev/null +++ b/configfiles/ClusterSearcher/MCRecoEventLoaderConfig @@ -0,0 +1,11 @@ +# MCRecoEventLoader config file + +verbosity 5 +GetPionKaonInfo 1 +GetNRings 1 +ParticleID 13 +DoParticleSelection 0 +xshift 0.0 +yshift 14.46469 +zshift -168.1 +IsMC 1 diff --git a/configfiles/ClusterSearcher/NeutronCheckConfig b/configfiles/ClusterSearcher/NeutronCheckConfig new file mode 100644 index 000000000..0658b1a35 --- /dev/null +++ b/configfiles/ClusterSearcher/NeutronCheckConfig @@ -0,0 +1,6 @@ +verbosity 5 +outfile /Data/0824Beamsim/NeutronCheck_CS +UseClean 1 +FinderCompare 0 +ParticleInfo 0 +VertexInfo 0 diff --git a/configfiles/ClusterSearcher/ToolChainConfig b/configfiles/ClusterSearcher/ToolChainConfig new file mode 100644 index 000000000..df77bb067 --- /dev/null +++ b/configfiles/ClusterSearcher/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/ClusterSearcher/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/ClusterSearcher/ToolsConfig b/configfiles/ClusterSearcher/ToolsConfig new file mode 100755 index 000000000..7da2cdb68 --- /dev/null +++ b/configfiles/ClusterSearcher/ToolsConfig @@ -0,0 +1,11 @@ +LoadGeometry LoadGeometry ./configfiles/ClusterSearcher/LoadGeometryConfig +LoadWCSim LoadWCSim ./configfiles/ClusterSearcher/LoadWCSimConfig +LoadWCSimLAPPD LoadWCSimLAPPD ./configfiles/ClusterSearcher/LoadWCSimLAPPDConfig +LoadGenieEvent LoadGenieEvent ./configfiles/ClusterSearcher/LoadGenieEventConfig +MCRecoEventLoader MCRecoEventLoader ./configfiles/ClusterSearcher/MCRecoEventLoaderConfig +MCParticleProperties MCParticleProperties ./configfiles/ClusterSearcher/MCParticlePropertiesConfig +DigitBuilder DigitBuilder ./configfiles/ClusterSearcher/DigitBuilderConfig +ClusterSearcher ClusterSearcher ./configfiles/ClusterSearcher/ClusterSearcherConfig +ClusterSearcher2 ClusterSearcher ./configfiles/ClusterSearcher/ClusterSearcher2Config +EventSelector EventSelector ./configfiles/ClusterSearcher/EventSelectorConfig +NeutronCheck NeutronCheck ./configfiles/ClusterSearcher/NeutronCheckConfig diff --git a/configfiles/EnergyReco/Predict/DNNTrackLengthPredictConfig b/configfiles/EnergyReco/Predict/DNNTrackLengthPredictConfig index 7dd7ac486..c36001a08 100644 --- a/configfiles/EnergyReco/Predict/DNNTrackLengthPredictConfig +++ b/configfiles/EnergyReco/Predict/DNNTrackLengthPredictConfig @@ -10,4 +10,4 @@ TrackLengthWeightsFile UserTools/DNNTrackLength/stand_alone/weights/weights_bets # Scaling Parameters -ScalingVarsBoostStoreFile Data_Energy_Reco/ScalingVarsStore.bs +ScalingVarsBoostStoreFile ScalingVarsStore.bs diff --git a/configfiles/EnergyReco/Predict/EventSelectorConfig b/configfiles/EnergyReco/Predict/EventSelectorConfig index ca6032811..fb4406966 100644 --- a/configfiles/EnergyReco/Predict/EventSelectorConfig +++ b/configfiles/EnergyReco/Predict/EventSelectorConfig @@ -9,6 +9,7 @@ MCIsMuonCut 1 MRDRecoCut 0 RecoPMTVolCut 0 RecoFVCut 0 +NoVeto 1 NHitCut 1 PromptTrigOnly 1 SaveStatusToStore 1 diff --git a/configfiles/EnergyReco/Predict/HitCleanerConfig b/configfiles/EnergyReco/Predict/HitCleanerConfig index 36d7f0137..028ed006d 100644 --- a/configfiles/EnergyReco/Predict/HitCleanerConfig +++ b/configfiles/EnergyReco/Predict/HitCleanerConfig @@ -1,6 +1,6 @@ # HitCleaner config file -verbosity 5 +verbosity 2 Config 2 #config type: 1 = pulse height cut, 2 = +neighbour cut, 3 = +cluster cut PmtMinPulseHeight 20 #minimum pulse height PmtNeighbourRadius 60 #digit neighbouring distance [cm] diff --git a/configfiles/EnergyReco/Predict/LoadWCSimConfig b/configfiles/EnergyReco/Predict/LoadWCSimConfig index 001d2e929..063730c02 100644 --- a/configfiles/EnergyReco/Predict/LoadWCSimConfig +++ b/configfiles/EnergyReco/Predict/LoadWCSimConfig @@ -1,6 +1,6 @@ #LoadWCSim Config File # all variables retrieved with m_variables.Get() must be defined here! -verbose 0 +verbose 1 InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/pmt/wcsim_0* #James's files diff --git a/configfiles/EnergyReco/Predict/LoadWCSimLAPPDConfig b/configfiles/EnergyReco/Predict/LoadWCSimLAPPDConfig index 2b82ff922..90892147f 100644 --- a/configfiles/EnergyReco/Predict/LoadWCSimLAPPDConfig +++ b/configfiles/EnergyReco/Predict/LoadWCSimLAPPDConfig @@ -1,6 +1,6 @@ #LoadWCSimLAPPD Config File # all variables retrieved with m_variables.Get() must be defined here! -verbose 0 +verbose 1 InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/lappd/wcsim_lappd_0* #James's files diff --git a/configfiles/EnergyReco/Predict/PhaseIITreeMakerConfig b/configfiles/EnergyReco/Predict/PhaseIITreeMakerConfig new file mode 100644 index 000000000..807461014 --- /dev/null +++ b/configfiles/EnergyReco/Predict/PhaseIITreeMakerConfig @@ -0,0 +1,18 @@ +verbose 5 + +OutputFile MC_BeamRun_999.ntuple.root +TankClusterProcessing 1 +MRDClusterProcessing 1 +TriggerProcessing 1 +TankHitInfo_fill 1 +MRDHitInfo_fill 1 +MRDReco_fill 1 +SiPMPulseInfo_fill 1 +fillCleanEventsOnly 1 +MCTruth_fill 1 +Reco_fill 0 +RecoDebug_fill 0 +muonTruthRecoDiff_fill 1 +IsData 0 +HasGenie 0 +Digit_fill 1 diff --git a/configfiles/EnergyReco/Predict/ToolsConfig b/configfiles/EnergyReco/Predict/ToolsConfig index 5926759d1..4073d2f1a 100644 --- a/configfiles/EnergyReco/Predict/ToolsConfig +++ b/configfiles/EnergyReco/Predict/ToolsConfig @@ -14,6 +14,7 @@ VtxSeedFineGrid VtxSeedFineGrid configfiles/EnergyReco/Predict/VtxSeedFineGridCo VtxExtendedVertexFinder VtxExtendedVertexFinder configfiles/EnergyReco/Predict/VtxExtendedVertexFinderConfig FindTrackLengthInWater FindTrackLengthInWater configfiles/EnergyReco/Predict/FindTrackLengthInWaterConfig +PhaseIITreeMaker PhaseIITreeMaker configfiles/EnergyReco/Predict/PhaseIITreeMakerConfig DNNTrackLengthPredict PythonScript configfiles/EnergyReco/Predict/DNNTrackLengthPredictConfig BDTMuonEnergyPredict PythonScript configfiles/EnergyReco/Predict/BDTMuonEnergyPredictConfig #PlotsTrackLengthAndEnergy PlotsTrackLengthAndEnergy configfiles/EnergyReco/Predict/PlotsTrackLengthAndEnergyConfig diff --git a/configfiles/EnergyReco/Train_Test/DNNTrackLengthTrainConfig b/configfiles/EnergyReco/Train_Test/DNNTrackLengthTrainConfig index 185227cd2..78515ed7c 100644 --- a/configfiles/EnergyReco/Train_Test/DNNTrackLengthTrainConfig +++ b/configfiles/EnergyReco/Train_Test/DNNTrackLengthTrainConfig @@ -15,4 +15,4 @@ TrackLengthOutputWeightsFile UserTools/DNNTrackLength/stand_alone/weights/weight # Training data TrackLengthTrainingInputBoostStoreFile EnergyReco.bs -ScalingVarsBoostStoreFile Data_Energy_Reco/ScalingVarsStore.bs +ScalingVarsBoostStoreFile ScalingVarsStore.bs diff --git a/configfiles/EnergyReco/Train_Test/EventSelectorConfig b/configfiles/EnergyReco/Train_Test/EventSelectorConfig index ca6032811..fb4406966 100644 --- a/configfiles/EnergyReco/Train_Test/EventSelectorConfig +++ b/configfiles/EnergyReco/Train_Test/EventSelectorConfig @@ -9,6 +9,7 @@ MCIsMuonCut 1 MRDRecoCut 0 RecoPMTVolCut 0 RecoFVCut 0 +NoVeto 1 NHitCut 1 PromptTrigOnly 1 SaveStatusToStore 1 diff --git a/configfiles/EnergyReco/Train_Test/HitCleanerConfig b/configfiles/EnergyReco/Train_Test/HitCleanerConfig index 36d7f0137..028ed006d 100644 --- a/configfiles/EnergyReco/Train_Test/HitCleanerConfig +++ b/configfiles/EnergyReco/Train_Test/HitCleanerConfig @@ -1,6 +1,6 @@ # HitCleaner config file -verbosity 5 +verbosity 2 Config 2 #config type: 1 = pulse height cut, 2 = +neighbour cut, 3 = +cluster cut PmtMinPulseHeight 20 #minimum pulse height PmtNeighbourRadius 60 #digit neighbouring distance [cm] diff --git a/configfiles/EnergyReco/Train_Test/LoadWCSimConfig b/configfiles/EnergyReco/Train_Test/LoadWCSimConfig index 001d2e929..063730c02 100644 --- a/configfiles/EnergyReco/Train_Test/LoadWCSimConfig +++ b/configfiles/EnergyReco/Train_Test/LoadWCSimConfig @@ -1,6 +1,6 @@ #LoadWCSim Config File # all variables retrieved with m_variables.Get() must be defined here! -verbose 0 +verbose 1 InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/pmt/wcsim_0* #James's files diff --git a/configfiles/EnergyReco/Train_Test/LoadWCSimLAPPDConfig b/configfiles/EnergyReco/Train_Test/LoadWCSimLAPPDConfig index 2b82ff922..90892147f 100644 --- a/configfiles/EnergyReco/Train_Test/LoadWCSimLAPPDConfig +++ b/configfiles/EnergyReco/Train_Test/LoadWCSimLAPPDConfig @@ -1,6 +1,6 @@ #LoadWCSimLAPPD Config File # all variables retrieved with m_variables.Get() must be defined here! -verbose 0 +verbose 1 InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/lappd/wcsim_lappd_0* #James's files diff --git a/configfiles/EnergyReco/Train_Test/PhaseIITreeMakerConfig b/configfiles/EnergyReco/Train_Test/PhaseIITreeMakerConfig new file mode 100644 index 000000000..807461014 --- /dev/null +++ b/configfiles/EnergyReco/Train_Test/PhaseIITreeMakerConfig @@ -0,0 +1,18 @@ +verbose 5 + +OutputFile MC_BeamRun_999.ntuple.root +TankClusterProcessing 1 +MRDClusterProcessing 1 +TriggerProcessing 1 +TankHitInfo_fill 1 +MRDHitInfo_fill 1 +MRDReco_fill 1 +SiPMPulseInfo_fill 1 +fillCleanEventsOnly 1 +MCTruth_fill 1 +Reco_fill 0 +RecoDebug_fill 0 +muonTruthRecoDiff_fill 1 +IsData 0 +HasGenie 0 +Digit_fill 1 diff --git a/configfiles/EnergyReco/Train_Test/TimeClusteringConfig b/configfiles/EnergyReco/Train_Test/TimeClusteringConfig index e3061f75f..cb6f15f76 100644 --- a/configfiles/EnergyReco/Train_Test/TimeClusteringConfig +++ b/configfiles/EnergyReco/Train_Test/TimeClusteringConfig @@ -1,6 +1,6 @@ #TimeClustering config file -verbosity 7 +verbosity 3 MinDigitsForTrack 4 MaxMrdSubEventDuration 40 MinSubeventTimeSep 40 diff --git a/configfiles/EnergyReco/Train_Test/ToolsConfig b/configfiles/EnergyReco/Train_Test/ToolsConfig index 8c68239ac..a72df5bd3 100644 --- a/configfiles/EnergyReco/Train_Test/ToolsConfig +++ b/configfiles/EnergyReco/Train_Test/ToolsConfig @@ -14,5 +14,6 @@ VtxSeedFineGrid VtxSeedFineGrid configfiles/EnergyReco/Train_Test/VtxSeedFineGri VtxExtendedVertexFinder VtxExtendedVertexFinder configfiles/EnergyReco/Train_Test/VtxExtendedVertexFinderConfig FindTrackLengthInWater FindTrackLengthInWater configfiles/EnergyReco/Train_Test/FindTrackLengthInWaterConfig +PhaseIITreeMaker PhaseIITreeMaker configfiles/EnergyReco/Predict/PhaseIITreeMakerConfig DNNTrackLengthTrainer PythonScript configfiles/EnergyReco/Train_Test/DNNTrackLengthTrainConfig BDTMuonEnergyTrainer PythonScript configfiles/EnergyReco/Train_Test/BDTMuonEnergyTrainConfig 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/BeamDecoderConfig b/configfiles/EventBuilder/BeamDecoderConfig deleted file mode 100644 index 3866c2b30..000000000 --- a/configfiles/EventBuilder/BeamDecoderConfig +++ /dev/null @@ -1,17 +0,0 @@ -# BeamDecoder config file -verbosity 0 -# Names of devices needed for beam quality cuts -HornCurrentDevice E:THCURR -# The "first" toroid is the one farther upstream from the target -FirstToroid E:TOR860 -SecondToroid E:TOR875 -# POT window -CutPOTMin 5e11 -CutPOTMax 8e12 -# Peak horn current window (in kA) -CutPeakHornCurrentMin 172 -CutPeakHornCurrentMax 176 -# Toroid agreement tolerance (fractional error) -CutToroidAgreement 0.05 -# DB vs DAQ timestamp agreement tolerance (ms) -CutTimestampAgreement 100 diff --git a/configfiles/EventBuilder/BeamDevices.txt b/configfiles/EventBuilder/BeamDevices.txt new file mode 100644 index 000000000..0bf9117bd --- /dev/null +++ b/configfiles/EventBuilder/BeamDevices.txt @@ -0,0 +1 @@ +BoosterNeutrinoBeam_read diff --git a/configfiles/EventBuilder/BeamFetcherV2Config b/configfiles/EventBuilder/BeamFetcherV2Config new file mode 100644 index 000000000..8a0bb9e7b --- /dev/null +++ b/configfiles/EventBuilder/BeamFetcherV2Config @@ -0,0 +1,17 @@ +# BeamFetcher config file +verbose 0 +# +# File containing one device per line or a bundle +DevicesFile ./configfiles/EventBuilder/BeamDevices.txt +# +# bool stating whether DevicesFile contains bundles or individual devices +IsBundle 1 +# +# bool defining how to grab the data (from input times (1) or trigger(0)) +FetchFromTimes 0 +# +# How much data to pull in one query (set to 1 hr) +TimeChunkStepInMilliseconds 3600000 +# +# bool, do you want to write a ROOT file with the timestamps and devices? +SaveROOT 0 \ No newline at end of file diff --git a/configfiles/EventBuilder/BeamQualityConfig b/configfiles/EventBuilder/BeamQualityConfig new file mode 100644 index 000000000..f478a3b2b --- /dev/null +++ b/configfiles/EventBuilder/BeamQualityConfig @@ -0,0 +1,13 @@ +# BeamQuality config file +verbose 0 +# +# POT window for "good" beam +POTMin 5e11 +POTMax 8e12 +# +# Horn current window for "good" beam (in kA) +HornCurrentMin 172 +HornCurrentMax 176 +# +# Fractional difference between the upstream and downstream POT measurements +BeamLossTolerance 0.05 \ No newline at end of file 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/MRDDataDecoderConfig b/configfiles/EventBuilder/MRDDataDecoderConfig index 4f4260f01..d9937ca9a 100644 --- a/configfiles/EventBuilder/MRDDataDecoderConfig +++ b/configfiles/EventBuilder/MRDDataDecoderConfig @@ -1,2 +1,2 @@ -verbosity 2 +verbosity 0 DaylightSavingsSpring 1 diff --git a/configfiles/EventBuilder/README.md b/configfiles/EventBuilder/README.md new file mode 100644 index 000000000..c956a4243 --- /dev/null +++ b/configfiles/EventBuilder/README.md @@ -0,0 +1,29 @@ +# EventBuilder + +*********************** +## Description +********************** + +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 + +************************ +## Tools +************************ + +The toolchain consists of the following tools: + +``` +LoadGeometry +LoadRawData +PMTDataDecoder +MRDDataDecoder +TriggerDataDecoder +BeamFetcherV2 +BeamQuality +PhaseIIADCCalibrator +PhaseIIADCHitFinder +SaveConfigInfo +ANNIEEventBuilder +``` diff --git a/configfiles/EventBuilder/ToolsConfig b/configfiles/EventBuilder/ToolsConfig index 95cc19f24..9d62fd3c6 100644 --- a/configfiles/EventBuilder/ToolsConfig +++ b/configfiles/EventBuilder/ToolsConfig @@ -3,6 +3,8 @@ LoadRawData LoadRawData ./configfiles/EventBuilder/LoadRawDataConfig PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilder/PMTDataDecoderConfig MRDDataDecoder MRDDataDecoder ./configfiles/EventBuilder/MRDDataDecoderConfig TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilder/TriggerDataDecoderConfig +BeamFetcherV2 BeamFetcherV2 ./configfiles/EventBuilder/BeamFetcherV2Config +BeamQuality BeamQuality ./configfiles/EventBuilder/BeamQualityConfig PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilder/PhaseIIADCCalibratorConfig PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilder/PhaseIIADCHitFinderConfig SaveConfigInfo SaveConfigInfo ./configfiles/EventBuilder/SaveConfigInfoConfig 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/ANNIEEventBuilderConfig b/configfiles/EventBuilderRaw/ANNIEEventBuilderConfig new file mode 100644 index 000000000..a87912902 --- /dev/null +++ b/configfiles/EventBuilderRaw/ANNIEEventBuilderConfig @@ -0,0 +1,20 @@ +verbosity 0 + +BuildType TankAndCTC +ProcessedFilesBasename ProcessedRawData +#NumEventsPerPairing 200 +SavePath ./ + +MinNumWavesInSet 1 // 1=Just throw any waveforms into ANNIE events if you got em + +ExecutesPerBuild 10 +OrphanOldTankTimestamps 1 +OldTimestampThreshold 150 +OrphanFileBase OrphanStore +#MaxStreamMatchingTimeSeparation 60 // seconds. If one stream is ahead of the others, pause reading + +SaveRawData 1 +StoreBeamStatus 0 + +BuildStage1Data 0 +SaveSeparatePartfiles 1 diff --git a/configfiles/EventBuilderRaw/DefaultTriggerMask.txt b/configfiles/EventBuilderRaw/DefaultTriggerMask.txt new file mode 100644 index 000000000..398850355 --- /dev/null +++ b/configfiles/EventBuilderRaw/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/EventBuilderRaw/LoadGeometryConfig b/configfiles/EventBuilderRaw/LoadGeometryConfig new file mode 100644 index 000000000..6c9e006fc --- /dev/null +++ b/configfiles/EventBuilderRaw/LoadGeometryConfig @@ -0,0 +1,9 @@ +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LoadGeometry/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains2023.csv +TankPMTTimingOffsetFile ./configfiles/LoadGeometry/TankPMTTimingOffsets.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv diff --git a/configfiles/EventBuilderRaw/LoadRawDataConfig b/configfiles/EventBuilderRaw/LoadRawDataConfig new file mode 100644 index 000000000..07d63ada4 --- /dev/null +++ b/configfiles/EventBuilderRaw/LoadRawDataConfig @@ -0,0 +1,8 @@ +verbosity 0 +BuildType TankAndCTC +Mode FileList +InputFile ./configfiles/DataDecoder/my_files.txt +DummyRunInfo 1 +StoreTrigOverlap 0 +ReadTrigOverlap 1 +StoreRawData 0 diff --git a/configfiles/EventBuilderRaw/PMTDataDecoderConfig b/configfiles/EventBuilderRaw/PMTDataDecoderConfig new file mode 100644 index 000000000..19e946601 --- /dev/null +++ b/configfiles/EventBuilderRaw/PMTDataDecoderConfig @@ -0,0 +1,5 @@ +verbosity 0 +ADCCountsToBuildWaves 0 +Mode Offline +OffsetVME03 0 +OffsetVME01 0 diff --git a/configfiles/EventBuilderRaw/PhaseIIADCCalibratorConfig b/configfiles/EventBuilderRaw/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..158dc6ed1 --- /dev/null +++ b/configfiles/EventBuilderRaw/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/EventBuilderRaw/PhaseIIADCHitFinderConfig b/configfiles/EventBuilderRaw/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..d183b7b27 --- /dev/null +++ b/configfiles/EventBuilderRaw/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType dynamic +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 1 diff --git a/configfiles/EventBuilderRaw/README.md b/configfiles/EventBuilderRaw/README.md new file mode 100644 index 000000000..73cc63a5e --- /dev/null +++ b/configfiles/EventBuilderRaw/README.md @@ -0,0 +1,25 @@ +# EventBuilderRaw + +*********************** +## Description +********************** + +The `EventBuilderRaw` toolchain can be used to produce Processed files that contain the raw waveforms (PMTs) and store them to the ANNIEEvent booststore. This toolchain is essentially the same as the `EventBuilder` toolchain, except that raw waveforms are saved, not just the hits. + +This toolchain only builts Tank + CTC events (no MRD). Hit finding tools are typically ommitted from the toolchain but can be including to also save the hits information in parallel with the raw waveforms. + +Warning to users: When using this toolchain, enormous amounts of disk space will be used as all ~121 active PMT channels (and aux channels + CTC information) will be saved for every trigger/event. Recommended to run a part file at a time. The output Processed files will be at least x10 larger than their hits only counterparts. + +************************ +## Tools +************************ + +The toolchain typically consists of the following tools: + +``` +LoadGeometry +LoadRawData +PMTDataDecoder +TriggerDataDecoder +ANNIEEventBuilder +``` diff --git a/configfiles/EventBuilderRaw/ToolChainConfig b/configfiles/EventBuilderRaw/ToolChainConfig new file mode 100644 index 000000000..e65304c6f --- /dev/null +++ b/configfiles/EventBuilderRaw/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/EventBuilderRaw/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/EventBuilderRaw/ToolsConfig b/configfiles/EventBuilderRaw/ToolsConfig new file mode 100644 index 000000000..9e731b51d --- /dev/null +++ b/configfiles/EventBuilderRaw/ToolsConfig @@ -0,0 +1,7 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +LoadRawData LoadRawData ./configfiles/EventBuilderRaw/LoadRawDataConfig +PMTDataDecoder PMTDataDecoder ./configfiles/EventBuilderRaw/PMTDataDecoderConfig +TriggerDataDecoder TriggerDataDecoder ./configfiles/EventBuilderRaw/TriggerDataDecoderConfig +#PhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/EventBuilderRaw/PhaseIIADCCalibratorConfig +#PhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/EventBuilderRaw/PhaseIIADCHitFinderConfig +ANNIEEventBuilder ANNIEEventBuilder ./configfiles/EventBuilderRaw/ANNIEEventBuilderConfig diff --git a/configfiles/EventBuilderRaw/TriggerDataDecoderConfig b/configfiles/EventBuilderRaw/TriggerDataDecoderConfig new file mode 100644 index 000000000..c80c66547 --- /dev/null +++ b/configfiles/EventBuilderRaw/TriggerDataDecoderConfig @@ -0,0 +1,4 @@ +verbosity 0 +TriggerMaskFile ./configfiles/EventBuilderRaw/DefaultTriggerMask.txt +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/EventBuilderRaw/my_files.txt b/configfiles/EventBuilderRaw/my_files.txt new file mode 100644 index 000000000..de43e7839 --- /dev/null +++ b/configfiles/EventBuilderRaw/my_files.txt @@ -0,0 +1 @@ +/pnfs/annie/persistent/raw/raw/4314/RAWDataR4314S0p1 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..46eb0bb9d --- /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/ConfigGeo b/configfiles/LAPPDProcessedAna/ConfigGeo new file mode 100644 index 000000000..ffe0ca918 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/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/LAPPDProcessedAna/ConfigPlot b/configfiles/LAPPDProcessedAna/ConfigPlot new file mode 100755 index 000000000..72c8b9721 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/ConfigPlot @@ -0,0 +1,136 @@ +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 7. +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 10 +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 #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 +LoadLAPPDMapInfo 1 + +#LAPPDStackStrip +verbosityStackStrip 0 +StackOutputFileName stacked.root +#StackInputWaveLabel BLsubtractedLAPPDData +StackInputWaveLabel RawLAPPDData +#StackInputWaveLabel LAPPDWaveforms +StackStripNumber 1 +StackStripSide 0 + +#LAPPDPlotWaveForms +NHistos 10 +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 -20 + +CanvasWidth 1000 +CanvasHeight 500 + +maxDrawEventNumber 100 + +DrawBinHist 1 +printEventNumber 0 +printLAPPDNumber 1 +printEventWaveform 1 + +LoadLAPPDMap 1 diff --git a/configfiles/LAPPDProcessedAna/ConfigPreProcess b/configfiles/LAPPDProcessedAna/ConfigPreProcess new file mode 100755 index 000000000..c1a0a8830 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/ConfigPreProcess @@ -0,0 +1,67 @@ +# 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 0 # for 2023 data +#GlobalShiftT0 80 # for 2024 data + +#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/LAPPDProcessedAna/ConfigStoreReadIn b/configfiles/LAPPDProcessedAna/ConfigStoreReadIn new file mode 100755 index 000000000..79f2d2fa7 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/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/LAPPDProcessedAna/ConfigTXT b/configfiles/LAPPDProcessedAna/ConfigTXT new file mode 100644 index 000000000..a982c4278 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/ConfigTXT @@ -0,0 +1,72 @@ +#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 1 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree_processedAna.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 diff --git a/configfiles/LAPPDProcessedAna/Configs b/configfiles/LAPPDProcessedAna/Configs new file mode 100644 index 000000000..e8ad7c851 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/Configs @@ -0,0 +1,72 @@ +#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/2022_LAPPD40/P + + +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 1 +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree_processedAna.root +LoadTriggerInfo 0 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 diff --git a/configfiles/LAPPDProcessedAna/FindMrdTracksConfig b/configfiles/LAPPDProcessedAna/FindMrdTracksConfig new file mode 100644 index 000000000..5ba5e8f77 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/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/LAPPDProcessedAna/LoadANNIEEventConfig b/configfiles/LAPPDProcessedAna/LoadANNIEEventConfig new file mode 100644 index 000000000..b7330eecc --- /dev/null +++ b/configfiles/LAPPDProcessedAna/LoadANNIEEventConfig @@ -0,0 +1,6 @@ +verbose 1 + +FileForListOfInputs configfiles/LAPPDProcessedAna/list.txt + +EventOffset 0 +GlobalEvNr 1 diff --git a/configfiles/LAPPDProcessedAna/ProcessedLAPPDFilterConfig b/configfiles/LAPPDProcessedAna/ProcessedLAPPDFilterConfig new file mode 100644 index 000000000..752200268 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/ProcessedLAPPDFilterConfig @@ -0,0 +1 @@ +verbosity 0 diff --git a/configfiles/LAPPDProcessedAna/TimeClusteringConfig b/configfiles/LAPPDProcessedAna/TimeClusteringConfig new file mode 100644 index 000000000..e778247fc --- /dev/null +++ b/configfiles/LAPPDProcessedAna/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/LAPPDProcessedAna/ToolChainConfig b/configfiles/LAPPDProcessedAna/ToolChainConfig new file mode 100644 index 000000000..3c8060cf1 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/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/LAPPDProcessedAna/ToolsConfig ## list of tools to run and their config files + +##### Run Type ##### +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/LAPPDProcessedAna/ToolsConfig b/configfiles/LAPPDProcessedAna/ToolsConfig new file mode 100644 index 000000000..3af77fe8a --- /dev/null +++ b/configfiles/LAPPDProcessedAna/ToolsConfig @@ -0,0 +1,16 @@ +LoadANNIEEvent LoadANNIEEvent configfiles/LAPPDProcessedAna/LoadANNIEEventConfig +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig + +myTimeClustering TimeClustering configfiles/LAPPDProcessedAna/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/LAPPDProcessedAna/FindMrdTracksConfig + +LAPPDLoadStore LAPPDLoadStore configfiles/LAPPDProcessedAna/Configs +LAPPDStoreReorder LAPPDStoreReorder configfiles/LAPPDProcessedAna/ConfigStoreReadIn + +LAPPDTimeAlignment LAPPDTimeAlignment configfiles/LAPPDProcessedAna/ConfigPreProcess +LAPPDBaseline LAPPDBaseline configfiles/LAPPDProcessedAna/ConfigPreProcess +LAPPDPlots LAPPDPlots configfiles/LAPPDProcessedAna/ConfigPlot + +LAPPDThresReco LAPPDThresReco configfiles/LAPPDProcessedAna/ConfigPlot + +LAPPDTreeMaker LAPPDTreeMaker configfiles/LAPPDProcessedAna/Configs diff --git a/configfiles/LAPPDProcessedAna/knownlist b/configfiles/LAPPDProcessedAna/knownlist new file mode 100644 index 000000000..22c51f858 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/knownlist @@ -0,0 +1 @@ +/pnfs/annie/persistent/users/yuefeng/EventBuildingV2/output/4843/ProcessedData_PMTMRDLAPPD_R4843S0p5 diff --git a/configfiles/LAPPDProcessedAna/list.txt b/configfiles/LAPPDProcessedAna/list.txt new file mode 100644 index 000000000..8894dadb6 --- /dev/null +++ b/configfiles/LAPPDProcessedAna/list.txt @@ -0,0 +1,15 @@ +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4200_0_106 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4208_0_15 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4210_0_275 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4213_0_499 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4213_500_903 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4215_0_42 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4217_0_499 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4217_500_507 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4218_0_262 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4222_0_381 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4223_0_499 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4223_500_870 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4224_0_337 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4228_0_175 +/pnfs/annie/persistent/processed/processed_EBV2_LAPPDFiltered/2023_LAPPD40/AllLAPPD/FilteredAllLAPPDData_4229_0_345 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/ConfigGeo b/configfiles/LAPPD_EB/ConfigGeo new file mode 100644 index 000000000..759b28663 --- /dev/null +++ b/configfiles/LAPPD_EB/ConfigGeo @@ -0,0 +1,12 @@ +#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/ChannelSPEGains2023.csv +TankPMTTimingOffsetFile ./configfiles/LoadGeometry/TankPMTTimingOffsets.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +LAPPDMerging 0 + diff --git a/configfiles/LAPPD_EB/Configs b/configfiles/LAPPD_EB/Configs new file mode 100644 index 000000000..0975b4615 --- /dev/null +++ b/configfiles/LAPPD_EB/Configs @@ -0,0 +1,56 @@ + 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 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 +OutputWavLabel RawLAPPDData +SelectSingleLAPPD false +SelectedLAPPD 0 +loadPSEC 1 +loadPPS 1 +loadOffsets 0 + + +#LAPPDTreeMaker +LoadPulse 0 +LoadHit 0 +LoadWaveform 0 +LoadLAPPDDataTimeStamp 1 +LoadPPSTimestamp 1 +LoadRunInfoRaw 1 +LoadRunInfoANNIEEvent 0 + +treeMakerVerbosity 0 + +treeMakerInputPulseLabel LAPPDPulses +treeMakerInputHitLabel LAPPDHits +treeMakerOutputFileName LAPPDTree.root +LoadTriggerInfo 1 +LoadGroupOption beam +LoadGroupedTriggerInfo 1 diff --git a/configfiles/LAPPD_EB/LoadRawDataConfig b/configfiles/LAPPD_EB/LoadRawDataConfig new file mode 100644 index 000000000..d849fc8f2 --- /dev/null +++ b/configfiles/LAPPD_EB/LoadRawDataConfig @@ -0,0 +1,12 @@ +verbosity 0 +BuildType LAPPDAndCTC +Mode FileList + + +InputFile ./configfiles/LAPPD_EB/my_files.txt + + +DummyRunInfo 1 +StoreTrigOverlap 0 +ReadTrigOverlap 0 +StoreRawData 0 diff --git a/configfiles/LAPPD_EB/ToolChainConfig b/configfiles/LAPPD_EB/ToolChainConfig new file mode 100644 index 000000000..fe4ab0be2 --- /dev/null +++ b/configfiles/LAPPD_EB/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/LAPPD_EB/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/LAPPD_EB/ToolsConfig b/configfiles/LAPPD_EB/ToolsConfig new file mode 100644 index 000000000..71b067fe2 --- /dev/null +++ b/configfiles/LAPPD_EB/ToolsConfig @@ -0,0 +1,5 @@ +LoadGeometry LoadGeometry configfiles/LAPPD_EB/ConfigGeo +LoadRawData LoadRawData configfiles/LAPPD_EB/LoadRawDataConfig +TriggerDataDecoder TriggerDataDecoder configfiles/LAPPD_EB/TriggerDataDecoderConfig +LAPPDLoadStore LAPPDLoadStore configfiles/LAPPD_EB/Configs +LAPPDTreeMaker LAPPDTreeMaker configfiles/LAPPD_EB/Configs diff --git a/configfiles/LAPPD_EB/TriggerDataDecoderConfig b/configfiles/LAPPD_EB/TriggerDataDecoderConfig new file mode 100644 index 000000000..d3e32f7f8 --- /dev/null +++ b/configfiles/LAPPD_EB/TriggerDataDecoderConfig @@ -0,0 +1,4 @@ +verbosity 0 +#TriggerMaskFile ./configfiles/LAPPDBeamAnalysis/LAPPDRawData/DefaultTriggerMask.txt +StoreTrigOverlap 0 +ReadTrigOverlap 0 diff --git a/configfiles/LAPPD_EB/my_files.txt b/configfiles/LAPPD_EB/my_files.txt new file mode 100644 index 000000000..8504035cc --- /dev/null +++ b/configfiles/LAPPD_EB/my_files.txt @@ -0,0 +1,6 @@ +/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/LAPPDana/ConfigASCIIReadIn b/configfiles/LAPPDana/ConfigASCIIReadIn index aca78cc07..d4c13390a 100755 --- a/configfiles/LAPPDana/ConfigASCIIReadIn +++ b/configfiles/LAPPDana/ConfigASCIIReadIn @@ -15,18 +15,31 @@ RawDataInputWavLabel RawLAPPDDataFrame #Label of the raw dataframe in the store RawDataInputWavLabel RawWaveform RawDataOutpuWavLabel RawLAPPDData BoardIndexLabel BoardIndex #Label of the vector of read out boards + #PSECinputfile /pnfs/annie/persistent/LAPPDData/LAPPD63/2023-01-23/ND2_7/2350V/LaserOff/All.txt #PSECinputfile /pnfs/annie/persistent/LAPPDData/LAPPD63/All_2023-01-25_ND3_2350V.txt #PSECinputfile /pnfs/annie/persistent/LAPPDData/LAPPD63/2023-01-23/ND2_5/2350V/LaserOn/All.txt #PSECinputfile /pnfs/annie/persistent/LAPPDData/LAPPD63/2023-01-26/ND3.5/2350V/LaserOn/All.txt -PSECinputfile /pnfs/annie/persistent/LAPPDData/LAPPD63/2023-01-26/ND4/2350V/LaserOn/All.txt +PSECinputfile /pnfs/annie/persistent/LAPPDData/LAPPD151/2025-03-14/crosstalk/P2/all.txt DoPedSubtraction 1 Nboards 2 #Number of pedestal files to be read in -Pedinputfile ../Data/PEDS_ACDC -PedinputfileTXT ../Data/3655/PEDS_ACDC_board #prefix of the pedestal files path+name. index and filetype will be set automatically -Pedinputfile1 /pnfs/annie/persistent/LAPPDData/Pedestals/ACDC33.txt -Pedinputfile2 /pnfs/annie/persistent/LAPPDData/Pedestals/ACDC27.txt + +#LAPPD39 +#Pedinputfile1 /pnfs/annie/persistent/LAPPDData/LAPPDana/Pedestals/P4.txt +#Pedinputfile2 /pnfs/annie/persistent/LAPPDData/Pedestals/P5.txt + +#LAPPD58 +#Pedinputfile1 /pnfs/annie/persistent/LAPPDData/Pedestals/P2.txt +#Pedinputfile2 /pnfs/annie/persistent/LAPPDData/Pedestals/P3.txt + +#LAPPD64 +#Pedinputfile1 /pnfs/annie/persistent/LAPPDData/Pedestals/P0.txt +#Pedinputfile2 /pnfs/annie/persistent/LAPPDData/Pedestals/P1.txt + +#LAPPD151 +Pedinputfile1 /pnfs/annie/persistent/LAPPDData/Pedestals/ACDC35.txt +Pedinputfile2 /pnfs/annie/persistent/LAPPDData/Pedestals/ACDC05.txt #LAPPDReorderData ReorderVerbosityLevel 0 diff --git a/configfiles/LAPPDana/ConfigGeo b/configfiles/LAPPDana/ConfigGeo index bd7d596c8..118339f63 100755 --- a/configfiles/LAPPDana/ConfigGeo +++ b/configfiles/LAPPDana/ConfigGeo @@ -5,5 +5,6 @@ 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 +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains2023.csv +TankPMTTimingOffsetFile ./configfiles/LoadGeometry/TankPMTTimingOffsets.csv AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv diff --git a/configfiles/LAPPDana/ConfigLAPPDWaveformDisplay b/configfiles/LAPPDana/ConfigLAPPDWaveformDisplay new file mode 100644 index 000000000..a47b1efbe --- /dev/null +++ b/configfiles/LAPPDana/ConfigLAPPDWaveformDisplay @@ -0,0 +1,24 @@ +# To display specific events, uncomment and set the range. +#FirstEventNumber 0 +#LastEventNumber 500 + +InputWaveformLabel ABLSLAPPDData +ChannelOffset 0 +TrigerChannel1 1005 +TrigerChannel2 1035 +WaveformDisplayVerbosity 0 +RequireT0Signal 0 +DisplayTriggerChannelInPlot 1 +OutputFileName LAPPDWaveformDisplay.pdf + +# If PrintRunInfo is set to 0, the other settings below it are ignored, and the run information is not printed. +PrintRunInfo 0 + +Date 2025-03-14 +LAPPDModel 151 +Path /pnfs/annie/persistent/LAPPDData/LAPPD151/2025-03-14/crosstalk/P2/all.txt +LaserStatus On +TriggerMode Forced +NDFilter 2.0 +RunInfo "" + diff --git a/configfiles/LAPPDana/ToolChainConfig b/configfiles/LAPPDana/ToolChainConfig index 660e82e0b..d2bbd2261 100644 --- a/configfiles/LAPPDana/ToolChainConfig +++ b/configfiles/LAPPDana/ToolChainConfig @@ -16,7 +16,7 @@ service_kick_sec -1 ##### Tools To Add ##### Tools_File configfiles/LAPPDana/ToolsConfig_ASCII ## list of tools to run and their config files - +#Tools_File configfiles/LAPPDana/ToolsConfig_LAPPDWaveformDisplay ##### Run Type ##### #Inline 102 ## number of Execute steps in program, -1 infinite loop that is ended by user #Inline 4990 ## number of Execute steps in program, -1 infinite loop that is ended by user diff --git a/configfiles/LAPPDana/ToolsConfig_LAPPDWaveformDisplay b/configfiles/LAPPDana/ToolsConfig_LAPPDWaveformDisplay new file mode 100644 index 000000000..03935fb17 --- /dev/null +++ b/configfiles/LAPPDana/ToolsConfig_LAPPDWaveformDisplay @@ -0,0 +1,8 @@ +LoadGeometry LoadGeometry configfiles/LAPPDana/ConfigGeo +LAPPDASCIIReadIn LAPPDASCIIReadIn configfiles/LAPPDana/ConfigASCIIReadIn +LAPPDReorderData LAPPDReorderData configfiles/LAPPDana/ConfigASCIIReadIn +LAPPDBaselineSubtract LAPPDBaselineSubtract configfiles/LAPPDana/ConfigPreProcess +LAPPDFindT0 LAPPDFindT0 configfiles/LAPPDana/ConfigPreProcess +LAPPDBaselineSubtract2 LAPPDBaselineSubtract configfiles/LAPPDana/ConfigSimplePulses +LAPPDWaveformDisplay LAPPDWaveformDisplay configfiles/LAPPDana/ConfigLAPPDWaveformDisplay + diff --git a/configfiles/LoadGeometry/ChannelSPEGains2023.csv b/configfiles/LoadGeometry/ChannelSPEGains2023.csv index a54a43f7b..e0dcfa7cf 100644 --- a/configfiles/LoadGeometry/ChannelSPEGains2023.csv +++ b/configfiles/LoadGeometry/ChannelSPEGains2023.csv @@ -79,6 +79,7 @@ 413,0.001499 414,0.001488 415,0.001217 +416,0.0 417,0.001468 418,0.001457 419,0.001248 diff --git a/configfiles/LoadGeometry/FullMRDGeometry_01_thru_05_2024_Runs_R4717_thru_R4890.csv b/configfiles/LoadGeometry/FullMRDGeometry_01_thru_05_2024_Runs_R4717_thru_R4890.csv new file mode 100644 index 000000000..78d542954 --- /dev/null +++ b/configfiles/LoadGeometry/FullMRDGeometry_01_thru_05_2024_Runs_R4717_thru_R4890.csv @@ -0,0 +1,342 @@ +#,,0=FMV,0=horizontal,,0=left,from left to right,,,,,,,,,,,,,,#NAME?,#NAME?,,,,,,,,,,, +#,,1=MRD,1=vertical,,1=right,from bottom to top,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,0=bottom,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,1=top,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,channel_num,detector_system,orientation,layer,side,num,x_center,y_center,z_center,x_width,y_width,z_width,rack,TDC_slot,TDC_channel,discrim_slot,discrim_ch,patch_panel_row,patch_panel_col,amp_slot,amp_channel,hv_crate,hv_slot,hv_channel,nominal_HV,polarity,PMT_type,cable_label,paddle_label,notes,detector_status,noise +########################################,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,-198.699875,5.08,320,30.5,2,8,2,0,1,1,1,1,-1,-1,2,14,0,-1871,-1,EMI9815,MRD_x00_y00_z00,4SW,None,ON,NORMAL +1,1,0,0,0,0,1,0,-167.999875,5.08,320,30.5,2,8,2,1,1,2,1,2,-1,-1,2,14,1,-1838,-1,EMI9815,MRD_x00_y01_z00,U39,None,ON,NORMAL +2,2,0,0,0,0,2,0,-137.299875,5.08,320,30.5,2,8,2,2,1,3,1,3,-1,-1,2,14,2,-1793,-1,EMI9815,MRD_x00_y02_z00,U58 (or U38; bad writing),None,ON,NORMAL +3,3,0,0,0,0,3,0,-106.599875,5.08,320,30.5,2,8,2,3,1,4,1,4,-1,-1,2,14,3,-1806,-1,EMI9815,MRD_x00_y03_z00,U29,None,ON,NORMAL +4,4,0,0,0,0,4,0,-75.899875,5.08,320,30.5,2,8,2,4,1,5,1,5,-1,-1,2,14,4,-1865,-1,EMI9815,MRD_x00_y04_z00,14SW,None,ON,NORMAL +5,5,0,0,0,0,5,0,-45.199875,5.08,320,30.5,2,8,2,5,1,6,1,6,-1,-1,2,14,5,-1823,-1,EMI9815,MRD_x00_y05_z00,Unknown4,None,ON,NORMAL +6,6,0,0,0,0,6,0,-14.499875,5.08,320,30.5,2,8,2,6,1,7,1,7,-1,-1,2,14,6,-1798,-1,EMI9815,MRD_x00_y06_z00,U17,None,ON,NORMAL +7,7,0,0,0,0,7,0,16.200125,5.08,320,30.5,2,8,2,7,1,8,1,8,-1,-1,2,14,7,-1823,-1,EMI9815,MRD_x00_y07_z00,11SE,None,ON,NORMAL +8,8,0,0,0,0,8,0,46.900125,5.08,320,30.5,2,8,2,8,1,9,1,9,-1,-1,2,14,8,-1871,-1,EMI9815,MRD_x00_y08_z00,18SE,None,ON,NORMAL +9,9,0,0,0,0,9,0,77.600125,5.08,320,30.5,2,8,2,9,1,10,1,10,-1,-1,2,14,9,-1836,-1,EMI9815,MRD_x00_y09_z00,21SW,None,ON,NORMAL +10,10,0,0,0,0,10,0,108.300125,5.08,320,30.5,2,8,2,10,1,11,1,11,-1,-1,2,14,10,-1814,-1,EMI9815,MRD_x00_y10_z00,3SE,None,ON,NORMAL +11,11,0,0,0,0,11,0,139.000125,5.08,320,30.5,2,8,2,11,1,12,1,12,-1,-1,2,14,11,-1781,-1,EMI9815,MRD_x00_y11_z00,24SE,None,ON,NORMAL +12,12,0,0,0,0,12,0,169.700125,5.08,320,30.5,2,8,2,12,1,13,1,13,-1,-1,2,14,12,-1816,-1,EMI9815,MRD_x00_y12_z00,U25,None,ON,NORMAL +13,13,0,0,0,1,0,0,-198.064875,7.28,320,30.5,2,8,2,16,3,1,2,1,-1,-1,2,15,0,-1805,-1,EMI9815,MRD_x01_y00_z00,28SE,None,ON,NORMAL +14,14,0,0,0,1,1,0,-167.364875,7.28,320,30.5,2,8,2,17,3,2,2,2,-1,-1,2,15,1,-1818,-1,EMI9815,MRD_x01_y01_z00,31SE,None,ON,NORMAL +15,15,0,0,0,1,2,0,-136.664875,7.28,320,30.5,2,8,2,18,3,3,2,3,-1,-1,2,15,2,-1860,-1,EMI9815,MRD_x01_y02_z00,8SE,None,ON,NORMAL +16,16,0,0,0,1,3,0,-105.964875,7.28,320,30.5,2,8,2,19,3,4,2,4,-1,-1,2,15,3,-1780,-1,EMI9815,MRD_x01_y03_z00,11SW,None,ON,NORMAL +17,17,0,0,0,1,4,0,-75.264875,7.28,320,30.5,2,8,2,20,3,5,2,5,-1,-1,2,15,4,-1841,-1,EMI9815,MRD_x01_y04_z00,U34,None,ON,NORMAL +18,18,0,0,0,1,5,0,-44.564875,7.28,320,30.5,2,8,2,21,3,6,2,6,-1,-1,2,15,5,-1786,-1,EMI9815,MRD_x01_y05_z010,U36,None,ON,NORMAL +19,19,0,0,0,1,6,0,-13.864875,7.28,320,30.5,2,8,2,22,3,7,2,7,-1,-1,2,15,6,-1864,-1,EMI9815,MRD_x01_y06_z00,U40,None,ON,NORMAL +20,20,0,0,0,1,7,0,16.835125,7.28,320,30.5,2,8,2,23,3,8,2,8,-1,-1,2,15,7,-1858,-1,EMI9815,MRD_x01_y07_z00,Unknown5,None,ON,NORMAL +21,21,0,0,0,1,8,0,47.535125,7.28,320,30.5,2,8,2,24,3,9,2,9,-1,-1,2,15,8,-1876,-1,EMI9815,MRD_x01_y08_z00,27SE,None,ON,NORMAL +22,22,0,0,0,1,9,0,78.235125,7.28,320,30.5,2,8,2,25,3,10,2,10,-1,-1,2,15,9,-1806,-1,EMI9815,MRD_x01_y09_z00,Unknown2,None,ON,NORMAL +23,23,0,0,0,1,10,0,108.935125,7.28,320,30.5,2,8,2,26,3,11,2,11,-1,-1,2,15,10,-1853,-1,EMI9815,MRD_x01_y10_z00,10SW,None,ON,NORMAL +24,24,0,0,0,1,11,0,139.635125,7.28,320,30.5,2,8,2,27,3,12,2,12,-1,-1,2,15,11,-1860,-1,EMI9815,MRD_x01_y11_z00,Bill2,None,ON,NORMAL +25,25,0,0,0,1,12,0,170.335125,7.28,320,30.5,2,8,2,28,3,13,2,13,-1,-1,2,15,12,-1844,-1,EMI9815,MRD_x01_y12_z00,13SE,None,ON,NORMAL +26,26,1,0,2,0,0,-73.75,-121.8,336.38,147.2,20,0.6,7,2,0,1,1,1,1,-1,-1,1,4,0,-2100,-1,-9999,MRD_x00_y00_z02,MRD_x00_y00_z02,None,ON,NORMAL +27,27,1,0,2,0,1,-73.75,-101.5,336.38,147.2,20,0.6,7,2,1,1,2,1,2,-1,-1,1,4,1,-2100,-1,-9999,MRD_x00_y01_z02,MRD_x00_y01_z02,None,ON,NORMAL +28,28,1,0,2,0,2,-73.75,-81.2,336.38,147.2,20,0.6,7,2,2,1,3,1,3,-1,-1,1,4,2,-2100,-1,-9999,MRD_x00_y02_z02,MRD_x00_y02_z02,None,ON,NORMAL +29,29,1,0,2,0,3,-73.75,-60.9,336.38,147.2,20,0.6,7,2,3,1,4,1,4,-1,-1,1,4,3,-2100,-1,-9999,MRD_x00_y03_z02,MRD_x00_y03_z02,None,ON,NORMAL +30,30,1,0,2,0,4,-73.75,-40.6,336.38,147.2,20,0.6,7,2,4,1,5,1,5,-1,-1,1,4,4,-2100,-1,-9999,MRD_x00_y04_z02,MRD_x00_y04_z02,None,ON,NORMAL +31,31,1,0,2,0,5,-73.75,-20.3,336.38,147.2,20,0.6,7,2,5,1,6,1,6,-1,-1,1,4,5,-2100,-1,-9999,MRD_x00_y05_z02,MRD_x00_y05_z02,None,ON,NORMAL +32,32,1,0,2,0,6,-73.75,0,336.38,147.2,20,0.6,7,2,6,1,7,1,7,-1,-1,1,4,6,-2100,-1,-9999,MRD_x00_y06_z02,MRD_x00_y06_z02,None,ON,NORMAL +33,33,1,0,2,0,7,-73.75,20.3,336.38,147.2,20,0.6,7,2,7,1,8,1,8,-1,-1,1,4,7,-2100,-1,-9999,MRD_x00_y07_z02,MRD_x00_y07_z02,None,ON,NORMAL +34,34,1,0,2,0,8,-73.75,40.6,336.38,147.2,20,0.6,7,2,8,1,9,1,9,-1,-1,1,4,8,-1900,-1,-9999,MRD_x00_y08_z02,MRD_x00_y08_z02,None,ON,NORMAL +35,35,1,0,2,0,9,-73.75,60.9,336.38,147.2,20,0.6,7,2,9,1,10,1,10,-1,-1,1,4,10,-1900,-1,-9999,MRD_x00_y09_z02,MRD_x00_y09_z02,None,ON,NORMAL +36,36,1,0,2,0,10,-73.75,81.2,336.38,147.2,20,0.6,7,2,10,1,11,1,11,-1,-1,1,4,11,-2100,-1,-9999,MRD_x00_y10_z02,MRD_x00_y10_z02,None,ON,NORMAL +37,37,1,0,2,0,11,-73.75,101.5,336.38,147.2,20,0.6,7,2,11,1,12,1,12,-1,-1,1,4,12,-2100,-1,-9999,MRD_x00_y11_z02,MRD_x00_y11_z02,None,ON,NORMAL +38,38,1,0,2,0,12,-73.75,121.8,336.38,147.2,20,0.6,7,2,12,1,13,1,13,-1,-1,1,4,13,-1900,-1,-9999,MRD_x00_y12_z02,MRD_x00_y12_z02,None,ON,NORMAL +39,39,1,0,2,1,0,73.75,-121.8,336.38,147.2,20,0.6,7,2,16,3,1,2,1,-1,-1,1,5,0,-2100,-1,-9999,MRD_x01_y00_z02,MRD_x01_y00_z02,None,ON,NORMAL +40,40,1,0,2,1,1,73.75,-101.5,336.38,147.2,20,0.6,7,2,17,3,2,2,2,-1,-1,1,5,1,-2100,-1,-9999,MRD_x01_y01_z02,MRD_x01_y01_z02,None,ON,NORMAL +41,41,1,0,2,1,2,73.75,-81.2,336.38,147.2,20,0.6,7,2,18,3,3,2,3,-1,-1,1,5,2,-1900,-1,-9999,MRD_x01_y02_z02,MRD_x01_y02_z02,None,ON,NORMAL +42,42,1,0,2,1,3,73.75,-60.9,336.38,147.2,20,0.6,7,2,19,3,4,2,4,-1,-1,1,5,3,-1900,-1,-9999,MRD_x01_y03_z02,MRD_x01_y03_z02,None,ON,NORMAL +43,43,1,0,2,1,4,73.75,-40.6,336.38,147.2,20,0.6,7,2,20,3,5,2,5,-1,-1,1,5,4,-2100,-1,-9999,MRD_x01_y04_z02,MRD_x01_y04_z02,None,ON,NORMAL +44,44,1,0,2,1,5,73.75,-20.3,336.38,147.2,20,0.6,7,2,21,3,6,2,6,-1,-1,1,5,5,-2100,-1,-9999,MRD_x01_y05_z02,MRD_x01_y05_z02,None,ON,NORMAL +45,45,1,0,2,1,6,73.75,0,336.38,147.2,20,0.6,7,2,22,3,7,2,7,-1,-1,1,5,6,-1900,-1,-9999,MRD_x01_y06_z02,MRD_x01_y06_z02,None,ON,NORMAL +46,46,1,0,2,1,7,73.75,20.3,336.38,147.2,20,0.6,7,2,23,3,8,2,8,-1,-1,1,5,7,-2100,-1,-9999,MRD_x01_y07_z02,MRD_x01_y07_z02,None,ON,NORMAL +47,47,1,0,2,1,8,73.75,40.6,336.38,147.2,20,0.6,7,2,24,3,9,2,9,-1,-1,1,5,8,-2100,-1,-9999,MRD_x01_y08_z02,MRD_x01_y08_z02,None,ON,NORMAL +48,48,1,0,2,1,9,73.75,60.9,336.38,147.2,20,0.6,7,2,25,3,10,2,10,-1,-1,1,5,9,-2100,-1,-9999,MRD_x01_y09_z02,MRD_x01_y09_z02,None,ON,NORMAL +49,49,1,0,2,1,10,73.75,81.2,336.38,147.2,20,0.6,7,2,26,3,11,2,11,-1,-1,1,5,10,-2100,-1,-9999,MRD_x01_y10_z02,MRD_x01_y10_z02,None,ON,NORMAL +50,50,1,0,2,1,11,73.75,101.5,336.38,147.2,20,0.6,7,2,27,3,12,2,12,-1,-1,1,5,11,-2100,-1,-9999,MRD_x01_y11_z02,MRD_x01_y11_z02,None,ON,NORMAL +51,51,1,0,2,1,12,73.75,121.8,336.38,147.2,20,0.6,7,2,28,3,13,2,13,-1,-1,1,5,12,-1900,-1,-9999,MRD_x01_y12_z02,MRD_x01_y12_z02,None,ON,NORMAL +52,52,1,1,3,0,0,-107.1,-65.25,348.84,15,130.2,1.3,8,5,0,4,1,3,1,-1,-1,1,6,0,-2000,-1,-9999,MRD_x00_y00_z03,MRD_x00_y00_z03,None,ON,NORMAL +53,53,1,1,3,0,1,-91.8,-65.25,348.84,15,130.2,1.3,8,5,1,4,2,3,2,-1,-1,1,6,1,-2000,-1,-9999,MRD_x01_y00_z03,MRD_x01_y00_z03,None,ON,NORMAL +54,54,1,1,3,0,2,-76.5,-65.25,348.84,15,130.2,1.3,8,5,2,4,3,3,3,-1,-1,1,6,2,-2000,-1,-9999,MRD_x02_y00_z03,MRD_x02_y00_z03,None,ON,HOT +55,55,1,1,3,0,3,-61.2,-65.25,348.84,15,130.2,1.3,8,5,3,4,4,3,4,-1,-1,1,6,3,-2000,-1,-9999,MRD_x03_y00_z03,MRD_x03_y00_z03,None,ON,NORMAL +56,56,1,1,3,0,4,-45.9,-65.25,348.84,15,130.2,1.3,8,5,4,4,5,3,5,-1,-1,1,6,4,-2000,-1,-9999,MRD_x04_y00_z03,MRD_x04_y00_z03,None,ON,NORMAL +57,57,1,1,3,0,5,-30.6,-65.25,348.84,15,130.2,1.3,8,5,5,4,6,3,6,-1,-1,1,6,5,-2000,-1,-9999,MRD_x05_y00_z03,MRD_x05_y00_z03,None,ON,NORMAL +58,58,1,1,3,0,6,-15.3,-65.25,348.84,15,130.2,1.3,8,5,6,4,7,3,7,-1,-1,1,6,6,-2000,-1,-9999,MRD_x06_y00_z03,MRD_x06_y00_z03,None,ON,NORMAL +59,59,1,1,3,0,7,0,-65.25,348.84,15,130.2,1.3,8,5,7,4,8,3,8,-1,-1,1,6,7,-2000,-1,-9999,MRD_x07_y00_z03,MRD_x07_y00_z03,None,ON,NORMAL +60,60,1,1,3,0,8,15.3,-65.25,348.84,15,130.2,1.3,8,5,8,4,9,3,9,-1,-1,1,6,8,-2000,-1,-9999,MRD_x08_y00_z03,MRD_x08_y00_z03,None,OFF,NORMAL +61,61,1,1,3,0,9,30.6,-65.25,348.84,15,130.2,1.3,8,5,9,4,10,3,10,-1,-1,1,6,9,-2000,-1,-9999,MRD_x09_y00_z03,MRD_x09_y00_z03,None,ON,NORMAL +62,62,1,1,3,0,10,45.9,-65.25,348.84,15,130.2,1.3,8,5,10,4,11,3,11,-1,-1,1,6,10,-2000,-1,-9999,MRD_x10_y00_z03,MRD_x10_y00_z03,None,ON,NORMAL +63,63,1,1,3,0,11,61.2,-65.25,348.84,15,130.2,1.3,8,5,11,4,12,3,12,-1,-1,1,6,11,-2000,-1,-9999,MRD_x11_y00_z03,MRD_x11_y00_z03,None,ON,NORMAL +64,64,1,1,3,0,12,76.5,-65.25,348.84,15,130.2,1.3,8,5,12,4,13,3,13,-1,-1,1,6,12,-2000,-1,-9999,MRD_x12_y00_z03,MRD_x12_y00_z03,None,ON,NORMAL +65,65,1,1,3,0,13,91.8,-65.25,348.84,15,130.2,1.3,8,5,13,4,14,3,14,-1,-1,1,6,13,-2000,-1,-9999,MRD_x13_y00_z03,MRD_x13_y00_z03,None,ON,NORMAL +66,66,1,1,3,0,14,107.1,-65.25,348.84,15,130.2,1.3,8,5,14,4,15,3,15,-1,-1,1,6,14,-1800,-1,-9999,MRD_x14_y00_z03,MRD_x14_y00_z03,None,ON,NORMAL +67,67,1,1,3,1,0,-107.1,65.25,348.84,15,130.2,1.3,8,5,16,6,1,4,1,-1,-1,1,7,0,-2200,-1,-9999,MRD_x00_y01_z03,MRD_x00_y01_z03,None,ON,HOT +68,68,1,1,3,1,1,-91.8,65.25,348.84,15,130.2,1.3,8,5,17,6,2,4,2,-1,-1,1,7,1,-2000,-1,-9999,MRD_x01_y01_z03,MRD_x01_y01_z03,None,ON,NORMAL +69,69,1,1,3,1,2,-76.5,65.25,348.84,15,130.2,1.3,8,5,18,6,3,4,3,-1,-1,1,7,2,-2000,-1,-9999,MRD_x02_y01_z03,MRD_x02_y01_z03,None,ON,NORMAL +70,70,1,1,3,1,3,-61.2,65.25,348.84,15,130.2,1.3,8,5,19,6,4,4,4,-1,-1,1,7,3,-2000,-1,-9999,MRD_x03_y01_z03,MRD_x03_y01_z03,None,ON,NORMAL +71,71,1,1,3,1,4,-45.9,65.25,348.84,15,130.2,1.3,8,5,20,6,5,4,5,-1,-1,1,7,4,-2000,-1,-9999,MRD_x04_y01_z03,MRD_x04_y01_z03,None,ON,NORMAL +72,72,1,1,3,1,5,-30.6,65.25,348.84,15,130.2,1.3,8,5,21,6,6,4,6,-1,-1,1,7,5,-2000,-1,-9999,MRD_x05_y01_z03,MRD_x05_y01_z03,None,ON,NORMAL +73,73,1,1,3,1,6,-15.3,65.25,348.84,15,130.2,1.3,8,5,22,6,7,4,7,-1,-1,1,7,6,-2000,-1,-9999,MRD_x06_y01_z03,MRD_x06_y01_z03,None,ON,NORMAL +74,74,1,1,3,1,7,0,65.25,348.84,15,130.2,1.3,8,5,23,6,8,4,8,-1,-1,1,7,7,-2000,-1,-9999,MRD_x07_y01_z03,MRD_x07_y01_z03,None,ON,HOT +75,75,1,1,3,1,8,15.3,65.25,348.84,15,130.2,1.3,8,5,24,6,9,4,9,-1,-1,1,7,8,-2000,-1,-9999,MRD_x08_y01_z03,MRD_x08_y01_z03,None,ON,NORMAL +76,76,1,1,3,1,9,30.6,65.25,348.84,15,130.2,1.3,8,5,25,6,10,4,10,-1,-1,1,7,9,-2000,-1,-9999,MRD_x09_y01_z03,MRD_x09_y01_z03,None,ON,HOT +77,77,1,1,3,1,10,45.9,65.25,348.84,15,130.2,1.3,8,5,26,6,11,4,11,-1,-1,1,7,10,-2000,-1,-9999,MRD_x10_y01_z03,MRD_x10_y01_z03,Currently using y1 z3 spare cableNone,ON,NORMAL +78,78,1,1,3,1,11,61.2,65.25,348.84,15,130.2,1.3,8,5,27,6,12,4,12,-1,-1,1,7,11,-2000,-1,-9999,MRD_x11_y01_z03,MRD_x11_y01_z03,None,ON,HOT +79,79,1,1,3,1,12,76.5,65.25,348.84,15,130.2,1.3,8,5,28,6,13,4,13,-1,-1,1,7,12,-2000,-1,-9999,MRD_x12_y01_z03,MRD_x12_y01_z03,None,ON,NORMAL +80,80,1,1,3,1,13,91.8,65.25,348.84,15,130.2,1.3,8,5,29,6,14,4,14,-1,-1,1,7,13,-2000,-1,-9999,MRD_x13_y01_z03,MRD_x13_y01_z03,None,ON,NORMAL +81,81,1,1,3,1,14,107.1,65.25,348.84,15,130.2,1.3,8,5,30,6,15,4,15,-1,-1,1,7,14,-2000,-1,-9999,MRD_x14_y01_z03,MRD_x14_y01_z03,None,ON,NORMAL +82,82,1,0,4,0,0,-73.75,-121.8,361.3,147.2,20,0.6,7,5,0,4,1,3,1,-1,-1,1,8,0,-2100,-1,-9999,MRD_x00_y00_z04,MRD_x00_y00_z04,None,ON,NORMAL +83,83,1,0,4,0,1,-73.75,-101.5,361.3,147.2,20,0.6,7,5,1,4,2,3,2,-1,-1,1,8,1,-2100,-1,-9999,MRD_x00_y01_z04,MRD_x00_y01_z04,None,ON,NORMAL +84,84,1,0,4,0,2,-73.75,-81.2,361.3,147.2,20,0.6,7,5,2,4,3,3,3,-1,-1,1,8,2,-2100,-1,-9999,MRD_x00_y02_z04,MRD_x00_y02_z04,None,ON,NORMAL +85,85,1,0,4,0,3,-73.75,-60.9,361.3,147.2,20,0.6,7,5,3,4,4,3,4,-1,-1,1,8,3,-2100,-1,-9999,MRD_x00_y03_z04,MRD_x00_y03_z04,None,ON,NORMAL +86,86,1,0,4,0,4,-73.75,-40.6,361.3,147.2,20,0.6,7,5,4,4,5,3,5,-1,-1,1,8,4,-2300,-1,-9999,MRD_x00_y04_z04,MRD_x00_y04_z04,None,ON,NORMAL +87,87,1,0,4,0,5,-73.75,-20.3,361.3,147.2,20,0.6,7,5,5,4,6,3,6,-1,-1,1,8,5,-2100,-1,-9999,MRD_x00_y05_z04,MRD_x00_y05_z04,None,ON,NORMAL +88,88,1,0,4,0,6,-73.75,0,361.3,147.2,20,0.6,7,5,6,4,7,3,7,-1,-1,1,8,6,-2100,-1,-9999,MRD_x00_y06_z04,MRD_x00_y06_z04,None,ON,NORMAL +89,89,1,0,4,0,7,-73.75,20.3,361.3,147.2,20,0.6,7,5,7,4,8,3,8,-1,-1,1,8,7,-2100,-1,-9999,MRD_x00_y07_z04,MRD_x00_y07_z04,None,ON,NORMAL +90,90,1,0,4,0,8,-73.75,40.6,361.3,147.2,20,0.6,7,5,8,4,9,3,9,-1,-1,1,8,8,-2100,-1,-9999,MRD_x00_y08_z04,MRD_x00_y08_z04,None,ON,NORMAL +91,91,1,0,4,0,9,-73.75,60.9,361.3,147.2,20,0.6,7,5,9,4,10,3,10,-1,-1,1,8,9,-2100,-1,-9999,MRD_x00_y09_z04,MRD_x00_y09_z04,None,ON,NORMAL +92,92,1,0,4,0,10,-73.75,81.2,361.3,147.2,20,0.6,7,5,10,4,11,3,11,-1,-1,1,8,10,-2100,-1,-9999,MRD_x00_y10_z04,MRD_x00_y10_z04,None,ON,NORMAL +93,93,1,0,4,0,11,-73.75,101.5,361.3,147.2,20,0.6,7,5,11,4,12,3,12,-1,-1,1,8,11,-2100,-1,-9999,MRD_x00_y11_z04,MRD_x00_y11_z04,None,ON,NORMAL +94,94,1,0,4,0,12,-73.75,121.8,361.3,147.2,20,0.6,7,5,12,4,13,3,13,-1,-1,1,8,12,-2300,-1,-9999,MRD_x00_y12_z04,MRD_x00_y12_z04,None,ON,NORMAL +95,95,1,0,4,1,0,73.75,-121.8,361.3,147.2,20,0.6,7,5,16,6,1,4,1,-1,-1,1,9,0,-2100,-1,-9999,MRD_x01_y00_z04,MRD_x01_y00_z04,None,ON,HOT +96,96,1,0,4,1,1,73.75,-101.5,361.3,147.2,20,0.6,7,5,17,6,2,4,2,-1,-1,1,9,1,-2100,-1,-9999,MRD_x01_y01_z04,MRD_x01_y01_z04,None,ON,NORMAL +97,97,1,0,4,1,2,73.75,-81.2,361.3,147.2,20,0.6,7,5,18,6,3,4,3,-1,-1,1,9,2,-2300,-1,-9999,MRD_x01_y02_z04,MRD_x01_y02_z04,None,ON,NORMAL +98,98,1,0,4,1,3,73.75,-60.9,361.3,147.2,20,0.6,7,5,19,6,4,4,4,-1,-1,1,9,3,-2300,-1,-9999,MRD_x01_y03_z04,MRD_x01_y03_z04,None,ON,NORMAL +99,99,1,0,4,1,4,73.75,-40.6,361.3,147.2,20,0.6,7,5,20,6,5,4,5,-1,-1,1,9,4,-2100,-1,-9999,MRD_x01_y04_z04,MRD_x01_y04_z04,None,ON,NORMAL +100,100,1,0,4,1,5,73.75,-20.3,361.3,147.2,20,0.6,7,5,21,6,6,4,6,-1,-1,1,9,5,-2100,-1,-9999,MRD_x01_y05_z04,MRD_x01_y05_z04,None,ON,NORMAL +101,101,1,0,4,1,6,73.75,0,361.3,147.2,20,0.6,7,5,22,6,7,4,7,-1,-1,1,9,6,-2100,-1,-9999,MRD_x01_y06_z04,MRD_x01_y06_z04,None,ON,NORMAL +102,102,1,0,4,1,7,73.75,20.3,361.3,147.2,20,0.6,7,5,23,6,8,4,8,-1,-1,1,9,7,-2100,-1,-9999,MRD_x01_y07_z04,MRD_x01_y07_z04,None,ON,NORMAL +103,103,1,0,4,1,8,73.75,40.6,361.3,147.2,20,0.6,7,5,24,6,9,4,9,-1,-1,1,9,8,-2100,-1,-9999,MRD_x01_y08_z04,MRD_x01_y08_z04,None,ON,NORMAL +104,104,1,0,4,1,9,73.75,60.9,361.3,147.2,20,0.6,7,5,25,6,10,4,10,-1,-1,1,9,9,-2100,-1,-9999,MRD_x01_y09_z04,MRD_x01_y09_z04,None,ON,NORMAL +105,105,1,0,4,1,10,73.75,81.2,361.3,147.2,20,0.6,7,5,26,6,11,4,11,-1,-1,1,9,10,-2100,-1,-9999,MRD_x01_y10_z04,MRD_x01_y10_z04,None,ON,NORMAL +106,106,1,0,4,1,11,73.75,101.5,361.3,147.2,20,0.6,7,5,27,6,12,4,12,-1,-1,1,9,11,-2100,-1,-9999,MRD_x01_y11_z04,MRD_x01_y11_z04,None,ON,NORMAL +107,107,1,0,4,1,12,73.75,121.8,361.3,147.2,20,0.6,7,5,28,6,13,4,13,-1,-1,1,9,12,-2100,-1,-9999,MRD_x01_y12_z04,MRD_x01_y12_z04,None,ON,NORMAL +108,108,1,1,5,0,0,-122.4,-65.25,373.76,15,130.2,1.3,8,8,0,7,1,5,1,-1,-1,1,10,0,-2200,-1,-9999,MRD_x00_y00_z05,MRD_x00_y00_z05,None,ON,NORMAL +109,109,1,1,5,0,1,-107.1,-65.25,373.76,15,130.2,1.3,8,8,1,7,2,5,2,-1,-1,1,10,1,-2200,-1,-9999,MRD_x01_y00_z05,MRD_x01_y00_z05,None,ON,NORMAL +110,110,1,1,5,0,2,-91.8,-65.25,373.76,15,130.2,1.3,8,8,2,7,3,5,3,-1,-1,1,10,2,-2000,-1,-9999,MRD_x02_y00_z05,MRD_x02_y00_z05,None,ON,NORMAL +111,111,1,1,5,0,3,-76.5,-65.25,373.76,15,130.2,1.3,8,8,7,7,8,5,4,-1,-1,1,10,3,-1500,-1,-9999,MRD_x03_y00_z05,MRD_x03_y00_z05,None,ON,NORMAL +112,112,1,1,5,0,4,-61.2,-65.25,373.76,15,130.2,1.3,8,8,3,7,4,5,5,-1,-1,1,10,4,-2000,-1,-9999,MRD_x04_y00_z05,MRD_x04_y00_z05,None,ON,NORMAL +113,113,1,1,5,0,5,-45.9,-65.25,373.76,15,130.2,1.3,8,8,4,7,5,5,6,-1,-1,1,10,5,-2000,-1,-9999,MRD_x05_y00_z05,MRD_x05_y00_z05,None,ON,NORMAL +114,114,1,1,5,0,6,-30.6,-65.25,373.76,15,130.2,1.3,8,8,6,7,7,5,7,-1,-1,1,10,6,-2000,-1,-9999,MRD_x06_y00_z05,MRD_x06_y00_z05,None,ON,NORMAL +115,115,1,1,5,0,7,-15.3,-65.25,373.76,15,130.2,1.3,8,8,5,7,6,5,8,-1,-1,1,10,7,-2000,-1,-9999,MRD_x07_y00_z05,MRD_x07_y00_z05,None,ON,NORMAL +116,116,1,1,5,0,8,0,-65.25,373.76,15,130.2,1.3,8,8,8,7,9,5,9,-1,-1,1,10,8,-2000,-1,-9999,MRD_x08_y00_z05,MRD_x08_y00_z05,None,ON,NORMAL +117,117,1,1,5,0,9,15.3,-65.25,373.76,15,130.2,1.3,8,8,14,7,15,5,10,-1,-1,1,10,9,-2000,-1,-9999,MRD_x09_y00_z05,MRD_x09_y00_z05,None,ON,NORMAL +118,118,1,1,5,0,10,30.6,-65.25,373.76,15,130.2,1.3,8,8,10,7,11,5,11,-1,-1,1,10,10,-2000,-1,-9999,MRD_x10_y00_z05,MRD_x10_y00_z05,None,ON,NORMAL +119,119,1,1,5,0,11,45.9,-65.25,373.76,15,130.2,1.3,8,8,11,7,12,5,12,-1,-1,1,10,11,-2000,-1,-9999,MRD_x11_y00_z05,MRD_x11_y00_z05,None,ON,NORMAL +120,120,1,1,5,0,12,61.2,-65.25,373.76,15,130.2,1.3,8,8,9,7,10,5,13,-1,-1,1,10,12,-2000,-1,-9999,MRD_x12_y00_z05,MRD_x12_y00_z05,Discriminator on slot 7 channel 13 has no NIM outputNone,ON,NORMAL +121,121,1,1,5,0,13,76.5,-65.25,373.76,15,130.2,1.3,8,8,12,7,13,5,14,-1,-1,1,10,13,-2000,-1,-9999,MRD_x13_y00_z05,MRD_x13_y00_z05,None,ON,NORMAL +122,122,1,1,5,0,14,91.8,-65.25,373.76,15,130.2,1.3,8,8,13,7,14,5,15,-1,-1,1,10,14,-2000,-1,-9999,MRD_x14_y00_z05,MRD_x14_y00_z05,None,ON,NORMAL +123,123,1,1,5,0,15,107.1,-65.25,373.76,15,130.2,1.3,8,8,15,7,16,5,16,-1,-1,1,5,14,-1500,-1,-9999,MRD_x15_y00_z05,MRD_x15_y00_z05,None,OFF,NORMAL +124,124,1,1,5,0,16,122.4,-65.25,373.76,15,130.2,1.3,8,17,15,16,16,5,17,-1,-1,1,4,14,-2200,-1,-9999,MRD_x16_y00_z05,MRD_x16_y00_z05,None,OFF,NORMAL +125,125,1,1,5,1,0,-122.4,65.25,373.76,15,130.2,1.3,8,8,16,9,1,6,1,-1,-1,1,11,0,-2000,-1,-9999,MRD_x00_y01_z05,MRD_x00_y01_z05,None,ON,NORMAL +126,126,1,1,5,1,1,-107.1,65.25,373.76,15,130.2,1.3,8,8,17,9,2,6,2,-1,-1,1,11,1,-2000,-1,-9999,MRD_x01_y01_z05,MRD_x01_y01_z05,possible dischargeNone,ON,NORMAL +127,127,1,1,5,1,2,-91.8,65.25,373.76,15,130.2,1.3,8,8,18,9,3,6,3,-1,-1,1,11,2,-2000,-1,-9999,MRD_x02_y01_z05,MRD_x02_y01_z05,None,ON,NORMAL +128,128,1,1,5,1,3,-76.5,65.25,373.76,15,130.2,1.3,8,8,19,9,4,6,4,-1,-1,1,11,3,-2000,-1,-9999,MRD_x03_y01_z05,MRD_x03_y01_z05,None,ON,NORMAL +129,129,1,1,5,1,4,-61.2,65.25,373.76,15,130.2,1.3,8,8,20,9,5,6,5,-1,-1,1,11,4,-1500,-1,-9999,MRD_x04_y01_z05,MRD_x04_y01_z05,None,ON,NORMAL +130,130,1,1,5,1,5,-45.9,65.25,373.76,15,130.2,1.3,8,8,21,9,6,6,6,-1,-1,1,11,5,-2000,-1,-9999,MRD_x05_y01_z05,MRD_x05_y01_z05,None,ON,NORMAL +131,131,1,1,5,1,6,-30.6,65.25,373.76,15,130.2,1.3,8,8,22,9,7,6,7,-1,-1,1,11,6,-2000,-1,-9999,MRD_x06_y01_z05,MRD_x06_y01_z05,None,ON,NORMAL +132,132,1,1,5,1,7,-15.3,65.25,373.76,15,130.2,1.3,8,8,23,9,8,6,8,-1,-1,1,11,7,-2000,-1,-9999,MRD_x07_y01_z05,MRD_x07_y01_z05,None,ON,NORMAL +133,133,1,1,5,1,8,0,65.25,373.76,15,130.2,1.3,8,8,24,9,9,6,9,-1,-1,1,11,8,-2000,-1,-9999,MRD_x08_y01_z05,MRD_x08_y01_z05,None,ON,NORMAL +134,134,1,1,5,1,9,15.3,65.25,373.76,15,130.2,1.3,8,8,25,9,10,6,10,-1,-1,1,11,9,-2000,-1,-9999,MRD_x09_y01_z05,MRD_x09_y01_z05,None,ON,NORMAL +135,135,1,1,5,1,10,30.6,65.25,373.76,15,130.2,1.3,8,8,26,9,11,6,11,-1,-1,1,11,10,-2000,-1,-9999,MRD_x10_y01_z05,MRD_x10_y01_z05,None,ON,NORMAL +136,136,1,1,5,1,11,45.9,65.25,373.76,15,130.2,1.3,8,8,27,9,12,6,12,-1,-1,1,11,11,-1800,-1,-9999,MRD_x11_y01_z05,MRD_x11_y01_z05,None,ON,NORMAL +137,137,1,1,5,1,12,61.2,65.25,373.76,15,130.2,1.3,8,8,28,9,13,6,13,-1,-1,1,11,12,-2000,-1,-9999,MRD_x12_y01_z05,MRD_x12_y01_z05,None,ON,NORMAL +138,138,1,1,5,1,13,76.5,65.25,373.76,15,130.2,1.3,8,8,29,9,14,6,14,-1,-1,1,11,13,-2000,-1,-9999,MRD_x13_y01_z05,MRD_x13_y01_z05,None,ON,NORMAL +139,139,1,1,5,1,14,91.8,65.25,373.76,15,130.2,1.3,8,8,30,9,15,6,15,-1,-1,1,11,14,-2000,-1,-9999,MRD_x14_y01_z05,MRD_x14_y01_z05,None,ON,NORMAL +140,140,1,1,5,1,15,107.1,65.25,373.76,15,130.2,1.3,8,8,31,9,16,6,16,-1,-1,1,11,15,-2000,-1,-9999,MRD_x15_y01_z05,MRD_x15_y01_z05,None,OFF,NORMAL +141,141,1,1,5,1,16,122.4,65.25,373.76,15,130.2,1.3,8,14,31,15,16,6,17,-1,-1,1,4,15,-2000,-1,-9999,MRD_x16_y01_z05,MRD_x16_y01_z05,Now uses y0 z5 spare; Rack 8 slot 18 channel 16 has no NIM output,OFF,NORMAL +142,142,1,0,6,0,0,-73.75,-121.8,386.22,147.2,20,0.6,7,8,0,7,1,5,1,-1,-1,1,12,0,-2100,-1,-9999,MRD_x00_y00_z06,MRD_x00_y00_z06,None,ON,NORMAL +143,143,1,0,6,0,1,-73.75,-101.5,386.22,147.2,20,0.6,7,8,1,7,2,5,2,-1,-1,1,12,1,-2100,-1,-9999,MRD_x00_y01_z06,MRD_x00_y01_z06,None,ON,NORMAL +144,144,1,0,6,0,2,-73.75,-81.2,386.22,147.2,20,0.6,7,8,2,7,3,5,3,-1,-1,1,12,2,-2100,-1,-9999,MRD_x00_y02_z06,MRD_x00_y02_z06,None,ON,NORMAL +145,145,1,0,6,0,3,-73.75,-60.9,386.22,147.2,20,0.6,7,8,3,7,4,5,4,-1,-1,1,12,3,-2100,-1,-9999,MRD_x00_y03_z06,MRD_x00_y03_z06,None,ON,NORMAL +146,146,1,0,6,0,4,-73.75,-40.6,386.22,147.2,20,0.6,7,8,4,7,5,5,5,-1,-1,1,12,4,-2100,-1,-9999,MRD_x00_y04_z06,MRD_x00_y04_z06,None,ON,NORMAL +147,147,1,0,6,0,5,-73.75,-20.3,386.22,147.2,20,0.6,7,8,5,7,6,5,6,-1,-1,1,12,5,-2100,-1,-9999,MRD_x00_y05_z06,MRD_x00_y05_z06,None,ON,NORMAL +148,148,1,0,6,0,6,-73.75,0,386.22,147.2,20,0.6,7,8,6,7,7,5,7,-1,-1,1,12,6,-2100,-1,-9999,MRD_x00_y06_z06,MRD_x00_y06_z06,None,ON,NORMAL +149,149,1,0,6,0,7,-73.75,20.3,386.22,147.2,20,0.6,7,8,7,7,8,5,8,-1,-1,1,12,7,-2100,-1,-9999,MRD_x00_y07_z06,MRD_x00_y07_z06,None,ON,NORMAL +150,150,1,0,6,0,8,-73.75,40.6,386.22,147.2,20,0.6,7,8,8,7,9,5,9,-1,-1,1,12,8,-2100,-1,-9999,MRD_x00_y08_z06,MRD_x00_y08_z06,None,ON,NORMAL +151,151,1,0,6,0,9,-73.75,60.9,386.22,147.2,20,0.6,7,8,9,7,10,5,10,-1,-1,1,12,9,-2100,-1,-9999,MRD_x00_y09_z06,MRD_x00_y09_z06,None,ON,NORMAL +152,152,1,0,6,0,10,-73.75,81.2,386.22,147.2,20,0.6,7,8,10,7,11,5,11,-1,-1,1,12,10,-2100,-1,-9999,MRD_x00_y10_z06,MRD_x00_y10_z06,None,ON,NORMAL +153,153,1,0,6,0,11,-73.75,101.5,386.22,147.2,20,0.6,7,8,11,7,12,5,12,-1,-1,1,12,11,-2100,-1,-9999,MRD_x00_y11_z06,MRD_x00_y11_z06,None,ON,NORMAL +154,154,1,0,6,0,12,-73.75,121.8,386.22,147.2,20,0.6,7,8,12,7,13,5,13,-1,-1,1,12,12,-2100,-1,-9999,MRD_x00_y12_z06,MRD_x00_y12_z06,None,ON,NORMAL +155,155,1,0,6,1,0,73.75,-121.8,386.22,147.2,20,0.6,7,8,16,9,1,6,1,-1,-1,1,13,0,-1900,-1,-9999,MRD_x01_y00_z06,MRD_x01_y00_z06,None,ON,NORMAL +156,156,1,0,6,1,1,73.75,-101.5,386.22,147.2,20,0.6,7,8,17,9,2,6,2,-1,-1,1,13,1,-2100,-1,-9999,MRD_x01_y01_z06,MRD_x01_y01_z06,None,ON,NORMAL +157,157,1,0,6,1,2,73.75,-81.2,386.22,147.2,20,0.6,7,8,18,9,3,6,3,-1,-1,1,13,2,-2100,-1,-9999,MRD_x01_y02_z06,MRD_x01_y02_z06,None,ON,HOT +158,158,1,0,6,1,3,73.75,-60.9,386.22,147.2,20,0.6,7,8,19,9,4,6,4,-1,-1,1,13,3,-2100,-1,-9999,MRD_x01_y03_z06,MRD_x01_y03_z06,None,ON,NORMAL +159,159,1,0,6,1,4,73.75,-40.6,386.22,147.2,20,0.6,7,8,20,9,5,6,5,-1,-1,1,13,4,-2100,-1,-9999,MRD_x01_y04_z06,MRD_x01_y04_z06,None,ON,NORMAL +160,160,1,0,6,1,5,73.75,-20.3,386.22,147.2,20,0.6,7,8,21,9,6,6,6,-1,-1,1,13,5,-2100,-1,-9999,MRD_x01_y05_z06,MRD_x01_y05_z06,None,ON,NORMAL +161,161,1,0,6,1,6,73.75,0,386.22,147.2,20,0.6,7,8,22,9,7,6,7,-1,-1,1,13,6,-2100,-1,-9999,MRD_x01_y06_z06,MRD_x01_y06_z06,None,ON,NORMAL +162,162,1,0,6,1,7,73.75,20.3,386.22,147.2,20,0.6,7,8,23,9,8,6,8,-1,-1,1,13,7,-2100,-1,-9999,MRD_x01_y07_z06,MRD_x01_y07_z06,None,ON,NORMAL +163,163,1,0,6,1,8,73.75,40.6,386.22,147.2,20,0.6,7,8,24,9,9,6,9,-1,-1,1,13,8,-2100,-1,-9999,MRD_x01_y08_z06,MRD_x01_y08_z06,None,ON,HOT +164,164,1,0,6,1,9,73.75,60.9,386.22,147.2,20,0.6,7,8,25,9,10,6,10,-1,-1,1,13,9,-1900,-1,-9999,MRD_x01_y09_z06,MRD_x01_y09_z06,None,ON,NORMAL +165,165,1,0,6,1,10,73.75,81.2,386.22,147.2,20,0.6,7,8,26,9,11,6,11,-1,-1,1,13,10,-2100,-1,-9999,MRD_x01_y10_z06,MRD_x01_y10_z06,None,ON,NORMAL +166,166,1,0,6,1,11,73.75,101.5,386.22,147.2,20,0.6,7,8,27,9,12,6,12,-1,-1,1,13,11,-2100,-1,-9999,MRD_x01_y11_z06,MRD_x01_y11_z06,None,ON,NORMAL +167,167,1,0,6,1,12,73.75,121.8,386.22,147.2,20,0.6,7,8,28,9,13,6,13,-1,-1,1,13,12,-2100,-1,-9999,MRD_x01_y12_z06,MRD_x01_y12_z06,None,ON,NORMAL +168,168,1,1,7,0,1,-121.8,-65.25,398.33,20,130.2,0.6,8,11,1,10,2,7,2,1,3,1,14,1,-1500,-1,-9999,MRD_x01_y00_z07,MRD_x01_y00_z07,None,ON,NORMAL +169,169,1,1,7,0,2,-101.5,-65.25,398.33,20,130.2,0.6,8,11,2,10,3,7,3,1,5,1,14,2,-1500,-1,-9999,MRD_x02_y00_z07,MRD_x02_y00_z07,None,ON,NORMAL +170,170,1,1,7,0,3,-81.2,-65.25,398.33,20,130.2,0.6,8,11,3,10,4,7,4,1,7,1,14,3,-1500,-1,-9999,MRD_x03_y00_z07,MRD_x03_y00_z07,None,ON,NORMAL +171,171,1,1,7,0,4,-60.9,-65.25,398.33,20,130.2,0.6,8,11,4,10,5,7,5,1,9,1,14,4,-1500,-1,-9999,MRD_x04_y00_z07,MRD_x04_y00_z07,None,ON,NORMAL +172,172,1,1,7,0,5,-40.6,-65.25,398.33,20,130.2,0.6,8,11,5,10,6,7,6,1,11,1,14,5,-1500,-1,-9999,MRD_x05_y00_z07,MRD_x05_y00_z07,None,ON,HOT +173,173,1,1,7,0,6,-20.3,-65.25,398.33,20,130.2,0.6,8,11,6,10,7,7,7,1,13,1,14,6,-1500,-1,-9999,MRD_x06_y00_z07,MRD_x06_y00_z07,None,ON,NORMAL +174,174,1,1,7,0,7,0,-65.25,398.33,20,130.2,0.6,8,11,7,10,8,7,8,12,2,1,14,7,-1500,-1,-9999,MRD_x07_y00_z07,MRD_x07_y00_z07,None,ON,NORMAL +175,175,1,1,7,0,8,20.3,-65.25,398.33,20,130.2,0.6,8,11,8,10,9,7,9,12,4,1,14,8,-1500,-1,-9999,MRD_x08_y00_z07,MRD_x08_y00_z07,None,ON,NORMAL +176,176,1,1,7,0,9,40.6,-65.25,398.33,20,130.2,0.6,8,11,9,10,10,7,10,12,6,1,14,9,-1500,-1,-9999,MRD_x09_y00_z07,MRD_x09_y00_z07,None,ON,NORMAL +177,177,1,1,7,0,10,60.9,-65.25,398.33,20,130.2,0.6,8,11,10,10,11,7,11,12,8,1,14,10,-1500,-1,-9999,MRD_x10_y00_z07,MRD_x10_y00_z07,None,ON,NORMAL +178,178,1,1,7,0,11,81.2,-65.25,398.33,20,130.2,0.6,8,11,11,10,12,7,12,12,10,1,14,11,-1500,-1,-9999,MRD_x11_y00_z07,MRD_x11_y00_z07,None,ON,NORMAL +179,179,1,1,7,0,12,101.5,-65.25,398.33,20,130.2,0.6,8,11,12,10,13,7,13,12,12,1,14,12,-1500,-1,-9999,MRD_x12_y00_z07,MRD_x12_y00_z07,None,ON,NORMAL +180,180,1,1,7,0,13,121.8,-65.25,398.33,20,130.2,0.6,8,11,13,10,14,7,14,12,14,1,14,13,-1500,-1,-9999,MRD_x13_y00_z07,MRD_x13_y00_z07,None,ON,NORMAL +181,181,1,1,7,1,1,-121.8,65.25,398.33,20,130.2,0.6,8,11,17,12,2,8,2,1,4,1,15,1,-1500,-1,-9999,MRD_x01_y01_z07,MRD_x01_y01_z07,None,ON,NORMAL +182,182,1,1,7,1,2,-101.5,65.25,398.33,20,130.2,0.6,8,11,18,12,3,8,3,1,6,1,15,2,-1500,-1,-9999,MRD_x02_y01_z07,MRD_x02_y01_z07,None,ON,NORMAL +183,183,1,1,7,1,3,-81.2,65.25,398.33,20,130.2,0.6,8,11,19,12,4,8,4,1,8,1,15,3,-1300,-1,-9999,MRD_x03_y01_z07,MRD_x03_y01_z07,None,ON,HOT +184,184,1,1,7,1,4,-60.9,65.25,398.33,20,130.2,0.6,8,11,20,12,5,8,5,1,10,1,15,4,-1500,-1,-9999,MRD_x04_y01_z07,MRD_x04_y01_z07,None,ON,NORMAL +185,185,1,1,7,1,5,-40.6,65.25,398.33,20,130.2,0.6,8,11,21,12,6,8,6,1,12,1,15,5,-2000,-1,-9999,MRD_x05_y01_z07,MRD_x05_y01_z07,None,ON,NORMAL +186,186,1,1,7,1,6,-20.3,65.25,398.33,20,130.2,0.6,8,11,22,12,7,8,7,1,14,1,15,6,-2000,-1,-9999,MRD_x06_y01_z07,MRD_x06_y01_z07,None,ON,NORMAL +187,187,1,1,7,1,7,0,65.25,398.33,20,130.2,0.6,8,11,23,12,8,8,8,12,1,1,15,7,-2000,-1,-9999,MRD_x07_y01_z07,MRD_x07_y01_z07,None,ON,NORMAL +188,188,1,1,7,1,8,20.3,65.25,398.33,20,130.2,0.6,8,11,24,12,9,8,9,12,3,1,15,8,-2000,-1,-9999,MRD_x08_y01_z07,MRD_x08_y01_z07,None,ON,NORMAL +189,189,1,1,7,1,9,40.6,65.25,398.33,20,130.2,0.6,8,11,25,12,10,8,10,12,5,1,15,9,-1500,-1,-9999,MRD_x09_y01_z07,MRD_x09_y01_z07,None,ON,NORMAL +190,190,1,1,7,1,10,60.9,65.25,398.33,20,130.2,0.6,8,11,26,12,11,8,11,12,7,1,15,10,-1500,-1,-9999,MRD_x10_y01_z07,MRD_x10_y01_z07,None,ON,NORMAL +191,191,1,1,7,1,11,81.2,65.25,398.33,20,130.2,0.6,8,11,27,12,12,8,12,12,9,1,15,11,-1500,-1,-9999,MRD_x11_y01_z07,MRD_x11_y01_z07,None,ON,HOT +192,192,1,1,7,1,12,101.5,65.25,398.33,20,130.2,0.6,8,11,28,12,13,8,13,12,11,1,15,12,-1500,-1,-9999,MRD_x12_y01_z07,MRD_x12_y01_z07,None,ON,NORMAL +193,193,1,1,7,1,13,121.8,65.25,398.33,20,130.2,0.6,8,11,29,12,14,8,14,12,13,1,15,13,-1500,-1,-9999,MRD_x13_y01_z07,MRD_x13_y01_z07,None,ON,NORMAL +194,194,1,0,8,0,0,-73.75,-121.8,410.44,147.2,20,0.6,7,11,0,10,1,7,1,-1,-1,1,0,0,2100,1,EMI 9939B,MRD_x00_y00_z08,MRD_x00_y00_z08,None,ON,NORMAL +195,195,1,0,8,0,1,-73.75,-101.5,410.44,147.2,20,0.6,7,11,1,10,2,7,2,-1,-1,1,0,1,2100,1,EMI 9939B,MRD_x00_y01_z08,MRD_x00_y01_z08,None,OFF,NORMAL +196,196,1,0,8,0,2,-73.75,-81.2,410.44,147.2,20,0.6,7,11,2,10,3,7,3,-1,-1,1,0,2,2100,1,EMI 9939B,MRD_x00_y02_z08,MRD_x00_y02_z08,None,ON,NORMAL +197,197,1,0,8,0,3,-73.75,-60.9,410.44,147.2,20,0.6,7,11,3,10,4,7,4,-1,-1,1,0,3,2100,1,EMI 9939B,MRD_x00_y03_z08,MRD_x00_y03_z08,None,ON,NORMAL +198,198,1,0,8,0,4,-73.75,-40.6,410.44,147.2,20,0.6,7,11,4,10,5,7,5,-1,-1,1,0,4,2100,1,EMI 9939B,MRD_x00_y04_z08,MRD_x00_y04_z08,None,ON,NORMAL +199,199,1,0,8,0,5,-73.75,-20.3,410.44,147.2,20,0.6,7,11,5,10,6,7,6,-1,-1,1,0,5,2100,1,EMI 9939B,MRD_x00_y05_z08,MRD_x00_y05_z08,None,ON,NORMAL +200,200,1,0,8,0,6,-73.75,0,410.44,147.2,20,0.6,7,11,6,10,7,7,7,-1,-1,1,0,6,2100,1,EMI 9939B,MRD_x00_y06_z08,MRD_x00_y06_z08,None,ON,NORMAL +201,201,1,0,8,0,7,-73.75,20.3,410.44,147.2,20,0.6,7,11,7,10,8,7,8,-1,-1,1,0,7,2100,1,EMI 9939B,MRD_x00_y07_z08,MRD_x00_y07_z08,None,ON,NORMAL +202,202,1,0,8,0,8,-73.75,40.6,410.44,147.2,20,0.6,7,11,8,10,9,7,9,-1,-1,1,0,8,2100,1,EMI 9939B,MRD_x00_y08_z08,MRD_x00_y08_z08,None,ON,NORMAL +203,203,1,0,8,0,9,-73.75,60.9,410.44,147.2,20,0.6,7,11,9,10,10,7,10,-1,-1,1,0,9,2100,1,EMI 9939B,MRD_x00_y09_z08,MRD_x00_y09_z08,None,ON,NORMAL +204,204,1,0,8,0,10,-73.75,81.2,410.44,147.2,20,0.6,7,11,10,10,11,7,11,-1,-1,1,0,10,2100,1,EMI 9939B,MRD_x00_y10_z08,MRD_x00_y10_z08,None,ON,NORMAL +205,205,1,0,8,0,11,-73.75,101.5,410.44,147.2,20,0.6,7,11,11,10,12,7,12,-1,-1,1,0,11,2100,1,EMI 9939B,MRD_x00_y11_z08,MRD_x00_y11_z08,None,ON,NORMAL +206,206,1,0,8,0,12,-73.75,121.8,410.44,147.2,20,0.6,7,11,12,10,13,7,13,-1,-1,1,0,12,2100,1,EMI 9939B,MRD_x00_y12_z08,MRD_x00_y12_z08,None,OFF,NORMAL +207,207,1,0,8,1,0,73.75,-121.8,410.44,147.2,20,0.6,7,11,16,12,1,8,1,-1,-1,1,1,13,2100,1,EMI 9939B,MRD_x01_y00_z08,MRD_x01_y00_z08,< HV 1-1-0 is brokenNone,ON,NORMAL +208,208,1,0,8,1,1,73.75,-101.5,410.44,147.2,20,0.6,7,11,17,12,2,8,2,-1,-1,1,1,1,2100,1,EMI 9939B,MRD_x01_y01_z08,MRD_x01_y01_z08,None,ON,NORMAL +209,209,1,0,8,1,2,73.75,-81.2,410.44,147.2,20,0.6,7,11,18,12,3,8,3,-1,-1,1,1,2,2100,1,EMI 9939B,MRD_x01_y02_z08,MRD_x01_y02_z08,None,ON,NORMAL +210,210,1,0,8,1,3,73.75,-60.9,410.44,147.2,20,0.6,7,11,19,12,4,8,4,-1,-1,1,1,3,2100,1,EMI 9939B,MRD_x01_y03_z08,MRD_x01_y03_z08,None,ON,NORMAL +211,211,1,0,8,1,4,73.75,-40.6,410.44,147.2,20,0.6,7,11,20,12,5,8,5,-1,-1,1,1,4,2100,1,EMI 9939B,MRD_x01_y04_z08,MRD_x01_y04_z08,None,ON,NORMAL +212,212,1,0,8,1,5,73.75,-20.3,410.44,147.2,20,0.6,7,11,21,12,6,8,6,-1,-1,1,1,5,2100,1,EMI 9939B,MRD_x01_y05_z08,MRD_x01_y05_z08,None,ON,HOT +213,213,1,0,8,1,6,73.75,0,410.44,147.2,20,0.6,7,11,22,12,7,8,7,-1,-1,1,1,6,2100,1,EMI 9939B,MRD_x01_y06_z08,MRD_x01_y06_z08,None,ON,HOT +214,214,1,0,8,1,7,73.75,20.3,410.44,147.2,20,0.6,7,11,23,12,8,8,8,-1,-1,1,1,7,2100,1,EMI 9939B,MRD_x01_y07_z08,MRD_x01_y07_z08,None,ON,NORMAL +215,215,1,0,8,1,8,73.75,40.6,410.44,147.2,20,0.6,7,11,24,12,9,8,9,-1,-1,1,1,8,2100,1,EMI 9939B,MRD_x01_y08_z08,MRD_x01_y08_z08,None,OFF,NORMAL +216,216,1,0,8,1,9,73.75,60.9,410.44,147.2,20,0.6,7,11,25,12,10,8,10,-1,-1,1,1,9,2100,1,EMI 9939B,MRD_x01_y09_z08,MRD_x01_y09_z08,None,ON,NORMAL +217,217,1,0,8,1,10,73.75,81.2,410.44,147.2,20,0.6,7,11,26,12,11,8,11,-1,-1,1,1,10,2100,1,EMI 9939B,MRD_x01_y10_z08,MRD_x01_y10_z08,None,OFF,NORMAL +218,218,1,0,8,1,11,73.75,101.5,410.44,147.2,20,0.6,7,11,27,12,12,8,12,-1,-1,1,1,11,2100,1,EMI 9939B,MRD_x01_y11_z08,MRD_x01_y11_z08,None,OFF,NORMAL +219,219,1,0,8,1,12,73.75,121.8,410.44,147.2,20,0.6,7,11,28,12,13,8,13,-1,-1,1,1,12,2100,1,EMI 9939B,MRD_x01_y12_z08,MRD_x01_y12_z08,None,ON,NORMAL +220,220,1,1,9,0,0,-142.1,-65.25,422.55,20,130.2,0.6,8,14,0,13,1,9,1,2,1,2,0,0,-1500,-1,-9999,MRD_x00_y00_z09,MRD_x00_y00_z09,None,ON,NORMAL +221,221,1,1,9,0,1,-121.8,-65.25,422.55,20,130.2,0.6,8,14,1,13,2,9,2,2,3,2,0,1,-1500,-1,-9999,MRD_x01_y00_z09,MRD_x01_y00_z09,None,ON,NORMAL +222,222,1,1,9,0,2,-101.5,-65.25,422.55,20,130.2,0.6,8,14,2,13,3,9,3,2,5,2,0,2,-1500,-1,-9999,MRD_x02_y00_z09,MRD_x02_y00_z09,None,ON,NORMAL +223,223,1,1,9,0,3,-81.2,-65.25,422.55,20,130.2,0.6,8,14,3,13,4,9,4,2,7,2,0,3,-1500,-1,-9999,MRD_x03_y00_z09,MRD_x03_y00_z09,None,ON,NORMAL +224,224,1,1,9,0,4,-60.9,-65.25,422.55,20,130.2,0.6,8,14,4,13,5,9,5,2,9,2,0,4,-1500,-1,-9999,MRD_x04_y00_z09,MRD_x04_y00_z09,None,OFF,HOT +225,225,1,1,9,0,5,-40.6,-65.25,422.55,20,130.2,0.6,8,14,5,13,6,9,6,2,11,2,0,5,-2000,-1,-9999,MRD_x05_y00_z09,MRD_x05_y00_z09,None,ON,NORMAL +226,226,1,1,9,0,6,-20.3,-65.25,422.55,20,130.2,0.6,8,14,6,13,7,9,7,2,13,2,0,6,-2000,-1,-9999,MRD_x06_y00_z09,MRD_x06_y00_z09,None,ON,NORMAL +227,227,1,1,9,0,7,0,-65.25,422.55,20,130.2,0.6,8,11,31,12,16,9,8,11,1,2,0,7,-2000,-1,-9999,MRD_x07_y00_z09,MRD_x07_y00_z09,Discriminator on rack 8 slot 13 channel 8 has no NIM outputNone,ON,NORMAL +228,228,1,1,9,0,8,20.3,-65.25,422.55,20,130.2,0.6,8,14,8,13,9,9,9,11,2,2,0,8,-2000,-1,-9999,MRD_x08_y00_z09,MRD_x08_y00_z09,None,ON,NORMAL +229,229,1,1,9,0,9,40.6,-65.25,422.55,20,130.2,0.6,8,14,9,13,10,9,10,11,3,2,0,9,-1500,-1,-9999,MRD_x09_y00_z09,MRD_x09_y00_z09,None,ON,NORMAL +230,230,1,1,9,0,10,60.9,-65.25,422.55,20,130.2,0.6,8,14,10,13,11,9,11,11,4,2,0,10,-1500,-1,-9999,MRD_x10_y00_z09,MRD_x10_y00_z09,None,ON,HOT +231,231,1,1,9,0,11,81.2,-65.25,422.55,20,130.2,0.6,8,14,11,13,12,9,12,11,5,2,0,11,-1500,-1,-9999,MRD_x11_y00_z09,MRD_x11_y00_z09,None,ON,NORMAL +232,232,1,1,9,0,12,101.5,-65.25,422.55,20,130.2,0.6,8,14,15,13,16,9,13,11,6,2,0,12,-1500,-1,-9999,MRD_x12_y00_z09,MRD_x12_y00_z09,slot 13 on this disc had a very high rate; shifted signal to slot 16None,ON,NORMAL +233,233,1,1,9,0,13,121.8,-65.25,422.55,20,130.2,0.6,8,14,13,13,14,9,14,11,7,2,0,13,-1500,-1,-9999,MRD_x13_y00_z09,MRD_x13_y00_z09,None,ON,NORMAL +234,234,1,1,9,0,14,142.1,-65.25,422.55,20,130.2,0.6,8,14,14,13,15,9,15,11,8,2,0,14,-1500,-1,-9999,MRD_x14_y00_z09,MRD_x14_y00_z09,None,ON,HOT +235,235,1,1,9,1,0,-142.1,65.25,422.55,20,130.2,0.6,8,14,16,15,1,10,1,2,2,2,1,0,-1500,-1,-9999,MRD_x00_y01_z09,MRD_x00_y01_z09,None,ON,NORMAL +236,236,1,1,9,1,1,-121.8,65.25,422.55,20,130.2,0.6,8,14,17,15,2,10,2,2,4,2,1,1,-1500,-1,-9999,MRD_x01_y01_z09,MRD_x01_y01_z09,None,ON,NORMAL +237,237,1,1,9,1,2,-101.5,65.25,422.55,20,130.2,0.6,8,14,18,15,3,10,3,2,6,2,1,2,-1300,-1,-9999,MRD_x02_y01_z09,MRD_x02_y01_z09,None,ON,NORMAL +238,238,1,1,9,1,3,-81.2,65.25,422.55,20,130.2,0.6,8,14,19,15,4,10,4,2,8,2,1,3,-1500,-1,-9999,MRD_x03_y01_z09,MRD_x03_y01_z09,None,ON,HOT +239,239,1,1,9,1,4,-60.9,65.25,422.55,20,130.2,0.6,8,14,20,15,5,10,5,2,10,2,1,4,-1500,-1,-9999,MRD_x04_y01_z09,MRD_x04_y01_z09,None,ON,NORMAL +240,240,1,1,9,1,5,-40.6,65.25,422.55,20,130.2,0.6,8,14,21,15,6,10,6,2,12,2,1,5,-1500,-1,-9999,MRD_x05_y01_z09,MRD_x05_y01_z09,None,ON,NORMAL +241,241,1,1,9,1,6,-20.3,65.25,422.55,20,130.2,0.6,8,14,22,15,7,10,7,2,14,2,1,6,-1500,-1,-9999,MRD_x06_y01_z09,MRD_x06_y01_z09,None,ON,NORMAL +242,242,1,1,9,1,7,0,65.25,422.55,20,130.2,0.6,8,14,23,15,8,10,8,12,18,2,1,7,-1500,-1,-9999,MRD_x07_y01_z09,MRD_x07_y01_z09,None,ON,NORMAL +243,243,1,1,9,1,8,20.3,65.25,422.55,20,130.2,0.6,8,14,24,15,9,10,9,12,20,2,1,8,-1500,-1,-9999,MRD_x08_y01_z09,MRD_x08_y01_z09,None,ON,NORMAL +244,244,1,1,9,1,9,40.6,65.25,422.55,20,130.2,0.6,8,14,25,15,10,10,10,12,22,2,1,9,-1500,-1,-9999,MRD_x09_y01_z09,MRD_x09_y01_z09,None,ON,NORMAL +245,245,1,1,9,1,10,60.9,65.25,422.55,20,130.2,0.6,8,14,26,15,11,10,11,12,24,2,1,10,-1500,-1,-9999,MRD_x10_y01_z09,MRD_x10_y01_z09,None,ON,NORMAL +246,246,1,1,9,1,11,81.2,65.25,422.55,20,130.2,0.6,8,14,27,15,12,10,12,12,26,2,1,11,-1500,-1,-9999,MRD_x11_y01_z09,MRD_x11_y01_z09,None,ON,NORMAL +247,247,1,1,9,1,12,101.5,65.25,422.55,20,130.2,0.6,8,14,28,15,13,10,13,12,28,2,1,12,-1500,-1,-9999,MRD_x12_y01_z09,MRD_x12_y01_z09,None,ON,NORMAL +248,248,1,1,9,1,13,121.8,65.25,422.55,20,130.2,0.6,8,14,29,15,14,10,14,12,30,2,1,13,-1500,-1,-9999,MRD_x13_y01_z09,MRD_x13_y01_z09,None,ON,NORMAL +249,249,1,1,9,1,14,142.1,65.25,422.55,20,130.2,0.6,8,14,30,15,15,10,15,12,32,2,1,14,-1500,-1,-9999,MRD_x14_y01_z09,MRD_x14_y01_z09,None,ON,HOT +250,250,1,0,10,0,0,-73.75,-121.8,434.66,147.2,20,0.6,7,19,0,18,1,9,1,-1,-1,2,2,0,-2100,-1,-9999,MRD_x00_y00_z10,MRD_x00_y00_z10,None,ON,NORMAL +251,251,1,0,10,0,1,-73.75,-101.5,434.66,147.2,20,0.6,7,19,1,18,2,9,2,-1,-1,2,2,1,-1600,-1,-9999,MRD_x00_y01_z10,MRD_x00_y01_z10,None,OFF,NORMAL +252,252,1,0,10,0,2,-73.75,-81.2,434.66,147.2,20,0.6,7,19,2,18,3,9,3,-1,-1,2,2,2,-2100,-1,-9999,MRD_x00_y02_z10,MRD_x00_y02_z10,None,ON,NORMAL +253,253,1,0,10,0,3,-73.75,-60.9,434.66,147.2,20,0.6,7,19,3,18,4,9,4,-1,-1,2,2,3,-2100,-1,-9999,MRD_x00_y03_z10,MRD_x00_y03_z10,None,ON,NORMAL +254,254,1,0,10,0,4,-73.75,-40.6,434.66,147.2,20,0.6,7,19,4,18,5,9,5,-1,-1,2,2,4,-2100,-1,-9999,MRD_x00_y04_z10,MRD_x00_y04_z10,None,OFF,NORMAL +255,255,1,0,10,0,5,-73.75,-20.3,434.66,147.2,20,0.6,7,19,5,18,6,9,6,-1,-1,2,2,5,-2100,-1,-9999,MRD_x00_y05_z10,MRD_x00_y05_z10,None,ON,NORMAL +256,256,1,0,10,0,6,-73.75,0,434.66,147.2,20,0.6,7,19,6,18,7,9,7,-1,-1,2,2,6,-2100,-1,-9999,MRD_x00_y06_z10,MRD_x00_y06_z10,None,ON,NORMAL +257,257,1,0,10,0,7,-73.75,20.3,434.66,147.2,20,0.6,7,19,7,18,8,9,8,-1,-1,2,2,7,-2100,-1,-9999,MRD_x00_y07_z10,MRD_x00_y07_z10,None,ON,NORMAL +258,258,1,0,10,0,8,-73.75,40.6,434.66,147.2,20,0.6,7,19,8,18,9,9,9,-1,-1,2,2,8,-1900,-1,-9999,MRD_x00_y08_z10,MRD_x00_y08_z10,None,ON,NORMAL +259,259,1,0,10,0,9,-73.75,60.9,434.66,147.2,20,0.6,7,19,9,18,10,9,10,-1,-1,2,2,9,-2100,-1,-9999,MRD_x00_y09_z10,MRD_x00_y09_z10,None,ON,NORMAL +260,260,1,0,10,0,10,-73.75,81.2,434.66,147.2,20,0.6,7,19,10,18,11,9,11,-1,-1,2,2,10,-2100,-1,-9999,MRD_x00_y10_z10,MRD_x00_y10_z10,None,OFF,NORMAL +261,261,1,0,10,0,11,-73.75,101.5,434.66,147.2,20,0.6,7,19,11,18,12,9,12,-1,-1,2,2,11,-2100,-1,-9999,MRD_x00_y11_z10,MRD_x00_y11_z10,Crate 2 card 3 ch11 is broken: nothing connectedNone,ON,NORMAL +262,262,1,0,10,0,12,-73.75,121.8,434.66,147.2,20,0.6,7,19,12,18,13,9,13,-1,-1,2,2,12,-2100,-1,-9999,MRD_x00_y12_z10,MRD_x00_y12_z10,None,ON,NORMAL +263,263,1,0,10,1,0,73.75,-121.8,434.66,147.2,20,0.6,7,19,16,20,1,10,1,-1,-1,2,3,0,-2100,-1,-9999,MRD_x01_y00_z10,MRD_x01_y00_z10,None,ON,HOT +264,264,1,0,10,1,1,73.75,-101.5,434.66,147.2,20,0.6,7,19,17,20,2,10,2,-1,-1,2,3,1,-1900,-1,-9999,MRD_x01_y01_z10,MRD_x01_y01_z10,None,ON,NORMAL +265,265,1,0,10,1,2,73.75,-81.2,434.66,147.2,20,0.6,7,19,18,20,3,10,3,-1,-1,2,3,2,-1600,-1,-9999,MRD_x01_y02_z10,MRD_x01_y02_z10,None,ON,NORMAL +266,266,1,0,10,1,3,73.75,-60.9,434.66,147.2,20,0.6,7,19,19,20,4,10,4,-1,-1,2,3,3,-1800,-1,-9999,MRD_x01_y03_z10,MRD_x01_y03_z10,None,ON,NORMAL +267,267,1,0,10,1,4,73.75,-40.6,434.66,147.2,20,0.6,7,19,20,20,5,10,5,-1,-1,2,3,4,-1800,-1,-9999,MRD_x01_y04_z10,MRD_x01_y04_z10,None,ON,NORMAL +268,268,1,0,10,1,5,73.75,-20.3,434.66,147.2,20,0.6,7,19,21,20,6,10,6,-1,-1,2,3,5,-2100,-1,-9999,MRD_x01_y05_z10,MRD_x01_y05_z10,None,ON,NORMAL +269,269,1,0,10,1,6,73.75,0,434.66,147.2,20,0.6,7,19,22,20,7,10,7,-1,-1,2,3,6,-2100,-1,-9999,MRD_x01_y06_z10,MRD_x01_y06_z10,None,ON,NORMAL +270,270,1,0,10,1,7,73.75,20.3,434.66,147.2,20,0.6,7,19,23,20,8,10,8,-1,-1,2,3,7,-1600,-1,-9999,MRD_x01_y07_z10,MRD_x01_y07_z10,None,ON,NORMAL +271,271,1,0,10,1,8,73.75,40.6,434.66,147.2,20,0.6,7,19,24,20,9,10,9,-1,-1,2,3,8,-2100,-1,-9999,MRD_x01_y08_z10,MRD_x01_y08_z10,None,OFF,HOT +272,272,1,0,10,1,9,73.75,60.9,434.66,147.2,20,0.6,7,19,25,20,10,10,10,-1,-1,2,3,9,-2100,-1,-9999,MRD_x01_y09_z10,MRD_x01_y09_z10,None,ON,HOT +273,273,1,0,10,1,10,73.75,81.2,434.66,147.2,20,0.6,7,19,26,20,11,10,11,-1,-1,2,3,10,-1600,-1,-9999,MRD_x01_y10_z10,MRD_x01_y10_z10,None,ON,NORMAL +274,274,1,0,10,1,11,73.75,101.5,434.66,147.2,20,0.6,7,19,27,20,12,10,12,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y11_z10,MRD_x01_y11_z10,None,ON,HOT +275,275,1,0,10,1,12,73.75,121.8,434.66,147.2,20,0.6,7,19,28,20,13,10,13,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y12_z10,MRD_x01_y12_z10,None,OFF,HOT +276,276,1,1,11,0,0,-142.1,-65.25,446.77,20,130.2,0.6,8,17,0,16,1,11,1,1,19,2,4,0,-1500,-1,-9999,MRD_x00_y00_z11,MRD_x00_y00_z11,None,ON,HOT +277,277,1,1,11,0,1,-121.8,-65.25,446.77,20,130.2,0.6,8,17,1,16,2,11,2,1,21,2,4,1,-1500,-1,-9999,MRD_x01_y00_z11,MRD_x01_y00_z11,None,ON,NORMAL +278,278,1,1,11,0,2,-101.5,-65.25,446.77,20,130.2,0.6,8,17,2,16,3,11,3,1,23,2,4,2,-1500,-1,-9999,MRD_x02_y00_z11,MRD_x02_y00_z11,None,ON,NORMAL +279,279,1,1,11,0,3,-81.2,-65.25,446.77,20,130.2,0.6,8,17,3,16,4,11,4,1,25,2,4,3,-1300,-1,-9999,MRD_x03_y00_z11,MRD_x03_y00_z11,None,ON,NORMAL +280,280,1,1,11,0,4,-60.9,-65.25,446.77,20,130.2,0.6,8,17,4,16,5,11,5,1,27,2,4,4,-1500,-1,-9999,MRD_x04_y00_z11,MRD_x04_y00_z11,None,ON,NORMAL +281,281,1,1,11,0,5,-40.6,-65.25,446.77,20,130.2,0.6,8,17,5,16,6,11,6,1,29,2,4,5,-1500,-1,-9999,MRD_x05_y00_z11,MRD_x05_y00_z11,None,ON,NORMAL +282,282,1,1,11,0,6,-20.3,-65.25,446.77,20,130.2,0.6,8,17,6,16,7,11,7,1,31,2,4,6,-1500,-1,-9999,MRD_x06_y00_z11,MRD_x06_y00_z11,None,ON,NORMAL +283,283,1,1,11,0,7,0,-65.25,446.77,20,130.2,0.6,8,17,7,16,8,11,8,12,17,2,4,7,-1500,-1,-9999,MRD_x07_y00_z11,MRD_x07_y00_z11,None,ON,HOT +284,284,1,1,11,0,8,20.3,-65.25,446.77,20,130.2,0.6,8,17,8,16,9,11,9,12,19,2,4,8,-1500,-1,-9999,MRD_x08_y00_z11,MRD_x08_y00_z11,None,ON,NORMAL +285,285,1,1,11,0,9,40.6,-65.25,446.77,20,130.2,0.6,8,17,9,16,10,11,10,12,21,2,4,9,-1300,-1,-9999,MRD_x09_y00_z11,MRD_x09_y00_z11,None,ON,NORMAL +286,286,1,1,11,0,10,60.9,-65.25,446.77,20,130.2,0.6,8,17,10,16,11,11,11,12,23,2,4,10,-1500,-1,-9999,MRD_x10_y00_z11,MRD_x10_y00_z11,None,ON,NORMAL +287,287,1,1,11,0,11,81.2,-65.25,446.77,20,130.2,0.6,8,17,11,16,12,11,12,12,25,2,4,11,-1500,-1,-9999,MRD_x11_y00_z11,MRD_x11_y00_z11,None,ON,NORMAL +288,288,1,1,11,0,12,101.5,-65.25,446.77,20,130.2,0.6,8,17,12,16,13,11,13,12,27,2,4,12,-1500,-1,-9999,MRD_x12_y00_z11,MRD_x12_y00_z11,None,ON,NORMAL +289,289,1,1,11,0,13,121.8,-65.25,446.77,20,130.2,0.6,8,17,13,16,14,11,14,12,29,2,4,13,-1500,-1,-9999,MRD_x13_y00_z11,MRD_x13_y00_z11,None,ON,NORMAL +290,290,1,1,11,0,14,142.1,-65.25,446.77,20,130.2,0.6,8,17,14,16,15,11,15,12,31,2,4,14,-1500,-1,-9999,MRD_x14_y00_z11,MRD_x14_y00_z11,None,ON,NORMAL +291,291,1,1,11,1,0,-142.1,65.25,446.77,20,130.2,0.6,8,17,16,18,1,12,1,1,20,2,5,0,-1500,-1,-9999,MRD_x00_y01_z11,MRD_x00_y01_z11,None,ON,NORMAL +292,292,1,1,11,1,1,-121.8,65.25,446.77,20,130.2,0.6,8,17,17,18,2,12,2,1,22,2,5,1,-1500,-1,-9999,MRD_x01_y01_z11,MRD_x01_y01_z11,None,ON,NORMAL +293,293,1,1,11,1,2,-101.5,65.25,446.77,20,130.2,0.6,8,17,18,18,3,12,3,1,24,2,5,3,-1500,-1,-9999,MRD_x02_y01_z11,MRD_x02_y01_z11,None,ON,NORMAL +294,294,1,1,11,1,3,-81.2,65.25,446.77,20,130.2,0.6,8,17,19,18,4,12,4,1,26,2,5,4,-1500,-1,-9999,MRD_x03_y01_z11,MRD_x03_y01_z11,None,ON,NORMAL +295,295,1,1,11,1,4,-60.9,65.25,446.77,20,130.2,0.6,8,17,20,18,5,12,5,1,28,2,5,5,-1500,-1,-9999,MRD_x04_y01_z11,MRD_x04_y01_z11,None,ON,NORMAL +296,296,1,1,11,1,5,-40.6,65.25,446.77,20,130.2,0.6,8,17,21,18,6,12,6,1,30,2,5,6,-1500,-1,-9999,MRD_x05_y01_z11,MRD_x05_y01_z11,None,ON,NORMAL +297,297,1,1,11,1,6,-20.3,65.25,446.77,20,130.2,0.6,8,17,22,18,7,12,7,1,32,2,5,7,-1500,-1,-9999,MRD_x06_y01_z11,MRD_x06_y01_z11,None,ON,NORMAL +298,298,1,1,11,1,7,0,65.25,446.77,20,130.2,0.6,8,17,23,18,8,12,8,10,1,2,5,8,-1500,-1,-9999,MRD_x07_y01_z11,MRD_x07_y01_z11,None,ON,NORMAL +299,299,1,1,11,1,8,20.3,65.25,446.77,20,130.2,0.6,8,17,24,18,9,12,9,10,2,2,5,9,-1500,-1,-9999,MRD_x08_y01_z11,MRD_x08_y01_z11,None,ON,NORMAL +300,300,1,1,11,1,9,40.6,65.25,446.77,20,130.2,0.6,8,17,25,18,10,12,10,10,3,2,5,10,-1300,-1,-9999,MRD_x09_y01_z11,MRD_x09_y01_z11,None,ON,NORMAL +301,301,1,1,11,1,10,60.9,65.25,446.77,20,130.2,0.6,8,17,26,18,11,12,11,10,4,2,5,11,-1300,-1,-9999,MRD_x10_y01_z11,MRD_x10_y01_z11,None,ON,NORMAL +302,302,1,1,11,1,11,81.2,65.25,446.77,20,130.2,0.6,8,17,27,18,12,12,12,10,5,2,5,12,-1300,-1,-9999,MRD_x11_y01_z11,MRD_x11_y01_z11,None,ON,NORMAL +303,303,1,1,11,1,12,101.5,65.25,446.77,20,130.2,0.6,8,17,28,18,13,12,13,10,6,2,5,13,-1300,-1,-9999,MRD_x12_y01_z11,MRD_x12_y01_z11,None,ON,NORMAL +304,304,1,1,11,1,13,121.8,65.25,446.77,20,130.2,0.6,8,17,29,18,14,12,14,10,7,2,5,14,-1500,-1,-9999,MRD_x13_y01_z11,MRD_x13_y01_z11,None,ON,NORMAL +305,305,1,1,11,1,14,142.1,65.25,446.77,20,130.2,0.6,8,17,30,18,15,12,15,10,8,2,5,14,-1500,-1,-9999,MRD_x14_y01_z11,MRD_x14_y01_z11,None,ON,NORMAL +306,306,1,0,12,0,0,-73.75,-121.8,458.88,147.2,20,0.6,7,22,0,21,1,11,1,-1,-1,2,6,0,-2100,-1,-9999,MRD_x00_y00_z12,MRD_x00_y00_z12,None,ON,NORMAL +307,307,1,0,12,0,1,-73.75,-101.5,458.88,147.2,20,0.6,7,22,1,21,2,11,2,-1,-1,2,6,1,-2100,-1,-9999,MRD_x00_y01_z12,MRD_x00_y01_z12,None,ON,NORMAL +308,308,1,0,12,0,2,-73.75,-81.2,458.88,147.2,20,0.6,7,22,2,21,3,11,3,-1,-1,2,6,2,-2100,-1,-9999,MRD_x00_y02_z12,MRD_x00_y02_z12,None,ON,NORMAL +309,309,1,0,12,0,3,-73.75,-60.9,458.88,147.2,20,0.6,7,22,3,21,4,11,4,-1,-1,2,6,3,-2100,-1,-9999,MRD_x00_y03_z12,MRD_x00_y03_z12,None,ON,NORMAL +310,310,1,0,12,0,4,-73.75,-40.6,458.88,147.2,20,0.6,7,22,4,21,5,11,5,-1,-1,2,6,4,-1900,-1,-9999,MRD_x00_y04_z12,MRD_x00_y04_z12,None,ON,NORMAL +311,311,1,0,12,0,5,-73.75,-20.3,458.88,147.2,20,0.6,7,22,5,21,6,11,6,-1,-1,2,6,5,-2100,-1,-9999,MRD_x00_y05_z12,MRD_x00_y05_z12,None,ON,NORMAL +312,312,1,0,12,0,6,-73.75,0,458.88,147.2,20,0.6,7,22,6,21,7,11,7,-1,-1,2,6,6,-1900,-1,-9999,MRD_x00_y06_z12,MRD_x00_y06_z12,None,ON,NORMAL +313,313,1,0,12,0,7,-73.75,20.3,458.88,147.2,20,0.6,7,22,7,21,8,11,8,-1,-1,2,6,7,-2100,-1,-9999,MRD_x00_y07_z12,MRD_x00_y07_z12,None,ON,NORMAL +314,314,1,0,12,0,8,-73.75,40.6,458.88,147.2,20,0.6,7,22,8,21,9,11,9,-1,-1,2,6,8,-2100,-1,-9999,MRD_x00_y08_z12,MRD_x00_y08_z12,None,ON,NORMAL +315,315,1,0,12,0,9,-73.75,60.9,458.88,147.2,20,0.6,7,22,9,21,10,11,10,-1,-1,2,6,9,-2100,-1,-9999,MRD_x00_y09_z12,MRD_x00_y09_z12,None,ON,NORMAL +316,316,1,0,12,0,10,-73.75,81.2,458.88,147.2,20,0.6,7,22,10,21,11,11,11,-1,-1,2,6,10,-2100,-1,-9999,MRD_x00_y10_z12,MRD_x00_y10_z12,None,ON,NORMAL +317,317,1,0,12,0,11,-73.75,101.5,458.88,147.2,20,0.6,7,22,11,21,12,11,12,-1,-1,2,6,11,-2100,-1,-9999,MRD_x00_y11_z12,MRD_x00_y11_z12,None,ON,NORMAL +318,318,1,0,12,0,12,-73.75,121.8,458.88,147.2,20,0.6,7,22,12,21,13,11,13,-1,-1,2,6,12,-2100,-1,-9999,MRD_x00_y12_z12,MRD_x00_y12_z12,None,ON,NORMAL +319,319,1,0,12,1,0,73.75,-121.8,458.88,147.2,20,0.6,7,22,16,23,1,12,1,-1,-1,2,7,0,-2100,-1,-9999,MRD_x01_y00_z12,MRD_x01_y00_z12,None,ON,NORMAL +320,320,1,0,12,1,1,73.75,-101.5,458.88,147.2,20,0.6,7,22,17,23,2,12,2,-1,-1,2,7,1,-2100,-1,-9999,MRD_x01_y01_z12,MRD_x01_y01_z12,None,ON,NORMAL +321,321,1,0,12,1,2,73.75,-81.2,458.88,147.2,20,0.6,7,22,18,23,3,12,3,-1,-1,2,7,2,-2100,-1,-9999,MRD_x01_y02_z12,MRD_x01_y02_z12,None,ON,NORMAL +322,322,1,0,12,1,3,73.75,-60.9,458.88,147.2,20,0.6,7,22,19,23,4,12,4,-1,-1,2,7,3,-2100,-1,-9999,MRD_x01_y03_z12,MRD_x01_y03_z12,None,ON,NORMAL +323,323,1,0,12,1,4,73.75,-40.6,458.88,147.2,20,0.6,7,22,20,23,5,12,5,-1,-1,2,7,4,-2100,-1,-9999,MRD_x01_y04_z12,MRD_x01_y04_z12,None,ON,NORMAL +324,324,1,0,12,1,5,73.75,-20.3,458.88,147.2,20,0.6,7,22,21,23,6,12,6,-1,-1,2,7,5,-2100,-1,-9999,MRD_x01_y05_z12,MRD_x01_y05_z12,None,ON,NORMAL +325,325,1,0,12,1,6,73.75,0,458.88,147.2,20,0.6,7,22,22,23,7,12,7,-1,-1,2,7,6,-2100,-1,-9999,MRD_x01_y06_z12,MRD_x01_y06_z12,None,ON,NORMAL +326,326,1,0,12,1,7,73.75,20.3,458.88,147.2,20,0.6,7,22,23,23,8,12,8,-1,-1,2,7,7,-2100,-1,-9999,MRD_x01_y07_z12,MRD_x01_y07_z12,None,ON,NORMAL +327,327,1,0,12,1,8,73.75,40.6,458.88,147.2,20,0.6,7,22,24,23,9,12,9,-1,-1,2,7,8,-2100,-1,-9999,MRD_x01_y08_z12,MRD_x01_y08_z12,None,ON,NORMAL +328,328,1,0,12,1,9,73.75,60.9,458.88,147.2,20,0.6,7,22,25,23,10,12,10,-1,-1,2,7,9,-2100,-1,-9999,MRD_x01_y09_z12,MRD_x01_y09_z12,None,ON,NORMAL +329,329,1,0,12,1,10,73.75,81.2,458.88,147.2,20,0.6,7,22,26,23,11,12,11,-1,-1,2,7,10,-2100,-1,-9999,MRD_x01_y10_z12,MRD_x01_y10_z12,None,ON,NORMAL +330,330,1,0,12,1,11,73.75,101.5,458.88,147.2,20,0.6,7,22,27,23,12,12,12,-1,-1,2,7,11,-2100,-1,-9999,MRD_x01_y11_z12,MRD_x01_y11_z12,None,ON,NORMAL +331,331,1,0,12,1,12,73.75,121.8,458.88,147.2,20,0.6,7,22,28,23,13,12,13,-1,-1,2,7,12,-2100,-1,-9999,MRD_x01_y12_z12,MRD_x01_y12_z12,None,ON,NORMAL +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/FullMRDGeometry_03_thru_05_2023_Runs_R4191_thru_R4342.csv b/configfiles/LoadGeometry/FullMRDGeometry_03_thru_05_2023_Runs_R4191_thru_R4342.csv new file mode 100644 index 000000000..95d487c7b --- /dev/null +++ b/configfiles/LoadGeometry/FullMRDGeometry_03_thru_05_2023_Runs_R4191_thru_R4342.csv @@ -0,0 +1,342 @@ +#,,0=FMV,0=horizontal,,0=left,from left to right,,,,,,,,,,,,,,#NAME?,#NAME?,,,,,,,,,,, +#,,1=MRD,1=vertical,,1=right,from bottom to top,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,0=bottom,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,1=top,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,channel_num,detector_system,orientation,layer,side,num,x_center,y_center,z_center,x_width,y_width,z_width,rack,TDC_slot,TDC_channel,discrim_slot,discrim_ch,patch_panel_row,patch_panel_col,amp_slot,amp_channel,hv_crate,hv_slot,hv_channel,nominal_HV,polarity,PMT_type,cable_label,paddle_label,notes,detector_status,noise +########################################,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,-198.699875,5.08,320,30.5,2,8,2,0,1,1,1,1,-1,-1,2,14,0,-1871,-1,EMI9815,MRD_x00_y00_z00,4SW,None,ON,NORMAL +1,1,0,0,0,0,1,0,-167.999875,5.08,320,30.5,2,8,2,1,1,2,1,2,-1,-1,2,14,1,-1838,-1,EMI9815,MRD_x00_y01_z00,U39,None,ON,NORMAL +2,2,0,0,0,0,2,0,-137.299875,5.08,320,30.5,2,8,2,2,1,3,1,3,-1,-1,2,14,2,-1793,-1,EMI9815,MRD_x00_y02_z00,U58 (or U38; bad writing),None,ON,NORMAL +3,3,0,0,0,0,3,0,-106.599875,5.08,320,30.5,2,8,2,3,1,4,1,4,-1,-1,2,14,3,-1806,-1,EMI9815,MRD_x00_y03_z00,U29,None,ON,NORMAL +4,4,0,0,0,0,4,0,-75.899875,5.08,320,30.5,2,8,2,4,1,5,1,5,-1,-1,2,14,4,-1865,-1,EMI9815,MRD_x00_y04_z00,14SW,None,ON,NORMAL +5,5,0,0,0,0,5,0,-45.199875,5.08,320,30.5,2,8,2,5,1,6,1,6,-1,-1,2,14,5,-1823,-1,EMI9815,MRD_x00_y05_z00,Unknown4,None,ON,NORMAL +6,6,0,0,0,0,6,0,-14.499875,5.08,320,30.5,2,8,2,6,1,7,1,7,-1,-1,2,14,6,-1798,-1,EMI9815,MRD_x00_y06_z00,U17,None,ON,NORMAL +7,7,0,0,0,0,7,0,16.200125,5.08,320,30.5,2,8,2,7,1,8,1,8,-1,-1,2,14,7,-1823,-1,EMI9815,MRD_x00_y07_z00,11SE,None,ON,NORMAL +8,8,0,0,0,0,8,0,46.900125,5.08,320,30.5,2,8,2,8,1,9,1,9,-1,-1,2,14,8,-1871,-1,EMI9815,MRD_x00_y08_z00,18SE,None,ON,NORMAL +9,9,0,0,0,0,9,0,77.600125,5.08,320,30.5,2,8,2,9,1,10,1,10,-1,-1,2,14,9,-1836,-1,EMI9815,MRD_x00_y09_z00,21SW,None,ON,NORMAL +10,10,0,0,0,0,10,0,108.300125,5.08,320,30.5,2,8,2,10,1,11,1,11,-1,-1,2,14,10,-1814,-1,EMI9815,MRD_x00_y10_z00,3SE,None,ON,NORMAL +11,11,0,0,0,0,11,0,139.000125,5.08,320,30.5,2,8,2,11,1,12,1,12,-1,-1,2,14,11,-1781,-1,EMI9815,MRD_x00_y11_z00,24SE,None,ON,NORMAL +12,12,0,0,0,0,12,0,169.700125,5.08,320,30.5,2,8,2,12,1,13,1,13,-1,-1,2,14,12,-1816,-1,EMI9815,MRD_x00_y12_z00,U25,None,ON,NORMAL +13,13,0,0,0,1,0,0,-198.064875,7.28,320,30.5,2,8,2,16,3,1,2,1,-1,-1,2,15,0,-1805,-1,EMI9815,MRD_x01_y00_z00,28SE,None,ON,NORMAL +14,14,0,0,0,1,1,0,-167.364875,7.28,320,30.5,2,8,2,17,3,2,2,2,-1,-1,2,15,1,-1818,-1,EMI9815,MRD_x01_y01_z00,31SE,None,ON,NORMAL +15,15,0,0,0,1,2,0,-136.664875,7.28,320,30.5,2,8,2,18,3,3,2,3,-1,-1,2,15,2,-1860,-1,EMI9815,MRD_x01_y02_z00,8SE,None,ON,NORMAL +16,16,0,0,0,1,3,0,-105.964875,7.28,320,30.5,2,8,2,19,3,4,2,4,-1,-1,2,15,3,-1780,-1,EMI9815,MRD_x01_y03_z00,11SW,None,ON,NORMAL +17,17,0,0,0,1,4,0,-75.264875,7.28,320,30.5,2,8,2,20,3,5,2,5,-1,-1,2,15,4,-1841,-1,EMI9815,MRD_x01_y04_z00,U34,None,ON,NORMAL +18,18,0,0,0,1,5,0,-44.564875,7.28,320,30.5,2,8,2,21,3,6,2,6,-1,-1,2,15,5,-1786,-1,EMI9815,MRD_x01_y05_z010,U36,None,ON,NORMAL +19,19,0,0,0,1,6,0,-13.864875,7.28,320,30.5,2,8,2,22,3,7,2,7,-1,-1,2,15,6,-1864,-1,EMI9815,MRD_x01_y06_z00,U40,None,ON,NORMAL +20,20,0,0,0,1,7,0,16.835125,7.28,320,30.5,2,8,2,23,3,8,2,8,-1,-1,2,15,7,-1858,-1,EMI9815,MRD_x01_y07_z00,Unknown5,None,ON,NORMAL +21,21,0,0,0,1,8,0,47.535125,7.28,320,30.5,2,8,2,24,3,9,2,9,-1,-1,2,15,8,-1876,-1,EMI9815,MRD_x01_y08_z00,27SE,None,ON,NORMAL +22,22,0,0,0,1,9,0,78.235125,7.28,320,30.5,2,8,2,25,3,10,2,10,-1,-1,2,15,9,-1806,-1,EMI9815,MRD_x01_y09_z00,Unknown2,None,ON,NORMAL +23,23,0,0,0,1,10,0,108.935125,7.28,320,30.5,2,8,2,26,3,11,2,11,-1,-1,2,15,10,-1853,-1,EMI9815,MRD_x01_y10_z00,10SW,None,ON,NORMAL +24,24,0,0,0,1,11,0,139.635125,7.28,320,30.5,2,8,2,27,3,12,2,12,-1,-1,2,15,11,-1860,-1,EMI9815,MRD_x01_y11_z00,Bill2,None,ON,NORMAL +25,25,0,0,0,1,12,0,170.335125,7.28,320,30.5,2,8,2,28,3,13,2,13,-1,-1,2,15,12,-1844,-1,EMI9815,MRD_x01_y12_z00,13SE,None,ON,NORMAL +26,26,1,0,2,0,0,-73.75,-121.8,336.38,147.2,20,0.6,7,2,0,1,1,1,1,-1,-1,1,4,0,-2100,-1,-9999,MRD_x00_y00_z02,MRD_x00_y00_z02,None,ON,NORMAL +27,27,1,0,2,0,1,-73.75,-101.5,336.38,147.2,20,0.6,7,2,1,1,2,1,2,-1,-1,1,4,1,-2100,-1,-9999,MRD_x00_y01_z02,MRD_x00_y01_z02,None,ON,NORMAL +28,28,1,0,2,0,2,-73.75,-81.2,336.38,147.2,20,0.6,7,2,2,1,3,1,3,-1,-1,1,4,2,-2100,-1,-9999,MRD_x00_y02_z02,MRD_x00_y02_z02,None,ON,NORMAL +29,29,1,0,2,0,3,-73.75,-60.9,336.38,147.2,20,0.6,7,2,3,1,4,1,4,-1,-1,1,4,3,-2100,-1,-9999,MRD_x00_y03_z02,MRD_x00_y03_z02,None,ON,NORMAL +30,30,1,0,2,0,4,-73.75,-40.6,336.38,147.2,20,0.6,7,2,4,1,5,1,5,-1,-1,1,4,4,-2100,-1,-9999,MRD_x00_y04_z02,MRD_x00_y04_z02,None,ON,NORMAL +31,31,1,0,2,0,5,-73.75,-20.3,336.38,147.2,20,0.6,7,2,5,1,6,1,6,-1,-1,1,4,5,-2100,-1,-9999,MRD_x00_y05_z02,MRD_x00_y05_z02,None,ON,NORMAL +32,32,1,0,2,0,6,-73.75,0,336.38,147.2,20,0.6,7,2,6,1,7,1,7,-1,-1,1,4,6,-2100,-1,-9999,MRD_x00_y06_z02,MRD_x00_y06_z02,None,ON,NORMAL +33,33,1,0,2,0,7,-73.75,20.3,336.38,147.2,20,0.6,7,2,7,1,8,1,8,-1,-1,1,4,7,-2100,-1,-9999,MRD_x00_y07_z02,MRD_x00_y07_z02,None,ON,NORMAL +34,34,1,0,2,0,8,-73.75,40.6,336.38,147.2,20,0.6,7,2,8,1,9,1,9,-1,-1,1,4,8,-1900,-1,-9999,MRD_x00_y08_z02,MRD_x00_y08_z02,None,ON,NORMAL +35,35,1,0,2,0,9,-73.75,60.9,336.38,147.2,20,0.6,7,2,9,1,10,1,10,-1,-1,1,4,10,-1900,-1,-9999,MRD_x00_y09_z02,MRD_x00_y09_z02,None,ON,NORMAL +36,36,1,0,2,0,10,-73.75,81.2,336.38,147.2,20,0.6,7,2,10,1,11,1,11,-1,-1,1,4,11,-2100,-1,-9999,MRD_x00_y10_z02,MRD_x00_y10_z02,None,ON,NORMAL +37,37,1,0,2,0,11,-73.75,101.5,336.38,147.2,20,0.6,7,2,11,1,12,1,12,-1,-1,1,4,12,-2100,-1,-9999,MRD_x00_y11_z02,MRD_x00_y11_z02,None,ON,NORMAL +38,38,1,0,2,0,12,-73.75,121.8,336.38,147.2,20,0.6,7,2,12,1,13,1,13,-1,-1,1,4,13,-1900,-1,-9999,MRD_x00_y12_z02,MRD_x00_y12_z02,None,ON,NORMAL +39,39,1,0,2,1,0,73.75,-121.8,336.38,147.2,20,0.6,7,2,16,3,1,2,1,-1,-1,1,5,0,-2100,-1,-9999,MRD_x01_y00_z02,MRD_x01_y00_z02,None,ON,NORMAL +40,40,1,0,2,1,1,73.75,-101.5,336.38,147.2,20,0.6,7,2,17,3,2,2,2,-1,-1,1,5,1,-2100,-1,-9999,MRD_x01_y01_z02,MRD_x01_y01_z02,None,ON,NORMAL +41,41,1,0,2,1,2,73.75,-81.2,336.38,147.2,20,0.6,7,2,18,3,3,2,3,-1,-1,1,5,2,-1900,-1,-9999,MRD_x01_y02_z02,MRD_x01_y02_z02,None,ON,NORMAL +42,42,1,0,2,1,3,73.75,-60.9,336.38,147.2,20,0.6,7,2,19,3,4,2,4,-1,-1,1,5,3,-1900,-1,-9999,MRD_x01_y03_z02,MRD_x01_y03_z02,None,ON,NORMAL +43,43,1,0,2,1,4,73.75,-40.6,336.38,147.2,20,0.6,7,2,20,3,5,2,5,-1,-1,1,5,4,-2100,-1,-9999,MRD_x01_y04_z02,MRD_x01_y04_z02,None,ON,NORMAL +44,44,1,0,2,1,5,73.75,-20.3,336.38,147.2,20,0.6,7,2,21,3,6,2,6,-1,-1,1,5,5,-2100,-1,-9999,MRD_x01_y05_z02,MRD_x01_y05_z02,None,ON,NORMAL +45,45,1,0,2,1,6,73.75,0,336.38,147.2,20,0.6,7,2,22,3,7,2,7,-1,-1,1,5,6,-1900,-1,-9999,MRD_x01_y06_z02,MRD_x01_y06_z02,None,ON,NORMAL +46,46,1,0,2,1,7,73.75,20.3,336.38,147.2,20,0.6,7,2,23,3,8,2,8,-1,-1,1,5,7,-2100,-1,-9999,MRD_x01_y07_z02,MRD_x01_y07_z02,None,ON,NORMAL +47,47,1,0,2,1,8,73.75,40.6,336.38,147.2,20,0.6,7,2,24,3,9,2,9,-1,-1,1,5,8,-2100,-1,-9999,MRD_x01_y08_z02,MRD_x01_y08_z02,None,ON,NORMAL +48,48,1,0,2,1,9,73.75,60.9,336.38,147.2,20,0.6,7,2,25,3,10,2,10,-1,-1,1,5,9,-2100,-1,-9999,MRD_x01_y09_z02,MRD_x01_y09_z02,None,ON,NORMAL +49,49,1,0,2,1,10,73.75,81.2,336.38,147.2,20,0.6,7,2,26,3,11,2,11,-1,-1,1,5,10,-2100,-1,-9999,MRD_x01_y10_z02,MRD_x01_y10_z02,None,ON,NORMAL +50,50,1,0,2,1,11,73.75,101.5,336.38,147.2,20,0.6,7,2,27,3,12,2,12,-1,-1,1,5,11,-2100,-1,-9999,MRD_x01_y11_z02,MRD_x01_y11_z02,None,ON,NORMAL +51,51,1,0,2,1,12,73.75,121.8,336.38,147.2,20,0.6,7,2,28,3,13,2,13,-1,-1,1,5,12,-1900,-1,-9999,MRD_x01_y12_z02,MRD_x01_y12_z02,None,OFF,NORMAL +52,52,1,1,3,0,0,-107.1,-65.25,348.84,15,130.2,1.3,8,5,0,4,1,3,1,-1,-1,1,6,0,-2000,-1,-9999,MRD_x00_y00_z03,MRD_x00_y00_z03,None,ON,NORMAL +53,53,1,1,3,0,1,-91.8,-65.25,348.84,15,130.2,1.3,8,5,1,4,2,3,2,-1,-1,1,6,1,-2000,-1,-9999,MRD_x01_y00_z03,MRD_x01_y00_z03,None,ON,NORMAL +54,54,1,1,3,0,2,-76.5,-65.25,348.84,15,130.2,1.3,8,5,2,4,3,3,3,-1,-1,1,6,2,-2000,-1,-9999,MRD_x02_y00_z03,MRD_x02_y00_z03,None,ON,NORMAL +55,55,1,1,3,0,3,-61.2,-65.25,348.84,15,130.2,1.3,8,5,3,4,4,3,4,-1,-1,1,6,3,-2000,-1,-9999,MRD_x03_y00_z03,MRD_x03_y00_z03,None,ON,NORMAL +56,56,1,1,3,0,4,-45.9,-65.25,348.84,15,130.2,1.3,8,5,4,4,5,3,5,-1,-1,1,6,4,-2000,-1,-9999,MRD_x04_y00_z03,MRD_x04_y00_z03,None,ON,NORMAL +57,57,1,1,3,0,5,-30.6,-65.25,348.84,15,130.2,1.3,8,5,5,4,6,3,6,-1,-1,1,6,5,-2000,-1,-9999,MRD_x05_y00_z03,MRD_x05_y00_z03,None,ON,NORMAL +58,58,1,1,3,0,6,-15.3,-65.25,348.84,15,130.2,1.3,8,5,6,4,7,3,7,-1,-1,1,6,6,-2000,-1,-9999,MRD_x06_y00_z03,MRD_x06_y00_z03,None,ON,NORMAL +59,59,1,1,3,0,7,0,-65.25,348.84,15,130.2,1.3,8,5,7,4,8,3,8,-1,-1,1,6,7,-2000,-1,-9999,MRD_x07_y00_z03,MRD_x07_y00_z03,None,ON,NORMAL +60,60,1,1,3,0,8,15.3,-65.25,348.84,15,130.2,1.3,8,5,8,4,9,3,9,-1,-1,1,6,8,-2000,-1,-9999,MRD_x08_y00_z03,MRD_x08_y00_z03,None,ON,NORMAL +61,61,1,1,3,0,9,30.6,-65.25,348.84,15,130.2,1.3,8,5,9,4,10,3,10,-1,-1,1,6,9,-2000,-1,-9999,MRD_x09_y00_z03,MRD_x09_y00_z03,None,ON,NORMAL +62,62,1,1,3,0,10,45.9,-65.25,348.84,15,130.2,1.3,8,5,10,4,11,3,11,-1,-1,1,6,10,-2000,-1,-9999,MRD_x10_y00_z03,MRD_x10_y00_z03,None,ON,NORMAL +63,63,1,1,3,0,11,61.2,-65.25,348.84,15,130.2,1.3,8,5,11,4,12,3,12,-1,-1,1,6,11,-2000,-1,-9999,MRD_x11_y00_z03,MRD_x11_y00_z03,None,ON,NORMAL +64,64,1,1,3,0,12,76.5,-65.25,348.84,15,130.2,1.3,8,5,12,4,13,3,13,-1,-1,1,6,12,-2000,-1,-9999,MRD_x12_y00_z03,MRD_x12_y00_z03,None,ON,NORMAL +65,65,1,1,3,0,13,91.8,-65.25,348.84,15,130.2,1.3,8,5,13,4,14,3,14,-1,-1,1,6,13,-2000,-1,-9999,MRD_x13_y00_z03,MRD_x13_y00_z03,None,ON,NORMAL +66,66,1,1,3,0,14,107.1,-65.25,348.84,15,130.2,1.3,8,5,14,4,15,3,15,-1,-1,1,6,14,-1800,-1,-9999,MRD_x14_y00_z03,MRD_x14_y00_z03,None,ON,NORMAL +67,67,1,1,3,1,0,-107.1,65.25,348.84,15,130.2,1.3,8,5,16,6,1,4,1,-1,-1,1,7,0,-2200,-1,-9999,MRD_x00_y01_z03,MRD_x00_y01_z03,None,ON,NORMAL +68,68,1,1,3,1,1,-91.8,65.25,348.84,15,130.2,1.3,8,5,17,6,2,4,2,-1,-1,1,7,1,-2000,-1,-9999,MRD_x01_y01_z03,MRD_x01_y01_z03,None,ON,NORMAL +69,69,1,1,3,1,2,-76.5,65.25,348.84,15,130.2,1.3,8,5,18,6,3,4,3,-1,-1,1,7,2,-2000,-1,-9999,MRD_x02_y01_z03,MRD_x02_y01_z03,None,ON,NORMAL +70,70,1,1,3,1,3,-61.2,65.25,348.84,15,130.2,1.3,8,5,19,6,4,4,4,-1,-1,1,7,3,-2000,-1,-9999,MRD_x03_y01_z03,MRD_x03_y01_z03,None,ON,NORMAL +71,71,1,1,3,1,4,-45.9,65.25,348.84,15,130.2,1.3,8,5,20,6,5,4,5,-1,-1,1,7,4,-2000,-1,-9999,MRD_x04_y01_z03,MRD_x04_y01_z03,None,ON,NORMAL +72,72,1,1,3,1,5,-30.6,65.25,348.84,15,130.2,1.3,8,5,21,6,6,4,6,-1,-1,1,7,5,-2000,-1,-9999,MRD_x05_y01_z03,MRD_x05_y01_z03,None,ON,NORMAL +73,73,1,1,3,1,6,-15.3,65.25,348.84,15,130.2,1.3,8,5,22,6,7,4,7,-1,-1,1,7,6,-2000,-1,-9999,MRD_x06_y01_z03,MRD_x06_y01_z03,None,ON,NORMAL +74,74,1,1,3,1,7,0,65.25,348.84,15,130.2,1.3,8,5,23,6,8,4,8,-1,-1,1,7,7,-2000,-1,-9999,MRD_x07_y01_z03,MRD_x07_y01_z03,None,ON,NORMAL +75,75,1,1,3,1,8,15.3,65.25,348.84,15,130.2,1.3,8,5,24,6,9,4,9,-1,-1,1,7,8,-2000,-1,-9999,MRD_x08_y01_z03,MRD_x08_y01_z03,None,ON,NORMAL +76,76,1,1,3,1,9,30.6,65.25,348.84,15,130.2,1.3,8,5,25,6,10,4,10,-1,-1,1,7,9,-2000,-1,-9999,MRD_x09_y01_z03,MRD_x09_y01_z03,None,ON,NORMAL +77,77,1,1,3,1,10,45.9,65.25,348.84,15,130.2,1.3,8,5,26,6,11,4,11,-1,-1,1,7,10,-2000,-1,-9999,MRD_x10_y01_z03,MRD_x10_y01_z03,Currently using y1 z3 spare cableNone,ON,NORMAL +78,78,1,1,3,1,11,61.2,65.25,348.84,15,130.2,1.3,8,5,27,6,12,4,12,-1,-1,1,7,11,-2000,-1,-9999,MRD_x11_y01_z03,MRD_x11_y01_z03,None,ON,NORMAL +79,79,1,1,3,1,12,76.5,65.25,348.84,15,130.2,1.3,8,5,28,6,13,4,13,-1,-1,1,7,12,-2000,-1,-9999,MRD_x12_y01_z03,MRD_x12_y01_z03,None,ON,NORMAL +80,80,1,1,3,1,13,91.8,65.25,348.84,15,130.2,1.3,8,5,29,6,14,4,14,-1,-1,1,7,13,-2000,-1,-9999,MRD_x13_y01_z03,MRD_x13_y01_z03,None,ON,NORMAL +81,81,1,1,3,1,14,107.1,65.25,348.84,15,130.2,1.3,8,5,30,6,15,4,15,-1,-1,1,7,14,-2000,-1,-9999,MRD_x14_y01_z03,MRD_x14_y01_z03,None,ON,NORMAL +82,82,1,0,4,0,0,-73.75,-121.8,361.3,147.2,20,0.6,7,5,0,4,1,3,1,-1,-1,1,8,0,-2100,-1,-9999,MRD_x00_y00_z04,MRD_x00_y00_z04,None,ON,NORMAL +83,83,1,0,4,0,1,-73.75,-101.5,361.3,147.2,20,0.6,7,5,1,4,2,3,2,-1,-1,1,8,1,-2100,-1,-9999,MRD_x00_y01_z04,MRD_x00_y01_z04,None,ON,NORMAL +84,84,1,0,4,0,2,-73.75,-81.2,361.3,147.2,20,0.6,7,5,2,4,3,3,3,-1,-1,1,8,2,-2100,-1,-9999,MRD_x00_y02_z04,MRD_x00_y02_z04,None,ON,NORMAL +85,85,1,0,4,0,3,-73.75,-60.9,361.3,147.2,20,0.6,7,5,3,4,4,3,4,-1,-1,1,8,3,-2100,-1,-9999,MRD_x00_y03_z04,MRD_x00_y03_z04,None,ON,NORMAL +86,86,1,0,4,0,4,-73.75,-40.6,361.3,147.2,20,0.6,7,5,4,4,5,3,5,-1,-1,1,8,4,-2300,-1,-9999,MRD_x00_y04_z04,MRD_x00_y04_z04,None,ON,NORMAL +87,87,1,0,4,0,5,-73.75,-20.3,361.3,147.2,20,0.6,7,5,5,4,6,3,6,-1,-1,1,8,5,-2100,-1,-9999,MRD_x00_y05_z04,MRD_x00_y05_z04,None,ON,NORMAL +88,88,1,0,4,0,6,-73.75,0,361.3,147.2,20,0.6,7,5,6,4,7,3,7,-1,-1,1,8,6,-2100,-1,-9999,MRD_x00_y06_z04,MRD_x00_y06_z04,None,ON,NORMAL +89,89,1,0,4,0,7,-73.75,20.3,361.3,147.2,20,0.6,7,5,7,4,8,3,8,-1,-1,1,8,7,-2100,-1,-9999,MRD_x00_y07_z04,MRD_x00_y07_z04,None,ON,NORMAL +90,90,1,0,4,0,8,-73.75,40.6,361.3,147.2,20,0.6,7,5,8,4,9,3,9,-1,-1,1,8,8,-2100,-1,-9999,MRD_x00_y08_z04,MRD_x00_y08_z04,None,ON,NORMAL +91,91,1,0,4,0,9,-73.75,60.9,361.3,147.2,20,0.6,7,5,9,4,10,3,10,-1,-1,1,8,9,-2100,-1,-9999,MRD_x00_y09_z04,MRD_x00_y09_z04,None,ON,NORMAL +92,92,1,0,4,0,10,-73.75,81.2,361.3,147.2,20,0.6,7,5,10,4,11,3,11,-1,-1,1,8,10,-2100,-1,-9999,MRD_x00_y10_z04,MRD_x00_y10_z04,None,ON,NORMAL +93,93,1,0,4,0,11,-73.75,101.5,361.3,147.2,20,0.6,7,5,11,4,12,3,12,-1,-1,1,8,11,-2100,-1,-9999,MRD_x00_y11_z04,MRD_x00_y11_z04,None,ON,NORMAL +94,94,1,0,4,0,12,-73.75,121.8,361.3,147.2,20,0.6,7,5,12,4,13,3,13,-1,-1,1,8,12,-2300,-1,-9999,MRD_x00_y12_z04,MRD_x00_y12_z04,None,ON,NORMAL +95,95,1,0,4,1,0,73.75,-121.8,361.3,147.2,20,0.6,7,5,16,6,1,4,1,-1,-1,1,9,0,-2100,-1,-9999,MRD_x01_y00_z04,MRD_x01_y00_z04,None,ON,NORMAL +96,96,1,0,4,1,1,73.75,-101.5,361.3,147.2,20,0.6,7,5,17,6,2,4,2,-1,-1,1,9,1,-2100,-1,-9999,MRD_x01_y01_z04,MRD_x01_y01_z04,None,ON,NORMAL +97,97,1,0,4,1,2,73.75,-81.2,361.3,147.2,20,0.6,7,5,18,6,3,4,3,-1,-1,1,9,2,-2300,-1,-9999,MRD_x01_y02_z04,MRD_x01_y02_z04,None,ON,NORMAL +98,98,1,0,4,1,3,73.75,-60.9,361.3,147.2,20,0.6,7,5,19,6,4,4,4,-1,-1,1,9,3,-2300,-1,-9999,MRD_x01_y03_z04,MRD_x01_y03_z04,None,ON,NORMAL +99,99,1,0,4,1,4,73.75,-40.6,361.3,147.2,20,0.6,7,5,20,6,5,4,5,-1,-1,1,9,4,-2100,-1,-9999,MRD_x01_y04_z04,MRD_x01_y04_z04,None,ON,NORMAL +100,100,1,0,4,1,5,73.75,-20.3,361.3,147.2,20,0.6,7,5,21,6,6,4,6,-1,-1,1,9,5,-2100,-1,-9999,MRD_x01_y05_z04,MRD_x01_y05_z04,None,ON,NORMAL +101,101,1,0,4,1,6,73.75,0,361.3,147.2,20,0.6,7,5,22,6,7,4,7,-1,-1,1,9,6,-2100,-1,-9999,MRD_x01_y06_z04,MRD_x01_y06_z04,None,ON,NORMAL +102,102,1,0,4,1,7,73.75,20.3,361.3,147.2,20,0.6,7,5,23,6,8,4,8,-1,-1,1,9,7,-2100,-1,-9999,MRD_x01_y07_z04,MRD_x01_y07_z04,None,ON,NORMAL +103,103,1,0,4,1,8,73.75,40.6,361.3,147.2,20,0.6,7,5,24,6,9,4,9,-1,-1,1,9,8,-2100,-1,-9999,MRD_x01_y08_z04,MRD_x01_y08_z04,None,ON,NORMAL +104,104,1,0,4,1,9,73.75,60.9,361.3,147.2,20,0.6,7,5,25,6,10,4,10,-1,-1,1,9,9,-2100,-1,-9999,MRD_x01_y09_z04,MRD_x01_y09_z04,None,ON,NORMAL +105,105,1,0,4,1,10,73.75,81.2,361.3,147.2,20,0.6,7,5,26,6,11,4,11,-1,-1,1,9,10,-2100,-1,-9999,MRD_x01_y10_z04,MRD_x01_y10_z04,None,ON,NORMAL +106,106,1,0,4,1,11,73.75,101.5,361.3,147.2,20,0.6,7,5,27,6,12,4,12,-1,-1,1,9,11,-2100,-1,-9999,MRD_x01_y11_z04,MRD_x01_y11_z04,None,ON,NORMAL +107,107,1,0,4,1,12,73.75,121.8,361.3,147.2,20,0.6,7,5,28,6,13,4,13,-1,-1,1,9,12,-2100,-1,-9999,MRD_x01_y12_z04,MRD_x01_y12_z04,None,ON,NORMAL +108,108,1,1,5,0,0,-122.4,-65.25,373.76,15,130.2,1.3,8,8,0,7,1,5,1,-1,-1,1,10,0,-2200,-1,-9999,MRD_x00_y00_z05,MRD_x00_y00_z05,None,ON,NORMAL +109,109,1,1,5,0,1,-107.1,-65.25,373.76,15,130.2,1.3,8,8,1,7,2,5,2,-1,-1,1,10,1,-2200,-1,-9999,MRD_x01_y00_z05,MRD_x01_y00_z05,None,ON,NORMAL +110,110,1,1,5,0,2,-91.8,-65.25,373.76,15,130.2,1.3,8,8,2,7,3,5,3,-1,-1,1,10,2,-2000,-1,-9999,MRD_x02_y00_z05,MRD_x02_y00_z05,None,ON,NORMAL +111,111,1,1,5,0,3,-76.5,-65.25,373.76,15,130.2,1.3,8,8,7,7,8,5,4,-1,-1,1,10,3,-1500,-1,-9999,MRD_x03_y00_z05,MRD_x03_y00_z05,None,ON,NORMAL +112,112,1,1,5,0,4,-61.2,-65.25,373.76,15,130.2,1.3,8,8,3,7,4,5,5,-1,-1,1,10,4,-2000,-1,-9999,MRD_x04_y00_z05,MRD_x04_y00_z05,None,ON,NORMAL +113,113,1,1,5,0,5,-45.9,-65.25,373.76,15,130.2,1.3,8,8,4,7,5,5,6,-1,-1,1,10,5,-2000,-1,-9999,MRD_x05_y00_z05,MRD_x05_y00_z05,None,ON,NORMAL +114,114,1,1,5,0,6,-30.6,-65.25,373.76,15,130.2,1.3,8,8,6,7,7,5,7,-1,-1,1,10,6,-2000,-1,-9999,MRD_x06_y00_z05,MRD_x06_y00_z05,None,ON,NORMAL +115,115,1,1,5,0,7,-15.3,-65.25,373.76,15,130.2,1.3,8,8,5,7,6,5,8,-1,-1,1,10,7,-2000,-1,-9999,MRD_x07_y00_z05,MRD_x07_y00_z05,None,ON,NORMAL +116,116,1,1,5,0,8,0,-65.25,373.76,15,130.2,1.3,8,8,8,7,9,5,9,-1,-1,1,10,8,-2000,-1,-9999,MRD_x08_y00_z05,MRD_x08_y00_z05,None,ON,NORMAL +117,117,1,1,5,0,9,15.3,-65.25,373.76,15,130.2,1.3,8,8,14,7,15,5,10,-1,-1,1,10,9,-2000,-1,-9999,MRD_x09_y00_z05,MRD_x09_y00_z05,None,ON,NORMAL +118,118,1,1,5,0,10,30.6,-65.25,373.76,15,130.2,1.3,8,8,10,7,11,5,11,-1,-1,1,10,10,-2000,-1,-9999,MRD_x10_y00_z05,MRD_x10_y00_z05,None,ON,NORMAL +119,119,1,1,5,0,11,45.9,-65.25,373.76,15,130.2,1.3,8,8,11,7,12,5,12,-1,-1,1,10,11,-2000,-1,-9999,MRD_x11_y00_z05,MRD_x11_y00_z05,None,ON,NORMAL +120,120,1,1,5,0,12,61.2,-65.25,373.76,15,130.2,1.3,8,8,9,7,10,5,13,-1,-1,1,10,12,-2000,-1,-9999,MRD_x12_y00_z05,MRD_x12_y00_z05,Discriminator on slot 7 channel 13 has no NIM outputNone,ON,NORMAL +121,121,1,1,5,0,13,76.5,-65.25,373.76,15,130.2,1.3,8,8,12,7,13,5,14,-1,-1,1,10,13,-2000,-1,-9999,MRD_x13_y00_z05,MRD_x13_y00_z05,None,ON,NORMAL +122,122,1,1,5,0,14,91.8,-65.25,373.76,15,130.2,1.3,8,8,13,7,14,5,15,-1,-1,1,10,14,-2000,-1,-9999,MRD_x14_y00_z05,MRD_x14_y00_z05,None,ON,NORMAL +123,123,1,1,5,0,15,107.1,-65.25,373.76,15,130.2,1.3,8,8,15,7,16,5,16,-1,-1,1,5,14,-1500,-1,-9999,MRD_x15_y00_z05,MRD_x15_y00_z05,None,OFF,NORMAL +124,124,1,1,5,0,16,122.4,-65.25,373.76,15,130.2,1.3,8,17,15,16,16,5,17,-1,-1,1,4,14,-2200,-1,-9999,MRD_x16_y00_z05,MRD_x16_y00_z05,None,OFF,NORMAL +125,125,1,1,5,1,0,-122.4,65.25,373.76,15,130.2,1.3,8,8,16,9,1,6,1,-1,-1,1,11,0,-2000,-1,-9999,MRD_x00_y01_z05,MRD_x00_y01_z05,None,ON,NORMAL +126,126,1,1,5,1,1,-107.1,65.25,373.76,15,130.2,1.3,8,8,17,9,2,6,2,-1,-1,1,11,1,-2000,-1,-9999,MRD_x01_y01_z05,MRD_x01_y01_z05,possible dischargeNone,ON,NORMAL +127,127,1,1,5,1,2,-91.8,65.25,373.76,15,130.2,1.3,8,8,18,9,3,6,3,-1,-1,1,11,2,-2000,-1,-9999,MRD_x02_y01_z05,MRD_x02_y01_z05,None,ON,NORMAL +128,128,1,1,5,1,3,-76.5,65.25,373.76,15,130.2,1.3,8,8,19,9,4,6,4,-1,-1,1,11,3,-2000,-1,-9999,MRD_x03_y01_z05,MRD_x03_y01_z05,None,ON,NORMAL +129,129,1,1,5,1,4,-61.2,65.25,373.76,15,130.2,1.3,8,8,20,9,5,6,5,-1,-1,1,11,4,-1500,-1,-9999,MRD_x04_y01_z05,MRD_x04_y01_z05,None,ON,NORMAL +130,130,1,1,5,1,5,-45.9,65.25,373.76,15,130.2,1.3,8,8,21,9,6,6,6,-1,-1,1,11,5,-2000,-1,-9999,MRD_x05_y01_z05,MRD_x05_y01_z05,None,ON,NORMAL +131,131,1,1,5,1,6,-30.6,65.25,373.76,15,130.2,1.3,8,8,22,9,7,6,7,-1,-1,1,11,6,-2000,-1,-9999,MRD_x06_y01_z05,MRD_x06_y01_z05,None,ON,NORMAL +132,132,1,1,5,1,7,-15.3,65.25,373.76,15,130.2,1.3,8,8,23,9,8,6,8,-1,-1,1,11,7,-2000,-1,-9999,MRD_x07_y01_z05,MRD_x07_y01_z05,None,ON,NORMAL +133,133,1,1,5,1,8,0,65.25,373.76,15,130.2,1.3,8,8,24,9,9,6,9,-1,-1,1,11,8,-2000,-1,-9999,MRD_x08_y01_z05,MRD_x08_y01_z05,None,ON,NORMAL +134,134,1,1,5,1,9,15.3,65.25,373.76,15,130.2,1.3,8,8,25,9,10,6,10,-1,-1,1,11,9,-2000,-1,-9999,MRD_x09_y01_z05,MRD_x09_y01_z05,None,ON,NORMAL +135,135,1,1,5,1,10,30.6,65.25,373.76,15,130.2,1.3,8,8,26,9,11,6,11,-1,-1,1,11,10,-2000,-1,-9999,MRD_x10_y01_z05,MRD_x10_y01_z05,None,ON,NORMAL +136,136,1,1,5,1,11,45.9,65.25,373.76,15,130.2,1.3,8,8,27,9,12,6,12,-1,-1,1,11,11,-1800,-1,-9999,MRD_x11_y01_z05,MRD_x11_y01_z05,None,ON,NORMAL +137,137,1,1,5,1,12,61.2,65.25,373.76,15,130.2,1.3,8,8,28,9,13,6,13,-1,-1,1,11,12,-2000,-1,-9999,MRD_x12_y01_z05,MRD_x12_y01_z05,None,ON,NORMAL +138,138,1,1,5,1,13,76.5,65.25,373.76,15,130.2,1.3,8,8,29,9,14,6,14,-1,-1,1,11,13,-2000,-1,-9999,MRD_x13_y01_z05,MRD_x13_y01_z05,None,ON,NORMAL +139,139,1,1,5,1,14,91.8,65.25,373.76,15,130.2,1.3,8,8,30,9,15,6,15,-1,-1,1,11,14,-2000,-1,-9999,MRD_x14_y01_z05,MRD_x14_y01_z05,None,ON,NORMAL +140,140,1,1,5,1,15,107.1,65.25,373.76,15,130.2,1.3,8,8,31,9,16,6,16,-1,-1,1,11,15,-2000,-1,-9999,MRD_x15_y01_z05,MRD_x15_y01_z05,None,OFF,NORMAL +141,141,1,1,5,1,16,122.4,65.25,373.76,15,130.2,1.3,8,14,31,15,16,6,17,-1,-1,1,4,15,-2000,-1,-9999,MRD_x16_y01_z05,MRD_x16_y01_z05,Now uses y0 z5 spare; Rack 8 slot 18 channel 16 has no NIM output,OFF,NORMAL +142,142,1,0,6,0,0,-73.75,-121.8,386.22,147.2,20,0.6,7,8,0,7,1,5,1,-1,-1,1,12,0,-2100,-1,-9999,MRD_x00_y00_z06,MRD_x00_y00_z06,None,ON,NORMAL +143,143,1,0,6,0,1,-73.75,-101.5,386.22,147.2,20,0.6,7,8,1,7,2,5,2,-1,-1,1,12,1,-2100,-1,-9999,MRD_x00_y01_z06,MRD_x00_y01_z06,None,ON,NORMAL +144,144,1,0,6,0,2,-73.75,-81.2,386.22,147.2,20,0.6,7,8,2,7,3,5,3,-1,-1,1,12,2,-2100,-1,-9999,MRD_x00_y02_z06,MRD_x00_y02_z06,None,ON,NORMAL +145,145,1,0,6,0,3,-73.75,-60.9,386.22,147.2,20,0.6,7,8,3,7,4,5,4,-1,-1,1,12,3,-2100,-1,-9999,MRD_x00_y03_z06,MRD_x00_y03_z06,None,ON,NORMAL +146,146,1,0,6,0,4,-73.75,-40.6,386.22,147.2,20,0.6,7,8,4,7,5,5,5,-1,-1,1,12,4,-2100,-1,-9999,MRD_x00_y04_z06,MRD_x00_y04_z06,None,ON,NORMAL +147,147,1,0,6,0,5,-73.75,-20.3,386.22,147.2,20,0.6,7,8,5,7,6,5,6,-1,-1,1,12,5,-2100,-1,-9999,MRD_x00_y05_z06,MRD_x00_y05_z06,None,ON,NORMAL +148,148,1,0,6,0,6,-73.75,0,386.22,147.2,20,0.6,7,8,6,7,7,5,7,-1,-1,1,12,6,-2100,-1,-9999,MRD_x00_y06_z06,MRD_x00_y06_z06,None,ON,NORMAL +149,149,1,0,6,0,7,-73.75,20.3,386.22,147.2,20,0.6,7,8,7,7,8,5,8,-1,-1,1,12,7,-2100,-1,-9999,MRD_x00_y07_z06,MRD_x00_y07_z06,None,ON,NORMAL +150,150,1,0,6,0,8,-73.75,40.6,386.22,147.2,20,0.6,7,8,8,7,9,5,9,-1,-1,1,12,8,-2100,-1,-9999,MRD_x00_y08_z06,MRD_x00_y08_z06,None,ON,NORMAL +151,151,1,0,6,0,9,-73.75,60.9,386.22,147.2,20,0.6,7,8,9,7,10,5,10,-1,-1,1,12,9,-2100,-1,-9999,MRD_x00_y09_z06,MRD_x00_y09_z06,None,ON,NORMAL +152,152,1,0,6,0,10,-73.75,81.2,386.22,147.2,20,0.6,7,8,10,7,11,5,11,-1,-1,1,12,10,-2100,-1,-9999,MRD_x00_y10_z06,MRD_x00_y10_z06,None,ON,NORMAL +153,153,1,0,6,0,11,-73.75,101.5,386.22,147.2,20,0.6,7,8,11,7,12,5,12,-1,-1,1,12,11,-2100,-1,-9999,MRD_x00_y11_z06,MRD_x00_y11_z06,None,ON,NORMAL +154,154,1,0,6,0,12,-73.75,121.8,386.22,147.2,20,0.6,7,8,12,7,13,5,13,-1,-1,1,12,12,-2100,-1,-9999,MRD_x00_y12_z06,MRD_x00_y12_z06,None,ON,NORMAL +155,155,1,0,6,1,0,73.75,-121.8,386.22,147.2,20,0.6,7,8,16,9,1,6,1,-1,-1,1,13,0,-1900,-1,-9999,MRD_x01_y00_z06,MRD_x01_y00_z06,None,ON,NORMAL +156,156,1,0,6,1,1,73.75,-101.5,386.22,147.2,20,0.6,7,8,17,9,2,6,2,-1,-1,1,13,1,-2100,-1,-9999,MRD_x01_y01_z06,MRD_x01_y01_z06,None,ON,NORMAL +157,157,1,0,6,1,2,73.75,-81.2,386.22,147.2,20,0.6,7,8,18,9,3,6,3,-1,-1,1,13,2,-2100,-1,-9999,MRD_x01_y02_z06,MRD_x01_y02_z06,None,ON,NORMAL +158,158,1,0,6,1,3,73.75,-60.9,386.22,147.2,20,0.6,7,8,19,9,4,6,4,-1,-1,1,13,3,-2100,-1,-9999,MRD_x01_y03_z06,MRD_x01_y03_z06,None,ON,NORMAL +159,159,1,0,6,1,4,73.75,-40.6,386.22,147.2,20,0.6,7,8,20,9,5,6,5,-1,-1,1,13,4,-2100,-1,-9999,MRD_x01_y04_z06,MRD_x01_y04_z06,None,ON,NORMAL +160,160,1,0,6,1,5,73.75,-20.3,386.22,147.2,20,0.6,7,8,21,9,6,6,6,-1,-1,1,13,5,-2100,-1,-9999,MRD_x01_y05_z06,MRD_x01_y05_z06,None,ON,NORMAL +161,161,1,0,6,1,6,73.75,0,386.22,147.2,20,0.6,7,8,22,9,7,6,7,-1,-1,1,13,6,-2100,-1,-9999,MRD_x01_y06_z06,MRD_x01_y06_z06,None,ON,NORMAL +162,162,1,0,6,1,7,73.75,20.3,386.22,147.2,20,0.6,7,8,23,9,8,6,8,-1,-1,1,13,7,-2100,-1,-9999,MRD_x01_y07_z06,MRD_x01_y07_z06,None,ON,NORMAL +163,163,1,0,6,1,8,73.75,40.6,386.22,147.2,20,0.6,7,8,24,9,9,6,9,-1,-1,1,13,8,-2100,-1,-9999,MRD_x01_y08_z06,MRD_x01_y08_z06,None,ON,NORMAL +164,164,1,0,6,1,9,73.75,60.9,386.22,147.2,20,0.6,7,8,25,9,10,6,10,-1,-1,1,13,9,-1900,-1,-9999,MRD_x01_y09_z06,MRD_x01_y09_z06,None,ON,NORMAL +165,165,1,0,6,1,10,73.75,81.2,386.22,147.2,20,0.6,7,8,26,9,11,6,11,-1,-1,1,13,10,-2100,-1,-9999,MRD_x01_y10_z06,MRD_x01_y10_z06,None,ON,NORMAL +166,166,1,0,6,1,11,73.75,101.5,386.22,147.2,20,0.6,7,8,27,9,12,6,12,-1,-1,1,13,11,-2100,-1,-9999,MRD_x01_y11_z06,MRD_x01_y11_z06,None,ON,NORMAL +167,167,1,0,6,1,12,73.75,121.8,386.22,147.2,20,0.6,7,8,28,9,13,6,13,-1,-1,1,13,12,-2100,-1,-9999,MRD_x01_y12_z06,MRD_x01_y12_z06,None,ON,NORMAL +168,168,1,1,7,0,1,-121.8,-65.25,398.33,20,130.2,0.6,8,11,1,10,2,7,2,1,3,1,14,1,-1500,-1,-9999,MRD_x01_y00_z07,MRD_x01_y00_z07,None,ON,NORMAL +169,169,1,1,7,0,2,-101.5,-65.25,398.33,20,130.2,0.6,8,11,2,10,3,7,3,1,5,1,14,2,-1500,-1,-9999,MRD_x02_y00_z07,MRD_x02_y00_z07,None,ON,NORMAL +170,170,1,1,7,0,3,-81.2,-65.25,398.33,20,130.2,0.6,8,11,3,10,4,7,4,1,7,1,14,3,-1500,-1,-9999,MRD_x03_y00_z07,MRD_x03_y00_z07,None,ON,NORMAL +171,171,1,1,7,0,4,-60.9,-65.25,398.33,20,130.2,0.6,8,11,4,10,5,7,5,1,9,1,14,4,-1500,-1,-9999,MRD_x04_y00_z07,MRD_x04_y00_z07,None,ON,NORMAL +172,172,1,1,7,0,5,-40.6,-65.25,398.33,20,130.2,0.6,8,11,5,10,6,7,6,1,11,1,14,5,-1500,-1,-9999,MRD_x05_y00_z07,MRD_x05_y00_z07,None,ON,NORMAL +173,173,1,1,7,0,6,-20.3,-65.25,398.33,20,130.2,0.6,8,11,6,10,7,7,7,1,13,1,14,6,-1500,-1,-9999,MRD_x06_y00_z07,MRD_x06_y00_z07,None,ON,NORMAL +174,174,1,1,7,0,7,0,-65.25,398.33,20,130.2,0.6,8,11,7,10,8,7,8,12,2,1,14,7,-1500,-1,-9999,MRD_x07_y00_z07,MRD_x07_y00_z07,None,ON,NORMAL +175,175,1,1,7,0,8,20.3,-65.25,398.33,20,130.2,0.6,8,11,8,10,9,7,9,12,4,1,14,8,-1500,-1,-9999,MRD_x08_y00_z07,MRD_x08_y00_z07,None,ON,NORMAL +176,176,1,1,7,0,9,40.6,-65.25,398.33,20,130.2,0.6,8,11,9,10,10,7,10,12,6,1,14,9,-1500,-1,-9999,MRD_x09_y00_z07,MRD_x09_y00_z07,None,ON,NORMAL +177,177,1,1,7,0,10,60.9,-65.25,398.33,20,130.2,0.6,8,11,10,10,11,7,11,12,8,1,14,10,-1500,-1,-9999,MRD_x10_y00_z07,MRD_x10_y00_z07,None,ON,NORMAL +178,178,1,1,7,0,11,81.2,-65.25,398.33,20,130.2,0.6,8,11,11,10,12,7,12,12,10,1,14,11,-1500,-1,-9999,MRD_x11_y00_z07,MRD_x11_y00_z07,None,ON,NORMAL +179,179,1,1,7,0,12,101.5,-65.25,398.33,20,130.2,0.6,8,11,12,10,13,7,13,12,12,1,14,12,-1500,-1,-9999,MRD_x12_y00_z07,MRD_x12_y00_z07,None,ON,NORMAL +180,180,1,1,7,0,13,121.8,-65.25,398.33,20,130.2,0.6,8,11,13,10,14,7,14,12,14,1,14,13,-1500,-1,-9999,MRD_x13_y00_z07,MRD_x13_y00_z07,None,ON,NORMAL +181,181,1,1,7,1,1,-121.8,65.25,398.33,20,130.2,0.6,8,11,17,12,2,8,2,1,4,1,15,1,-1500,-1,-9999,MRD_x01_y01_z07,MRD_x01_y01_z07,None,ON,NORMAL +182,182,1,1,7,1,2,-101.5,65.25,398.33,20,130.2,0.6,8,11,18,12,3,8,3,1,6,1,15,2,-1500,-1,-9999,MRD_x02_y01_z07,MRD_x02_y01_z07,None,ON,NORMAL +183,183,1,1,7,1,3,-81.2,65.25,398.33,20,130.2,0.6,8,11,19,12,4,8,4,1,8,1,15,3,-1300,-1,-9999,MRD_x03_y01_z07,MRD_x03_y01_z07,None,ON,HOT +184,184,1,1,7,1,4,-60.9,65.25,398.33,20,130.2,0.6,8,11,20,12,5,8,5,1,10,1,15,4,-1500,-1,-9999,MRD_x04_y01_z07,MRD_x04_y01_z07,None,ON,NORMAL +185,185,1,1,7,1,5,-40.6,65.25,398.33,20,130.2,0.6,8,11,21,12,6,8,6,1,12,1,15,5,-2000,-1,-9999,MRD_x05_y01_z07,MRD_x05_y01_z07,None,ON,NORMAL +186,186,1,1,7,1,6,-20.3,65.25,398.33,20,130.2,0.6,8,11,22,12,7,8,7,1,14,1,15,6,-2000,-1,-9999,MRD_x06_y01_z07,MRD_x06_y01_z07,None,ON,NORMAL +187,187,1,1,7,1,7,0,65.25,398.33,20,130.2,0.6,8,11,23,12,8,8,8,12,1,1,15,7,-2000,-1,-9999,MRD_x07_y01_z07,MRD_x07_y01_z07,None,ON,NORMAL +188,188,1,1,7,1,8,20.3,65.25,398.33,20,130.2,0.6,8,11,24,12,9,8,9,12,3,1,15,8,-2000,-1,-9999,MRD_x08_y01_z07,MRD_x08_y01_z07,None,ON,NORMAL +189,189,1,1,7,1,9,40.6,65.25,398.33,20,130.2,0.6,8,11,25,12,10,8,10,12,5,1,15,9,-1500,-1,-9999,MRD_x09_y01_z07,MRD_x09_y01_z07,None,ON,NORMAL +190,190,1,1,7,1,10,60.9,65.25,398.33,20,130.2,0.6,8,11,26,12,11,8,11,12,7,1,15,10,-1500,-1,-9999,MRD_x10_y01_z07,MRD_x10_y01_z07,None,ON,NORMAL +191,191,1,1,7,1,11,81.2,65.25,398.33,20,130.2,0.6,8,11,27,12,12,8,12,12,9,1,15,11,-1500,-1,-9999,MRD_x11_y01_z07,MRD_x11_y01_z07,None,ON,NORMAL +192,192,1,1,7,1,12,101.5,65.25,398.33,20,130.2,0.6,8,11,28,12,13,8,13,12,11,1,15,12,-1500,-1,-9999,MRD_x12_y01_z07,MRD_x12_y01_z07,None,ON,NORMAL +193,193,1,1,7,1,13,121.8,65.25,398.33,20,130.2,0.6,8,11,29,12,14,8,14,12,13,1,15,13,-1500,-1,-9999,MRD_x13_y01_z07,MRD_x13_y01_z07,None,ON,NORMAL +194,194,1,0,8,0,0,-73.75,-121.8,410.44,147.2,20,0.6,7,11,0,10,1,7,1,-1,-1,1,0,0,2100,1,EMI 9939B,MRD_x00_y00_z08,MRD_x00_y00_z08,None,ON,NORMAL +195,195,1,0,8,0,1,-73.75,-101.5,410.44,147.2,20,0.6,7,11,1,10,2,7,2,-1,-1,1,0,1,2100,1,EMI 9939B,MRD_x00_y01_z08,MRD_x00_y01_z08,None,OFF,HOT +196,196,1,0,8,0,2,-73.75,-81.2,410.44,147.2,20,0.6,7,11,2,10,3,7,3,-1,-1,1,0,2,2100,1,EMI 9939B,MRD_x00_y02_z08,MRD_x00_y02_z08,None,ON,NORMAL +197,197,1,0,8,0,3,-73.75,-60.9,410.44,147.2,20,0.6,7,11,3,10,4,7,4,-1,-1,1,0,3,2100,1,EMI 9939B,MRD_x00_y03_z08,MRD_x00_y03_z08,None,ON,NORMAL +198,198,1,0,8,0,4,-73.75,-40.6,410.44,147.2,20,0.6,7,11,4,10,5,7,5,-1,-1,1,0,4,2100,1,EMI 9939B,MRD_x00_y04_z08,MRD_x00_y04_z08,None,ON,NORMAL +199,199,1,0,8,0,5,-73.75,-20.3,410.44,147.2,20,0.6,7,11,5,10,6,7,6,-1,-1,1,0,5,2100,1,EMI 9939B,MRD_x00_y05_z08,MRD_x00_y05_z08,None,ON,NORMAL +200,200,1,0,8,0,6,-73.75,0,410.44,147.2,20,0.6,7,11,6,10,7,7,7,-1,-1,1,0,6,2100,1,EMI 9939B,MRD_x00_y06_z08,MRD_x00_y06_z08,None,ON,NORMAL +201,201,1,0,8,0,7,-73.75,20.3,410.44,147.2,20,0.6,7,11,7,10,8,7,8,-1,-1,1,0,7,2100,1,EMI 9939B,MRD_x00_y07_z08,MRD_x00_y07_z08,None,ON,NORMAL +202,202,1,0,8,0,8,-73.75,40.6,410.44,147.2,20,0.6,7,11,8,10,9,7,9,-1,-1,1,0,8,2100,1,EMI 9939B,MRD_x00_y08_z08,MRD_x00_y08_z08,None,ON,NORMAL +203,203,1,0,8,0,9,-73.75,60.9,410.44,147.2,20,0.6,7,11,9,10,10,7,10,-1,-1,1,0,9,2100,1,EMI 9939B,MRD_x00_y09_z08,MRD_x00_y09_z08,None,ON,NORMAL +204,204,1,0,8,0,10,-73.75,81.2,410.44,147.2,20,0.6,7,11,10,10,11,7,11,-1,-1,1,0,10,2100,1,EMI 9939B,MRD_x00_y10_z08,MRD_x00_y10_z08,None,ON,NORMAL +205,205,1,0,8,0,11,-73.75,101.5,410.44,147.2,20,0.6,7,11,11,10,12,7,12,-1,-1,1,0,11,2100,1,EMI 9939B,MRD_x00_y11_z08,MRD_x00_y11_z08,None,ON,NORMAL +206,206,1,0,8,0,12,-73.75,121.8,410.44,147.2,20,0.6,7,11,12,10,13,7,13,-1,-1,1,0,12,2100,1,EMI 9939B,MRD_x00_y12_z08,MRD_x00_y12_z08,None,ON,NORMAL +207,207,1,0,8,1,0,73.75,-121.8,410.44,147.2,20,0.6,7,11,16,12,1,8,1,-1,-1,1,1,13,2100,1,EMI 9939B,MRD_x01_y00_z08,MRD_x01_y00_z08,< HV 1-1-0 is brokenNone,ON,NORMAL +208,208,1,0,8,1,1,73.75,-101.5,410.44,147.2,20,0.6,7,11,17,12,2,8,2,-1,-1,1,1,1,2100,1,EMI 9939B,MRD_x01_y01_z08,MRD_x01_y01_z08,None,ON,NORMAL +209,209,1,0,8,1,2,73.75,-81.2,410.44,147.2,20,0.6,7,11,18,12,3,8,3,-1,-1,1,1,2,2100,1,EMI 9939B,MRD_x01_y02_z08,MRD_x01_y02_z08,None,ON,NORMAL +210,210,1,0,8,1,3,73.75,-60.9,410.44,147.2,20,0.6,7,11,19,12,4,8,4,-1,-1,1,1,3,2100,1,EMI 9939B,MRD_x01_y03_z08,MRD_x01_y03_z08,None,ON,NORMAL +211,211,1,0,8,1,4,73.75,-40.6,410.44,147.2,20,0.6,7,11,20,12,5,8,5,-1,-1,1,1,4,2100,1,EMI 9939B,MRD_x01_y04_z08,MRD_x01_y04_z08,None,ON,NORMAL +212,212,1,0,8,1,5,73.75,-20.3,410.44,147.2,20,0.6,7,11,21,12,6,8,6,-1,-1,1,1,5,2100,1,EMI 9939B,MRD_x01_y05_z08,MRD_x01_y05_z08,None,ON,HOT +213,213,1,0,8,1,6,73.75,0,410.44,147.2,20,0.6,7,11,22,12,7,8,7,-1,-1,1,1,6,2100,1,EMI 9939B,MRD_x01_y06_z08,MRD_x01_y06_z08,None,ON,NORMAL +214,214,1,0,8,1,7,73.75,20.3,410.44,147.2,20,0.6,7,11,23,12,8,8,8,-1,-1,1,1,7,2100,1,EMI 9939B,MRD_x01_y07_z08,MRD_x01_y07_z08,None,ON,NORMAL +215,215,1,0,8,1,8,73.75,40.6,410.44,147.2,20,0.6,7,11,24,12,9,8,9,-1,-1,1,1,8,2100,1,EMI 9939B,MRD_x01_y08_z08,MRD_x01_y08_z08,None,OFF,NORMAL +216,216,1,0,8,1,9,73.75,60.9,410.44,147.2,20,0.6,7,11,25,12,10,8,10,-1,-1,1,1,9,2100,1,EMI 9939B,MRD_x01_y09_z08,MRD_x01_y09_z08,None,ON,NORMAL +217,217,1,0,8,1,10,73.75,81.2,410.44,147.2,20,0.6,7,11,26,12,11,8,11,-1,-1,1,1,10,2100,1,EMI 9939B,MRD_x01_y10_z08,MRD_x01_y10_z08,None,OFF,NORMAL +218,218,1,0,8,1,11,73.75,101.5,410.44,147.2,20,0.6,7,11,27,12,12,8,12,-1,-1,1,1,11,2100,1,EMI 9939B,MRD_x01_y11_z08,MRD_x01_y11_z08,None,OFF,NORMAL +219,219,1,0,8,1,12,73.75,121.8,410.44,147.2,20,0.6,7,11,28,12,13,8,13,-1,-1,1,1,12,2100,1,EMI 9939B,MRD_x01_y12_z08,MRD_x01_y12_z08,None,ON,NORMAL +220,220,1,1,9,0,0,-142.1,-65.25,422.55,20,130.2,0.6,8,14,0,13,1,9,1,2,1,2,0,0,-1500,-1,-9999,MRD_x00_y00_z09,MRD_x00_y00_z09,None,ON,NORMAL +221,221,1,1,9,0,1,-121.8,-65.25,422.55,20,130.2,0.6,8,14,1,13,2,9,2,2,3,2,0,1,-1500,-1,-9999,MRD_x01_y00_z09,MRD_x01_y00_z09,None,ON,NORMAL +222,222,1,1,9,0,2,-101.5,-65.25,422.55,20,130.2,0.6,8,14,2,13,3,9,3,2,5,2,0,2,-1500,-1,-9999,MRD_x02_y00_z09,MRD_x02_y00_z09,None,ON,NORMAL +223,223,1,1,9,0,3,-81.2,-65.25,422.55,20,130.2,0.6,8,14,3,13,4,9,4,2,7,2,0,3,-1500,-1,-9999,MRD_x03_y00_z09,MRD_x03_y00_z09,None,ON,NORMAL +224,224,1,1,9,0,4,-60.9,-65.25,422.55,20,130.2,0.6,8,14,4,13,5,9,5,2,9,2,0,4,-1500,-1,-9999,MRD_x04_y00_z09,MRD_x04_y00_z09,None,OFF,HOT +225,225,1,1,9,0,5,-40.6,-65.25,422.55,20,130.2,0.6,8,14,5,13,6,9,6,2,11,2,0,5,-2000,-1,-9999,MRD_x05_y00_z09,MRD_x05_y00_z09,None,ON,NORMAL +226,226,1,1,9,0,6,-20.3,-65.25,422.55,20,130.2,0.6,8,14,6,13,7,9,7,2,13,2,0,6,-2000,-1,-9999,MRD_x06_y00_z09,MRD_x06_y00_z09,None,ON,NORMAL +227,227,1,1,9,0,7,0,-65.25,422.55,20,130.2,0.6,8,11,31,12,16,9,8,11,1,2,0,7,-2000,-1,-9999,MRD_x07_y00_z09,MRD_x07_y00_z09,Discriminator on rack 8 slot 13 channel 8 has no NIM outputNone,ON,NORMAL +228,228,1,1,9,0,8,20.3,-65.25,422.55,20,130.2,0.6,8,14,8,13,9,9,9,11,2,2,0,8,-2000,-1,-9999,MRD_x08_y00_z09,MRD_x08_y00_z09,None,ON,NORMAL +229,229,1,1,9,0,9,40.6,-65.25,422.55,20,130.2,0.6,8,14,9,13,10,9,10,11,3,2,0,9,-1500,-1,-9999,MRD_x09_y00_z09,MRD_x09_y00_z09,None,ON,NORMAL +230,230,1,1,9,0,10,60.9,-65.25,422.55,20,130.2,0.6,8,14,10,13,11,9,11,11,4,2,0,10,-1500,-1,-9999,MRD_x10_y00_z09,MRD_x10_y00_z09,None,ON,NORMAL +231,231,1,1,9,0,11,81.2,-65.25,422.55,20,130.2,0.6,8,14,11,13,12,9,12,11,5,2,0,11,-1500,-1,-9999,MRD_x11_y00_z09,MRD_x11_y00_z09,None,ON,NORMAL +232,232,1,1,9,0,12,101.5,-65.25,422.55,20,130.2,0.6,8,14,15,13,16,9,13,11,6,2,0,12,-1500,-1,-9999,MRD_x12_y00_z09,MRD_x12_y00_z09,slot 13 on this disc had a very high rate; shifted signal to slot 16None,ON,NORMAL +233,233,1,1,9,0,13,121.8,-65.25,422.55,20,130.2,0.6,8,14,13,13,14,9,14,11,7,2,0,13,-1500,-1,-9999,MRD_x13_y00_z09,MRD_x13_y00_z09,None,ON,NORMAL +234,234,1,1,9,0,14,142.1,-65.25,422.55,20,130.2,0.6,8,14,14,13,15,9,15,11,8,2,0,14,-1500,-1,-9999,MRD_x14_y00_z09,MRD_x14_y00_z09,None,ON,NORMAL +235,235,1,1,9,1,0,-142.1,65.25,422.55,20,130.2,0.6,8,14,16,15,1,10,1,2,2,2,1,0,-1500,-1,-9999,MRD_x00_y01_z09,MRD_x00_y01_z09,None,ON,NORMAL +236,236,1,1,9,1,1,-121.8,65.25,422.55,20,130.2,0.6,8,14,17,15,2,10,2,2,4,2,1,1,-1500,-1,-9999,MRD_x01_y01_z09,MRD_x01_y01_z09,None,ON,NORMAL +237,237,1,1,9,1,2,-101.5,65.25,422.55,20,130.2,0.6,8,14,18,15,3,10,3,2,6,2,1,2,-1300,-1,-9999,MRD_x02_y01_z09,MRD_x02_y01_z09,None,ON,NORMAL +238,238,1,1,9,1,3,-81.2,65.25,422.55,20,130.2,0.6,8,14,19,15,4,10,4,2,8,2,1,3,-1500,-1,-9999,MRD_x03_y01_z09,MRD_x03_y01_z09,None,ON,NORMAL +239,239,1,1,9,1,4,-60.9,65.25,422.55,20,130.2,0.6,8,14,20,15,5,10,5,2,10,2,1,4,-1500,-1,-9999,MRD_x04_y01_z09,MRD_x04_y01_z09,None,ON,NORMAL +240,240,1,1,9,1,5,-40.6,65.25,422.55,20,130.2,0.6,8,14,21,15,6,10,6,2,12,2,1,5,-1500,-1,-9999,MRD_x05_y01_z09,MRD_x05_y01_z09,None,ON,NORMAL +241,241,1,1,9,1,6,-20.3,65.25,422.55,20,130.2,0.6,8,14,22,15,7,10,7,2,14,2,1,6,-1500,-1,-9999,MRD_x06_y01_z09,MRD_x06_y01_z09,None,ON,NORMAL +242,242,1,1,9,1,7,0,65.25,422.55,20,130.2,0.6,8,14,23,15,8,10,8,12,18,2,1,7,-1500,-1,-9999,MRD_x07_y01_z09,MRD_x07_y01_z09,None,ON,NORMAL +243,243,1,1,9,1,8,20.3,65.25,422.55,20,130.2,0.6,8,14,24,15,9,10,9,12,20,2,1,8,-1500,-1,-9999,MRD_x08_y01_z09,MRD_x08_y01_z09,None,ON,NORMAL +244,244,1,1,9,1,9,40.6,65.25,422.55,20,130.2,0.6,8,14,25,15,10,10,10,12,22,2,1,9,-1500,-1,-9999,MRD_x09_y01_z09,MRD_x09_y01_z09,None,ON,NORMAL +245,245,1,1,9,1,10,60.9,65.25,422.55,20,130.2,0.6,8,14,26,15,11,10,11,12,24,2,1,10,-1500,-1,-9999,MRD_x10_y01_z09,MRD_x10_y01_z09,None,ON,NORMAL +246,246,1,1,9,1,11,81.2,65.25,422.55,20,130.2,0.6,8,14,27,15,12,10,12,12,26,2,1,11,-1500,-1,-9999,MRD_x11_y01_z09,MRD_x11_y01_z09,None,ON,NORMAL +247,247,1,1,9,1,12,101.5,65.25,422.55,20,130.2,0.6,8,14,28,15,13,10,13,12,28,2,1,12,-1500,-1,-9999,MRD_x12_y01_z09,MRD_x12_y01_z09,None,ON,NORMAL +248,248,1,1,9,1,13,121.8,65.25,422.55,20,130.2,0.6,8,14,29,15,14,10,14,12,30,2,1,13,-1500,-1,-9999,MRD_x13_y01_z09,MRD_x13_y01_z09,None,ON,NORMAL +249,249,1,1,9,1,14,142.1,65.25,422.55,20,130.2,0.6,8,14,30,15,15,10,15,12,32,2,1,14,-1500,-1,-9999,MRD_x14_y01_z09,MRD_x14_y01_z09,None,ON,HOT +250,250,1,0,10,0,0,-73.75,-121.8,434.66,147.2,20,0.6,7,19,0,18,1,9,1,-1,-1,2,2,0,-2100,-1,-9999,MRD_x00_y00_z10,MRD_x00_y00_z10,None,ON,NORMAL +251,251,1,0,10,0,1,-73.75,-101.5,434.66,147.2,20,0.6,7,19,1,18,2,9,2,-1,-1,2,2,1,-1600,-1,-9999,MRD_x00_y01_z10,MRD_x00_y01_z10,None,OFF,NORMAL +252,252,1,0,10,0,2,-73.75,-81.2,434.66,147.2,20,0.6,7,19,2,18,3,9,3,-1,-1,2,2,2,-2100,-1,-9999,MRD_x00_y02_z10,MRD_x00_y02_z10,None,ON,NORMAL +253,253,1,0,10,0,3,-73.75,-60.9,434.66,147.2,20,0.6,7,19,3,18,4,9,4,-1,-1,2,2,3,-2100,-1,-9999,MRD_x00_y03_z10,MRD_x00_y03_z10,None,ON,NORMAL +254,254,1,0,10,0,4,-73.75,-40.6,434.66,147.2,20,0.6,7,19,4,18,5,9,5,-1,-1,2,2,4,-2100,-1,-9999,MRD_x00_y04_z10,MRD_x00_y04_z10,None,OFF,NORMAL +255,255,1,0,10,0,5,-73.75,-20.3,434.66,147.2,20,0.6,7,19,5,18,6,9,6,-1,-1,2,2,5,-2100,-1,-9999,MRD_x00_y05_z10,MRD_x00_y05_z10,None,ON,NORMAL +256,256,1,0,10,0,6,-73.75,0,434.66,147.2,20,0.6,7,19,6,18,7,9,7,-1,-1,2,2,6,-2100,-1,-9999,MRD_x00_y06_z10,MRD_x00_y06_z10,None,ON,NORMAL +257,257,1,0,10,0,7,-73.75,20.3,434.66,147.2,20,0.6,7,19,7,18,8,9,8,-1,-1,2,2,7,-2100,-1,-9999,MRD_x00_y07_z10,MRD_x00_y07_z10,None,ON,NORMAL +258,258,1,0,10,0,8,-73.75,40.6,434.66,147.2,20,0.6,7,19,8,18,9,9,9,-1,-1,2,2,8,-1900,-1,-9999,MRD_x00_y08_z10,MRD_x00_y08_z10,None,ON,NORMAL +259,259,1,0,10,0,9,-73.75,60.9,434.66,147.2,20,0.6,7,19,9,18,10,9,10,-1,-1,2,2,9,-2100,-1,-9999,MRD_x00_y09_z10,MRD_x00_y09_z10,None,ON,NORMAL +260,260,1,0,10,0,10,-73.75,81.2,434.66,147.2,20,0.6,7,19,10,18,11,9,11,-1,-1,2,2,10,-2100,-1,-9999,MRD_x00_y10_z10,MRD_x00_y10_z10,None,OFF,NORMAL +261,261,1,0,10,0,11,-73.75,101.5,434.66,147.2,20,0.6,7,19,11,18,12,9,12,-1,-1,2,2,11,-2100,-1,-9999,MRD_x00_y11_z10,MRD_x00_y11_z10,Crate 2 card 3 ch11 is broken: nothing connectedNone,ON,NORMAL +262,262,1,0,10,0,12,-73.75,121.8,434.66,147.2,20,0.6,7,19,12,18,13,9,13,-1,-1,2,2,12,-2100,-1,-9999,MRD_x00_y12_z10,MRD_x00_y12_z10,None,ON,NORMAL +263,263,1,0,10,1,0,73.75,-121.8,434.66,147.2,20,0.6,7,19,16,20,1,10,1,-1,-1,2,3,0,-2100,-1,-9999,MRD_x01_y00_z10,MRD_x01_y00_z10,None,ON,HOT +264,264,1,0,10,1,1,73.75,-101.5,434.66,147.2,20,0.6,7,19,17,20,2,10,2,-1,-1,2,3,1,-1900,-1,-9999,MRD_x01_y01_z10,MRD_x01_y01_z10,None,ON,NORMAL +265,265,1,0,10,1,2,73.75,-81.2,434.66,147.2,20,0.6,7,19,18,20,3,10,3,-1,-1,2,3,2,-1600,-1,-9999,MRD_x01_y02_z10,MRD_x01_y02_z10,None,ON,NORMAL +266,266,1,0,10,1,3,73.75,-60.9,434.66,147.2,20,0.6,7,19,19,20,4,10,4,-1,-1,2,3,3,-1800,-1,-9999,MRD_x01_y03_z10,MRD_x01_y03_z10,None,ON,NORMAL +267,267,1,0,10,1,4,73.75,-40.6,434.66,147.2,20,0.6,7,19,20,20,5,10,5,-1,-1,2,3,4,-1800,-1,-9999,MRD_x01_y04_z10,MRD_x01_y04_z10,None,ON,NORMAL +268,268,1,0,10,1,5,73.75,-20.3,434.66,147.2,20,0.6,7,19,21,20,6,10,6,-1,-1,2,3,5,-2100,-1,-9999,MRD_x01_y05_z10,MRD_x01_y05_z10,None,ON,NORMAL +269,269,1,0,10,1,6,73.75,0,434.66,147.2,20,0.6,7,19,22,20,7,10,7,-1,-1,2,3,6,-2100,-1,-9999,MRD_x01_y06_z10,MRD_x01_y06_z10,None,ON,NORMAL +270,270,1,0,10,1,7,73.75,20.3,434.66,147.2,20,0.6,7,19,23,20,8,10,8,-1,-1,2,3,7,-1600,-1,-9999,MRD_x01_y07_z10,MRD_x01_y07_z10,None,ON,NORMAL +271,271,1,0,10,1,8,73.75,40.6,434.66,147.2,20,0.6,7,19,24,20,9,10,9,-1,-1,2,3,8,-2100,-1,-9999,MRD_x01_y08_z10,MRD_x01_y08_z10,None,OFF,HOT +272,272,1,0,10,1,9,73.75,60.9,434.66,147.2,20,0.6,7,19,25,20,10,10,10,-1,-1,2,3,9,-2100,-1,-9999,MRD_x01_y09_z10,MRD_x01_y09_z10,None,ON,HOT +273,273,1,0,10,1,10,73.75,81.2,434.66,147.2,20,0.6,7,19,26,20,11,10,11,-1,-1,2,3,10,-1600,-1,-9999,MRD_x01_y10_z10,MRD_x01_y10_z10,None,ON,NORMAL +274,274,1,0,10,1,11,73.75,101.5,434.66,147.2,20,0.6,7,19,27,20,12,10,12,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y11_z10,MRD_x01_y11_z10,None,ON,NORMAL +275,275,1,0,10,1,12,73.75,121.8,434.66,147.2,20,0.6,7,19,28,20,13,10,13,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y12_z10,MRD_x01_y12_z10,None,OFF,HOT +276,276,1,1,11,0,0,-142.1,-65.25,446.77,20,130.2,0.6,8,17,0,16,1,11,1,1,19,2,4,0,-1500,-1,-9999,MRD_x00_y00_z11,MRD_x00_y00_z11,None,ON,HOT +277,277,1,1,11,0,1,-121.8,-65.25,446.77,20,130.2,0.6,8,17,1,16,2,11,2,1,21,2,4,1,-1500,-1,-9999,MRD_x01_y00_z11,MRD_x01_y00_z11,None,ON,NORMAL +278,278,1,1,11,0,2,-101.5,-65.25,446.77,20,130.2,0.6,8,17,2,16,3,11,3,1,23,2,4,2,-1500,-1,-9999,MRD_x02_y00_z11,MRD_x02_y00_z11,None,ON,NORMAL +279,279,1,1,11,0,3,-81.2,-65.25,446.77,20,130.2,0.6,8,17,3,16,4,11,4,1,25,2,4,3,-1300,-1,-9999,MRD_x03_y00_z11,MRD_x03_y00_z11,None,ON,NORMAL +280,280,1,1,11,0,4,-60.9,-65.25,446.77,20,130.2,0.6,8,17,4,16,5,11,5,1,27,2,4,4,-1500,-1,-9999,MRD_x04_y00_z11,MRD_x04_y00_z11,None,ON,NORMAL +281,281,1,1,11,0,5,-40.6,-65.25,446.77,20,130.2,0.6,8,17,5,16,6,11,6,1,29,2,4,5,-1500,-1,-9999,MRD_x05_y00_z11,MRD_x05_y00_z11,None,ON,NORMAL +282,282,1,1,11,0,6,-20.3,-65.25,446.77,20,130.2,0.6,8,17,6,16,7,11,7,1,31,2,4,6,-1500,-1,-9999,MRD_x06_y00_z11,MRD_x06_y00_z11,None,ON,NORMAL +283,283,1,1,11,0,7,0,-65.25,446.77,20,130.2,0.6,8,17,7,16,8,11,8,12,17,2,4,7,-1500,-1,-9999,MRD_x07_y00_z11,MRD_x07_y00_z11,None,ON,HOT +284,284,1,1,11,0,8,20.3,-65.25,446.77,20,130.2,0.6,8,17,8,16,9,11,9,12,19,2,4,8,-1500,-1,-9999,MRD_x08_y00_z11,MRD_x08_y00_z11,None,ON,NORMAL +285,285,1,1,11,0,9,40.6,-65.25,446.77,20,130.2,0.6,8,17,9,16,10,11,10,12,21,2,4,9,-1300,-1,-9999,MRD_x09_y00_z11,MRD_x09_y00_z11,None,ON,NORMAL +286,286,1,1,11,0,10,60.9,-65.25,446.77,20,130.2,0.6,8,17,10,16,11,11,11,12,23,2,4,10,-1500,-1,-9999,MRD_x10_y00_z11,MRD_x10_y00_z11,None,ON,NORMAL +287,287,1,1,11,0,11,81.2,-65.25,446.77,20,130.2,0.6,8,17,11,16,12,11,12,12,25,2,4,11,-1500,-1,-9999,MRD_x11_y00_z11,MRD_x11_y00_z11,None,ON,NORMAL +288,288,1,1,11,0,12,101.5,-65.25,446.77,20,130.2,0.6,8,17,12,16,13,11,13,12,27,2,4,12,-1500,-1,-9999,MRD_x12_y00_z11,MRD_x12_y00_z11,None,ON,NORMAL +289,289,1,1,11,0,13,121.8,-65.25,446.77,20,130.2,0.6,8,17,13,16,14,11,14,12,29,2,4,13,-1500,-1,-9999,MRD_x13_y00_z11,MRD_x13_y00_z11,None,ON,NORMAL +290,290,1,1,11,0,14,142.1,-65.25,446.77,20,130.2,0.6,8,17,14,16,15,11,15,12,31,2,4,14,-1500,-1,-9999,MRD_x14_y00_z11,MRD_x14_y00_z11,None,ON,NORMAL +291,291,1,1,11,1,0,-142.1,65.25,446.77,20,130.2,0.6,8,17,16,18,1,12,1,1,20,2,5,0,-1500,-1,-9999,MRD_x00_y01_z11,MRD_x00_y01_z11,None,ON,NORMAL +292,292,1,1,11,1,1,-121.8,65.25,446.77,20,130.2,0.6,8,17,17,18,2,12,2,1,22,2,5,1,-1500,-1,-9999,MRD_x01_y01_z11,MRD_x01_y01_z11,None,ON,NORMAL +293,293,1,1,11,1,2,-101.5,65.25,446.77,20,130.2,0.6,8,17,18,18,3,12,3,1,24,2,5,3,-1500,-1,-9999,MRD_x02_y01_z11,MRD_x02_y01_z11,None,ON,NORMAL +294,294,1,1,11,1,3,-81.2,65.25,446.77,20,130.2,0.6,8,17,19,18,4,12,4,1,26,2,5,4,-1500,-1,-9999,MRD_x03_y01_z11,MRD_x03_y01_z11,None,ON,NORMAL +295,295,1,1,11,1,4,-60.9,65.25,446.77,20,130.2,0.6,8,17,20,18,5,12,5,1,28,2,5,5,-1500,-1,-9999,MRD_x04_y01_z11,MRD_x04_y01_z11,None,ON,NORMAL +296,296,1,1,11,1,5,-40.6,65.25,446.77,20,130.2,0.6,8,17,21,18,6,12,6,1,30,2,5,6,-1500,-1,-9999,MRD_x05_y01_z11,MRD_x05_y01_z11,None,ON,NORMAL +297,297,1,1,11,1,6,-20.3,65.25,446.77,20,130.2,0.6,8,17,22,18,7,12,7,1,32,2,5,7,-1500,-1,-9999,MRD_x06_y01_z11,MRD_x06_y01_z11,None,ON,NORMAL +298,298,1,1,11,1,7,0,65.25,446.77,20,130.2,0.6,8,17,23,18,8,12,8,10,1,2,5,8,-1500,-1,-9999,MRD_x07_y01_z11,MRD_x07_y01_z11,None,ON,NORMAL +299,299,1,1,11,1,8,20.3,65.25,446.77,20,130.2,0.6,8,17,24,18,9,12,9,10,2,2,5,9,-1500,-1,-9999,MRD_x08_y01_z11,MRD_x08_y01_z11,None,ON,NORMAL +300,300,1,1,11,1,9,40.6,65.25,446.77,20,130.2,0.6,8,17,25,18,10,12,10,10,3,2,5,10,-1300,-1,-9999,MRD_x09_y01_z11,MRD_x09_y01_z11,None,ON,NORMAL +301,301,1,1,11,1,10,60.9,65.25,446.77,20,130.2,0.6,8,17,26,18,11,12,11,10,4,2,5,11,-1300,-1,-9999,MRD_x10_y01_z11,MRD_x10_y01_z11,None,ON,NORMAL +302,302,1,1,11,1,11,81.2,65.25,446.77,20,130.2,0.6,8,17,27,18,12,12,12,10,5,2,5,12,-1300,-1,-9999,MRD_x11_y01_z11,MRD_x11_y01_z11,None,ON,NORMAL +303,303,1,1,11,1,12,101.5,65.25,446.77,20,130.2,0.6,8,17,28,18,13,12,13,10,6,2,5,13,-1300,-1,-9999,MRD_x12_y01_z11,MRD_x12_y01_z11,None,ON,NORMAL +304,304,1,1,11,1,13,121.8,65.25,446.77,20,130.2,0.6,8,17,29,18,14,12,14,10,7,2,5,14,-1500,-1,-9999,MRD_x13_y01_z11,MRD_x13_y01_z11,None,ON,NORMAL +305,305,1,1,11,1,14,142.1,65.25,446.77,20,130.2,0.6,8,17,30,18,15,12,15,10,8,2,5,14,-1500,-1,-9999,MRD_x14_y01_z11,MRD_x14_y01_z11,None,ON,NORMAL +306,306,1,0,12,0,0,-73.75,-121.8,458.88,147.2,20,0.6,7,22,0,21,1,11,1,-1,-1,2,6,0,-2100,-1,-9999,MRD_x00_y00_z12,MRD_x00_y00_z12,None,ON,NORMAL +307,307,1,0,12,0,1,-73.75,-101.5,458.88,147.2,20,0.6,7,22,1,21,2,11,2,-1,-1,2,6,1,-2100,-1,-9999,MRD_x00_y01_z12,MRD_x00_y01_z12,None,ON,NORMAL +308,308,1,0,12,0,2,-73.75,-81.2,458.88,147.2,20,0.6,7,22,2,21,3,11,3,-1,-1,2,6,2,-2100,-1,-9999,MRD_x00_y02_z12,MRD_x00_y02_z12,None,ON,NORMAL +309,309,1,0,12,0,3,-73.75,-60.9,458.88,147.2,20,0.6,7,22,3,21,4,11,4,-1,-1,2,6,3,-2100,-1,-9999,MRD_x00_y03_z12,MRD_x00_y03_z12,None,ON,NORMAL +310,310,1,0,12,0,4,-73.75,-40.6,458.88,147.2,20,0.6,7,22,4,21,5,11,5,-1,-1,2,6,4,-1900,-1,-9999,MRD_x00_y04_z12,MRD_x00_y04_z12,None,ON,NORMAL +311,311,1,0,12,0,5,-73.75,-20.3,458.88,147.2,20,0.6,7,22,5,21,6,11,6,-1,-1,2,6,5,-2100,-1,-9999,MRD_x00_y05_z12,MRD_x00_y05_z12,None,ON,NORMAL +312,312,1,0,12,0,6,-73.75,0,458.88,147.2,20,0.6,7,22,6,21,7,11,7,-1,-1,2,6,6,-1900,-1,-9999,MRD_x00_y06_z12,MRD_x00_y06_z12,None,ON,NORMAL +313,313,1,0,12,0,7,-73.75,20.3,458.88,147.2,20,0.6,7,22,7,21,8,11,8,-1,-1,2,6,7,-2100,-1,-9999,MRD_x00_y07_z12,MRD_x00_y07_z12,None,ON,NORMAL +314,314,1,0,12,0,8,-73.75,40.6,458.88,147.2,20,0.6,7,22,8,21,9,11,9,-1,-1,2,6,8,-2100,-1,-9999,MRD_x00_y08_z12,MRD_x00_y08_z12,None,ON,NORMAL +315,315,1,0,12,0,9,-73.75,60.9,458.88,147.2,20,0.6,7,22,9,21,10,11,10,-1,-1,2,6,9,-2100,-1,-9999,MRD_x00_y09_z12,MRD_x00_y09_z12,None,ON,NORMAL +316,316,1,0,12,0,10,-73.75,81.2,458.88,147.2,20,0.6,7,22,10,21,11,11,11,-1,-1,2,6,10,-2100,-1,-9999,MRD_x00_y10_z12,MRD_x00_y10_z12,None,ON,NORMAL +317,317,1,0,12,0,11,-73.75,101.5,458.88,147.2,20,0.6,7,22,11,21,12,11,12,-1,-1,2,6,11,-2100,-1,-9999,MRD_x00_y11_z12,MRD_x00_y11_z12,None,ON,NORMAL +318,318,1,0,12,0,12,-73.75,121.8,458.88,147.2,20,0.6,7,22,12,21,13,11,13,-1,-1,2,6,12,-2100,-1,-9999,MRD_x00_y12_z12,MRD_x00_y12_z12,None,ON,NORMAL +319,319,1,0,12,1,0,73.75,-121.8,458.88,147.2,20,0.6,7,22,16,23,1,12,1,-1,-1,2,7,0,-2100,-1,-9999,MRD_x01_y00_z12,MRD_x01_y00_z12,None,OFF,NORMAL +320,320,1,0,12,1,1,73.75,-101.5,458.88,147.2,20,0.6,7,22,17,23,2,12,2,-1,-1,2,7,1,-2100,-1,-9999,MRD_x01_y01_z12,MRD_x01_y01_z12,None,ON,NORMAL +321,321,1,0,12,1,2,73.75,-81.2,458.88,147.2,20,0.6,7,22,18,23,3,12,3,-1,-1,2,7,2,-2100,-1,-9999,MRD_x01_y02_z12,MRD_x01_y02_z12,None,ON,NORMAL +322,322,1,0,12,1,3,73.75,-60.9,458.88,147.2,20,0.6,7,22,19,23,4,12,4,-1,-1,2,7,3,-2100,-1,-9999,MRD_x01_y03_z12,MRD_x01_y03_z12,None,ON,NORMAL +323,323,1,0,12,1,4,73.75,-40.6,458.88,147.2,20,0.6,7,22,20,23,5,12,5,-1,-1,2,7,4,-2100,-1,-9999,MRD_x01_y04_z12,MRD_x01_y04_z12,None,ON,NORMAL +324,324,1,0,12,1,5,73.75,-20.3,458.88,147.2,20,0.6,7,22,21,23,6,12,6,-1,-1,2,7,5,-2100,-1,-9999,MRD_x01_y05_z12,MRD_x01_y05_z12,None,ON,NORMAL +325,325,1,0,12,1,6,73.75,0,458.88,147.2,20,0.6,7,22,22,23,7,12,7,-1,-1,2,7,6,-2100,-1,-9999,MRD_x01_y06_z12,MRD_x01_y06_z12,None,ON,NORMAL +326,326,1,0,12,1,7,73.75,20.3,458.88,147.2,20,0.6,7,22,23,23,8,12,8,-1,-1,2,7,7,-2100,-1,-9999,MRD_x01_y07_z12,MRD_x01_y07_z12,None,ON,NORMAL +327,327,1,0,12,1,8,73.75,40.6,458.88,147.2,20,0.6,7,22,24,23,9,12,9,-1,-1,2,7,8,-2100,-1,-9999,MRD_x01_y08_z12,MRD_x01_y08_z12,None,ON,NORMAL +328,328,1,0,12,1,9,73.75,60.9,458.88,147.2,20,0.6,7,22,25,23,10,12,10,-1,-1,2,7,9,-2100,-1,-9999,MRD_x01_y09_z12,MRD_x01_y09_z12,None,ON,NORMAL +329,329,1,0,12,1,10,73.75,81.2,458.88,147.2,20,0.6,7,22,26,23,11,12,11,-1,-1,2,7,10,-2100,-1,-9999,MRD_x01_y10_z12,MRD_x01_y10_z12,None,ON,NORMAL +330,330,1,0,12,1,11,73.75,101.5,458.88,147.2,20,0.6,7,22,27,23,12,12,12,-1,-1,2,7,11,-2100,-1,-9999,MRD_x01_y11_z12,MRD_x01_y11_z12,None,ON,NORMAL +331,331,1,0,12,1,12,73.75,121.8,458.88,147.2,20,0.6,7,22,28,23,13,12,13,-1,-1,2,7,12,-2100,-1,-9999,MRD_x01_y12_z12,MRD_x01_y12_z12,None,ON,NORMAL +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/FullMRDGeometry_04_2025_thru_07_2025_Runs_R5445_thru_R5714.csv b/configfiles/LoadGeometry/FullMRDGeometry_04_2025_thru_07_2025_Runs_R5445_thru_R5714.csv new file mode 100644 index 000000000..3ace0c991 --- /dev/null +++ b/configfiles/LoadGeometry/FullMRDGeometry_04_2025_thru_07_2025_Runs_R5445_thru_R5714.csv @@ -0,0 +1,342 @@ +#,,0=FMV,0=horizontal,,0=left,from left to right,,,,,,,,,,,,,,#NAME?,#NAME?,,,,,,,,,,, +#,,1=MRD,1=vertical,,1=right,from bottom to top,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,0=bottom,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,1=top,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,channel_num,detector_system,orientation,layer,side,num,x_center,y_center,z_center,x_width,y_width,z_width,rack,TDC_slot,TDC_channel,discrim_slot,discrim_ch,patch_panel_row,patch_panel_col,amp_slot,amp_channel,hv_crate,hv_slot,hv_channel,nominal_HV,polarity,PMT_type,cable_label,paddle_label,notes,detector_status,noise +########################################,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,-198.699875,5.08,320,30.5,2,8,2,0,1,1,1,1,-1,-1,2,14,0,-1871,-1,EMI9815,MRD_x00_y00_z00,4SW,None,ON,NORMAL +1,1,0,0,0,0,1,0,-167.999875,5.08,320,30.5,2,8,2,1,1,2,1,2,-1,-1,2,14,1,-1838,-1,EMI9815,MRD_x00_y01_z00,U39,None,ON,NORMAL +2,2,0,0,0,0,2,0,-137.299875,5.08,320,30.5,2,8,2,2,1,3,1,3,-1,-1,2,14,2,-1793,-1,EMI9815,MRD_x00_y02_z00,U58 (or U38; bad writing),None,ON,NORMAL +3,3,0,0,0,0,3,0,-106.599875,5.08,320,30.5,2,8,2,3,1,4,1,4,-1,-1,2,14,3,-1806,-1,EMI9815,MRD_x00_y03_z00,U29,None,ON,NORMAL +4,4,0,0,0,0,4,0,-75.899875,5.08,320,30.5,2,8,2,4,1,5,1,5,-1,-1,2,14,4,-1865,-1,EMI9815,MRD_x00_y04_z00,14SW,None,ON,NORMAL +5,5,0,0,0,0,5,0,-45.199875,5.08,320,30.5,2,8,2,5,1,6,1,6,-1,-1,2,14,5,-1823,-1,EMI9815,MRD_x00_y05_z00,Unknown4,None,ON,NORMAL +6,6,0,0,0,0,6,0,-14.499875,5.08,320,30.5,2,8,2,6,1,7,1,7,-1,-1,2,14,6,-1798,-1,EMI9815,MRD_x00_y06_z00,U17,None,ON,NORMAL +7,7,0,0,0,0,7,0,16.200125,5.08,320,30.5,2,8,2,7,1,8,1,8,-1,-1,2,14,7,-1823,-1,EMI9815,MRD_x00_y07_z00,11SE,None,ON,NORMAL +8,8,0,0,0,0,8,0,46.900125,5.08,320,30.5,2,8,2,8,1,9,1,9,-1,-1,2,14,8,-1871,-1,EMI9815,MRD_x00_y08_z00,18SE,None,ON,NORMAL +9,9,0,0,0,0,9,0,77.600125,5.08,320,30.5,2,8,2,9,1,10,1,10,-1,-1,2,14,9,-1836,-1,EMI9815,MRD_x00_y09_z00,21SW,None,ON,NORMAL +10,10,0,0,0,0,10,0,108.300125,5.08,320,30.5,2,8,2,10,1,11,1,11,-1,-1,2,14,10,-1814,-1,EMI9815,MRD_x00_y10_z00,3SE,None,ON,NORMAL +11,11,0,0,0,0,11,0,139.000125,5.08,320,30.5,2,8,2,11,1,12,1,12,-1,-1,2,14,11,-1781,-1,EMI9815,MRD_x00_y11_z00,24SE,None,ON,NORMAL +12,12,0,0,0,0,12,0,169.700125,5.08,320,30.5,2,8,2,12,1,13,1,13,-1,-1,2,14,12,-1816,-1,EMI9815,MRD_x00_y12_z00,U25,None,ON,NORMAL +13,13,0,0,0,1,0,0,-198.064875,7.28,320,30.5,2,8,2,16,3,1,2,1,-1,-1,2,15,0,-1805,-1,EMI9815,MRD_x01_y00_z00,28SE,None,ON,NORMAL +14,14,0,0,0,1,1,0,-167.364875,7.28,320,30.5,2,8,2,17,3,2,2,2,-1,-1,2,15,1,-1818,-1,EMI9815,MRD_x01_y01_z00,31SE,None,ON,NORMAL +15,15,0,0,0,1,2,0,-136.664875,7.28,320,30.5,2,8,2,18,3,3,2,3,-1,-1,2,15,2,-1860,-1,EMI9815,MRD_x01_y02_z00,8SE,None,ON,NORMAL +16,16,0,0,0,1,3,0,-105.964875,7.28,320,30.5,2,8,2,19,3,4,2,4,-1,-1,2,15,3,-1780,-1,EMI9815,MRD_x01_y03_z00,11SW,None,ON,NORMAL +17,17,0,0,0,1,4,0,-75.264875,7.28,320,30.5,2,8,2,20,3,5,2,5,-1,-1,2,15,4,-1841,-1,EMI9815,MRD_x01_y04_z00,U34,None,ON,NORMAL +18,18,0,0,0,1,5,0,-44.564875,7.28,320,30.5,2,8,2,21,3,6,2,6,-1,-1,2,15,5,-1786,-1,EMI9815,MRD_x01_y05_z010,U36,None,ON,NORMAL +19,19,0,0,0,1,6,0,-13.864875,7.28,320,30.5,2,8,2,22,3,7,2,7,-1,-1,2,15,6,-1864,-1,EMI9815,MRD_x01_y06_z00,U40,None,ON,NORMAL +20,20,0,0,0,1,7,0,16.835125,7.28,320,30.5,2,8,2,23,3,8,2,8,-1,-1,2,15,7,-1858,-1,EMI9815,MRD_x01_y07_z00,Unknown5,None,ON,NORMAL +21,21,0,0,0,1,8,0,47.535125,7.28,320,30.5,2,8,2,24,3,9,2,9,-1,-1,2,15,8,-1876,-1,EMI9815,MRD_x01_y08_z00,27SE,None,ON,NORMAL +22,22,0,0,0,1,9,0,78.235125,7.28,320,30.5,2,8,2,25,3,10,2,10,-1,-1,2,15,9,-1806,-1,EMI9815,MRD_x01_y09_z00,Unknown2,None,ON,NORMAL +23,23,0,0,0,1,10,0,108.935125,7.28,320,30.5,2,8,2,26,3,11,2,11,-1,-1,2,15,10,-1853,-1,EMI9815,MRD_x01_y10_z00,10SW,None,ON,NORMAL +24,24,0,0,0,1,11,0,139.635125,7.28,320,30.5,2,8,2,27,3,12,2,12,-1,-1,2,15,11,-1860,-1,EMI9815,MRD_x01_y11_z00,Bill2,None,ON,NORMAL +25,25,0,0,0,1,12,0,170.335125,7.28,320,30.5,2,8,2,28,3,13,2,13,-1,-1,2,15,12,-1844,-1,EMI9815,MRD_x01_y12_z00,13SE,None,ON,NORMAL +26,26,1,0,2,0,0,-73.75,-121.8,336.38,147.2,20,0.6,7,2,0,1,1,1,1,-1,-1,1,4,0,-2100,-1,-9999,MRD_x00_y00_z02,MRD_x00_y00_z02,None,ON,NORMAL +27,27,1,0,2,0,1,-73.75,-101.5,336.38,147.2,20,0.6,7,2,1,1,2,1,2,-1,-1,1,4,1,-2100,-1,-9999,MRD_x00_y01_z02,MRD_x00_y01_z02,None,ON,NORMAL +28,28,1,0,2,0,2,-73.75,-81.2,336.38,147.2,20,0.6,7,2,2,1,3,1,3,-1,-1,1,4,2,-2100,-1,-9999,MRD_x00_y02_z02,MRD_x00_y02_z02,None,ON,NORMAL +29,29,1,0,2,0,3,-73.75,-60.9,336.38,147.2,20,0.6,7,2,3,1,4,1,4,-1,-1,1,4,3,-2100,-1,-9999,MRD_x00_y03_z02,MRD_x00_y03_z02,None,ON,NORMAL +30,30,1,0,2,0,4,-73.75,-40.6,336.38,147.2,20,0.6,7,2,4,1,5,1,5,-1,-1,1,4,4,-2100,-1,-9999,MRD_x00_y04_z02,MRD_x00_y04_z02,None,ON,NORMAL +31,31,1,0,2,0,5,-73.75,-20.3,336.38,147.2,20,0.6,7,2,5,1,6,1,6,-1,-1,1,4,5,-2100,-1,-9999,MRD_x00_y05_z02,MRD_x00_y05_z02,None,ON,NORMAL +32,32,1,0,2,0,6,-73.75,0,336.38,147.2,20,0.6,7,2,6,1,7,1,7,-1,-1,1,4,6,-2100,-1,-9999,MRD_x00_y06_z02,MRD_x00_y06_z02,None,ON,NORMAL +33,33,1,0,2,0,7,-73.75,20.3,336.38,147.2,20,0.6,7,2,7,1,8,1,8,-1,-1,1,4,7,-2100,-1,-9999,MRD_x00_y07_z02,MRD_x00_y07_z02,None,ON,NORMAL +34,34,1,0,2,0,8,-73.75,40.6,336.38,147.2,20,0.6,7,2,8,1,9,1,9,-1,-1,1,4,8,-1900,-1,-9999,MRD_x00_y08_z02,MRD_x00_y08_z02,None,ON,NORMAL +35,35,1,0,2,0,9,-73.75,60.9,336.38,147.2,20,0.6,7,2,9,1,10,1,10,-1,-1,1,4,10,-1900,-1,-9999,MRD_x00_y09_z02,MRD_x00_y09_z02,None,ON,NORMAL +36,36,1,0,2,0,10,-73.75,81.2,336.38,147.2,20,0.6,7,2,10,1,11,1,11,-1,-1,1,4,11,-2100,-1,-9999,MRD_x00_y10_z02,MRD_x00_y10_z02,None,ON,NORMAL +37,37,1,0,2,0,11,-73.75,101.5,336.38,147.2,20,0.6,7,2,11,1,12,1,12,-1,-1,1,4,12,-2100,-1,-9999,MRD_x00_y11_z02,MRD_x00_y11_z02,None,ON,NORMAL +38,38,1,0,2,0,12,-73.75,121.8,336.38,147.2,20,0.6,7,2,12,1,13,1,13,-1,-1,1,4,13,-1900,-1,-9999,MRD_x00_y12_z02,MRD_x00_y12_z02,None,ON,NORMAL +39,39,1,0,2,1,0,73.75,-121.8,336.38,147.2,20,0.6,7,2,16,3,1,2,1,-1,-1,1,5,0,-2100,-1,-9999,MRD_x01_y00_z02,MRD_x01_y00_z02,None,ON,NORMAL +40,40,1,0,2,1,1,73.75,-101.5,336.38,147.2,20,0.6,7,2,17,3,2,2,2,-1,-1,1,5,1,-2100,-1,-9999,MRD_x01_y01_z02,MRD_x01_y01_z02,None,ON,NORMAL +41,41,1,0,2,1,2,73.75,-81.2,336.38,147.2,20,0.6,7,2,18,3,3,2,3,-1,-1,1,5,2,-1900,-1,-9999,MRD_x01_y02_z02,MRD_x01_y02_z02,None,ON,NORMAL +42,42,1,0,2,1,3,73.75,-60.9,336.38,147.2,20,0.6,7,2,19,3,4,2,4,-1,-1,1,5,3,-1900,-1,-9999,MRD_x01_y03_z02,MRD_x01_y03_z02,None,ON,NORMAL +43,43,1,0,2,1,4,73.75,-40.6,336.38,147.2,20,0.6,7,2,20,3,5,2,5,-1,-1,1,5,4,-2100,-1,-9999,MRD_x01_y04_z02,MRD_x01_y04_z02,None,ON,NORMAL +44,44,1,0,2,1,5,73.75,-20.3,336.38,147.2,20,0.6,7,2,21,3,6,2,6,-1,-1,1,5,5,-2100,-1,-9999,MRD_x01_y05_z02,MRD_x01_y05_z02,None,ON,NORMAL +45,45,1,0,2,1,6,73.75,0,336.38,147.2,20,0.6,7,2,22,3,7,2,7,-1,-1,1,5,6,-1900,-1,-9999,MRD_x01_y06_z02,MRD_x01_y06_z02,None,ON,NORMAL +46,46,1,0,2,1,7,73.75,20.3,336.38,147.2,20,0.6,7,2,23,3,8,2,8,-1,-1,1,5,7,-2100,-1,-9999,MRD_x01_y07_z02,MRD_x01_y07_z02,None,ON,NORMAL +47,47,1,0,2,1,8,73.75,40.6,336.38,147.2,20,0.6,7,2,24,3,9,2,9,-1,-1,1,5,8,-2100,-1,-9999,MRD_x01_y08_z02,MRD_x01_y08_z02,None,ON,NORMAL +48,48,1,0,2,1,9,73.75,60.9,336.38,147.2,20,0.6,7,2,25,3,10,2,10,-1,-1,1,5,9,-2100,-1,-9999,MRD_x01_y09_z02,MRD_x01_y09_z02,None,ON,NORMAL +49,49,1,0,2,1,10,73.75,81.2,336.38,147.2,20,0.6,7,2,26,3,11,2,11,-1,-1,1,5,10,-2100,-1,-9999,MRD_x01_y10_z02,MRD_x01_y10_z02,None,ON,NORMAL +50,50,1,0,2,1,11,73.75,101.5,336.38,147.2,20,0.6,7,2,27,3,12,2,12,-1,-1,1,5,11,-2100,-1,-9999,MRD_x01_y11_z02,MRD_x01_y11_z02,None,ON,NORMAL +51,51,1,0,2,1,12,73.75,121.8,336.38,147.2,20,0.6,7,2,28,3,13,2,13,-1,-1,1,5,12,-1900,-1,-9999,MRD_x01_y12_z02,MRD_x01_y12_z02,None,ON,NORMAL +52,52,1,1,3,0,0,-107.1,-65.25,348.84,15,130.2,1.3,8,5,0,4,1,3,1,-1,-1,1,6,0,-2000,-1,-9999,MRD_x00_y00_z03,MRD_x00_y00_z03,None,OFF,NORMAL +53,53,1,1,3,0,1,-91.8,-65.25,348.84,15,130.2,1.3,8,5,1,4,2,3,2,-1,-1,1,6,1,-2000,-1,-9999,MRD_x01_y00_z03,MRD_x01_y00_z03,None,ON,NORMAL +54,54,1,1,3,0,2,-76.5,-65.25,348.84,15,130.2,1.3,8,5,2,4,3,3,3,-1,-1,1,6,2,-2000,-1,-9999,MRD_x02_y00_z03,MRD_x02_y00_z03,None,ON,NORMAL +55,55,1,1,3,0,3,-61.2,-65.25,348.84,15,130.2,1.3,8,5,3,4,4,3,4,-1,-1,1,6,3,-2000,-1,-9999,MRD_x03_y00_z03,MRD_x03_y00_z03,None,ON,NORMAL +56,56,1,1,3,0,4,-45.9,-65.25,348.84,15,130.2,1.3,8,5,4,4,5,3,5,-1,-1,1,6,4,-2000,-1,-9999,MRD_x04_y00_z03,MRD_x04_y00_z03,None,ON,NORMAL +57,57,1,1,3,0,5,-30.6,-65.25,348.84,15,130.2,1.3,8,5,5,4,6,3,6,-1,-1,1,6,5,-2000,-1,-9999,MRD_x05_y00_z03,MRD_x05_y00_z03,None,ON,NORMAL +58,58,1,1,3,0,6,-15.3,-65.25,348.84,15,130.2,1.3,8,5,6,4,7,3,7,-1,-1,1,6,6,-2000,-1,-9999,MRD_x06_y00_z03,MRD_x06_y00_z03,None,ON,NORMAL +59,59,1,1,3,0,7,0,-65.25,348.84,15,130.2,1.3,8,5,7,4,8,3,8,-1,-1,1,6,7,-2000,-1,-9999,MRD_x07_y00_z03,MRD_x07_y00_z03,None,ON,NORMAL +60,60,1,1,3,0,8,15.3,-65.25,348.84,15,130.2,1.3,8,5,8,4,9,3,9,-1,-1,1,6,8,-2000,-1,-9999,MRD_x08_y00_z03,MRD_x08_y00_z03,None,ON,NORMAL +61,61,1,1,3,0,9,30.6,-65.25,348.84,15,130.2,1.3,8,5,9,4,10,3,10,-1,-1,1,6,9,-2000,-1,-9999,MRD_x09_y00_z03,MRD_x09_y00_z03,None,ON,NORMAL +62,62,1,1,3,0,10,45.9,-65.25,348.84,15,130.2,1.3,8,5,10,4,11,3,11,-1,-1,1,6,10,-2000,-1,-9999,MRD_x10_y00_z03,MRD_x10_y00_z03,None,ON,NORMAL +63,63,1,1,3,0,11,61.2,-65.25,348.84,15,130.2,1.3,8,5,11,4,12,3,12,-1,-1,1,6,11,-2000,-1,-9999,MRD_x11_y00_z03,MRD_x11_y00_z03,None,ON,NORMAL +64,64,1,1,3,0,12,76.5,-65.25,348.84,15,130.2,1.3,8,5,12,4,13,3,13,-1,-1,1,6,12,-2000,-1,-9999,MRD_x12_y00_z03,MRD_x12_y00_z03,None,ON,NORMAL +65,65,1,1,3,0,13,91.8,-65.25,348.84,15,130.2,1.3,8,5,13,4,14,3,14,-1,-1,1,6,13,-2000,-1,-9999,MRD_x13_y00_z03,MRD_x13_y00_z03,None,ON,NORMAL +66,66,1,1,3,0,14,107.1,-65.25,348.84,15,130.2,1.3,8,5,14,4,15,3,15,-1,-1,1,6,14,-1800,-1,-9999,MRD_x14_y00_z03,MRD_x14_y00_z03,None,ON,NORMAL +67,67,1,1,3,1,0,-107.1,65.25,348.84,15,130.2,1.3,8,5,16,6,1,4,1,-1,-1,1,7,0,-2200,-1,-9999,MRD_x00_y01_z03,MRD_x00_y01_z03,None,ON,NORMAL +68,68,1,1,3,1,1,-91.8,65.25,348.84,15,130.2,1.3,8,5,17,6,2,4,2,-1,-1,1,7,1,-2000,-1,-9999,MRD_x01_y01_z03,MRD_x01_y01_z03,None,ON,NORMAL +69,69,1,1,3,1,2,-76.5,65.25,348.84,15,130.2,1.3,8,5,18,6,3,4,3,-1,-1,1,7,2,-2000,-1,-9999,MRD_x02_y01_z03,MRD_x02_y01_z03,None,ON,NORMAL +70,70,1,1,3,1,3,-61.2,65.25,348.84,15,130.2,1.3,8,5,19,6,4,4,4,-1,-1,1,7,3,-2000,-1,-9999,MRD_x03_y01_z03,MRD_x03_y01_z03,None,ON,NORMAL +71,71,1,1,3,1,4,-45.9,65.25,348.84,15,130.2,1.3,8,5,20,6,5,4,5,-1,-1,1,7,4,-2000,-1,-9999,MRD_x04_y01_z03,MRD_x04_y01_z03,None,ON,NORMAL +72,72,1,1,3,1,5,-30.6,65.25,348.84,15,130.2,1.3,8,5,21,6,6,4,6,-1,-1,1,7,5,-2000,-1,-9999,MRD_x05_y01_z03,MRD_x05_y01_z03,None,ON,NORMAL +73,73,1,1,3,1,6,-15.3,65.25,348.84,15,130.2,1.3,8,5,22,6,7,4,7,-1,-1,1,7,6,-2000,-1,-9999,MRD_x06_y01_z03,MRD_x06_y01_z03,None,ON,NORMAL +74,74,1,1,3,1,7,0,65.25,348.84,15,130.2,1.3,8,5,23,6,8,4,8,-1,-1,1,7,7,-2000,-1,-9999,MRD_x07_y01_z03,MRD_x07_y01_z03,None,ON,NORMAL +75,75,1,1,3,1,8,15.3,65.25,348.84,15,130.2,1.3,8,5,24,6,9,4,9,-1,-1,1,7,8,-2000,-1,-9999,MRD_x08_y01_z03,MRD_x08_y01_z03,None,ON,NORMAL +76,76,1,1,3,1,9,30.6,65.25,348.84,15,130.2,1.3,8,5,25,6,10,4,10,-1,-1,1,7,9,-2000,-1,-9999,MRD_x09_y01_z03,MRD_x09_y01_z03,None,ON,NORMAL +77,77,1,1,3,1,10,45.9,65.25,348.84,15,130.2,1.3,8,5,26,6,11,4,11,-1,-1,1,7,10,-2000,-1,-9999,MRD_x10_y01_z03,MRD_x10_y01_z03,Currently using y1 z3 spare cableNone,ON,NORMAL +78,78,1,1,3,1,11,61.2,65.25,348.84,15,130.2,1.3,8,5,27,6,12,4,12,-1,-1,1,7,11,-2000,-1,-9999,MRD_x11_y01_z03,MRD_x11_y01_z03,None,ON,NORMAL +79,79,1,1,3,1,12,76.5,65.25,348.84,15,130.2,1.3,8,5,28,6,13,4,13,-1,-1,1,7,12,-2000,-1,-9999,MRD_x12_y01_z03,MRD_x12_y01_z03,None,ON,NORMAL +80,80,1,1,3,1,13,91.8,65.25,348.84,15,130.2,1.3,8,5,29,6,14,4,14,-1,-1,1,7,13,-2000,-1,-9999,MRD_x13_y01_z03,MRD_x13_y01_z03,None,ON,NORMAL +81,81,1,1,3,1,14,107.1,65.25,348.84,15,130.2,1.3,8,5,30,6,15,4,15,-1,-1,1,7,14,-2000,-1,-9999,MRD_x14_y01_z03,MRD_x14_y01_z03,None,ON,NORMAL +82,82,1,0,4,0,0,-73.75,-121.8,361.3,147.2,20,0.6,7,5,0,4,1,3,1,-1,-1,1,8,0,-2100,-1,-9999,MRD_x00_y00_z04,MRD_x00_y00_z04,None,ON,NORMAL +83,83,1,0,4,0,1,-73.75,-101.5,361.3,147.2,20,0.6,7,5,1,4,2,3,2,-1,-1,1,8,1,-2100,-1,-9999,MRD_x00_y01_z04,MRD_x00_y01_z04,None,ON,NORMAL +84,84,1,0,4,0,2,-73.75,-81.2,361.3,147.2,20,0.6,7,5,2,4,3,3,3,-1,-1,1,8,2,-2100,-1,-9999,MRD_x00_y02_z04,MRD_x00_y02_z04,None,ON,NORMAL +85,85,1,0,4,0,3,-73.75,-60.9,361.3,147.2,20,0.6,7,5,3,4,4,3,4,-1,-1,1,8,3,-2100,-1,-9999,MRD_x00_y03_z04,MRD_x00_y03_z04,None,ON,NORMAL +86,86,1,0,4,0,4,-73.75,-40.6,361.3,147.2,20,0.6,7,5,4,4,5,3,5,-1,-1,1,8,4,-2300,-1,-9999,MRD_x00_y04_z04,MRD_x00_y04_z04,None,ON,NORMAL +87,87,1,0,4,0,5,-73.75,-20.3,361.3,147.2,20,0.6,7,5,5,4,6,3,6,-1,-1,1,8,5,-2100,-1,-9999,MRD_x00_y05_z04,MRD_x00_y05_z04,None,ON,NORMAL +88,88,1,0,4,0,6,-73.75,0,361.3,147.2,20,0.6,7,5,6,4,7,3,7,-1,-1,1,8,6,-2100,-1,-9999,MRD_x00_y06_z04,MRD_x00_y06_z04,None,ON,NORMAL +89,89,1,0,4,0,7,-73.75,20.3,361.3,147.2,20,0.6,7,5,7,4,8,3,8,-1,-1,1,8,7,-2100,-1,-9999,MRD_x00_y07_z04,MRD_x00_y07_z04,None,ON,NORMAL +90,90,1,0,4,0,8,-73.75,40.6,361.3,147.2,20,0.6,7,5,8,4,9,3,9,-1,-1,1,8,8,-2100,-1,-9999,MRD_x00_y08_z04,MRD_x00_y08_z04,None,ON,NORMAL +91,91,1,0,4,0,9,-73.75,60.9,361.3,147.2,20,0.6,7,5,9,4,10,3,10,-1,-1,1,8,9,-2100,-1,-9999,MRD_x00_y09_z04,MRD_x00_y09_z04,None,ON,NORMAL +92,92,1,0,4,0,10,-73.75,81.2,361.3,147.2,20,0.6,7,5,10,4,11,3,11,-1,-1,1,8,10,-2100,-1,-9999,MRD_x00_y10_z04,MRD_x00_y10_z04,None,ON,NORMAL +93,93,1,0,4,0,11,-73.75,101.5,361.3,147.2,20,0.6,7,5,11,4,12,3,12,-1,-1,1,8,11,-2100,-1,-9999,MRD_x00_y11_z04,MRD_x00_y11_z04,None,ON,NORMAL +94,94,1,0,4,0,12,-73.75,121.8,361.3,147.2,20,0.6,7,5,12,4,13,3,13,-1,-1,1,8,12,-2300,-1,-9999,MRD_x00_y12_z04,MRD_x00_y12_z04,None,ON,NORMAL +95,95,1,0,4,1,0,73.75,-121.8,361.3,147.2,20,0.6,7,5,16,6,1,4,1,-1,-1,1,9,0,-2100,-1,-9999,MRD_x01_y00_z04,MRD_x01_y00_z04,None,ON,NORMAL +96,96,1,0,4,1,1,73.75,-101.5,361.3,147.2,20,0.6,7,5,17,6,2,4,2,-1,-1,1,9,1,-2100,-1,-9999,MRD_x01_y01_z04,MRD_x01_y01_z04,None,ON,NORMAL +97,97,1,0,4,1,2,73.75,-81.2,361.3,147.2,20,0.6,7,5,18,6,3,4,3,-1,-1,1,9,2,-2300,-1,-9999,MRD_x01_y02_z04,MRD_x01_y02_z04,None,ON,NORMAL +98,98,1,0,4,1,3,73.75,-60.9,361.3,147.2,20,0.6,7,5,19,6,4,4,4,-1,-1,1,9,3,-2300,-1,-9999,MRD_x01_y03_z04,MRD_x01_y03_z04,None,ON,NORMAL +99,99,1,0,4,1,4,73.75,-40.6,361.3,147.2,20,0.6,7,5,20,6,5,4,5,-1,-1,1,9,4,-2100,-1,-9999,MRD_x01_y04_z04,MRD_x01_y04_z04,None,ON,NORMAL +100,100,1,0,4,1,5,73.75,-20.3,361.3,147.2,20,0.6,7,5,21,6,6,4,6,-1,-1,1,9,5,-2100,-1,-9999,MRD_x01_y05_z04,MRD_x01_y05_z04,None,ON,NORMAL +101,101,1,0,4,1,6,73.75,0,361.3,147.2,20,0.6,7,5,22,6,7,4,7,-1,-1,1,9,6,-2100,-1,-9999,MRD_x01_y06_z04,MRD_x01_y06_z04,None,ON,NORMAL +102,102,1,0,4,1,7,73.75,20.3,361.3,147.2,20,0.6,7,5,23,6,8,4,8,-1,-1,1,9,7,-2100,-1,-9999,MRD_x01_y07_z04,MRD_x01_y07_z04,None,ON,NORMAL +103,103,1,0,4,1,8,73.75,40.6,361.3,147.2,20,0.6,7,5,24,6,9,4,9,-1,-1,1,9,8,-2100,-1,-9999,MRD_x01_y08_z04,MRD_x01_y08_z04,None,ON,NORMAL +104,104,1,0,4,1,9,73.75,60.9,361.3,147.2,20,0.6,7,5,25,6,10,4,10,-1,-1,1,9,9,-2100,-1,-9999,MRD_x01_y09_z04,MRD_x01_y09_z04,None,ON,NORMAL +105,105,1,0,4,1,10,73.75,81.2,361.3,147.2,20,0.6,7,5,26,6,11,4,11,-1,-1,1,9,10,-2100,-1,-9999,MRD_x01_y10_z04,MRD_x01_y10_z04,None,ON,NORMAL +106,106,1,0,4,1,11,73.75,101.5,361.3,147.2,20,0.6,7,5,27,6,12,4,12,-1,-1,1,9,11,-2100,-1,-9999,MRD_x01_y11_z04,MRD_x01_y11_z04,None,ON,NORMAL +107,107,1,0,4,1,12,73.75,121.8,361.3,147.2,20,0.6,7,5,28,6,13,4,13,-1,-1,1,9,12,-2100,-1,-9999,MRD_x01_y12_z04,MRD_x01_y12_z04,None,ON,NORMAL +108,108,1,1,5,0,0,-122.4,-65.25,373.76,15,130.2,1.3,8,8,0,7,1,5,1,-1,-1,1,10,0,-2200,-1,-9999,MRD_x00_y00_z05,MRD_x00_y00_z05,None,ON,NORMAL +109,109,1,1,5,0,1,-107.1,-65.25,373.76,15,130.2,1.3,8,8,1,7,2,5,2,-1,-1,1,10,1,-2200,-1,-9999,MRD_x01_y00_z05,MRD_x01_y00_z05,None,ON,NORMAL +110,110,1,1,5,0,2,-91.8,-65.25,373.76,15,130.2,1.3,8,8,2,7,3,5,3,-1,-1,1,10,2,-2000,-1,-9999,MRD_x02_y00_z05,MRD_x02_y00_z05,None,ON,NORMAL +111,111,1,1,5,0,3,-76.5,-65.25,373.76,15,130.2,1.3,8,8,7,7,8,5,4,-1,-1,1,10,3,-1500,-1,-9999,MRD_x03_y00_z05,MRD_x03_y00_z05,None,ON,NORMAL +112,112,1,1,5,0,4,-61.2,-65.25,373.76,15,130.2,1.3,8,8,3,7,4,5,5,-1,-1,1,10,4,-2000,-1,-9999,MRD_x04_y00_z05,MRD_x04_y00_z05,None,ON,NORMAL +113,113,1,1,5,0,5,-45.9,-65.25,373.76,15,130.2,1.3,8,8,4,7,5,5,6,-1,-1,1,10,5,-2000,-1,-9999,MRD_x05_y00_z05,MRD_x05_y00_z05,None,ON,NORMAL +114,114,1,1,5,0,6,-30.6,-65.25,373.76,15,130.2,1.3,8,8,6,7,7,5,7,-1,-1,1,10,6,-2000,-1,-9999,MRD_x06_y00_z05,MRD_x06_y00_z05,None,ON,NORMAL +115,115,1,1,5,0,7,-15.3,-65.25,373.76,15,130.2,1.3,8,8,5,7,6,5,8,-1,-1,1,10,7,-2000,-1,-9999,MRD_x07_y00_z05,MRD_x07_y00_z05,None,ON,NORMAL +116,116,1,1,5,0,8,0,-65.25,373.76,15,130.2,1.3,8,8,8,7,9,5,9,-1,-1,1,10,8,-2000,-1,-9999,MRD_x08_y00_z05,MRD_x08_y00_z05,None,ON,NORMAL +117,117,1,1,5,0,9,15.3,-65.25,373.76,15,130.2,1.3,8,8,14,7,15,5,10,-1,-1,1,10,9,-2000,-1,-9999,MRD_x09_y00_z05,MRD_x09_y00_z05,None,ON,NORMAL +118,118,1,1,5,0,10,30.6,-65.25,373.76,15,130.2,1.3,8,8,10,7,11,5,11,-1,-1,1,10,10,-2000,-1,-9999,MRD_x10_y00_z05,MRD_x10_y00_z05,None,ON,NORMAL +119,119,1,1,5,0,11,45.9,-65.25,373.76,15,130.2,1.3,8,8,11,7,12,5,12,-1,-1,1,10,11,-2000,-1,-9999,MRD_x11_y00_z05,MRD_x11_y00_z05,None,ON,NORMAL +120,120,1,1,5,0,12,61.2,-65.25,373.76,15,130.2,1.3,8,8,9,7,10,5,13,-1,-1,1,10,12,-2000,-1,-9999,MRD_x12_y00_z05,MRD_x12_y00_z05,Discriminator on slot 7 channel 13 has no NIM outputNone,ON,NORMAL +121,121,1,1,5,0,13,76.5,-65.25,373.76,15,130.2,1.3,8,8,12,7,13,5,14,-1,-1,1,10,13,-2000,-1,-9999,MRD_x13_y00_z05,MRD_x13_y00_z05,None,ON,NORMAL +122,122,1,1,5,0,14,91.8,-65.25,373.76,15,130.2,1.3,8,8,13,7,14,5,15,-1,-1,1,10,14,-2000,-1,-9999,MRD_x14_y00_z05,MRD_x14_y00_z05,None,ON,NORMAL +123,123,1,1,5,0,15,107.1,-65.25,373.76,15,130.2,1.3,8,8,15,7,16,5,16,-1,-1,1,5,14,-1500,-1,-9999,MRD_x15_y00_z05,MRD_x15_y00_z05,None,OFF,NORMAL +124,124,1,1,5,0,16,122.4,-65.25,373.76,15,130.2,1.3,8,17,15,16,16,5,17,-1,-1,1,4,14,-2200,-1,-9999,MRD_x16_y00_z05,MRD_x16_y00_z05,None,OFF,NORMAL +125,125,1,1,5,1,0,-122.4,65.25,373.76,15,130.2,1.3,8,8,16,9,1,6,1,-1,-1,1,11,0,-2000,-1,-9999,MRD_x00_y01_z05,MRD_x00_y01_z05,None,ON,NORMAL +126,126,1,1,5,1,1,-107.1,65.25,373.76,15,130.2,1.3,8,8,17,9,2,6,2,-1,-1,1,11,1,-2000,-1,-9999,MRD_x01_y01_z05,MRD_x01_y01_z05,possible dischargeNone,ON,NORMAL +127,127,1,1,5,1,2,-91.8,65.25,373.76,15,130.2,1.3,8,8,18,9,3,6,3,-1,-1,1,11,2,-2000,-1,-9999,MRD_x02_y01_z05,MRD_x02_y01_z05,None,ON,NORMAL +128,128,1,1,5,1,3,-76.5,65.25,373.76,15,130.2,1.3,8,8,19,9,4,6,4,-1,-1,1,11,3,-2000,-1,-9999,MRD_x03_y01_z05,MRD_x03_y01_z05,None,ON,NORMAL +129,129,1,1,5,1,4,-61.2,65.25,373.76,15,130.2,1.3,8,8,20,9,5,6,5,-1,-1,1,11,4,-1500,-1,-9999,MRD_x04_y01_z05,MRD_x04_y01_z05,None,ON,NORMAL +130,130,1,1,5,1,5,-45.9,65.25,373.76,15,130.2,1.3,8,8,21,9,6,6,6,-1,-1,1,11,5,-2000,-1,-9999,MRD_x05_y01_z05,MRD_x05_y01_z05,None,ON,NORMAL +131,131,1,1,5,1,6,-30.6,65.25,373.76,15,130.2,1.3,8,8,22,9,7,6,7,-1,-1,1,11,6,-2000,-1,-9999,MRD_x06_y01_z05,MRD_x06_y01_z05,None,ON,NORMAL +132,132,1,1,5,1,7,-15.3,65.25,373.76,15,130.2,1.3,8,8,23,9,8,6,8,-1,-1,1,11,7,-2000,-1,-9999,MRD_x07_y01_z05,MRD_x07_y01_z05,None,ON,HOT +133,133,1,1,5,1,8,0,65.25,373.76,15,130.2,1.3,8,8,24,9,9,6,9,-1,-1,1,11,8,-2000,-1,-9999,MRD_x08_y01_z05,MRD_x08_y01_z05,None,OFF,NORMAL +134,134,1,1,5,1,9,15.3,65.25,373.76,15,130.2,1.3,8,8,25,9,10,6,10,-1,-1,1,11,9,-2000,-1,-9999,MRD_x09_y01_z05,MRD_x09_y01_z05,None,ON,NORMAL +135,135,1,1,5,1,10,30.6,65.25,373.76,15,130.2,1.3,8,8,26,9,11,6,11,-1,-1,1,11,10,-2000,-1,-9999,MRD_x10_y01_z05,MRD_x10_y01_z05,None,ON,NORMAL +136,136,1,1,5,1,11,45.9,65.25,373.76,15,130.2,1.3,8,8,27,9,12,6,12,-1,-1,1,11,11,-1800,-1,-9999,MRD_x11_y01_z05,MRD_x11_y01_z05,None,ON,NORMAL +137,137,1,1,5,1,12,61.2,65.25,373.76,15,130.2,1.3,8,8,28,9,13,6,13,-1,-1,1,11,12,-2000,-1,-9999,MRD_x12_y01_z05,MRD_x12_y01_z05,None,ON,NORMAL +138,138,1,1,5,1,13,76.5,65.25,373.76,15,130.2,1.3,8,8,29,9,14,6,14,-1,-1,1,11,13,-2000,-1,-9999,MRD_x13_y01_z05,MRD_x13_y01_z05,None,ON,NORMAL +139,139,1,1,5,1,14,91.8,65.25,373.76,15,130.2,1.3,8,8,30,9,15,6,15,-1,-1,1,11,14,-2000,-1,-9999,MRD_x14_y01_z05,MRD_x14_y01_z05,None,ON,NORMAL +140,140,1,1,5,1,15,107.1,65.25,373.76,15,130.2,1.3,8,8,31,9,16,6,16,-1,-1,1,11,15,-2000,-1,-9999,MRD_x15_y01_z05,MRD_x15_y01_z05,None,OFF,NORMAL +141,141,1,1,5,1,16,122.4,65.25,373.76,15,130.2,1.3,8,14,31,15,16,6,17,-1,-1,1,4,15,-2000,-1,-9999,MRD_x16_y01_z05,MRD_x16_y01_z05,Now uses y0 z5 spare; Rack 8 slot 18 channel 16 has no NIM output,OFF,NORMAL +142,142,1,0,6,0,0,-73.75,-121.8,386.22,147.2,20,0.6,7,8,0,7,1,5,1,-1,-1,1,12,0,-2100,-1,-9999,MRD_x00_y00_z06,MRD_x00_y00_z06,None,ON,NORMAL +143,143,1,0,6,0,1,-73.75,-101.5,386.22,147.2,20,0.6,7,8,1,7,2,5,2,-1,-1,1,12,1,-2100,-1,-9999,MRD_x00_y01_z06,MRD_x00_y01_z06,None,ON,NORMAL +144,144,1,0,6,0,2,-73.75,-81.2,386.22,147.2,20,0.6,7,8,2,7,3,5,3,-1,-1,1,12,2,-2100,-1,-9999,MRD_x00_y02_z06,MRD_x00_y02_z06,None,ON,NORMAL +145,145,1,0,6,0,3,-73.75,-60.9,386.22,147.2,20,0.6,7,8,3,7,4,5,4,-1,-1,1,12,3,-2100,-1,-9999,MRD_x00_y03_z06,MRD_x00_y03_z06,None,ON,NORMAL +146,146,1,0,6,0,4,-73.75,-40.6,386.22,147.2,20,0.6,7,8,4,7,5,5,5,-1,-1,1,12,4,-2100,-1,-9999,MRD_x00_y04_z06,MRD_x00_y04_z06,None,ON,NORMAL +147,147,1,0,6,0,5,-73.75,-20.3,386.22,147.2,20,0.6,7,8,5,7,6,5,6,-1,-1,1,12,5,-2100,-1,-9999,MRD_x00_y05_z06,MRD_x00_y05_z06,None,ON,NORMAL +148,148,1,0,6,0,6,-73.75,0,386.22,147.2,20,0.6,7,8,6,7,7,5,7,-1,-1,1,12,6,-2100,-1,-9999,MRD_x00_y06_z06,MRD_x00_y06_z06,None,ON,NORMAL +149,149,1,0,6,0,7,-73.75,20.3,386.22,147.2,20,0.6,7,8,7,7,8,5,8,-1,-1,1,12,7,-2100,-1,-9999,MRD_x00_y07_z06,MRD_x00_y07_z06,None,ON,NORMAL +150,150,1,0,6,0,8,-73.75,40.6,386.22,147.2,20,0.6,7,8,8,7,9,5,9,-1,-1,1,12,8,-2100,-1,-9999,MRD_x00_y08_z06,MRD_x00_y08_z06,None,ON,NORMAL +151,151,1,0,6,0,9,-73.75,60.9,386.22,147.2,20,0.6,7,8,9,7,10,5,10,-1,-1,1,12,9,-2100,-1,-9999,MRD_x00_y09_z06,MRD_x00_y09_z06,None,ON,NORMAL +152,152,1,0,6,0,10,-73.75,81.2,386.22,147.2,20,0.6,7,8,10,7,11,5,11,-1,-1,1,12,10,-2100,-1,-9999,MRD_x00_y10_z06,MRD_x00_y10_z06,None,ON,NORMAL +153,153,1,0,6,0,11,-73.75,101.5,386.22,147.2,20,0.6,7,8,11,7,12,5,12,-1,-1,1,12,11,-2100,-1,-9999,MRD_x00_y11_z06,MRD_x00_y11_z06,None,ON,NORMAL +154,154,1,0,6,0,12,-73.75,121.8,386.22,147.2,20,0.6,7,8,12,7,13,5,13,-1,-1,1,12,12,-2100,-1,-9999,MRD_x00_y12_z06,MRD_x00_y12_z06,None,ON,NORMAL +155,155,1,0,6,1,0,73.75,-121.8,386.22,147.2,20,0.6,7,8,16,9,1,6,1,-1,-1,1,13,0,-1900,-1,-9999,MRD_x01_y00_z06,MRD_x01_y00_z06,None,ON,NORMAL +156,156,1,0,6,1,1,73.75,-101.5,386.22,147.2,20,0.6,7,8,17,9,2,6,2,-1,-1,1,13,1,-2100,-1,-9999,MRD_x01_y01_z06,MRD_x01_y01_z06,None,ON,NORMAL +157,157,1,0,6,1,2,73.75,-81.2,386.22,147.2,20,0.6,7,8,18,9,3,6,3,-1,-1,1,13,2,-2100,-1,-9999,MRD_x01_y02_z06,MRD_x01_y02_z06,None,ON,NORMAL +158,158,1,0,6,1,3,73.75,-60.9,386.22,147.2,20,0.6,7,8,19,9,4,6,4,-1,-1,1,13,3,-2100,-1,-9999,MRD_x01_y03_z06,MRD_x01_y03_z06,None,ON,NORMAL +159,159,1,0,6,1,4,73.75,-40.6,386.22,147.2,20,0.6,7,8,20,9,5,6,5,-1,-1,1,13,4,-2100,-1,-9999,MRD_x01_y04_z06,MRD_x01_y04_z06,None,ON,NORMAL +160,160,1,0,6,1,5,73.75,-20.3,386.22,147.2,20,0.6,7,8,21,9,6,6,6,-1,-1,1,13,5,-2100,-1,-9999,MRD_x01_y05_z06,MRD_x01_y05_z06,None,ON,NORMAL +161,161,1,0,6,1,6,73.75,0,386.22,147.2,20,0.6,7,8,22,9,7,6,7,-1,-1,1,13,6,-2100,-1,-9999,MRD_x01_y06_z06,MRD_x01_y06_z06,None,ON,NORMAL +162,162,1,0,6,1,7,73.75,20.3,386.22,147.2,20,0.6,7,8,23,9,8,6,8,-1,-1,1,13,7,-2100,-1,-9999,MRD_x01_y07_z06,MRD_x01_y07_z06,None,ON,NORMAL +163,163,1,0,6,1,8,73.75,40.6,386.22,147.2,20,0.6,7,8,24,9,9,6,9,-1,-1,1,13,8,-2100,-1,-9999,MRD_x01_y08_z06,MRD_x01_y08_z06,None,ON,NORMAL +164,164,1,0,6,1,9,73.75,60.9,386.22,147.2,20,0.6,7,8,25,9,10,6,10,-1,-1,1,13,9,-1900,-1,-9999,MRD_x01_y09_z06,MRD_x01_y09_z06,None,ON,NORMAL +165,165,1,0,6,1,10,73.75,81.2,386.22,147.2,20,0.6,7,8,26,9,11,6,11,-1,-1,1,13,10,-2100,-1,-9999,MRD_x01_y10_z06,MRD_x01_y10_z06,None,ON,NORMAL +166,166,1,0,6,1,11,73.75,101.5,386.22,147.2,20,0.6,7,8,27,9,12,6,12,-1,-1,1,13,11,-2100,-1,-9999,MRD_x01_y11_z06,MRD_x01_y11_z06,None,ON,NORMAL +167,167,1,0,6,1,12,73.75,121.8,386.22,147.2,20,0.6,7,8,28,9,13,6,13,-1,-1,1,13,12,-2100,-1,-9999,MRD_x01_y12_z06,MRD_x01_y12_z06,None,ON,NORMAL +168,168,1,1,7,0,1,-121.8,-65.25,398.33,20,130.2,0.6,8,11,1,10,2,7,2,1,3,1,14,1,-1500,-1,-9999,MRD_x01_y00_z07,MRD_x01_y00_z07,None,ON,NORMAL +169,169,1,1,7,0,2,-101.5,-65.25,398.33,20,130.2,0.6,8,11,2,10,3,7,3,1,5,1,14,2,-1500,-1,-9999,MRD_x02_y00_z07,MRD_x02_y00_z07,None,ON,NORMAL +170,170,1,1,7,0,3,-81.2,-65.25,398.33,20,130.2,0.6,8,11,3,10,4,7,4,1,7,1,14,3,-1500,-1,-9999,MRD_x03_y00_z07,MRD_x03_y00_z07,None,ON,NORMAL +171,171,1,1,7,0,4,-60.9,-65.25,398.33,20,130.2,0.6,8,11,4,10,5,7,5,1,9,1,14,4,-1500,-1,-9999,MRD_x04_y00_z07,MRD_x04_y00_z07,None,ON,NORMAL +172,172,1,1,7,0,5,-40.6,-65.25,398.33,20,130.2,0.6,8,11,5,10,6,7,6,1,11,1,14,5,-1500,-1,-9999,MRD_x05_y00_z07,MRD_x05_y00_z07,None,ON,NORMAL +173,173,1,1,7,0,6,-20.3,-65.25,398.33,20,130.2,0.6,8,11,6,10,7,7,7,1,13,1,14,6,-1500,-1,-9999,MRD_x06_y00_z07,MRD_x06_y00_z07,None,ON,NORMAL +174,174,1,1,7,0,7,0,-65.25,398.33,20,130.2,0.6,8,11,7,10,8,7,8,12,2,1,14,7,-1500,-1,-9999,MRD_x07_y00_z07,MRD_x07_y00_z07,None,ON,NORMAL +175,175,1,1,7,0,8,20.3,-65.25,398.33,20,130.2,0.6,8,11,8,10,9,7,9,12,4,1,14,8,-1500,-1,-9999,MRD_x08_y00_z07,MRD_x08_y00_z07,None,ON,NORMAL +176,176,1,1,7,0,9,40.6,-65.25,398.33,20,130.2,0.6,8,11,9,10,10,7,10,12,6,1,14,9,-1500,-1,-9999,MRD_x09_y00_z07,MRD_x09_y00_z07,None,ON,NORMAL +177,177,1,1,7,0,10,60.9,-65.25,398.33,20,130.2,0.6,8,11,10,10,11,7,11,12,8,1,14,10,-1500,-1,-9999,MRD_x10_y00_z07,MRD_x10_y00_z07,None,ON,HOT +178,178,1,1,7,0,11,81.2,-65.25,398.33,20,130.2,0.6,8,11,11,10,12,7,12,12,10,1,14,11,-1500,-1,-9999,MRD_x11_y00_z07,MRD_x11_y00_z07,None,ON,NORMAL +179,179,1,1,7,0,12,101.5,-65.25,398.33,20,130.2,0.6,8,11,12,10,13,7,13,12,12,1,14,12,-1500,-1,-9999,MRD_x12_y00_z07,MRD_x12_y00_z07,None,ON,NORMAL +180,180,1,1,7,0,13,121.8,-65.25,398.33,20,130.2,0.6,8,11,13,10,14,7,14,12,14,1,14,13,-1500,-1,-9999,MRD_x13_y00_z07,MRD_x13_y00_z07,None,ON,NORMAL +181,181,1,1,7,1,1,-121.8,65.25,398.33,20,130.2,0.6,8,11,17,12,2,8,2,1,4,1,15,1,-1500,-1,-9999,MRD_x01_y01_z07,MRD_x01_y01_z07,None,ON,NORMAL +182,182,1,1,7,1,2,-101.5,65.25,398.33,20,130.2,0.6,8,11,18,12,3,8,3,1,6,1,15,2,-1500,-1,-9999,MRD_x02_y01_z07,MRD_x02_y01_z07,None,ON,NORMAL +183,183,1,1,7,1,3,-81.2,65.25,398.33,20,130.2,0.6,8,11,19,12,4,8,4,1,8,1,15,3,-1300,-1,-9999,MRD_x03_y01_z07,MRD_x03_y01_z07,None,ON,HOT +184,184,1,1,7,1,4,-60.9,65.25,398.33,20,130.2,0.6,8,11,20,12,5,8,5,1,10,1,15,4,-1500,-1,-9999,MRD_x04_y01_z07,MRD_x04_y01_z07,None,ON,NORMAL +185,185,1,1,7,1,5,-40.6,65.25,398.33,20,130.2,0.6,8,11,21,12,6,8,6,1,12,1,15,5,-2000,-1,-9999,MRD_x05_y01_z07,MRD_x05_y01_z07,None,ON,NORMAL +186,186,1,1,7,1,6,-20.3,65.25,398.33,20,130.2,0.6,8,11,22,12,7,8,7,1,14,1,15,6,-2000,-1,-9999,MRD_x06_y01_z07,MRD_x06_y01_z07,None,ON,NORMAL +187,187,1,1,7,1,7,0,65.25,398.33,20,130.2,0.6,8,11,23,12,8,8,8,12,1,1,15,7,-2000,-1,-9999,MRD_x07_y01_z07,MRD_x07_y01_z07,None,ON,NORMAL +188,188,1,1,7,1,8,20.3,65.25,398.33,20,130.2,0.6,8,11,24,12,9,8,9,12,3,1,15,8,-2000,-1,-9999,MRD_x08_y01_z07,MRD_x08_y01_z07,None,ON,NORMAL +189,189,1,1,7,1,9,40.6,65.25,398.33,20,130.2,0.6,8,11,25,12,10,8,10,12,5,1,15,9,-1500,-1,-9999,MRD_x09_y01_z07,MRD_x09_y01_z07,None,ON,NORMAL +190,190,1,1,7,1,10,60.9,65.25,398.33,20,130.2,0.6,8,11,26,12,11,8,11,12,7,1,15,10,-1500,-1,-9999,MRD_x10_y01_z07,MRD_x10_y01_z07,None,ON,NORMAL +191,191,1,1,7,1,11,81.2,65.25,398.33,20,130.2,0.6,8,11,27,12,12,8,12,12,9,1,15,11,-1500,-1,-9999,MRD_x11_y01_z07,MRD_x11_y01_z07,None,ON,HOT +192,192,1,1,7,1,12,101.5,65.25,398.33,20,130.2,0.6,8,11,28,12,13,8,13,12,11,1,15,12,-1500,-1,-9999,MRD_x12_y01_z07,MRD_x12_y01_z07,None,ON,NORMAL +193,193,1,1,7,1,13,121.8,65.25,398.33,20,130.2,0.6,8,11,29,12,14,8,14,12,13,1,15,13,-1500,-1,-9999,MRD_x13_y01_z07,MRD_x13_y01_z07,None,ON,NORMAL +194,194,1,0,8,0,0,-73.75,-121.8,410.44,147.2,20,0.6,7,11,0,10,1,7,1,-1,-1,1,0,0,2100,1,EMI 9939B,MRD_x00_y00_z08,MRD_x00_y00_z08,None,ON,NORMAL +195,195,1,0,8,0,1,-73.75,-101.5,410.44,147.2,20,0.6,7,11,1,10,2,7,2,-1,-1,1,0,1,2100,1,EMI 9939B,MRD_x00_y01_z08,MRD_x00_y01_z08,None,OFF,NORMAL +196,196,1,0,8,0,2,-73.75,-81.2,410.44,147.2,20,0.6,7,11,2,10,3,7,3,-1,-1,1,0,2,2100,1,EMI 9939B,MRD_x00_y02_z08,MRD_x00_y02_z08,None,ON,NORMAL +197,197,1,0,8,0,3,-73.75,-60.9,410.44,147.2,20,0.6,7,11,3,10,4,7,4,-1,-1,1,0,3,2100,1,EMI 9939B,MRD_x00_y03_z08,MRD_x00_y03_z08,None,ON,NORMAL +198,198,1,0,8,0,4,-73.75,-40.6,410.44,147.2,20,0.6,7,11,4,10,5,7,5,-1,-1,1,0,4,2100,1,EMI 9939B,MRD_x00_y04_z08,MRD_x00_y04_z08,None,ON,NORMAL +199,199,1,0,8,0,5,-73.75,-20.3,410.44,147.2,20,0.6,7,11,5,10,6,7,6,-1,-1,1,0,5,2100,1,EMI 9939B,MRD_x00_y05_z08,MRD_x00_y05_z08,None,ON,NORMAL +200,200,1,0,8,0,6,-73.75,0,410.44,147.2,20,0.6,7,11,6,10,7,7,7,-1,-1,1,0,6,2100,1,EMI 9939B,MRD_x00_y06_z08,MRD_x00_y06_z08,None,ON,NORMAL +201,201,1,0,8,0,7,-73.75,20.3,410.44,147.2,20,0.6,7,11,7,10,8,7,8,-1,-1,1,0,7,2100,1,EMI 9939B,MRD_x00_y07_z08,MRD_x00_y07_z08,None,ON,NORMAL +202,202,1,0,8,0,8,-73.75,40.6,410.44,147.2,20,0.6,7,11,8,10,9,7,9,-1,-1,1,0,8,2100,1,EMI 9939B,MRD_x00_y08_z08,MRD_x00_y08_z08,None,ON,NORMAL +203,203,1,0,8,0,9,-73.75,60.9,410.44,147.2,20,0.6,7,11,9,10,10,7,10,-1,-1,1,0,9,2100,1,EMI 9939B,MRD_x00_y09_z08,MRD_x00_y09_z08,None,ON,NORMAL +204,204,1,0,8,0,10,-73.75,81.2,410.44,147.2,20,0.6,7,11,10,10,11,7,11,-1,-1,1,0,10,2100,1,EMI 9939B,MRD_x00_y10_z08,MRD_x00_y10_z08,None,ON,NORMAL +205,205,1,0,8,0,11,-73.75,101.5,410.44,147.2,20,0.6,7,11,11,10,12,7,12,-1,-1,1,0,11,2100,1,EMI 9939B,MRD_x00_y11_z08,MRD_x00_y11_z08,None,ON,NORMAL +206,206,1,0,8,0,12,-73.75,121.8,410.44,147.2,20,0.6,7,11,12,10,13,7,13,-1,-1,1,0,12,2100,1,EMI 9939B,MRD_x00_y12_z08,MRD_x00_y12_z08,None,OFF,NORMAL +207,207,1,0,8,1,0,73.75,-121.8,410.44,147.2,20,0.6,7,11,16,12,1,8,1,-1,-1,1,1,13,2100,1,EMI 9939B,MRD_x01_y00_z08,MRD_x01_y00_z08,< HV 1-1-0 is brokenNone,ON,NORMAL +208,208,1,0,8,1,1,73.75,-101.5,410.44,147.2,20,0.6,7,11,17,12,2,8,2,-1,-1,1,1,1,2100,1,EMI 9939B,MRD_x01_y01_z08,MRD_x01_y01_z08,None,ON,NORMAL +209,209,1,0,8,1,2,73.75,-81.2,410.44,147.2,20,0.6,7,11,18,12,3,8,3,-1,-1,1,1,2,2100,1,EMI 9939B,MRD_x01_y02_z08,MRD_x01_y02_z08,None,ON,NORMAL +210,210,1,0,8,1,3,73.75,-60.9,410.44,147.2,20,0.6,7,11,19,12,4,8,4,-1,-1,1,1,3,2100,1,EMI 9939B,MRD_x01_y03_z08,MRD_x01_y03_z08,None,ON,NORMAL +211,211,1,0,8,1,4,73.75,-40.6,410.44,147.2,20,0.6,7,11,20,12,5,8,5,-1,-1,1,1,4,2100,1,EMI 9939B,MRD_x01_y04_z08,MRD_x01_y04_z08,None,ON,NORMAL +212,212,1,0,8,1,5,73.75,-20.3,410.44,147.2,20,0.6,7,11,21,12,6,8,6,-1,-1,1,1,5,2100,1,EMI 9939B,MRD_x01_y05_z08,MRD_x01_y05_z08,None,ON,NORMAL +213,213,1,0,8,1,6,73.75,0,410.44,147.2,20,0.6,7,11,22,12,7,8,7,-1,-1,1,1,6,2100,1,EMI 9939B,MRD_x01_y06_z08,MRD_x01_y06_z08,None,ON,HOT +214,214,1,0,8,1,7,73.75,20.3,410.44,147.2,20,0.6,7,11,23,12,8,8,8,-1,-1,1,1,7,2100,1,EMI 9939B,MRD_x01_y07_z08,MRD_x01_y07_z08,None,ON,NORMAL +215,215,1,0,8,1,8,73.75,40.6,410.44,147.2,20,0.6,7,11,24,12,9,8,9,-1,-1,1,1,8,2100,1,EMI 9939B,MRD_x01_y08_z08,MRD_x01_y08_z08,None,OFF,NORMAL +216,216,1,0,8,1,9,73.75,60.9,410.44,147.2,20,0.6,7,11,25,12,10,8,10,-1,-1,1,1,9,2100,1,EMI 9939B,MRD_x01_y09_z08,MRD_x01_y09_z08,None,ON,NORMAL +217,217,1,0,8,1,10,73.75,81.2,410.44,147.2,20,0.6,7,11,26,12,11,8,11,-1,-1,1,1,10,2100,1,EMI 9939B,MRD_x01_y10_z08,MRD_x01_y10_z08,None,OFF,NORMAL +218,218,1,0,8,1,11,73.75,101.5,410.44,147.2,20,0.6,7,11,27,12,12,8,12,-1,-1,1,1,11,2100,1,EMI 9939B,MRD_x01_y11_z08,MRD_x01_y11_z08,None,OFF,NORMAL +219,219,1,0,8,1,12,73.75,121.8,410.44,147.2,20,0.6,7,11,28,12,13,8,13,-1,-1,1,1,12,2100,1,EMI 9939B,MRD_x01_y12_z08,MRD_x01_y12_z08,None,ON,NORMAL +220,220,1,1,9,0,0,-142.1,-65.25,422.55,20,130.2,0.6,8,14,0,13,1,9,1,2,1,2,0,0,-1500,-1,-9999,MRD_x00_y00_z09,MRD_x00_y00_z09,None,OFF,NORMAL +221,221,1,1,9,0,1,-121.8,-65.25,422.55,20,130.2,0.6,8,14,1,13,2,9,2,2,3,2,0,1,-1500,-1,-9999,MRD_x01_y00_z09,MRD_x01_y00_z09,None,ON,NORMAL +222,222,1,1,9,0,2,-101.5,-65.25,422.55,20,130.2,0.6,8,14,2,13,3,9,3,2,5,2,0,2,-1500,-1,-9999,MRD_x02_y00_z09,MRD_x02_y00_z09,None,ON,NORMAL +223,223,1,1,9,0,3,-81.2,-65.25,422.55,20,130.2,0.6,8,14,3,13,4,9,4,2,7,2,0,3,-1500,-1,-9999,MRD_x03_y00_z09,MRD_x03_y00_z09,None,ON,NORMAL +224,224,1,1,9,0,4,-60.9,-65.25,422.55,20,130.2,0.6,8,14,4,13,5,9,5,2,9,2,0,4,-1500,-1,-9999,MRD_x04_y00_z09,MRD_x04_y00_z09,None,OFF,NORMAL +225,225,1,1,9,0,5,-40.6,-65.25,422.55,20,130.2,0.6,8,14,5,13,6,9,6,2,11,2,0,5,-2000,-1,-9999,MRD_x05_y00_z09,MRD_x05_y00_z09,None,ON,NORMAL +226,226,1,1,9,0,6,-20.3,-65.25,422.55,20,130.2,0.6,8,14,6,13,7,9,7,2,13,2,0,6,-2000,-1,-9999,MRD_x06_y00_z09,MRD_x06_y00_z09,None,ON,NORMAL +227,227,1,1,9,0,7,0,-65.25,422.55,20,130.2,0.6,8,11,31,12,16,9,8,11,1,2,0,7,-2000,-1,-9999,MRD_x07_y00_z09,MRD_x07_y00_z09,Discriminator on rack 8 slot 13 channel 8 has no NIM outputNone,ON,NORMAL +228,228,1,1,9,0,8,20.3,-65.25,422.55,20,130.2,0.6,8,14,8,13,9,9,9,11,2,2,0,8,-2000,-1,-9999,MRD_x08_y00_z09,MRD_x08_y00_z09,None,ON,NORMAL +229,229,1,1,9,0,9,40.6,-65.25,422.55,20,130.2,0.6,8,14,9,13,10,9,10,11,3,2,0,9,-1500,-1,-9999,MRD_x09_y00_z09,MRD_x09_y00_z09,None,ON,NORMAL +230,230,1,1,9,0,10,60.9,-65.25,422.55,20,130.2,0.6,8,14,10,13,11,9,11,11,4,2,0,10,-1500,-1,-9999,MRD_x10_y00_z09,MRD_x10_y00_z09,None,ON,NORMAL +231,231,1,1,9,0,11,81.2,-65.25,422.55,20,130.2,0.6,8,14,11,13,12,9,12,11,5,2,0,11,-1500,-1,-9999,MRD_x11_y00_z09,MRD_x11_y00_z09,None,ON,NORMAL +232,232,1,1,9,0,12,101.5,-65.25,422.55,20,130.2,0.6,8,14,15,13,16,9,13,11,6,2,0,12,-1500,-1,-9999,MRD_x12_y00_z09,MRD_x12_y00_z09,slot 13 on this disc had a very high rate; shifted signal to slot 16None,ON,NORMAL +233,233,1,1,9,0,13,121.8,-65.25,422.55,20,130.2,0.6,8,14,13,13,14,9,14,11,7,2,0,13,-1500,-1,-9999,MRD_x13_y00_z09,MRD_x13_y00_z09,None,ON,NORMAL +234,234,1,1,9,0,14,142.1,-65.25,422.55,20,130.2,0.6,8,14,14,13,15,9,15,11,8,2,0,14,-1500,-1,-9999,MRD_x14_y00_z09,MRD_x14_y00_z09,None,ON,NORMAL +235,235,1,1,9,1,0,-142.1,65.25,422.55,20,130.2,0.6,8,14,16,15,1,10,1,2,2,2,1,0,-1500,-1,-9999,MRD_x00_y01_z09,MRD_x00_y01_z09,None,ON,NORMAL +236,236,1,1,9,1,1,-121.8,65.25,422.55,20,130.2,0.6,8,14,17,15,2,10,2,2,4,2,1,1,-1500,-1,-9999,MRD_x01_y01_z09,MRD_x01_y01_z09,None,ON,NORMAL +237,237,1,1,9,1,2,-101.5,65.25,422.55,20,130.2,0.6,8,14,18,15,3,10,3,2,6,2,1,2,-1300,-1,-9999,MRD_x02_y01_z09,MRD_x02_y01_z09,None,ON,NORMAL +238,238,1,1,9,1,3,-81.2,65.25,422.55,20,130.2,0.6,8,14,19,15,4,10,4,2,8,2,1,3,-1500,-1,-9999,MRD_x03_y01_z09,MRD_x03_y01_z09,None,ON,HOT +239,239,1,1,9,1,4,-60.9,65.25,422.55,20,130.2,0.6,8,14,20,15,5,10,5,2,10,2,1,4,-1500,-1,-9999,MRD_x04_y01_z09,MRD_x04_y01_z09,None,ON,NORMAL +240,240,1,1,9,1,5,-40.6,65.25,422.55,20,130.2,0.6,8,14,21,15,6,10,6,2,12,2,1,5,-1500,-1,-9999,MRD_x05_y01_z09,MRD_x05_y01_z09,None,ON,NORMAL +241,241,1,1,9,1,6,-20.3,65.25,422.55,20,130.2,0.6,8,14,22,15,7,10,7,2,14,2,1,6,-1500,-1,-9999,MRD_x06_y01_z09,MRD_x06_y01_z09,None,ON,NORMAL +242,242,1,1,9,1,7,0,65.25,422.55,20,130.2,0.6,8,14,23,15,8,10,8,12,18,2,1,7,-1500,-1,-9999,MRD_x07_y01_z09,MRD_x07_y01_z09,None,ON,NORMAL +243,243,1,1,9,1,8,20.3,65.25,422.55,20,130.2,0.6,8,14,24,15,9,10,9,12,20,2,1,8,-1500,-1,-9999,MRD_x08_y01_z09,MRD_x08_y01_z09,None,ON,NORMAL +244,244,1,1,9,1,9,40.6,65.25,422.55,20,130.2,0.6,8,14,25,15,10,10,10,12,22,2,1,9,-1500,-1,-9999,MRD_x09_y01_z09,MRD_x09_y01_z09,None,ON,NORMAL +245,245,1,1,9,1,10,60.9,65.25,422.55,20,130.2,0.6,8,14,26,15,11,10,11,12,24,2,1,10,-1500,-1,-9999,MRD_x10_y01_z09,MRD_x10_y01_z09,None,ON,NORMAL +246,246,1,1,9,1,11,81.2,65.25,422.55,20,130.2,0.6,8,14,27,15,12,10,12,12,26,2,1,11,-1500,-1,-9999,MRD_x11_y01_z09,MRD_x11_y01_z09,None,ON,NORMAL +247,247,1,1,9,1,12,101.5,65.25,422.55,20,130.2,0.6,8,14,28,15,13,10,13,12,28,2,1,12,-1500,-1,-9999,MRD_x12_y01_z09,MRD_x12_y01_z09,None,ON,NORMAL +248,248,1,1,9,1,13,121.8,65.25,422.55,20,130.2,0.6,8,14,29,15,14,10,14,12,30,2,1,13,-1500,-1,-9999,MRD_x13_y01_z09,MRD_x13_y01_z09,None,ON,NORMAL +249,249,1,1,9,1,14,142.1,65.25,422.55,20,130.2,0.6,8,14,30,15,15,10,15,12,32,2,1,14,-1500,-1,-9999,MRD_x14_y01_z09,MRD_x14_y01_z09,None,ON,NORMAL +250,250,1,0,10,0,0,-73.75,-121.8,434.66,147.2,20,0.6,7,19,0,18,1,9,1,-1,-1,2,2,0,-2100,-1,-9999,MRD_x00_y00_z10,MRD_x00_y00_z10,None,ON,NORMAL +251,251,1,0,10,0,1,-73.75,-101.5,434.66,147.2,20,0.6,7,19,1,18,2,9,2,-1,-1,2,2,1,-1600,-1,-9999,MRD_x00_y01_z10,MRD_x00_y01_z10,None,OFF,NORMAL +252,252,1,0,10,0,2,-73.75,-81.2,434.66,147.2,20,0.6,7,19,2,18,3,9,3,-1,-1,2,2,2,-2100,-1,-9999,MRD_x00_y02_z10,MRD_x00_y02_z10,None,ON,NORMAL +253,253,1,0,10,0,3,-73.75,-60.9,434.66,147.2,20,0.6,7,19,3,18,4,9,4,-1,-1,2,2,3,-2100,-1,-9999,MRD_x00_y03_z10,MRD_x00_y03_z10,None,ON,NORMAL +254,254,1,0,10,0,4,-73.75,-40.6,434.66,147.2,20,0.6,7,19,4,18,5,9,5,-1,-1,2,2,4,-2100,-1,-9999,MRD_x00_y04_z10,MRD_x00_y04_z10,None,OFF,NORMAL +255,255,1,0,10,0,5,-73.75,-20.3,434.66,147.2,20,0.6,7,19,5,18,6,9,6,-1,-1,2,2,5,-2100,-1,-9999,MRD_x00_y05_z10,MRD_x00_y05_z10,None,ON,NORMAL +256,256,1,0,10,0,6,-73.75,0,434.66,147.2,20,0.6,7,19,6,18,7,9,7,-1,-1,2,2,6,-2100,-1,-9999,MRD_x00_y06_z10,MRD_x00_y06_z10,None,ON,NORMAL +257,257,1,0,10,0,7,-73.75,20.3,434.66,147.2,20,0.6,7,19,7,18,8,9,8,-1,-1,2,2,7,-2100,-1,-9999,MRD_x00_y07_z10,MRD_x00_y07_z10,None,ON,NORMAL +258,258,1,0,10,0,8,-73.75,40.6,434.66,147.2,20,0.6,7,19,8,18,9,9,9,-1,-1,2,2,8,-1900,-1,-9999,MRD_x00_y08_z10,MRD_x00_y08_z10,None,ON,NORMAL +259,259,1,0,10,0,9,-73.75,60.9,434.66,147.2,20,0.6,7,19,9,18,10,9,10,-1,-1,2,2,9,-2100,-1,-9999,MRD_x00_y09_z10,MRD_x00_y09_z10,None,ON,NORMAL +260,260,1,0,10,0,10,-73.75,81.2,434.66,147.2,20,0.6,7,19,10,18,11,9,11,-1,-1,2,2,10,-2100,-1,-9999,MRD_x00_y10_z10,MRD_x00_y10_z10,None,OFF,NORMAL +261,261,1,0,10,0,11,-73.75,101.5,434.66,147.2,20,0.6,7,19,11,18,12,9,12,-1,-1,2,2,11,-2100,-1,-9999,MRD_x00_y11_z10,MRD_x00_y11_z10,Crate 2 card 3 ch11 is broken: nothing connectedNone,ON,NORMAL +262,262,1,0,10,0,12,-73.75,121.8,434.66,147.2,20,0.6,7,19,12,18,13,9,13,-1,-1,2,2,12,-2100,-1,-9999,MRD_x00_y12_z10,MRD_x00_y12_z10,None,ON,NORMAL +263,263,1,0,10,1,0,73.75,-121.8,434.66,147.2,20,0.6,7,19,16,20,1,10,1,-1,-1,2,3,0,-2100,-1,-9999,MRD_x01_y00_z10,MRD_x01_y00_z10,None,ON,NORMAL +264,264,1,0,10,1,1,73.75,-101.5,434.66,147.2,20,0.6,7,19,17,20,2,10,2,-1,-1,2,3,1,-1900,-1,-9999,MRD_x01_y01_z10,MRD_x01_y01_z10,None,ON,NORMAL +265,265,1,0,10,1,2,73.75,-81.2,434.66,147.2,20,0.6,7,19,18,20,3,10,3,-1,-1,2,3,2,-1600,-1,-9999,MRD_x01_y02_z10,MRD_x01_y02_z10,None,ON,NORMAL +266,266,1,0,10,1,3,73.75,-60.9,434.66,147.2,20,0.6,7,19,19,20,4,10,4,-1,-1,2,3,3,-1800,-1,-9999,MRD_x01_y03_z10,MRD_x01_y03_z10,None,ON,NORMAL +267,267,1,0,10,1,4,73.75,-40.6,434.66,147.2,20,0.6,7,19,20,20,5,10,5,-1,-1,2,3,4,-1800,-1,-9999,MRD_x01_y04_z10,MRD_x01_y04_z10,None,ON,NORMAL +268,268,1,0,10,1,5,73.75,-20.3,434.66,147.2,20,0.6,7,19,21,20,6,10,6,-1,-1,2,3,5,-2100,-1,-9999,MRD_x01_y05_z10,MRD_x01_y05_z10,None,ON,NORMAL +269,269,1,0,10,1,6,73.75,0,434.66,147.2,20,0.6,7,19,22,20,7,10,7,-1,-1,2,3,6,-2100,-1,-9999,MRD_x01_y06_z10,MRD_x01_y06_z10,None,ON,NORMAL +270,270,1,0,10,1,7,73.75,20.3,434.66,147.2,20,0.6,7,19,23,20,8,10,8,-1,-1,2,3,7,-1600,-1,-9999,MRD_x01_y07_z10,MRD_x01_y07_z10,None,ON,NORMAL +271,271,1,0,10,1,8,73.75,40.6,434.66,147.2,20,0.6,7,19,24,20,9,10,9,-1,-1,2,3,8,-2100,-1,-9999,MRD_x01_y08_z10,MRD_x01_y08_z10,None,OFF,HOT +272,272,1,0,10,1,9,73.75,60.9,434.66,147.2,20,0.6,7,19,25,20,10,10,10,-1,-1,2,3,9,-2100,-1,-9999,MRD_x01_y09_z10,MRD_x01_y09_z10,None,ON,NORMAL +273,273,1,0,10,1,10,73.75,81.2,434.66,147.2,20,0.6,7,19,26,20,11,10,11,-1,-1,2,3,10,-1600,-1,-9999,MRD_x01_y10_z10,MRD_x01_y10_z10,None,ON,NORMAL +274,274,1,0,10,1,11,73.75,101.5,434.66,147.2,20,0.6,7,19,27,20,12,10,12,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y11_z10,MRD_x01_y11_z10,None,ON,NORMAL +275,275,1,0,10,1,12,73.75,121.8,434.66,147.2,20,0.6,7,19,28,20,13,10,13,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y12_z10,MRD_x01_y12_z10,None,OFF,HOT +276,276,1,1,11,0,0,-142.1,-65.25,446.77,20,130.2,0.6,8,17,0,16,1,11,1,1,19,2,4,0,-1500,-1,-9999,MRD_x00_y00_z11,MRD_x00_y00_z11,None,ON,HOT +277,277,1,1,11,0,1,-121.8,-65.25,446.77,20,130.2,0.6,8,17,1,16,2,11,2,1,21,2,4,1,-1500,-1,-9999,MRD_x01_y00_z11,MRD_x01_y00_z11,None,ON,NORMAL +278,278,1,1,11,0,2,-101.5,-65.25,446.77,20,130.2,0.6,8,17,2,16,3,11,3,1,23,2,4,2,-1500,-1,-9999,MRD_x02_y00_z11,MRD_x02_y00_z11,None,ON,NORMAL +279,279,1,1,11,0,3,-81.2,-65.25,446.77,20,130.2,0.6,8,17,3,16,4,11,4,1,25,2,4,3,-1300,-1,-9999,MRD_x03_y00_z11,MRD_x03_y00_z11,None,ON,NORMAL +280,280,1,1,11,0,4,-60.9,-65.25,446.77,20,130.2,0.6,8,17,4,16,5,11,5,1,27,2,4,4,-1500,-1,-9999,MRD_x04_y00_z11,MRD_x04_y00_z11,None,ON,NORMAL +281,281,1,1,11,0,5,-40.6,-65.25,446.77,20,130.2,0.6,8,17,5,16,6,11,6,1,29,2,4,5,-1500,-1,-9999,MRD_x05_y00_z11,MRD_x05_y00_z11,None,ON,NORMAL +282,282,1,1,11,0,6,-20.3,-65.25,446.77,20,130.2,0.6,8,17,6,16,7,11,7,1,31,2,4,6,-1500,-1,-9999,MRD_x06_y00_z11,MRD_x06_y00_z11,None,ON,NORMAL +283,283,1,1,11,0,7,0,-65.25,446.77,20,130.2,0.6,8,17,7,16,8,11,8,12,17,2,4,7,-1500,-1,-9999,MRD_x07_y00_z11,MRD_x07_y00_z11,None,ON,NORMAL +284,284,1,1,11,0,8,20.3,-65.25,446.77,20,130.2,0.6,8,17,8,16,9,11,9,12,19,2,4,8,-1500,-1,-9999,MRD_x08_y00_z11,MRD_x08_y00_z11,None,ON,NORMAL +285,285,1,1,11,0,9,40.6,-65.25,446.77,20,130.2,0.6,8,17,9,16,10,11,10,12,21,2,4,9,-1300,-1,-9999,MRD_x09_y00_z11,MRD_x09_y00_z11,None,ON,NORMAL +286,286,1,1,11,0,10,60.9,-65.25,446.77,20,130.2,0.6,8,17,10,16,11,11,11,12,23,2,4,10,-1500,-1,-9999,MRD_x10_y00_z11,MRD_x10_y00_z11,None,ON,NORMAL +287,287,1,1,11,0,11,81.2,-65.25,446.77,20,130.2,0.6,8,17,11,16,12,11,12,12,25,2,4,11,-1500,-1,-9999,MRD_x11_y00_z11,MRD_x11_y00_z11,None,ON,NORMAL +288,288,1,1,11,0,12,101.5,-65.25,446.77,20,130.2,0.6,8,17,12,16,13,11,13,12,27,2,4,12,-1500,-1,-9999,MRD_x12_y00_z11,MRD_x12_y00_z11,None,ON,NORMAL +289,289,1,1,11,0,13,121.8,-65.25,446.77,20,130.2,0.6,8,17,13,16,14,11,14,12,29,2,4,13,-1500,-1,-9999,MRD_x13_y00_z11,MRD_x13_y00_z11,None,ON,NORMAL +290,290,1,1,11,0,14,142.1,-65.25,446.77,20,130.2,0.6,8,17,14,16,15,11,15,12,31,2,4,14,-1500,-1,-9999,MRD_x14_y00_z11,MRD_x14_y00_z11,None,ON,NORMAL +291,291,1,1,11,1,0,-142.1,65.25,446.77,20,130.2,0.6,8,17,16,18,1,12,1,1,20,2,5,0,-1500,-1,-9999,MRD_x00_y01_z11,MRD_x00_y01_z11,None,ON,HOT +292,292,1,1,11,1,1,-121.8,65.25,446.77,20,130.2,0.6,8,17,17,18,2,12,2,1,22,2,5,1,-1500,-1,-9999,MRD_x01_y01_z11,MRD_x01_y01_z11,None,ON,HOT +293,293,1,1,11,1,2,-101.5,65.25,446.77,20,130.2,0.6,8,17,18,18,3,12,3,1,24,2,5,3,-1500,-1,-9999,MRD_x02_y01_z11,MRD_x02_y01_z11,None,ON,HOT +294,294,1,1,11,1,3,-81.2,65.25,446.77,20,130.2,0.6,8,17,19,18,4,12,4,1,26,2,5,4,-1500,-1,-9999,MRD_x03_y01_z11,MRD_x03_y01_z11,None,ON,NORMAL +295,295,1,1,11,1,4,-60.9,65.25,446.77,20,130.2,0.6,8,17,20,18,5,12,5,1,28,2,5,5,-1500,-1,-9999,MRD_x04_y01_z11,MRD_x04_y01_z11,None,ON,NORMAL +296,296,1,1,11,1,5,-40.6,65.25,446.77,20,130.2,0.6,8,17,21,18,6,12,6,1,30,2,5,6,-1500,-1,-9999,MRD_x05_y01_z11,MRD_x05_y01_z11,None,ON,NORMAL +297,297,1,1,11,1,6,-20.3,65.25,446.77,20,130.2,0.6,8,17,22,18,7,12,7,1,32,2,5,7,-1500,-1,-9999,MRD_x06_y01_z11,MRD_x06_y01_z11,None,ON,NORMAL +298,298,1,1,11,1,7,0,65.25,446.77,20,130.2,0.6,8,17,23,18,8,12,8,10,1,2,5,8,-1500,-1,-9999,MRD_x07_y01_z11,MRD_x07_y01_z11,None,ON,HOT +299,299,1,1,11,1,8,20.3,65.25,446.77,20,130.2,0.6,8,17,24,18,9,12,9,10,2,2,5,9,-1500,-1,-9999,MRD_x08_y01_z11,MRD_x08_y01_z11,None,ON,NORMAL +300,300,1,1,11,1,9,40.6,65.25,446.77,20,130.2,0.6,8,17,25,18,10,12,10,10,3,2,5,10,-1300,-1,-9999,MRD_x09_y01_z11,MRD_x09_y01_z11,None,ON,HOT +301,301,1,1,11,1,10,60.9,65.25,446.77,20,130.2,0.6,8,17,26,18,11,12,11,10,4,2,5,11,-1300,-1,-9999,MRD_x10_y01_z11,MRD_x10_y01_z11,None,ON,NORMAL +302,302,1,1,11,1,11,81.2,65.25,446.77,20,130.2,0.6,8,17,27,18,12,12,12,10,5,2,5,12,-1300,-1,-9999,MRD_x11_y01_z11,MRD_x11_y01_z11,None,ON,NORMAL +303,303,1,1,11,1,12,101.5,65.25,446.77,20,130.2,0.6,8,17,28,18,13,12,13,10,6,2,5,13,-1300,-1,-9999,MRD_x12_y01_z11,MRD_x12_y01_z11,None,ON,NORMAL +304,304,1,1,11,1,13,121.8,65.25,446.77,20,130.2,0.6,8,17,29,18,14,12,14,10,7,2,5,14,-1500,-1,-9999,MRD_x13_y01_z11,MRD_x13_y01_z11,None,ON,HOT +305,305,1,1,11,1,14,142.1,65.25,446.77,20,130.2,0.6,8,17,30,18,15,12,15,10,8,2,5,14,-1500,-1,-9999,MRD_x14_y01_z11,MRD_x14_y01_z11,None,ON,NORMAL +306,306,1,0,12,0,0,-73.75,-121.8,458.88,147.2,20,0.6,7,22,0,21,1,11,1,-1,-1,2,6,0,-2100,-1,-9999,MRD_x00_y00_z12,MRD_x00_y00_z12,None,ON,NORMAL +307,307,1,0,12,0,1,-73.75,-101.5,458.88,147.2,20,0.6,7,22,1,21,2,11,2,-1,-1,2,6,1,-2100,-1,-9999,MRD_x00_y01_z12,MRD_x00_y01_z12,None,ON,NORMAL +308,308,1,0,12,0,2,-73.75,-81.2,458.88,147.2,20,0.6,7,22,2,21,3,11,3,-1,-1,2,6,2,-2100,-1,-9999,MRD_x00_y02_z12,MRD_x00_y02_z12,None,ON,NORMAL +309,309,1,0,12,0,3,-73.75,-60.9,458.88,147.2,20,0.6,7,22,3,21,4,11,4,-1,-1,2,6,3,-2100,-1,-9999,MRD_x00_y03_z12,MRD_x00_y03_z12,None,ON,NORMAL +310,310,1,0,12,0,4,-73.75,-40.6,458.88,147.2,20,0.6,7,22,4,21,5,11,5,-1,-1,2,6,4,-1900,-1,-9999,MRD_x00_y04_z12,MRD_x00_y04_z12,None,ON,NORMAL +311,311,1,0,12,0,5,-73.75,-20.3,458.88,147.2,20,0.6,7,22,5,21,6,11,6,-1,-1,2,6,5,-2100,-1,-9999,MRD_x00_y05_z12,MRD_x00_y05_z12,None,ON,NORMAL +312,312,1,0,12,0,6,-73.75,0,458.88,147.2,20,0.6,7,22,6,21,7,11,7,-1,-1,2,6,6,-1900,-1,-9999,MRD_x00_y06_z12,MRD_x00_y06_z12,None,ON,NORMAL +313,313,1,0,12,0,7,-73.75,20.3,458.88,147.2,20,0.6,7,22,7,21,8,11,8,-1,-1,2,6,7,-2100,-1,-9999,MRD_x00_y07_z12,MRD_x00_y07_z12,None,ON,NORMAL +314,314,1,0,12,0,8,-73.75,40.6,458.88,147.2,20,0.6,7,22,8,21,9,11,9,-1,-1,2,6,8,-2100,-1,-9999,MRD_x00_y08_z12,MRD_x00_y08_z12,None,ON,NORMAL +315,315,1,0,12,0,9,-73.75,60.9,458.88,147.2,20,0.6,7,22,9,21,10,11,10,-1,-1,2,6,9,-2100,-1,-9999,MRD_x00_y09_z12,MRD_x00_y09_z12,None,ON,NORMAL +316,316,1,0,12,0,10,-73.75,81.2,458.88,147.2,20,0.6,7,22,10,21,11,11,11,-1,-1,2,6,10,-2100,-1,-9999,MRD_x00_y10_z12,MRD_x00_y10_z12,None,ON,NORMAL +317,317,1,0,12,0,11,-73.75,101.5,458.88,147.2,20,0.6,7,22,11,21,12,11,12,-1,-1,2,6,11,-2100,-1,-9999,MRD_x00_y11_z12,MRD_x00_y11_z12,None,ON,NORMAL +318,318,1,0,12,0,12,-73.75,121.8,458.88,147.2,20,0.6,7,22,12,21,13,11,13,-1,-1,2,6,12,-2100,-1,-9999,MRD_x00_y12_z12,MRD_x00_y12_z12,None,ON,NORMAL +319,319,1,0,12,1,0,73.75,-121.8,458.88,147.2,20,0.6,7,22,16,23,1,12,1,-1,-1,2,7,0,-2100,-1,-9999,MRD_x01_y00_z12,MRD_x01_y00_z12,None,ON,NORMAL +320,320,1,0,12,1,1,73.75,-101.5,458.88,147.2,20,0.6,7,22,17,23,2,12,2,-1,-1,2,7,1,-2100,-1,-9999,MRD_x01_y01_z12,MRD_x01_y01_z12,None,ON,NORMAL +321,321,1,0,12,1,2,73.75,-81.2,458.88,147.2,20,0.6,7,22,18,23,3,12,3,-1,-1,2,7,2,-2100,-1,-9999,MRD_x01_y02_z12,MRD_x01_y02_z12,None,ON,NORMAL +322,322,1,0,12,1,3,73.75,-60.9,458.88,147.2,20,0.6,7,22,19,23,4,12,4,-1,-1,2,7,3,-2100,-1,-9999,MRD_x01_y03_z12,MRD_x01_y03_z12,None,ON,NORMAL +323,323,1,0,12,1,4,73.75,-40.6,458.88,147.2,20,0.6,7,22,20,23,5,12,5,-1,-1,2,7,4,-2100,-1,-9999,MRD_x01_y04_z12,MRD_x01_y04_z12,None,ON,NORMAL +324,324,1,0,12,1,5,73.75,-20.3,458.88,147.2,20,0.6,7,22,21,23,6,12,6,-1,-1,2,7,5,-2100,-1,-9999,MRD_x01_y05_z12,MRD_x01_y05_z12,None,ON,NORMAL +325,325,1,0,12,1,6,73.75,0,458.88,147.2,20,0.6,7,22,22,23,7,12,7,-1,-1,2,7,6,-2100,-1,-9999,MRD_x01_y06_z12,MRD_x01_y06_z12,None,OFF,NORMAL +326,326,1,0,12,1,7,73.75,20.3,458.88,147.2,20,0.6,7,22,23,23,8,12,8,-1,-1,2,7,7,-2100,-1,-9999,MRD_x01_y07_z12,MRD_x01_y07_z12,None,ON,NORMAL +327,327,1,0,12,1,8,73.75,40.6,458.88,147.2,20,0.6,7,22,24,23,9,12,9,-1,-1,2,7,8,-2100,-1,-9999,MRD_x01_y08_z12,MRD_x01_y08_z12,None,ON,NORMAL +328,328,1,0,12,1,9,73.75,60.9,458.88,147.2,20,0.6,7,22,25,23,10,12,10,-1,-1,2,7,9,-2100,-1,-9999,MRD_x01_y09_z12,MRD_x01_y09_z12,None,ON,NORMAL +329,329,1,0,12,1,10,73.75,81.2,458.88,147.2,20,0.6,7,22,26,23,11,12,11,-1,-1,2,7,10,-2100,-1,-9999,MRD_x01_y10_z12,MRD_x01_y10_z12,None,ON,NORMAL +330,330,1,0,12,1,11,73.75,101.5,458.88,147.2,20,0.6,7,22,27,23,12,12,12,-1,-1,2,7,11,-2100,-1,-9999,MRD_x01_y11_z12,MRD_x01_y11_z12,None,ON,NORMAL +331,331,1,0,12,1,12,73.75,121.8,458.88,147.2,20,0.6,7,22,28,23,13,12,13,-1,-1,2,7,12,-2100,-1,-9999,MRD_x01_y12_z12,MRD_x01_y12_z12,None,ON,NORMAL +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/FullMRDGeometry_06_thru_09_2023_Runs_R4343_thru_R4614.csv b/configfiles/LoadGeometry/FullMRDGeometry_06_thru_09_2023_Runs_R4343_thru_R4614.csv new file mode 100644 index 000000000..06088d6c6 --- /dev/null +++ b/configfiles/LoadGeometry/FullMRDGeometry_06_thru_09_2023_Runs_R4343_thru_R4614.csv @@ -0,0 +1,342 @@ +#,,0=FMV,0=horizontal,,0=left,from left to right,,,,,,,,,,,,,,#NAME?,#NAME?,,,,,,,,,,, +#,,1=MRD,1=vertical,,1=right,from bottom to top,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,0=bottom,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,1=top,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,channel_num,detector_system,orientation,layer,side,num,x_center,y_center,z_center,x_width,y_width,z_width,rack,TDC_slot,TDC_channel,discrim_slot,discrim_ch,patch_panel_row,patch_panel_col,amp_slot,amp_channel,hv_crate,hv_slot,hv_channel,nominal_HV,polarity,PMT_type,cable_label,paddle_label,notes,detector_status,noise +########################################,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,-198.699875,5.08,320,30.5,2,8,2,0,1,1,1,1,-1,-1,2,14,0,-1871,-1,EMI9815,MRD_x00_y00_z00,4SW,None,ON,NORMAL +1,1,0,0,0,0,1,0,-167.999875,5.08,320,30.5,2,8,2,1,1,2,1,2,-1,-1,2,14,1,-1838,-1,EMI9815,MRD_x00_y01_z00,U39,None,ON,NORMAL +2,2,0,0,0,0,2,0,-137.299875,5.08,320,30.5,2,8,2,2,1,3,1,3,-1,-1,2,14,2,-1793,-1,EMI9815,MRD_x00_y02_z00,U58 (or U38; bad writing),None,ON,NORMAL +3,3,0,0,0,0,3,0,-106.599875,5.08,320,30.5,2,8,2,3,1,4,1,4,-1,-1,2,14,3,-1806,-1,EMI9815,MRD_x00_y03_z00,U29,None,ON,NORMAL +4,4,0,0,0,0,4,0,-75.899875,5.08,320,30.5,2,8,2,4,1,5,1,5,-1,-1,2,14,4,-1865,-1,EMI9815,MRD_x00_y04_z00,14SW,None,ON,NORMAL +5,5,0,0,0,0,5,0,-45.199875,5.08,320,30.5,2,8,2,5,1,6,1,6,-1,-1,2,14,5,-1823,-1,EMI9815,MRD_x00_y05_z00,Unknown4,None,ON,NORMAL +6,6,0,0,0,0,6,0,-14.499875,5.08,320,30.5,2,8,2,6,1,7,1,7,-1,-1,2,14,6,-1798,-1,EMI9815,MRD_x00_y06_z00,U17,None,ON,NORMAL +7,7,0,0,0,0,7,0,16.200125,5.08,320,30.5,2,8,2,7,1,8,1,8,-1,-1,2,14,7,-1823,-1,EMI9815,MRD_x00_y07_z00,11SE,None,ON,NORMAL +8,8,0,0,0,0,8,0,46.900125,5.08,320,30.5,2,8,2,8,1,9,1,9,-1,-1,2,14,8,-1871,-1,EMI9815,MRD_x00_y08_z00,18SE,None,ON,NORMAL +9,9,0,0,0,0,9,0,77.600125,5.08,320,30.5,2,8,2,9,1,10,1,10,-1,-1,2,14,9,-1836,-1,EMI9815,MRD_x00_y09_z00,21SW,None,ON,NORMAL +10,10,0,0,0,0,10,0,108.300125,5.08,320,30.5,2,8,2,10,1,11,1,11,-1,-1,2,14,10,-1814,-1,EMI9815,MRD_x00_y10_z00,3SE,None,ON,NORMAL +11,11,0,0,0,0,11,0,139.000125,5.08,320,30.5,2,8,2,11,1,12,1,12,-1,-1,2,14,11,-1781,-1,EMI9815,MRD_x00_y11_z00,24SE,None,ON,NORMAL +12,12,0,0,0,0,12,0,169.700125,5.08,320,30.5,2,8,2,12,1,13,1,13,-1,-1,2,14,12,-1816,-1,EMI9815,MRD_x00_y12_z00,U25,None,ON,NORMAL +13,13,0,0,0,1,0,0,-198.064875,7.28,320,30.5,2,8,2,16,3,1,2,1,-1,-1,2,15,0,-1805,-1,EMI9815,MRD_x01_y00_z00,28SE,None,ON,NORMAL +14,14,0,0,0,1,1,0,-167.364875,7.28,320,30.5,2,8,2,17,3,2,2,2,-1,-1,2,15,1,-1818,-1,EMI9815,MRD_x01_y01_z00,31SE,None,ON,NORMAL +15,15,0,0,0,1,2,0,-136.664875,7.28,320,30.5,2,8,2,18,3,3,2,3,-1,-1,2,15,2,-1860,-1,EMI9815,MRD_x01_y02_z00,8SE,None,ON,NORMAL +16,16,0,0,0,1,3,0,-105.964875,7.28,320,30.5,2,8,2,19,3,4,2,4,-1,-1,2,15,3,-1780,-1,EMI9815,MRD_x01_y03_z00,11SW,None,ON,NORMAL +17,17,0,0,0,1,4,0,-75.264875,7.28,320,30.5,2,8,2,20,3,5,2,5,-1,-1,2,15,4,-1841,-1,EMI9815,MRD_x01_y04_z00,U34,None,ON,NORMAL +18,18,0,0,0,1,5,0,-44.564875,7.28,320,30.5,2,8,2,21,3,6,2,6,-1,-1,2,15,5,-1786,-1,EMI9815,MRD_x01_y05_z010,U36,None,ON,NORMAL +19,19,0,0,0,1,6,0,-13.864875,7.28,320,30.5,2,8,2,22,3,7,2,7,-1,-1,2,15,6,-1864,-1,EMI9815,MRD_x01_y06_z00,U40,None,ON,NORMAL +20,20,0,0,0,1,7,0,16.835125,7.28,320,30.5,2,8,2,23,3,8,2,8,-1,-1,2,15,7,-1858,-1,EMI9815,MRD_x01_y07_z00,Unknown5,None,ON,NORMAL +21,21,0,0,0,1,8,0,47.535125,7.28,320,30.5,2,8,2,24,3,9,2,9,-1,-1,2,15,8,-1876,-1,EMI9815,MRD_x01_y08_z00,27SE,None,ON,NORMAL +22,22,0,0,0,1,9,0,78.235125,7.28,320,30.5,2,8,2,25,3,10,2,10,-1,-1,2,15,9,-1806,-1,EMI9815,MRD_x01_y09_z00,Unknown2,None,ON,NORMAL +23,23,0,0,0,1,10,0,108.935125,7.28,320,30.5,2,8,2,26,3,11,2,11,-1,-1,2,15,10,-1853,-1,EMI9815,MRD_x01_y10_z00,10SW,None,ON,NORMAL +24,24,0,0,0,1,11,0,139.635125,7.28,320,30.5,2,8,2,27,3,12,2,12,-1,-1,2,15,11,-1860,-1,EMI9815,MRD_x01_y11_z00,Bill2,None,ON,NORMAL +25,25,0,0,0,1,12,0,170.335125,7.28,320,30.5,2,8,2,28,3,13,2,13,-1,-1,2,15,12,-1844,-1,EMI9815,MRD_x01_y12_z00,13SE,None,ON,NORMAL +26,26,1,0,2,0,0,-73.75,-121.8,336.38,147.2,20,0.6,7,2,0,1,1,1,1,-1,-1,1,4,0,-2100,-1,-9999,MRD_x00_y00_z02,MRD_x00_y00_z02,None,ON,NORMAL +27,27,1,0,2,0,1,-73.75,-101.5,336.38,147.2,20,0.6,7,2,1,1,2,1,2,-1,-1,1,4,1,-2100,-1,-9999,MRD_x00_y01_z02,MRD_x00_y01_z02,None,ON,NORMAL +28,28,1,0,2,0,2,-73.75,-81.2,336.38,147.2,20,0.6,7,2,2,1,3,1,3,-1,-1,1,4,2,-2100,-1,-9999,MRD_x00_y02_z02,MRD_x00_y02_z02,None,ON,NORMAL +29,29,1,0,2,0,3,-73.75,-60.9,336.38,147.2,20,0.6,7,2,3,1,4,1,4,-1,-1,1,4,3,-2100,-1,-9999,MRD_x00_y03_z02,MRD_x00_y03_z02,None,ON,NORMAL +30,30,1,0,2,0,4,-73.75,-40.6,336.38,147.2,20,0.6,7,2,4,1,5,1,5,-1,-1,1,4,4,-2100,-1,-9999,MRD_x00_y04_z02,MRD_x00_y04_z02,None,ON,NORMAL +31,31,1,0,2,0,5,-73.75,-20.3,336.38,147.2,20,0.6,7,2,5,1,6,1,6,-1,-1,1,4,5,-2100,-1,-9999,MRD_x00_y05_z02,MRD_x00_y05_z02,None,ON,NORMAL +32,32,1,0,2,0,6,-73.75,0,336.38,147.2,20,0.6,7,2,6,1,7,1,7,-1,-1,1,4,6,-2100,-1,-9999,MRD_x00_y06_z02,MRD_x00_y06_z02,None,ON,NORMAL +33,33,1,0,2,0,7,-73.75,20.3,336.38,147.2,20,0.6,7,2,7,1,8,1,8,-1,-1,1,4,7,-2100,-1,-9999,MRD_x00_y07_z02,MRD_x00_y07_z02,None,ON,NORMAL +34,34,1,0,2,0,8,-73.75,40.6,336.38,147.2,20,0.6,7,2,8,1,9,1,9,-1,-1,1,4,8,-1900,-1,-9999,MRD_x00_y08_z02,MRD_x00_y08_z02,None,ON,NORMAL +35,35,1,0,2,0,9,-73.75,60.9,336.38,147.2,20,0.6,7,2,9,1,10,1,10,-1,-1,1,4,10,-1900,-1,-9999,MRD_x00_y09_z02,MRD_x00_y09_z02,None,ON,NORMAL +36,36,1,0,2,0,10,-73.75,81.2,336.38,147.2,20,0.6,7,2,10,1,11,1,11,-1,-1,1,4,11,-2100,-1,-9999,MRD_x00_y10_z02,MRD_x00_y10_z02,None,ON,NORMAL +37,37,1,0,2,0,11,-73.75,101.5,336.38,147.2,20,0.6,7,2,11,1,12,1,12,-1,-1,1,4,12,-2100,-1,-9999,MRD_x00_y11_z02,MRD_x00_y11_z02,None,ON,NORMAL +38,38,1,0,2,0,12,-73.75,121.8,336.38,147.2,20,0.6,7,2,12,1,13,1,13,-1,-1,1,4,13,-1900,-1,-9999,MRD_x00_y12_z02,MRD_x00_y12_z02,None,ON,NORMAL +39,39,1,0,2,1,0,73.75,-121.8,336.38,147.2,20,0.6,7,2,16,3,1,2,1,-1,-1,1,5,0,-2100,-1,-9999,MRD_x01_y00_z02,MRD_x01_y00_z02,None,ON,NORMAL +40,40,1,0,2,1,1,73.75,-101.5,336.38,147.2,20,0.6,7,2,17,3,2,2,2,-1,-1,1,5,1,-2100,-1,-9999,MRD_x01_y01_z02,MRD_x01_y01_z02,None,ON,NORMAL +41,41,1,0,2,1,2,73.75,-81.2,336.38,147.2,20,0.6,7,2,18,3,3,2,3,-1,-1,1,5,2,-1900,-1,-9999,MRD_x01_y02_z02,MRD_x01_y02_z02,None,ON,NORMAL +42,42,1,0,2,1,3,73.75,-60.9,336.38,147.2,20,0.6,7,2,19,3,4,2,4,-1,-1,1,5,3,-1900,-1,-9999,MRD_x01_y03_z02,MRD_x01_y03_z02,None,ON,NORMAL +43,43,1,0,2,1,4,73.75,-40.6,336.38,147.2,20,0.6,7,2,20,3,5,2,5,-1,-1,1,5,4,-2100,-1,-9999,MRD_x01_y04_z02,MRD_x01_y04_z02,None,ON,NORMAL +44,44,1,0,2,1,5,73.75,-20.3,336.38,147.2,20,0.6,7,2,21,3,6,2,6,-1,-1,1,5,5,-2100,-1,-9999,MRD_x01_y05_z02,MRD_x01_y05_z02,None,ON,NORMAL +45,45,1,0,2,1,6,73.75,0,336.38,147.2,20,0.6,7,2,22,3,7,2,7,-1,-1,1,5,6,-1900,-1,-9999,MRD_x01_y06_z02,MRD_x01_y06_z02,None,ON,NORMAL +46,46,1,0,2,1,7,73.75,20.3,336.38,147.2,20,0.6,7,2,23,3,8,2,8,-1,-1,1,5,7,-2100,-1,-9999,MRD_x01_y07_z02,MRD_x01_y07_z02,None,ON,NORMAL +47,47,1,0,2,1,8,73.75,40.6,336.38,147.2,20,0.6,7,2,24,3,9,2,9,-1,-1,1,5,8,-2100,-1,-9999,MRD_x01_y08_z02,MRD_x01_y08_z02,None,ON,NORMAL +48,48,1,0,2,1,9,73.75,60.9,336.38,147.2,20,0.6,7,2,25,3,10,2,10,-1,-1,1,5,9,-2100,-1,-9999,MRD_x01_y09_z02,MRD_x01_y09_z02,None,ON,NORMAL +49,49,1,0,2,1,10,73.75,81.2,336.38,147.2,20,0.6,7,2,26,3,11,2,11,-1,-1,1,5,10,-2100,-1,-9999,MRD_x01_y10_z02,MRD_x01_y10_z02,None,ON,NORMAL +50,50,1,0,2,1,11,73.75,101.5,336.38,147.2,20,0.6,7,2,27,3,12,2,12,-1,-1,1,5,11,-2100,-1,-9999,MRD_x01_y11_z02,MRD_x01_y11_z02,None,ON,NORMAL +51,51,1,0,2,1,12,73.75,121.8,336.38,147.2,20,0.6,7,2,28,3,13,2,13,-1,-1,1,5,12,-1900,-1,-9999,MRD_x01_y12_z02,MRD_x01_y12_z02,None,OFF,NORMAL +52,52,1,1,3,0,0,-107.1,-65.25,348.84,15,130.2,1.3,8,5,0,4,1,3,1,-1,-1,1,6,0,-2000,-1,-9999,MRD_x00_y00_z03,MRD_x00_y00_z03,None,ON,NORMAL +53,53,1,1,3,0,1,-91.8,-65.25,348.84,15,130.2,1.3,8,5,1,4,2,3,2,-1,-1,1,6,1,-2000,-1,-9999,MRD_x01_y00_z03,MRD_x01_y00_z03,None,ON,NORMAL +54,54,1,1,3,0,2,-76.5,-65.25,348.84,15,130.2,1.3,8,5,2,4,3,3,3,-1,-1,1,6,2,-2000,-1,-9999,MRD_x02_y00_z03,MRD_x02_y00_z03,None,ON,NORMAL +55,55,1,1,3,0,3,-61.2,-65.25,348.84,15,130.2,1.3,8,5,3,4,4,3,4,-1,-1,1,6,3,-2000,-1,-9999,MRD_x03_y00_z03,MRD_x03_y00_z03,None,ON,NORMAL +56,56,1,1,3,0,4,-45.9,-65.25,348.84,15,130.2,1.3,8,5,4,4,5,3,5,-1,-1,1,6,4,-2000,-1,-9999,MRD_x04_y00_z03,MRD_x04_y00_z03,None,ON,NORMAL +57,57,1,1,3,0,5,-30.6,-65.25,348.84,15,130.2,1.3,8,5,5,4,6,3,6,-1,-1,1,6,5,-2000,-1,-9999,MRD_x05_y00_z03,MRD_x05_y00_z03,None,ON,NORMAL +58,58,1,1,3,0,6,-15.3,-65.25,348.84,15,130.2,1.3,8,5,6,4,7,3,7,-1,-1,1,6,6,-2000,-1,-9999,MRD_x06_y00_z03,MRD_x06_y00_z03,None,ON,NORMAL +59,59,1,1,3,0,7,0,-65.25,348.84,15,130.2,1.3,8,5,7,4,8,3,8,-1,-1,1,6,7,-2000,-1,-9999,MRD_x07_y00_z03,MRD_x07_y00_z03,None,ON,NORMAL +60,60,1,1,3,0,8,15.3,-65.25,348.84,15,130.2,1.3,8,5,8,4,9,3,9,-1,-1,1,6,8,-2000,-1,-9999,MRD_x08_y00_z03,MRD_x08_y00_z03,None,ON,NORMAL +61,61,1,1,3,0,9,30.6,-65.25,348.84,15,130.2,1.3,8,5,9,4,10,3,10,-1,-1,1,6,9,-2000,-1,-9999,MRD_x09_y00_z03,MRD_x09_y00_z03,None,ON,NORMAL +62,62,1,1,3,0,10,45.9,-65.25,348.84,15,130.2,1.3,8,5,10,4,11,3,11,-1,-1,1,6,10,-2000,-1,-9999,MRD_x10_y00_z03,MRD_x10_y00_z03,None,ON,NORMAL +63,63,1,1,3,0,11,61.2,-65.25,348.84,15,130.2,1.3,8,5,11,4,12,3,12,-1,-1,1,6,11,-2000,-1,-9999,MRD_x11_y00_z03,MRD_x11_y00_z03,None,ON,NORMAL +64,64,1,1,3,0,12,76.5,-65.25,348.84,15,130.2,1.3,8,5,12,4,13,3,13,-1,-1,1,6,12,-2000,-1,-9999,MRD_x12_y00_z03,MRD_x12_y00_z03,None,ON,NORMAL +65,65,1,1,3,0,13,91.8,-65.25,348.84,15,130.2,1.3,8,5,13,4,14,3,14,-1,-1,1,6,13,-2000,-1,-9999,MRD_x13_y00_z03,MRD_x13_y00_z03,None,ON,NORMAL +66,66,1,1,3,0,14,107.1,-65.25,348.84,15,130.2,1.3,8,5,14,4,15,3,15,-1,-1,1,6,14,-1800,-1,-9999,MRD_x14_y00_z03,MRD_x14_y00_z03,None,ON,NORMAL +67,67,1,1,3,1,0,-107.1,65.25,348.84,15,130.2,1.3,8,5,16,6,1,4,1,-1,-1,1,7,0,-2200,-1,-9999,MRD_x00_y01_z03,MRD_x00_y01_z03,None,ON,NORMAL +68,68,1,1,3,1,1,-91.8,65.25,348.84,15,130.2,1.3,8,5,17,6,2,4,2,-1,-1,1,7,1,-2000,-1,-9999,MRD_x01_y01_z03,MRD_x01_y01_z03,None,ON,NORMAL +69,69,1,1,3,1,2,-76.5,65.25,348.84,15,130.2,1.3,8,5,18,6,3,4,3,-1,-1,1,7,2,-2000,-1,-9999,MRD_x02_y01_z03,MRD_x02_y01_z03,None,ON,NORMAL +70,70,1,1,3,1,3,-61.2,65.25,348.84,15,130.2,1.3,8,5,19,6,4,4,4,-1,-1,1,7,3,-2000,-1,-9999,MRD_x03_y01_z03,MRD_x03_y01_z03,None,ON,NORMAL +71,71,1,1,3,1,4,-45.9,65.25,348.84,15,130.2,1.3,8,5,20,6,5,4,5,-1,-1,1,7,4,-2000,-1,-9999,MRD_x04_y01_z03,MRD_x04_y01_z03,None,ON,NORMAL +72,72,1,1,3,1,5,-30.6,65.25,348.84,15,130.2,1.3,8,5,21,6,6,4,6,-1,-1,1,7,5,-2000,-1,-9999,MRD_x05_y01_z03,MRD_x05_y01_z03,None,ON,NORMAL +73,73,1,1,3,1,6,-15.3,65.25,348.84,15,130.2,1.3,8,5,22,6,7,4,7,-1,-1,1,7,6,-2000,-1,-9999,MRD_x06_y01_z03,MRD_x06_y01_z03,None,ON,NORMAL +74,74,1,1,3,1,7,0,65.25,348.84,15,130.2,1.3,8,5,23,6,8,4,8,-1,-1,1,7,7,-2000,-1,-9999,MRD_x07_y01_z03,MRD_x07_y01_z03,None,ON,NORMAL +75,75,1,1,3,1,8,15.3,65.25,348.84,15,130.2,1.3,8,5,24,6,9,4,9,-1,-1,1,7,8,-2000,-1,-9999,MRD_x08_y01_z03,MRD_x08_y01_z03,None,ON,NORMAL +76,76,1,1,3,1,9,30.6,65.25,348.84,15,130.2,1.3,8,5,25,6,10,4,10,-1,-1,1,7,9,-2000,-1,-9999,MRD_x09_y01_z03,MRD_x09_y01_z03,None,ON,HOT +77,77,1,1,3,1,10,45.9,65.25,348.84,15,130.2,1.3,8,5,26,6,11,4,11,-1,-1,1,7,10,-2000,-1,-9999,MRD_x10_y01_z03,MRD_x10_y01_z03,Currently using y1 z3 spare cableNone,ON,NORMAL +78,78,1,1,3,1,11,61.2,65.25,348.84,15,130.2,1.3,8,5,27,6,12,4,12,-1,-1,1,7,11,-2000,-1,-9999,MRD_x11_y01_z03,MRD_x11_y01_z03,None,ON,NORMAL +79,79,1,1,3,1,12,76.5,65.25,348.84,15,130.2,1.3,8,5,28,6,13,4,13,-1,-1,1,7,12,-2000,-1,-9999,MRD_x12_y01_z03,MRD_x12_y01_z03,None,ON,NORMAL +80,80,1,1,3,1,13,91.8,65.25,348.84,15,130.2,1.3,8,5,29,6,14,4,14,-1,-1,1,7,13,-2000,-1,-9999,MRD_x13_y01_z03,MRD_x13_y01_z03,None,ON,NORMAL +81,81,1,1,3,1,14,107.1,65.25,348.84,15,130.2,1.3,8,5,30,6,15,4,15,-1,-1,1,7,14,-2000,-1,-9999,MRD_x14_y01_z03,MRD_x14_y01_z03,None,ON,NORMAL +82,82,1,0,4,0,0,-73.75,-121.8,361.3,147.2,20,0.6,7,5,0,4,1,3,1,-1,-1,1,8,0,-2100,-1,-9999,MRD_x00_y00_z04,MRD_x00_y00_z04,None,ON,NORMAL +83,83,1,0,4,0,1,-73.75,-101.5,361.3,147.2,20,0.6,7,5,1,4,2,3,2,-1,-1,1,8,1,-2100,-1,-9999,MRD_x00_y01_z04,MRD_x00_y01_z04,None,ON,NORMAL +84,84,1,0,4,0,2,-73.75,-81.2,361.3,147.2,20,0.6,7,5,2,4,3,3,3,-1,-1,1,8,2,-2100,-1,-9999,MRD_x00_y02_z04,MRD_x00_y02_z04,None,ON,NORMAL +85,85,1,0,4,0,3,-73.75,-60.9,361.3,147.2,20,0.6,7,5,3,4,4,3,4,-1,-1,1,8,3,-2100,-1,-9999,MRD_x00_y03_z04,MRD_x00_y03_z04,None,ON,NORMAL +86,86,1,0,4,0,4,-73.75,-40.6,361.3,147.2,20,0.6,7,5,4,4,5,3,5,-1,-1,1,8,4,-2300,-1,-9999,MRD_x00_y04_z04,MRD_x00_y04_z04,None,ON,NORMAL +87,87,1,0,4,0,5,-73.75,-20.3,361.3,147.2,20,0.6,7,5,5,4,6,3,6,-1,-1,1,8,5,-2100,-1,-9999,MRD_x00_y05_z04,MRD_x00_y05_z04,None,ON,NORMAL +88,88,1,0,4,0,6,-73.75,0,361.3,147.2,20,0.6,7,5,6,4,7,3,7,-1,-1,1,8,6,-2100,-1,-9999,MRD_x00_y06_z04,MRD_x00_y06_z04,None,ON,NORMAL +89,89,1,0,4,0,7,-73.75,20.3,361.3,147.2,20,0.6,7,5,7,4,8,3,8,-1,-1,1,8,7,-2100,-1,-9999,MRD_x00_y07_z04,MRD_x00_y07_z04,None,ON,NORMAL +90,90,1,0,4,0,8,-73.75,40.6,361.3,147.2,20,0.6,7,5,8,4,9,3,9,-1,-1,1,8,8,-2100,-1,-9999,MRD_x00_y08_z04,MRD_x00_y08_z04,None,ON,NORMAL +91,91,1,0,4,0,9,-73.75,60.9,361.3,147.2,20,0.6,7,5,9,4,10,3,10,-1,-1,1,8,9,-2100,-1,-9999,MRD_x00_y09_z04,MRD_x00_y09_z04,None,ON,NORMAL +92,92,1,0,4,0,10,-73.75,81.2,361.3,147.2,20,0.6,7,5,10,4,11,3,11,-1,-1,1,8,10,-2100,-1,-9999,MRD_x00_y10_z04,MRD_x00_y10_z04,None,ON,NORMAL +93,93,1,0,4,0,11,-73.75,101.5,361.3,147.2,20,0.6,7,5,11,4,12,3,12,-1,-1,1,8,11,-2100,-1,-9999,MRD_x00_y11_z04,MRD_x00_y11_z04,None,ON,NORMAL +94,94,1,0,4,0,12,-73.75,121.8,361.3,147.2,20,0.6,7,5,12,4,13,3,13,-1,-1,1,8,12,-2300,-1,-9999,MRD_x00_y12_z04,MRD_x00_y12_z04,None,ON,NORMAL +95,95,1,0,4,1,0,73.75,-121.8,361.3,147.2,20,0.6,7,5,16,6,1,4,1,-1,-1,1,9,0,-2100,-1,-9999,MRD_x01_y00_z04,MRD_x01_y00_z04,None,ON,NORMAL +96,96,1,0,4,1,1,73.75,-101.5,361.3,147.2,20,0.6,7,5,17,6,2,4,2,-1,-1,1,9,1,-2100,-1,-9999,MRD_x01_y01_z04,MRD_x01_y01_z04,None,ON,NORMAL +97,97,1,0,4,1,2,73.75,-81.2,361.3,147.2,20,0.6,7,5,18,6,3,4,3,-1,-1,1,9,2,-2300,-1,-9999,MRD_x01_y02_z04,MRD_x01_y02_z04,None,ON,NORMAL +98,98,1,0,4,1,3,73.75,-60.9,361.3,147.2,20,0.6,7,5,19,6,4,4,4,-1,-1,1,9,3,-2300,-1,-9999,MRD_x01_y03_z04,MRD_x01_y03_z04,None,ON,NORMAL +99,99,1,0,4,1,4,73.75,-40.6,361.3,147.2,20,0.6,7,5,20,6,5,4,5,-1,-1,1,9,4,-2100,-1,-9999,MRD_x01_y04_z04,MRD_x01_y04_z04,None,ON,NORMAL +100,100,1,0,4,1,5,73.75,-20.3,361.3,147.2,20,0.6,7,5,21,6,6,4,6,-1,-1,1,9,5,-2100,-1,-9999,MRD_x01_y05_z04,MRD_x01_y05_z04,None,ON,NORMAL +101,101,1,0,4,1,6,73.75,0,361.3,147.2,20,0.6,7,5,22,6,7,4,7,-1,-1,1,9,6,-2100,-1,-9999,MRD_x01_y06_z04,MRD_x01_y06_z04,None,ON,NORMAL +102,102,1,0,4,1,7,73.75,20.3,361.3,147.2,20,0.6,7,5,23,6,8,4,8,-1,-1,1,9,7,-2100,-1,-9999,MRD_x01_y07_z04,MRD_x01_y07_z04,None,ON,NORMAL +103,103,1,0,4,1,8,73.75,40.6,361.3,147.2,20,0.6,7,5,24,6,9,4,9,-1,-1,1,9,8,-2100,-1,-9999,MRD_x01_y08_z04,MRD_x01_y08_z04,None,ON,NORMAL +104,104,1,0,4,1,9,73.75,60.9,361.3,147.2,20,0.6,7,5,25,6,10,4,10,-1,-1,1,9,9,-2100,-1,-9999,MRD_x01_y09_z04,MRD_x01_y09_z04,None,ON,NORMAL +105,105,1,0,4,1,10,73.75,81.2,361.3,147.2,20,0.6,7,5,26,6,11,4,11,-1,-1,1,9,10,-2100,-1,-9999,MRD_x01_y10_z04,MRD_x01_y10_z04,None,ON,HOT +106,106,1,0,4,1,11,73.75,101.5,361.3,147.2,20,0.6,7,5,27,6,12,4,12,-1,-1,1,9,11,-2100,-1,-9999,MRD_x01_y11_z04,MRD_x01_y11_z04,None,ON,NORMAL +107,107,1,0,4,1,12,73.75,121.8,361.3,147.2,20,0.6,7,5,28,6,13,4,13,-1,-1,1,9,12,-2100,-1,-9999,MRD_x01_y12_z04,MRD_x01_y12_z04,None,ON,NORMAL +108,108,1,1,5,0,0,-122.4,-65.25,373.76,15,130.2,1.3,8,8,0,7,1,5,1,-1,-1,1,10,0,-2200,-1,-9999,MRD_x00_y00_z05,MRD_x00_y00_z05,None,ON,NORMAL +109,109,1,1,5,0,1,-107.1,-65.25,373.76,15,130.2,1.3,8,8,1,7,2,5,2,-1,-1,1,10,1,-2200,-1,-9999,MRD_x01_y00_z05,MRD_x01_y00_z05,None,ON,NORMAL +110,110,1,1,5,0,2,-91.8,-65.25,373.76,15,130.2,1.3,8,8,2,7,3,5,3,-1,-1,1,10,2,-2000,-1,-9999,MRD_x02_y00_z05,MRD_x02_y00_z05,None,ON,NORMAL +111,111,1,1,5,0,3,-76.5,-65.25,373.76,15,130.2,1.3,8,8,7,7,8,5,4,-1,-1,1,10,3,-1500,-1,-9999,MRD_x03_y00_z05,MRD_x03_y00_z05,None,ON,NORMAL +112,112,1,1,5,0,4,-61.2,-65.25,373.76,15,130.2,1.3,8,8,3,7,4,5,5,-1,-1,1,10,4,-2000,-1,-9999,MRD_x04_y00_z05,MRD_x04_y00_z05,None,ON,NORMAL +113,113,1,1,5,0,5,-45.9,-65.25,373.76,15,130.2,1.3,8,8,4,7,5,5,6,-1,-1,1,10,5,-2000,-1,-9999,MRD_x05_y00_z05,MRD_x05_y00_z05,None,ON,NORMAL +114,114,1,1,5,0,6,-30.6,-65.25,373.76,15,130.2,1.3,8,8,6,7,7,5,7,-1,-1,1,10,6,-2000,-1,-9999,MRD_x06_y00_z05,MRD_x06_y00_z05,None,ON,NORMAL +115,115,1,1,5,0,7,-15.3,-65.25,373.76,15,130.2,1.3,8,8,5,7,6,5,8,-1,-1,1,10,7,-2000,-1,-9999,MRD_x07_y00_z05,MRD_x07_y00_z05,None,ON,NORMAL +116,116,1,1,5,0,8,0,-65.25,373.76,15,130.2,1.3,8,8,8,7,9,5,9,-1,-1,1,10,8,-2000,-1,-9999,MRD_x08_y00_z05,MRD_x08_y00_z05,None,ON,NORMAL +117,117,1,1,5,0,9,15.3,-65.25,373.76,15,130.2,1.3,8,8,14,7,15,5,10,-1,-1,1,10,9,-2000,-1,-9999,MRD_x09_y00_z05,MRD_x09_y00_z05,None,ON,NORMAL +118,118,1,1,5,0,10,30.6,-65.25,373.76,15,130.2,1.3,8,8,10,7,11,5,11,-1,-1,1,10,10,-2000,-1,-9999,MRD_x10_y00_z05,MRD_x10_y00_z05,None,ON,NORMAL +119,119,1,1,5,0,11,45.9,-65.25,373.76,15,130.2,1.3,8,8,11,7,12,5,12,-1,-1,1,10,11,-2000,-1,-9999,MRD_x11_y00_z05,MRD_x11_y00_z05,None,ON,NORMAL +120,120,1,1,5,0,12,61.2,-65.25,373.76,15,130.2,1.3,8,8,9,7,10,5,13,-1,-1,1,10,12,-2000,-1,-9999,MRD_x12_y00_z05,MRD_x12_y00_z05,Discriminator on slot 7 channel 13 has no NIM outputNone,ON,NORMAL +121,121,1,1,5,0,13,76.5,-65.25,373.76,15,130.2,1.3,8,8,12,7,13,5,14,-1,-1,1,10,13,-2000,-1,-9999,MRD_x13_y00_z05,MRD_x13_y00_z05,None,ON,NORMAL +122,122,1,1,5,0,14,91.8,-65.25,373.76,15,130.2,1.3,8,8,13,7,14,5,15,-1,-1,1,10,14,-2000,-1,-9999,MRD_x14_y00_z05,MRD_x14_y00_z05,None,ON,NORMAL +123,123,1,1,5,0,15,107.1,-65.25,373.76,15,130.2,1.3,8,8,15,7,16,5,16,-1,-1,1,5,14,-1500,-1,-9999,MRD_x15_y00_z05,MRD_x15_y00_z05,None,OFF,NORMAL +124,124,1,1,5,0,16,122.4,-65.25,373.76,15,130.2,1.3,8,17,15,16,16,5,17,-1,-1,1,4,14,-2200,-1,-9999,MRD_x16_y00_z05,MRD_x16_y00_z05,None,OFF,NORMAL +125,125,1,1,5,1,0,-122.4,65.25,373.76,15,130.2,1.3,8,8,16,9,1,6,1,-1,-1,1,11,0,-2000,-1,-9999,MRD_x00_y01_z05,MRD_x00_y01_z05,None,ON,NORMAL +126,126,1,1,5,1,1,-107.1,65.25,373.76,15,130.2,1.3,8,8,17,9,2,6,2,-1,-1,1,11,1,-2000,-1,-9999,MRD_x01_y01_z05,MRD_x01_y01_z05,possible dischargeNone,ON,NORMAL +127,127,1,1,5,1,2,-91.8,65.25,373.76,15,130.2,1.3,8,8,18,9,3,6,3,-1,-1,1,11,2,-2000,-1,-9999,MRD_x02_y01_z05,MRD_x02_y01_z05,None,ON,NORMAL +128,128,1,1,5,1,3,-76.5,65.25,373.76,15,130.2,1.3,8,8,19,9,4,6,4,-1,-1,1,11,3,-2000,-1,-9999,MRD_x03_y01_z05,MRD_x03_y01_z05,None,ON,NORMAL +129,129,1,1,5,1,4,-61.2,65.25,373.76,15,130.2,1.3,8,8,20,9,5,6,5,-1,-1,1,11,4,-1500,-1,-9999,MRD_x04_y01_z05,MRD_x04_y01_z05,None,ON,NORMAL +130,130,1,1,5,1,5,-45.9,65.25,373.76,15,130.2,1.3,8,8,21,9,6,6,6,-1,-1,1,11,5,-2000,-1,-9999,MRD_x05_y01_z05,MRD_x05_y01_z05,None,ON,NORMAL +131,131,1,1,5,1,6,-30.6,65.25,373.76,15,130.2,1.3,8,8,22,9,7,6,7,-1,-1,1,11,6,-2000,-1,-9999,MRD_x06_y01_z05,MRD_x06_y01_z05,None,ON,NORMAL +132,132,1,1,5,1,7,-15.3,65.25,373.76,15,130.2,1.3,8,8,23,9,8,6,8,-1,-1,1,11,7,-2000,-1,-9999,MRD_x07_y01_z05,MRD_x07_y01_z05,None,ON,NORMAL +133,133,1,1,5,1,8,0,65.25,373.76,15,130.2,1.3,8,8,24,9,9,6,9,-1,-1,1,11,8,-2000,-1,-9999,MRD_x08_y01_z05,MRD_x08_y01_z05,None,ON,NORMAL +134,134,1,1,5,1,9,15.3,65.25,373.76,15,130.2,1.3,8,8,25,9,10,6,10,-1,-1,1,11,9,-2000,-1,-9999,MRD_x09_y01_z05,MRD_x09_y01_z05,None,ON,NORMAL +135,135,1,1,5,1,10,30.6,65.25,373.76,15,130.2,1.3,8,8,26,9,11,6,11,-1,-1,1,11,10,-2000,-1,-9999,MRD_x10_y01_z05,MRD_x10_y01_z05,None,ON,NORMAL +136,136,1,1,5,1,11,45.9,65.25,373.76,15,130.2,1.3,8,8,27,9,12,6,12,-1,-1,1,11,11,-1800,-1,-9999,MRD_x11_y01_z05,MRD_x11_y01_z05,None,ON,NORMAL +137,137,1,1,5,1,12,61.2,65.25,373.76,15,130.2,1.3,8,8,28,9,13,6,13,-1,-1,1,11,12,-2000,-1,-9999,MRD_x12_y01_z05,MRD_x12_y01_z05,None,ON,NORMAL +138,138,1,1,5,1,13,76.5,65.25,373.76,15,130.2,1.3,8,8,29,9,14,6,14,-1,-1,1,11,13,-2000,-1,-9999,MRD_x13_y01_z05,MRD_x13_y01_z05,None,ON,NORMAL +139,139,1,1,5,1,14,91.8,65.25,373.76,15,130.2,1.3,8,8,30,9,15,6,15,-1,-1,1,11,14,-2000,-1,-9999,MRD_x14_y01_z05,MRD_x14_y01_z05,None,ON,NORMAL +140,140,1,1,5,1,15,107.1,65.25,373.76,15,130.2,1.3,8,8,31,9,16,6,16,-1,-1,1,11,15,-2000,-1,-9999,MRD_x15_y01_z05,MRD_x15_y01_z05,None,OFF,NORMAL +141,141,1,1,5,1,16,122.4,65.25,373.76,15,130.2,1.3,8,14,31,15,16,6,17,-1,-1,1,4,15,-2000,-1,-9999,MRD_x16_y01_z05,MRD_x16_y01_z05,Now uses y0 z5 spare; Rack 8 slot 18 channel 16 has no NIM output,OFF,NORMAL +142,142,1,0,6,0,0,-73.75,-121.8,386.22,147.2,20,0.6,7,8,0,7,1,5,1,-1,-1,1,12,0,-2100,-1,-9999,MRD_x00_y00_z06,MRD_x00_y00_z06,None,ON,NORMAL +143,143,1,0,6,0,1,-73.75,-101.5,386.22,147.2,20,0.6,7,8,1,7,2,5,2,-1,-1,1,12,1,-2100,-1,-9999,MRD_x00_y01_z06,MRD_x00_y01_z06,None,ON,NORMAL +144,144,1,0,6,0,2,-73.75,-81.2,386.22,147.2,20,0.6,7,8,2,7,3,5,3,-1,-1,1,12,2,-2100,-1,-9999,MRD_x00_y02_z06,MRD_x00_y02_z06,None,ON,NORMAL +145,145,1,0,6,0,3,-73.75,-60.9,386.22,147.2,20,0.6,7,8,3,7,4,5,4,-1,-1,1,12,3,-2100,-1,-9999,MRD_x00_y03_z06,MRD_x00_y03_z06,None,ON,NORMAL +146,146,1,0,6,0,4,-73.75,-40.6,386.22,147.2,20,0.6,7,8,4,7,5,5,5,-1,-1,1,12,4,-2100,-1,-9999,MRD_x00_y04_z06,MRD_x00_y04_z06,None,ON,NORMAL +147,147,1,0,6,0,5,-73.75,-20.3,386.22,147.2,20,0.6,7,8,5,7,6,5,6,-1,-1,1,12,5,-2100,-1,-9999,MRD_x00_y05_z06,MRD_x00_y05_z06,None,ON,NORMAL +148,148,1,0,6,0,6,-73.75,0,386.22,147.2,20,0.6,7,8,6,7,7,5,7,-1,-1,1,12,6,-2100,-1,-9999,MRD_x00_y06_z06,MRD_x00_y06_z06,None,ON,NORMAL +149,149,1,0,6,0,7,-73.75,20.3,386.22,147.2,20,0.6,7,8,7,7,8,5,8,-1,-1,1,12,7,-2100,-1,-9999,MRD_x00_y07_z06,MRD_x00_y07_z06,None,ON,NORMAL +150,150,1,0,6,0,8,-73.75,40.6,386.22,147.2,20,0.6,7,8,8,7,9,5,9,-1,-1,1,12,8,-2100,-1,-9999,MRD_x00_y08_z06,MRD_x00_y08_z06,None,ON,NORMAL +151,151,1,0,6,0,9,-73.75,60.9,386.22,147.2,20,0.6,7,8,9,7,10,5,10,-1,-1,1,12,9,-2100,-1,-9999,MRD_x00_y09_z06,MRD_x00_y09_z06,None,ON,NORMAL +152,152,1,0,6,0,10,-73.75,81.2,386.22,147.2,20,0.6,7,8,10,7,11,5,11,-1,-1,1,12,10,-2100,-1,-9999,MRD_x00_y10_z06,MRD_x00_y10_z06,None,ON,NORMAL +153,153,1,0,6,0,11,-73.75,101.5,386.22,147.2,20,0.6,7,8,11,7,12,5,12,-1,-1,1,12,11,-2100,-1,-9999,MRD_x00_y11_z06,MRD_x00_y11_z06,None,ON,NORMAL +154,154,1,0,6,0,12,-73.75,121.8,386.22,147.2,20,0.6,7,8,12,7,13,5,13,-1,-1,1,12,12,-2100,-1,-9999,MRD_x00_y12_z06,MRD_x00_y12_z06,None,ON,NORMAL +155,155,1,0,6,1,0,73.75,-121.8,386.22,147.2,20,0.6,7,8,16,9,1,6,1,-1,-1,1,13,0,-1900,-1,-9999,MRD_x01_y00_z06,MRD_x01_y00_z06,None,ON,NORMAL +156,156,1,0,6,1,1,73.75,-101.5,386.22,147.2,20,0.6,7,8,17,9,2,6,2,-1,-1,1,13,1,-2100,-1,-9999,MRD_x01_y01_z06,MRD_x01_y01_z06,None,ON,NORMAL +157,157,1,0,6,1,2,73.75,-81.2,386.22,147.2,20,0.6,7,8,18,9,3,6,3,-1,-1,1,13,2,-2100,-1,-9999,MRD_x01_y02_z06,MRD_x01_y02_z06,None,ON,HOT +158,158,1,0,6,1,3,73.75,-60.9,386.22,147.2,20,0.6,7,8,19,9,4,6,4,-1,-1,1,13,3,-2100,-1,-9999,MRD_x01_y03_z06,MRD_x01_y03_z06,None,ON,NORMAL +159,159,1,0,6,1,4,73.75,-40.6,386.22,147.2,20,0.6,7,8,20,9,5,6,5,-1,-1,1,13,4,-2100,-1,-9999,MRD_x01_y04_z06,MRD_x01_y04_z06,None,ON,NORMAL +160,160,1,0,6,1,5,73.75,-20.3,386.22,147.2,20,0.6,7,8,21,9,6,6,6,-1,-1,1,13,5,-2100,-1,-9999,MRD_x01_y05_z06,MRD_x01_y05_z06,None,ON,NORMAL +161,161,1,0,6,1,6,73.75,0,386.22,147.2,20,0.6,7,8,22,9,7,6,7,-1,-1,1,13,6,-2100,-1,-9999,MRD_x01_y06_z06,MRD_x01_y06_z06,None,ON,NORMAL +162,162,1,0,6,1,7,73.75,20.3,386.22,147.2,20,0.6,7,8,23,9,8,6,8,-1,-1,1,13,7,-2100,-1,-9999,MRD_x01_y07_z06,MRD_x01_y07_z06,None,ON,NORMAL +163,163,1,0,6,1,8,73.75,40.6,386.22,147.2,20,0.6,7,8,24,9,9,6,9,-1,-1,1,13,8,-2100,-1,-9999,MRD_x01_y08_z06,MRD_x01_y08_z06,None,ON,NORMAL +164,164,1,0,6,1,9,73.75,60.9,386.22,147.2,20,0.6,7,8,25,9,10,6,10,-1,-1,1,13,9,-1900,-1,-9999,MRD_x01_y09_z06,MRD_x01_y09_z06,None,ON,NORMAL +165,165,1,0,6,1,10,73.75,81.2,386.22,147.2,20,0.6,7,8,26,9,11,6,11,-1,-1,1,13,10,-2100,-1,-9999,MRD_x01_y10_z06,MRD_x01_y10_z06,None,ON,NORMAL +166,166,1,0,6,1,11,73.75,101.5,386.22,147.2,20,0.6,7,8,27,9,12,6,12,-1,-1,1,13,11,-2100,-1,-9999,MRD_x01_y11_z06,MRD_x01_y11_z06,None,ON,NORMAL +167,167,1,0,6,1,12,73.75,121.8,386.22,147.2,20,0.6,7,8,28,9,13,6,13,-1,-1,1,13,12,-2100,-1,-9999,MRD_x01_y12_z06,MRD_x01_y12_z06,None,ON,NORMAL +168,168,1,1,7,0,1,-121.8,-65.25,398.33,20,130.2,0.6,8,11,1,10,2,7,2,1,3,1,14,1,-1500,-1,-9999,MRD_x01_y00_z07,MRD_x01_y00_z07,None,ON,NORMAL +169,169,1,1,7,0,2,-101.5,-65.25,398.33,20,130.2,0.6,8,11,2,10,3,7,3,1,5,1,14,2,-1500,-1,-9999,MRD_x02_y00_z07,MRD_x02_y00_z07,None,ON,NORMAL +170,170,1,1,7,0,3,-81.2,-65.25,398.33,20,130.2,0.6,8,11,3,10,4,7,4,1,7,1,14,3,-1500,-1,-9999,MRD_x03_y00_z07,MRD_x03_y00_z07,None,ON,NORMAL +171,171,1,1,7,0,4,-60.9,-65.25,398.33,20,130.2,0.6,8,11,4,10,5,7,5,1,9,1,14,4,-1500,-1,-9999,MRD_x04_y00_z07,MRD_x04_y00_z07,None,ON,NORMAL +172,172,1,1,7,0,5,-40.6,-65.25,398.33,20,130.2,0.6,8,11,5,10,6,7,6,1,11,1,14,5,-1500,-1,-9999,MRD_x05_y00_z07,MRD_x05_y00_z07,None,ON,NORMAL +173,173,1,1,7,0,6,-20.3,-65.25,398.33,20,130.2,0.6,8,11,6,10,7,7,7,1,13,1,14,6,-1500,-1,-9999,MRD_x06_y00_z07,MRD_x06_y00_z07,None,ON,NORMAL +174,174,1,1,7,0,7,0,-65.25,398.33,20,130.2,0.6,8,11,7,10,8,7,8,12,2,1,14,7,-1500,-1,-9999,MRD_x07_y00_z07,MRD_x07_y00_z07,None,ON,NORMAL +175,175,1,1,7,0,8,20.3,-65.25,398.33,20,130.2,0.6,8,11,8,10,9,7,9,12,4,1,14,8,-1500,-1,-9999,MRD_x08_y00_z07,MRD_x08_y00_z07,None,ON,NORMAL +176,176,1,1,7,0,9,40.6,-65.25,398.33,20,130.2,0.6,8,11,9,10,10,7,10,12,6,1,14,9,-1500,-1,-9999,MRD_x09_y00_z07,MRD_x09_y00_z07,None,ON,NORMAL +177,177,1,1,7,0,10,60.9,-65.25,398.33,20,130.2,0.6,8,11,10,10,11,7,11,12,8,1,14,10,-1500,-1,-9999,MRD_x10_y00_z07,MRD_x10_y00_z07,None,ON,NORMAL +178,178,1,1,7,0,11,81.2,-65.25,398.33,20,130.2,0.6,8,11,11,10,12,7,12,12,10,1,14,11,-1500,-1,-9999,MRD_x11_y00_z07,MRD_x11_y00_z07,None,ON,NORMAL +179,179,1,1,7,0,12,101.5,-65.25,398.33,20,130.2,0.6,8,11,12,10,13,7,13,12,12,1,14,12,-1500,-1,-9999,MRD_x12_y00_z07,MRD_x12_y00_z07,None,ON,NORMAL +180,180,1,1,7,0,13,121.8,-65.25,398.33,20,130.2,0.6,8,11,13,10,14,7,14,12,14,1,14,13,-1500,-1,-9999,MRD_x13_y00_z07,MRD_x13_y00_z07,None,ON,NORMAL +181,181,1,1,7,1,1,-121.8,65.25,398.33,20,130.2,0.6,8,11,17,12,2,8,2,1,4,1,15,1,-1500,-1,-9999,MRD_x01_y01_z07,MRD_x01_y01_z07,None,ON,NORMAL +182,182,1,1,7,1,2,-101.5,65.25,398.33,20,130.2,0.6,8,11,18,12,3,8,3,1,6,1,15,2,-1500,-1,-9999,MRD_x02_y01_z07,MRD_x02_y01_z07,None,ON,NORMAL +183,183,1,1,7,1,3,-81.2,65.25,398.33,20,130.2,0.6,8,11,19,12,4,8,4,1,8,1,15,3,-1300,-1,-9999,MRD_x03_y01_z07,MRD_x03_y01_z07,None,ON,HOT +184,184,1,1,7,1,4,-60.9,65.25,398.33,20,130.2,0.6,8,11,20,12,5,8,5,1,10,1,15,4,-1500,-1,-9999,MRD_x04_y01_z07,MRD_x04_y01_z07,None,ON,NORMAL +185,185,1,1,7,1,5,-40.6,65.25,398.33,20,130.2,0.6,8,11,21,12,6,8,6,1,12,1,15,5,-2000,-1,-9999,MRD_x05_y01_z07,MRD_x05_y01_z07,None,ON,NORMAL +186,186,1,1,7,1,6,-20.3,65.25,398.33,20,130.2,0.6,8,11,22,12,7,8,7,1,14,1,15,6,-2000,-1,-9999,MRD_x06_y01_z07,MRD_x06_y01_z07,None,ON,NORMAL +187,187,1,1,7,1,7,0,65.25,398.33,20,130.2,0.6,8,11,23,12,8,8,8,12,1,1,15,7,-2000,-1,-9999,MRD_x07_y01_z07,MRD_x07_y01_z07,None,ON,NORMAL +188,188,1,1,7,1,8,20.3,65.25,398.33,20,130.2,0.6,8,11,24,12,9,8,9,12,3,1,15,8,-2000,-1,-9999,MRD_x08_y01_z07,MRD_x08_y01_z07,None,ON,NORMAL +189,189,1,1,7,1,9,40.6,65.25,398.33,20,130.2,0.6,8,11,25,12,10,8,10,12,5,1,15,9,-1500,-1,-9999,MRD_x09_y01_z07,MRD_x09_y01_z07,None,ON,NORMAL +190,190,1,1,7,1,10,60.9,65.25,398.33,20,130.2,0.6,8,11,26,12,11,8,11,12,7,1,15,10,-1500,-1,-9999,MRD_x10_y01_z07,MRD_x10_y01_z07,None,ON,NORMAL +191,191,1,1,7,1,11,81.2,65.25,398.33,20,130.2,0.6,8,11,27,12,12,8,12,12,9,1,15,11,-1500,-1,-9999,MRD_x11_y01_z07,MRD_x11_y01_z07,None,ON,NORMAL +192,192,1,1,7,1,12,101.5,65.25,398.33,20,130.2,0.6,8,11,28,12,13,8,13,12,11,1,15,12,-1500,-1,-9999,MRD_x12_y01_z07,MRD_x12_y01_z07,None,ON,NORMAL +193,193,1,1,7,1,13,121.8,65.25,398.33,20,130.2,0.6,8,11,29,12,14,8,14,12,13,1,15,13,-1500,-1,-9999,MRD_x13_y01_z07,MRD_x13_y01_z07,None,ON,NORMAL +194,194,1,0,8,0,0,-73.75,-121.8,410.44,147.2,20,0.6,7,11,0,10,1,7,1,-1,-1,1,0,0,2100,1,EMI 9939B,MRD_x00_y00_z08,MRD_x00_y00_z08,None,ON,NORMAL +195,195,1,0,8,0,1,-73.75,-101.5,410.44,147.2,20,0.6,7,11,1,10,2,7,2,-1,-1,1,0,1,2100,1,EMI 9939B,MRD_x00_y01_z08,MRD_x00_y01_z08,None,OFF,NORMAL +196,196,1,0,8,0,2,-73.75,-81.2,410.44,147.2,20,0.6,7,11,2,10,3,7,3,-1,-1,1,0,2,2100,1,EMI 9939B,MRD_x00_y02_z08,MRD_x00_y02_z08,None,ON,NORMAL +197,197,1,0,8,0,3,-73.75,-60.9,410.44,147.2,20,0.6,7,11,3,10,4,7,4,-1,-1,1,0,3,2100,1,EMI 9939B,MRD_x00_y03_z08,MRD_x00_y03_z08,None,ON,NORMAL +198,198,1,0,8,0,4,-73.75,-40.6,410.44,147.2,20,0.6,7,11,4,10,5,7,5,-1,-1,1,0,4,2100,1,EMI 9939B,MRD_x00_y04_z08,MRD_x00_y04_z08,None,ON,NORMAL +199,199,1,0,8,0,5,-73.75,-20.3,410.44,147.2,20,0.6,7,11,5,10,6,7,6,-1,-1,1,0,5,2100,1,EMI 9939B,MRD_x00_y05_z08,MRD_x00_y05_z08,None,ON,NORMAL +200,200,1,0,8,0,6,-73.75,0,410.44,147.2,20,0.6,7,11,6,10,7,7,7,-1,-1,1,0,6,2100,1,EMI 9939B,MRD_x00_y06_z08,MRD_x00_y06_z08,None,ON,NORMAL +201,201,1,0,8,0,7,-73.75,20.3,410.44,147.2,20,0.6,7,11,7,10,8,7,8,-1,-1,1,0,7,2100,1,EMI 9939B,MRD_x00_y07_z08,MRD_x00_y07_z08,None,ON,NORMAL +202,202,1,0,8,0,8,-73.75,40.6,410.44,147.2,20,0.6,7,11,8,10,9,7,9,-1,-1,1,0,8,2100,1,EMI 9939B,MRD_x00_y08_z08,MRD_x00_y08_z08,None,ON,NORMAL +203,203,1,0,8,0,9,-73.75,60.9,410.44,147.2,20,0.6,7,11,9,10,10,7,10,-1,-1,1,0,9,2100,1,EMI 9939B,MRD_x00_y09_z08,MRD_x00_y09_z08,None,ON,NORMAL +204,204,1,0,8,0,10,-73.75,81.2,410.44,147.2,20,0.6,7,11,10,10,11,7,11,-1,-1,1,0,10,2100,1,EMI 9939B,MRD_x00_y10_z08,MRD_x00_y10_z08,None,ON,NORMAL +205,205,1,0,8,0,11,-73.75,101.5,410.44,147.2,20,0.6,7,11,11,10,12,7,12,-1,-1,1,0,11,2100,1,EMI 9939B,MRD_x00_y11_z08,MRD_x00_y11_z08,None,ON,NORMAL +206,206,1,0,8,0,12,-73.75,121.8,410.44,147.2,20,0.6,7,11,12,10,13,7,13,-1,-1,1,0,12,2100,1,EMI 9939B,MRD_x00_y12_z08,MRD_x00_y12_z08,None,ON,NORMAL +207,207,1,0,8,1,0,73.75,-121.8,410.44,147.2,20,0.6,7,11,16,12,1,8,1,-1,-1,1,1,13,2100,1,EMI 9939B,MRD_x01_y00_z08,MRD_x01_y00_z08,< HV 1-1-0 is brokenNone,ON,NORMAL +208,208,1,0,8,1,1,73.75,-101.5,410.44,147.2,20,0.6,7,11,17,12,2,8,2,-1,-1,1,1,1,2100,1,EMI 9939B,MRD_x01_y01_z08,MRD_x01_y01_z08,None,ON,NORMAL +209,209,1,0,8,1,2,73.75,-81.2,410.44,147.2,20,0.6,7,11,18,12,3,8,3,-1,-1,1,1,2,2100,1,EMI 9939B,MRD_x01_y02_z08,MRD_x01_y02_z08,None,ON,NORMAL +210,210,1,0,8,1,3,73.75,-60.9,410.44,147.2,20,0.6,7,11,19,12,4,8,4,-1,-1,1,1,3,2100,1,EMI 9939B,MRD_x01_y03_z08,MRD_x01_y03_z08,None,ON,NORMAL +211,211,1,0,8,1,4,73.75,-40.6,410.44,147.2,20,0.6,7,11,20,12,5,8,5,-1,-1,1,1,4,2100,1,EMI 9939B,MRD_x01_y04_z08,MRD_x01_y04_z08,None,ON,NORMAL +212,212,1,0,8,1,5,73.75,-20.3,410.44,147.2,20,0.6,7,11,21,12,6,8,6,-1,-1,1,1,5,2100,1,EMI 9939B,MRD_x01_y05_z08,MRD_x01_y05_z08,None,ON,HOT +213,213,1,0,8,1,6,73.75,0,410.44,147.2,20,0.6,7,11,22,12,7,8,7,-1,-1,1,1,6,2100,1,EMI 9939B,MRD_x01_y06_z08,MRD_x01_y06_z08,None,ON,NORMAL +214,214,1,0,8,1,7,73.75,20.3,410.44,147.2,20,0.6,7,11,23,12,8,8,8,-1,-1,1,1,7,2100,1,EMI 9939B,MRD_x01_y07_z08,MRD_x01_y07_z08,None,ON,NORMAL +215,215,1,0,8,1,8,73.75,40.6,410.44,147.2,20,0.6,7,11,24,12,9,8,9,-1,-1,1,1,8,2100,1,EMI 9939B,MRD_x01_y08_z08,MRD_x01_y08_z08,None,OFF,NORMAL +216,216,1,0,8,1,9,73.75,60.9,410.44,147.2,20,0.6,7,11,25,12,10,8,10,-1,-1,1,1,9,2100,1,EMI 9939B,MRD_x01_y09_z08,MRD_x01_y09_z08,None,ON,NORMAL +217,217,1,0,8,1,10,73.75,81.2,410.44,147.2,20,0.6,7,11,26,12,11,8,11,-1,-1,1,1,10,2100,1,EMI 9939B,MRD_x01_y10_z08,MRD_x01_y10_z08,None,OFF,NORMAL +218,218,1,0,8,1,11,73.75,101.5,410.44,147.2,20,0.6,7,11,27,12,12,8,12,-1,-1,1,1,11,2100,1,EMI 9939B,MRD_x01_y11_z08,MRD_x01_y11_z08,None,OFF,NORMAL +219,219,1,0,8,1,12,73.75,121.8,410.44,147.2,20,0.6,7,11,28,12,13,8,13,-1,-1,1,1,12,2100,1,EMI 9939B,MRD_x01_y12_z08,MRD_x01_y12_z08,None,ON,NORMAL +220,220,1,1,9,0,0,-142.1,-65.25,422.55,20,130.2,0.6,8,14,0,13,1,9,1,2,1,2,0,0,-1500,-1,-9999,MRD_x00_y00_z09,MRD_x00_y00_z09,None,ON,NORMAL +221,221,1,1,9,0,1,-121.8,-65.25,422.55,20,130.2,0.6,8,14,1,13,2,9,2,2,3,2,0,1,-1500,-1,-9999,MRD_x01_y00_z09,MRD_x01_y00_z09,None,ON,NORMAL +222,222,1,1,9,0,2,-101.5,-65.25,422.55,20,130.2,0.6,8,14,2,13,3,9,3,2,5,2,0,2,-1500,-1,-9999,MRD_x02_y00_z09,MRD_x02_y00_z09,None,ON,NORMAL +223,223,1,1,9,0,3,-81.2,-65.25,422.55,20,130.2,0.6,8,14,3,13,4,9,4,2,7,2,0,3,-1500,-1,-9999,MRD_x03_y00_z09,MRD_x03_y00_z09,None,ON,NORMAL +224,224,1,1,9,0,4,-60.9,-65.25,422.55,20,130.2,0.6,8,14,4,13,5,9,5,2,9,2,0,4,-1500,-1,-9999,MRD_x04_y00_z09,MRD_x04_y00_z09,None,OFF,HOT +225,225,1,1,9,0,5,-40.6,-65.25,422.55,20,130.2,0.6,8,14,5,13,6,9,6,2,11,2,0,5,-2000,-1,-9999,MRD_x05_y00_z09,MRD_x05_y00_z09,None,ON,NORMAL +226,226,1,1,9,0,6,-20.3,-65.25,422.55,20,130.2,0.6,8,14,6,13,7,9,7,2,13,2,0,6,-2000,-1,-9999,MRD_x06_y00_z09,MRD_x06_y00_z09,None,ON,NORMAL +227,227,1,1,9,0,7,0,-65.25,422.55,20,130.2,0.6,8,11,31,12,16,9,8,11,1,2,0,7,-2000,-1,-9999,MRD_x07_y00_z09,MRD_x07_y00_z09,Discriminator on rack 8 slot 13 channel 8 has no NIM outputNone,ON,NORMAL +228,228,1,1,9,0,8,20.3,-65.25,422.55,20,130.2,0.6,8,14,8,13,9,9,9,11,2,2,0,8,-2000,-1,-9999,MRD_x08_y00_z09,MRD_x08_y00_z09,None,ON,NORMAL +229,229,1,1,9,0,9,40.6,-65.25,422.55,20,130.2,0.6,8,14,9,13,10,9,10,11,3,2,0,9,-1500,-1,-9999,MRD_x09_y00_z09,MRD_x09_y00_z09,None,ON,NORMAL +230,230,1,1,9,0,10,60.9,-65.25,422.55,20,130.2,0.6,8,14,10,13,11,9,11,11,4,2,0,10,-1500,-1,-9999,MRD_x10_y00_z09,MRD_x10_y00_z09,None,ON,HOT +231,231,1,1,9,0,11,81.2,-65.25,422.55,20,130.2,0.6,8,14,11,13,12,9,12,11,5,2,0,11,-1500,-1,-9999,MRD_x11_y00_z09,MRD_x11_y00_z09,None,ON,NORMAL +232,232,1,1,9,0,12,101.5,-65.25,422.55,20,130.2,0.6,8,14,15,13,16,9,13,11,6,2,0,12,-1500,-1,-9999,MRD_x12_y00_z09,MRD_x12_y00_z09,slot 13 on this disc had a very high rate; shifted signal to slot 16None,ON,NORMAL +233,233,1,1,9,0,13,121.8,-65.25,422.55,20,130.2,0.6,8,14,13,13,14,9,14,11,7,2,0,13,-1500,-1,-9999,MRD_x13_y00_z09,MRD_x13_y00_z09,None,ON,NORMAL +234,234,1,1,9,0,14,142.1,-65.25,422.55,20,130.2,0.6,8,14,14,13,15,9,15,11,8,2,0,14,-1500,-1,-9999,MRD_x14_y00_z09,MRD_x14_y00_z09,None,ON,NORMAL +235,235,1,1,9,1,0,-142.1,65.25,422.55,20,130.2,0.6,8,14,16,15,1,10,1,2,2,2,1,0,-1500,-1,-9999,MRD_x00_y01_z09,MRD_x00_y01_z09,None,ON,NORMAL +236,236,1,1,9,1,1,-121.8,65.25,422.55,20,130.2,0.6,8,14,17,15,2,10,2,2,4,2,1,1,-1500,-1,-9999,MRD_x01_y01_z09,MRD_x01_y01_z09,None,ON,NORMAL +237,237,1,1,9,1,2,-101.5,65.25,422.55,20,130.2,0.6,8,14,18,15,3,10,3,2,6,2,1,2,-1300,-1,-9999,MRD_x02_y01_z09,MRD_x02_y01_z09,None,ON,NORMAL +238,238,1,1,9,1,3,-81.2,65.25,422.55,20,130.2,0.6,8,14,19,15,4,10,4,2,8,2,1,3,-1500,-1,-9999,MRD_x03_y01_z09,MRD_x03_y01_z09,None,ON,NORMAL +239,239,1,1,9,1,4,-60.9,65.25,422.55,20,130.2,0.6,8,14,20,15,5,10,5,2,10,2,1,4,-1500,-1,-9999,MRD_x04_y01_z09,MRD_x04_y01_z09,None,ON,NORMAL +240,240,1,1,9,1,5,-40.6,65.25,422.55,20,130.2,0.6,8,14,21,15,6,10,6,2,12,2,1,5,-1500,-1,-9999,MRD_x05_y01_z09,MRD_x05_y01_z09,None,ON,NORMAL +241,241,1,1,9,1,6,-20.3,65.25,422.55,20,130.2,0.6,8,14,22,15,7,10,7,2,14,2,1,6,-1500,-1,-9999,MRD_x06_y01_z09,MRD_x06_y01_z09,None,ON,NORMAL +242,242,1,1,9,1,7,0,65.25,422.55,20,130.2,0.6,8,14,23,15,8,10,8,12,18,2,1,7,-1500,-1,-9999,MRD_x07_y01_z09,MRD_x07_y01_z09,None,ON,NORMAL +243,243,1,1,9,1,8,20.3,65.25,422.55,20,130.2,0.6,8,14,24,15,9,10,9,12,20,2,1,8,-1500,-1,-9999,MRD_x08_y01_z09,MRD_x08_y01_z09,None,ON,NORMAL +244,244,1,1,9,1,9,40.6,65.25,422.55,20,130.2,0.6,8,14,25,15,10,10,10,12,22,2,1,9,-1500,-1,-9999,MRD_x09_y01_z09,MRD_x09_y01_z09,None,ON,NORMAL +245,245,1,1,9,1,10,60.9,65.25,422.55,20,130.2,0.6,8,14,26,15,11,10,11,12,24,2,1,10,-1500,-1,-9999,MRD_x10_y01_z09,MRD_x10_y01_z09,None,ON,NORMAL +246,246,1,1,9,1,11,81.2,65.25,422.55,20,130.2,0.6,8,14,27,15,12,10,12,12,26,2,1,11,-1500,-1,-9999,MRD_x11_y01_z09,MRD_x11_y01_z09,None,ON,NORMAL +247,247,1,1,9,1,12,101.5,65.25,422.55,20,130.2,0.6,8,14,28,15,13,10,13,12,28,2,1,12,-1500,-1,-9999,MRD_x12_y01_z09,MRD_x12_y01_z09,None,ON,NORMAL +248,248,1,1,9,1,13,121.8,65.25,422.55,20,130.2,0.6,8,14,29,15,14,10,14,12,30,2,1,13,-1500,-1,-9999,MRD_x13_y01_z09,MRD_x13_y01_z09,None,ON,NORMAL +249,249,1,1,9,1,14,142.1,65.25,422.55,20,130.2,0.6,8,14,30,15,15,10,15,12,32,2,1,14,-1500,-1,-9999,MRD_x14_y01_z09,MRD_x14_y01_z09,None,ON,HOT +250,250,1,0,10,0,0,-73.75,-121.8,434.66,147.2,20,0.6,7,19,0,18,1,9,1,-1,-1,2,2,0,-2100,-1,-9999,MRD_x00_y00_z10,MRD_x00_y00_z10,None,ON,NORMAL +251,251,1,0,10,0,1,-73.75,-101.5,434.66,147.2,20,0.6,7,19,1,18,2,9,2,-1,-1,2,2,1,-1600,-1,-9999,MRD_x00_y01_z10,MRD_x00_y01_z10,None,OFF,NORMAL +252,252,1,0,10,0,2,-73.75,-81.2,434.66,147.2,20,0.6,7,19,2,18,3,9,3,-1,-1,2,2,2,-2100,-1,-9999,MRD_x00_y02_z10,MRD_x00_y02_z10,None,ON,NORMAL +253,253,1,0,10,0,3,-73.75,-60.9,434.66,147.2,20,0.6,7,19,3,18,4,9,4,-1,-1,2,2,3,-2100,-1,-9999,MRD_x00_y03_z10,MRD_x00_y03_z10,None,ON,NORMAL +254,254,1,0,10,0,4,-73.75,-40.6,434.66,147.2,20,0.6,7,19,4,18,5,9,5,-1,-1,2,2,4,-2100,-1,-9999,MRD_x00_y04_z10,MRD_x00_y04_z10,None,OFF,NORMAL +255,255,1,0,10,0,5,-73.75,-20.3,434.66,147.2,20,0.6,7,19,5,18,6,9,6,-1,-1,2,2,5,-2100,-1,-9999,MRD_x00_y05_z10,MRD_x00_y05_z10,None,ON,NORMAL +256,256,1,0,10,0,6,-73.75,0,434.66,147.2,20,0.6,7,19,6,18,7,9,7,-1,-1,2,2,6,-2100,-1,-9999,MRD_x00_y06_z10,MRD_x00_y06_z10,None,ON,NORMAL +257,257,1,0,10,0,7,-73.75,20.3,434.66,147.2,20,0.6,7,19,7,18,8,9,8,-1,-1,2,2,7,-2100,-1,-9999,MRD_x00_y07_z10,MRD_x00_y07_z10,None,ON,NORMAL +258,258,1,0,10,0,8,-73.75,40.6,434.66,147.2,20,0.6,7,19,8,18,9,9,9,-1,-1,2,2,8,-1900,-1,-9999,MRD_x00_y08_z10,MRD_x00_y08_z10,None,ON,NORMAL +259,259,1,0,10,0,9,-73.75,60.9,434.66,147.2,20,0.6,7,19,9,18,10,9,10,-1,-1,2,2,9,-2100,-1,-9999,MRD_x00_y09_z10,MRD_x00_y09_z10,None,ON,NORMAL +260,260,1,0,10,0,10,-73.75,81.2,434.66,147.2,20,0.6,7,19,10,18,11,9,11,-1,-1,2,2,10,-2100,-1,-9999,MRD_x00_y10_z10,MRD_x00_y10_z10,None,OFF,NORMAL +261,261,1,0,10,0,11,-73.75,101.5,434.66,147.2,20,0.6,7,19,11,18,12,9,12,-1,-1,2,2,11,-2100,-1,-9999,MRD_x00_y11_z10,MRD_x00_y11_z10,Crate 2 card 3 ch11 is broken: nothing connectedNone,ON,NORMAL +262,262,1,0,10,0,12,-73.75,121.8,434.66,147.2,20,0.6,7,19,12,18,13,9,13,-1,-1,2,2,12,-2100,-1,-9999,MRD_x00_y12_z10,MRD_x00_y12_z10,None,ON,NORMAL +263,263,1,0,10,1,0,73.75,-121.8,434.66,147.2,20,0.6,7,19,16,20,1,10,1,-1,-1,2,3,0,-2100,-1,-9999,MRD_x01_y00_z10,MRD_x01_y00_z10,None,ON,HOT +264,264,1,0,10,1,1,73.75,-101.5,434.66,147.2,20,0.6,7,19,17,20,2,10,2,-1,-1,2,3,1,-1900,-1,-9999,MRD_x01_y01_z10,MRD_x01_y01_z10,None,ON,NORMAL +265,265,1,0,10,1,2,73.75,-81.2,434.66,147.2,20,0.6,7,19,18,20,3,10,3,-1,-1,2,3,2,-1600,-1,-9999,MRD_x01_y02_z10,MRD_x01_y02_z10,None,ON,NORMAL +266,266,1,0,10,1,3,73.75,-60.9,434.66,147.2,20,0.6,7,19,19,20,4,10,4,-1,-1,2,3,3,-1800,-1,-9999,MRD_x01_y03_z10,MRD_x01_y03_z10,None,ON,NORMAL +267,267,1,0,10,1,4,73.75,-40.6,434.66,147.2,20,0.6,7,19,20,20,5,10,5,-1,-1,2,3,4,-1800,-1,-9999,MRD_x01_y04_z10,MRD_x01_y04_z10,None,ON,NORMAL +268,268,1,0,10,1,5,73.75,-20.3,434.66,147.2,20,0.6,7,19,21,20,6,10,6,-1,-1,2,3,5,-2100,-1,-9999,MRD_x01_y05_z10,MRD_x01_y05_z10,None,ON,NORMAL +269,269,1,0,10,1,6,73.75,0,434.66,147.2,20,0.6,7,19,22,20,7,10,7,-1,-1,2,3,6,-2100,-1,-9999,MRD_x01_y06_z10,MRD_x01_y06_z10,None,ON,NORMAL +270,270,1,0,10,1,7,73.75,20.3,434.66,147.2,20,0.6,7,19,23,20,8,10,8,-1,-1,2,3,7,-1600,-1,-9999,MRD_x01_y07_z10,MRD_x01_y07_z10,None,ON,NORMAL +271,271,1,0,10,1,8,73.75,40.6,434.66,147.2,20,0.6,7,19,24,20,9,10,9,-1,-1,2,3,8,-2100,-1,-9999,MRD_x01_y08_z10,MRD_x01_y08_z10,None,OFF,HOT +272,272,1,0,10,1,9,73.75,60.9,434.66,147.2,20,0.6,7,19,25,20,10,10,10,-1,-1,2,3,9,-2100,-1,-9999,MRD_x01_y09_z10,MRD_x01_y09_z10,None,ON,HOT +273,273,1,0,10,1,10,73.75,81.2,434.66,147.2,20,0.6,7,19,26,20,11,10,11,-1,-1,2,3,10,-1600,-1,-9999,MRD_x01_y10_z10,MRD_x01_y10_z10,None,ON,NORMAL +274,274,1,0,10,1,11,73.75,101.5,434.66,147.2,20,0.6,7,19,27,20,12,10,12,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y11_z10,MRD_x01_y11_z10,None,ON,HOT +275,275,1,0,10,1,12,73.75,121.8,434.66,147.2,20,0.6,7,19,28,20,13,10,13,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y12_z10,MRD_x01_y12_z10,None,OFF,HOT +276,276,1,1,11,0,0,-142.1,-65.25,446.77,20,130.2,0.6,8,17,0,16,1,11,1,1,19,2,4,0,-1500,-1,-9999,MRD_x00_y00_z11,MRD_x00_y00_z11,None,ON,HOT +277,277,1,1,11,0,1,-121.8,-65.25,446.77,20,130.2,0.6,8,17,1,16,2,11,2,1,21,2,4,1,-1500,-1,-9999,MRD_x01_y00_z11,MRD_x01_y00_z11,None,ON,NORMAL +278,278,1,1,11,0,2,-101.5,-65.25,446.77,20,130.2,0.6,8,17,2,16,3,11,3,1,23,2,4,2,-1500,-1,-9999,MRD_x02_y00_z11,MRD_x02_y00_z11,None,ON,NORMAL +279,279,1,1,11,0,3,-81.2,-65.25,446.77,20,130.2,0.6,8,17,3,16,4,11,4,1,25,2,4,3,-1300,-1,-9999,MRD_x03_y00_z11,MRD_x03_y00_z11,None,ON,NORMAL +280,280,1,1,11,0,4,-60.9,-65.25,446.77,20,130.2,0.6,8,17,4,16,5,11,5,1,27,2,4,4,-1500,-1,-9999,MRD_x04_y00_z11,MRD_x04_y00_z11,None,ON,NORMAL +281,281,1,1,11,0,5,-40.6,-65.25,446.77,20,130.2,0.6,8,17,5,16,6,11,6,1,29,2,4,5,-1500,-1,-9999,MRD_x05_y00_z11,MRD_x05_y00_z11,None,ON,NORMAL +282,282,1,1,11,0,6,-20.3,-65.25,446.77,20,130.2,0.6,8,17,6,16,7,11,7,1,31,2,4,6,-1500,-1,-9999,MRD_x06_y00_z11,MRD_x06_y00_z11,None,ON,NORMAL +283,283,1,1,11,0,7,0,-65.25,446.77,20,130.2,0.6,8,17,7,16,8,11,8,12,17,2,4,7,-1500,-1,-9999,MRD_x07_y00_z11,MRD_x07_y00_z11,None,ON,HOT +284,284,1,1,11,0,8,20.3,-65.25,446.77,20,130.2,0.6,8,17,8,16,9,11,9,12,19,2,4,8,-1500,-1,-9999,MRD_x08_y00_z11,MRD_x08_y00_z11,None,ON,NORMAL +285,285,1,1,11,0,9,40.6,-65.25,446.77,20,130.2,0.6,8,17,9,16,10,11,10,12,21,2,4,9,-1300,-1,-9999,MRD_x09_y00_z11,MRD_x09_y00_z11,None,ON,NORMAL +286,286,1,1,11,0,10,60.9,-65.25,446.77,20,130.2,0.6,8,17,10,16,11,11,11,12,23,2,4,10,-1500,-1,-9999,MRD_x10_y00_z11,MRD_x10_y00_z11,None,ON,NORMAL +287,287,1,1,11,0,11,81.2,-65.25,446.77,20,130.2,0.6,8,17,11,16,12,11,12,12,25,2,4,11,-1500,-1,-9999,MRD_x11_y00_z11,MRD_x11_y00_z11,None,ON,NORMAL +288,288,1,1,11,0,12,101.5,-65.25,446.77,20,130.2,0.6,8,17,12,16,13,11,13,12,27,2,4,12,-1500,-1,-9999,MRD_x12_y00_z11,MRD_x12_y00_z11,None,ON,NORMAL +289,289,1,1,11,0,13,121.8,-65.25,446.77,20,130.2,0.6,8,17,13,16,14,11,14,12,29,2,4,13,-1500,-1,-9999,MRD_x13_y00_z11,MRD_x13_y00_z11,None,ON,NORMAL +290,290,1,1,11,0,14,142.1,-65.25,446.77,20,130.2,0.6,8,17,14,16,15,11,15,12,31,2,4,14,-1500,-1,-9999,MRD_x14_y00_z11,MRD_x14_y00_z11,None,ON,NORMAL +291,291,1,1,11,1,0,-142.1,65.25,446.77,20,130.2,0.6,8,17,16,18,1,12,1,1,20,2,5,0,-1500,-1,-9999,MRD_x00_y01_z11,MRD_x00_y01_z11,None,ON,NORMAL +292,292,1,1,11,1,1,-121.8,65.25,446.77,20,130.2,0.6,8,17,17,18,2,12,2,1,22,2,5,1,-1500,-1,-9999,MRD_x01_y01_z11,MRD_x01_y01_z11,None,ON,NORMAL +293,293,1,1,11,1,2,-101.5,65.25,446.77,20,130.2,0.6,8,17,18,18,3,12,3,1,24,2,5,3,-1500,-1,-9999,MRD_x02_y01_z11,MRD_x02_y01_z11,None,ON,NORMAL +294,294,1,1,11,1,3,-81.2,65.25,446.77,20,130.2,0.6,8,17,19,18,4,12,4,1,26,2,5,4,-1500,-1,-9999,MRD_x03_y01_z11,MRD_x03_y01_z11,None,ON,NORMAL +295,295,1,1,11,1,4,-60.9,65.25,446.77,20,130.2,0.6,8,17,20,18,5,12,5,1,28,2,5,5,-1500,-1,-9999,MRD_x04_y01_z11,MRD_x04_y01_z11,None,ON,NORMAL +296,296,1,1,11,1,5,-40.6,65.25,446.77,20,130.2,0.6,8,17,21,18,6,12,6,1,30,2,5,6,-1500,-1,-9999,MRD_x05_y01_z11,MRD_x05_y01_z11,None,ON,NORMAL +297,297,1,1,11,1,6,-20.3,65.25,446.77,20,130.2,0.6,8,17,22,18,7,12,7,1,32,2,5,7,-1500,-1,-9999,MRD_x06_y01_z11,MRD_x06_y01_z11,None,ON,NORMAL +298,298,1,1,11,1,7,0,65.25,446.77,20,130.2,0.6,8,17,23,18,8,12,8,10,1,2,5,8,-1500,-1,-9999,MRD_x07_y01_z11,MRD_x07_y01_z11,None,ON,NORMAL +299,299,1,1,11,1,8,20.3,65.25,446.77,20,130.2,0.6,8,17,24,18,9,12,9,10,2,2,5,9,-1500,-1,-9999,MRD_x08_y01_z11,MRD_x08_y01_z11,None,ON,NORMAL +300,300,1,1,11,1,9,40.6,65.25,446.77,20,130.2,0.6,8,17,25,18,10,12,10,10,3,2,5,10,-1300,-1,-9999,MRD_x09_y01_z11,MRD_x09_y01_z11,None,ON,NORMAL +301,301,1,1,11,1,10,60.9,65.25,446.77,20,130.2,0.6,8,17,26,18,11,12,11,10,4,2,5,11,-1300,-1,-9999,MRD_x10_y01_z11,MRD_x10_y01_z11,None,ON,NORMAL +302,302,1,1,11,1,11,81.2,65.25,446.77,20,130.2,0.6,8,17,27,18,12,12,12,10,5,2,5,12,-1300,-1,-9999,MRD_x11_y01_z11,MRD_x11_y01_z11,None,ON,NORMAL +303,303,1,1,11,1,12,101.5,65.25,446.77,20,130.2,0.6,8,17,28,18,13,12,13,10,6,2,5,13,-1300,-1,-9999,MRD_x12_y01_z11,MRD_x12_y01_z11,None,ON,NORMAL +304,304,1,1,11,1,13,121.8,65.25,446.77,20,130.2,0.6,8,17,29,18,14,12,14,10,7,2,5,14,-1500,-1,-9999,MRD_x13_y01_z11,MRD_x13_y01_z11,None,ON,NORMAL +305,305,1,1,11,1,14,142.1,65.25,446.77,20,130.2,0.6,8,17,30,18,15,12,15,10,8,2,5,14,-1500,-1,-9999,MRD_x14_y01_z11,MRD_x14_y01_z11,None,ON,NORMAL +306,306,1,0,12,0,0,-73.75,-121.8,458.88,147.2,20,0.6,7,22,0,21,1,11,1,-1,-1,2,6,0,-2100,-1,-9999,MRD_x00_y00_z12,MRD_x00_y00_z12,None,ON,NORMAL +307,307,1,0,12,0,1,-73.75,-101.5,458.88,147.2,20,0.6,7,22,1,21,2,11,2,-1,-1,2,6,1,-2100,-1,-9999,MRD_x00_y01_z12,MRD_x00_y01_z12,None,ON,NORMAL +308,308,1,0,12,0,2,-73.75,-81.2,458.88,147.2,20,0.6,7,22,2,21,3,11,3,-1,-1,2,6,2,-2100,-1,-9999,MRD_x00_y02_z12,MRD_x00_y02_z12,None,ON,NORMAL +309,309,1,0,12,0,3,-73.75,-60.9,458.88,147.2,20,0.6,7,22,3,21,4,11,4,-1,-1,2,6,3,-2100,-1,-9999,MRD_x00_y03_z12,MRD_x00_y03_z12,None,ON,NORMAL +310,310,1,0,12,0,4,-73.75,-40.6,458.88,147.2,20,0.6,7,22,4,21,5,11,5,-1,-1,2,6,4,-1900,-1,-9999,MRD_x00_y04_z12,MRD_x00_y04_z12,None,ON,NORMAL +311,311,1,0,12,0,5,-73.75,-20.3,458.88,147.2,20,0.6,7,22,5,21,6,11,6,-1,-1,2,6,5,-2100,-1,-9999,MRD_x00_y05_z12,MRD_x00_y05_z12,None,ON,NORMAL +312,312,1,0,12,0,6,-73.75,0,458.88,147.2,20,0.6,7,22,6,21,7,11,7,-1,-1,2,6,6,-1900,-1,-9999,MRD_x00_y06_z12,MRD_x00_y06_z12,None,ON,NORMAL +313,313,1,0,12,0,7,-73.75,20.3,458.88,147.2,20,0.6,7,22,7,21,8,11,8,-1,-1,2,6,7,-2100,-1,-9999,MRD_x00_y07_z12,MRD_x00_y07_z12,None,ON,NORMAL +314,314,1,0,12,0,8,-73.75,40.6,458.88,147.2,20,0.6,7,22,8,21,9,11,9,-1,-1,2,6,8,-2100,-1,-9999,MRD_x00_y08_z12,MRD_x00_y08_z12,None,ON,NORMAL +315,315,1,0,12,0,9,-73.75,60.9,458.88,147.2,20,0.6,7,22,9,21,10,11,10,-1,-1,2,6,9,-2100,-1,-9999,MRD_x00_y09_z12,MRD_x00_y09_z12,None,ON,NORMAL +316,316,1,0,12,0,10,-73.75,81.2,458.88,147.2,20,0.6,7,22,10,21,11,11,11,-1,-1,2,6,10,-2100,-1,-9999,MRD_x00_y10_z12,MRD_x00_y10_z12,None,ON,NORMAL +317,317,1,0,12,0,11,-73.75,101.5,458.88,147.2,20,0.6,7,22,11,21,12,11,12,-1,-1,2,6,11,-2100,-1,-9999,MRD_x00_y11_z12,MRD_x00_y11_z12,None,ON,NORMAL +318,318,1,0,12,0,12,-73.75,121.8,458.88,147.2,20,0.6,7,22,12,21,13,11,13,-1,-1,2,6,12,-2100,-1,-9999,MRD_x00_y12_z12,MRD_x00_y12_z12,None,ON,NORMAL +319,319,1,0,12,1,0,73.75,-121.8,458.88,147.2,20,0.6,7,22,16,23,1,12,1,-1,-1,2,7,0,-2100,-1,-9999,MRD_x01_y00_z12,MRD_x01_y00_z12,None,ON,NORMAL +320,320,1,0,12,1,1,73.75,-101.5,458.88,147.2,20,0.6,7,22,17,23,2,12,2,-1,-1,2,7,1,-2100,-1,-9999,MRD_x01_y01_z12,MRD_x01_y01_z12,None,ON,NORMAL +321,321,1,0,12,1,2,73.75,-81.2,458.88,147.2,20,0.6,7,22,18,23,3,12,3,-1,-1,2,7,2,-2100,-1,-9999,MRD_x01_y02_z12,MRD_x01_y02_z12,None,ON,NORMAL +322,322,1,0,12,1,3,73.75,-60.9,458.88,147.2,20,0.6,7,22,19,23,4,12,4,-1,-1,2,7,3,-2100,-1,-9999,MRD_x01_y03_z12,MRD_x01_y03_z12,None,ON,NORMAL +323,323,1,0,12,1,4,73.75,-40.6,458.88,147.2,20,0.6,7,22,20,23,5,12,5,-1,-1,2,7,4,-2100,-1,-9999,MRD_x01_y04_z12,MRD_x01_y04_z12,None,ON,NORMAL +324,324,1,0,12,1,5,73.75,-20.3,458.88,147.2,20,0.6,7,22,21,23,6,12,6,-1,-1,2,7,5,-2100,-1,-9999,MRD_x01_y05_z12,MRD_x01_y05_z12,None,ON,NORMAL +325,325,1,0,12,1,6,73.75,0,458.88,147.2,20,0.6,7,22,22,23,7,12,7,-1,-1,2,7,6,-2100,-1,-9999,MRD_x01_y06_z12,MRD_x01_y06_z12,None,ON,NORMAL +326,326,1,0,12,1,7,73.75,20.3,458.88,147.2,20,0.6,7,22,23,23,8,12,8,-1,-1,2,7,7,-2100,-1,-9999,MRD_x01_y07_z12,MRD_x01_y07_z12,None,ON,NORMAL +327,327,1,0,12,1,8,73.75,40.6,458.88,147.2,20,0.6,7,22,24,23,9,12,9,-1,-1,2,7,8,-2100,-1,-9999,MRD_x01_y08_z12,MRD_x01_y08_z12,None,ON,NORMAL +328,328,1,0,12,1,9,73.75,60.9,458.88,147.2,20,0.6,7,22,25,23,10,12,10,-1,-1,2,7,9,-2100,-1,-9999,MRD_x01_y09_z12,MRD_x01_y09_z12,None,ON,NORMAL +329,329,1,0,12,1,10,73.75,81.2,458.88,147.2,20,0.6,7,22,26,23,11,12,11,-1,-1,2,7,10,-2100,-1,-9999,MRD_x01_y10_z12,MRD_x01_y10_z12,None,ON,NORMAL +330,330,1,0,12,1,11,73.75,101.5,458.88,147.2,20,0.6,7,22,27,23,12,12,12,-1,-1,2,7,11,-2100,-1,-9999,MRD_x01_y11_z12,MRD_x01_y11_z12,None,ON,NORMAL +331,331,1,0,12,1,12,73.75,121.8,458.88,147.2,20,0.6,7,22,28,23,13,12,13,-1,-1,2,7,12,-2100,-1,-9999,MRD_x01_y12_z12,MRD_x01_y12_z12,None,ON,NORMAL +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/FullMRDGeometry_09_2024_thru_03_2025_Runs_R5008_thru_R5444.csv b/configfiles/LoadGeometry/FullMRDGeometry_09_2024_thru_03_2025_Runs_R5008_thru_R5444.csv new file mode 100644 index 000000000..392f27d2b --- /dev/null +++ b/configfiles/LoadGeometry/FullMRDGeometry_09_2024_thru_03_2025_Runs_R5008_thru_R5444.csv @@ -0,0 +1,342 @@ +#,,0=FMV,0=horizontal,,0=left,from left to right,,,,,,,,,,,,,,#NAME?,#NAME?,,,,,,,,,,, +#,,1=MRD,1=vertical,,1=right,from bottom to top,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,0=bottom,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,1=top,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,channel_num,detector_system,orientation,layer,side,num,x_center,y_center,z_center,x_width,y_width,z_width,rack,TDC_slot,TDC_channel,discrim_slot,discrim_ch,patch_panel_row,patch_panel_col,amp_slot,amp_channel,hv_crate,hv_slot,hv_channel,nominal_HV,polarity,PMT_type,cable_label,paddle_label,notes,detector_status,noise +########################################,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,-198.699875,5.08,320,30.5,2,8,2,0,1,1,1,1,-1,-1,2,14,0,-1871,-1,EMI9815,MRD_x00_y00_z00,4SW,None,ON,NORMAL +1,1,0,0,0,0,1,0,-167.999875,5.08,320,30.5,2,8,2,1,1,2,1,2,-1,-1,2,14,1,-1838,-1,EMI9815,MRD_x00_y01_z00,U39,None,ON,NORMAL +2,2,0,0,0,0,2,0,-137.299875,5.08,320,30.5,2,8,2,2,1,3,1,3,-1,-1,2,14,2,-1793,-1,EMI9815,MRD_x00_y02_z00,U58 (or U38; bad writing),None,ON,NORMAL +3,3,0,0,0,0,3,0,-106.599875,5.08,320,30.5,2,8,2,3,1,4,1,4,-1,-1,2,14,3,-1806,-1,EMI9815,MRD_x00_y03_z00,U29,None,ON,NORMAL +4,4,0,0,0,0,4,0,-75.899875,5.08,320,30.5,2,8,2,4,1,5,1,5,-1,-1,2,14,4,-1865,-1,EMI9815,MRD_x00_y04_z00,14SW,None,ON,NORMAL +5,5,0,0,0,0,5,0,-45.199875,5.08,320,30.5,2,8,2,5,1,6,1,6,-1,-1,2,14,5,-1823,-1,EMI9815,MRD_x00_y05_z00,Unknown4,None,ON,NORMAL +6,6,0,0,0,0,6,0,-14.499875,5.08,320,30.5,2,8,2,6,1,7,1,7,-1,-1,2,14,6,-1798,-1,EMI9815,MRD_x00_y06_z00,U17,None,ON,NORMAL +7,7,0,0,0,0,7,0,16.200125,5.08,320,30.5,2,8,2,7,1,8,1,8,-1,-1,2,14,7,-1823,-1,EMI9815,MRD_x00_y07_z00,11SE,None,ON,NORMAL +8,8,0,0,0,0,8,0,46.900125,5.08,320,30.5,2,8,2,8,1,9,1,9,-1,-1,2,14,8,-1871,-1,EMI9815,MRD_x00_y08_z00,18SE,None,ON,NORMAL +9,9,0,0,0,0,9,0,77.600125,5.08,320,30.5,2,8,2,9,1,10,1,10,-1,-1,2,14,9,-1836,-1,EMI9815,MRD_x00_y09_z00,21SW,None,ON,NORMAL +10,10,0,0,0,0,10,0,108.300125,5.08,320,30.5,2,8,2,10,1,11,1,11,-1,-1,2,14,10,-1814,-1,EMI9815,MRD_x00_y10_z00,3SE,None,ON,NORMAL +11,11,0,0,0,0,11,0,139.000125,5.08,320,30.5,2,8,2,11,1,12,1,12,-1,-1,2,14,11,-1781,-1,EMI9815,MRD_x00_y11_z00,24SE,None,ON,NORMAL +12,12,0,0,0,0,12,0,169.700125,5.08,320,30.5,2,8,2,12,1,13,1,13,-1,-1,2,14,12,-1816,-1,EMI9815,MRD_x00_y12_z00,U25,None,ON,NORMAL +13,13,0,0,0,1,0,0,-198.064875,7.28,320,30.5,2,8,2,16,3,1,2,1,-1,-1,2,15,0,-1805,-1,EMI9815,MRD_x01_y00_z00,28SE,None,ON,NORMAL +14,14,0,0,0,1,1,0,-167.364875,7.28,320,30.5,2,8,2,17,3,2,2,2,-1,-1,2,15,1,-1818,-1,EMI9815,MRD_x01_y01_z00,31SE,None,ON,NORMAL +15,15,0,0,0,1,2,0,-136.664875,7.28,320,30.5,2,8,2,18,3,3,2,3,-1,-1,2,15,2,-1860,-1,EMI9815,MRD_x01_y02_z00,8SE,None,ON,NORMAL +16,16,0,0,0,1,3,0,-105.964875,7.28,320,30.5,2,8,2,19,3,4,2,4,-1,-1,2,15,3,-1780,-1,EMI9815,MRD_x01_y03_z00,11SW,None,ON,NORMAL +17,17,0,0,0,1,4,0,-75.264875,7.28,320,30.5,2,8,2,20,3,5,2,5,-1,-1,2,15,4,-1841,-1,EMI9815,MRD_x01_y04_z00,U34,None,ON,NORMAL +18,18,0,0,0,1,5,0,-44.564875,7.28,320,30.5,2,8,2,21,3,6,2,6,-1,-1,2,15,5,-1786,-1,EMI9815,MRD_x01_y05_z010,U36,None,ON,NORMAL +19,19,0,0,0,1,6,0,-13.864875,7.28,320,30.5,2,8,2,22,3,7,2,7,-1,-1,2,15,6,-1864,-1,EMI9815,MRD_x01_y06_z00,U40,None,ON,NORMAL +20,20,0,0,0,1,7,0,16.835125,7.28,320,30.5,2,8,2,23,3,8,2,8,-1,-1,2,15,7,-1858,-1,EMI9815,MRD_x01_y07_z00,Unknown5,None,ON,NORMAL +21,21,0,0,0,1,8,0,47.535125,7.28,320,30.5,2,8,2,24,3,9,2,9,-1,-1,2,15,8,-1876,-1,EMI9815,MRD_x01_y08_z00,27SE,None,ON,NORMAL +22,22,0,0,0,1,9,0,78.235125,7.28,320,30.5,2,8,2,25,3,10,2,10,-1,-1,2,15,9,-1806,-1,EMI9815,MRD_x01_y09_z00,Unknown2,None,ON,NORMAL +23,23,0,0,0,1,10,0,108.935125,7.28,320,30.5,2,8,2,26,3,11,2,11,-1,-1,2,15,10,-1853,-1,EMI9815,MRD_x01_y10_z00,10SW,None,ON,NORMAL +24,24,0,0,0,1,11,0,139.635125,7.28,320,30.5,2,8,2,27,3,12,2,12,-1,-1,2,15,11,-1860,-1,EMI9815,MRD_x01_y11_z00,Bill2,None,ON,NORMAL +25,25,0,0,0,1,12,0,170.335125,7.28,320,30.5,2,8,2,28,3,13,2,13,-1,-1,2,15,12,-1844,-1,EMI9815,MRD_x01_y12_z00,13SE,None,ON,NORMAL +26,26,1,0,2,0,0,-73.75,-121.8,336.38,147.2,20,0.6,7,2,0,1,1,1,1,-1,-1,1,4,0,-2100,-1,-9999,MRD_x00_y00_z02,MRD_x00_y00_z02,None,ON,NORMAL +27,27,1,0,2,0,1,-73.75,-101.5,336.38,147.2,20,0.6,7,2,1,1,2,1,2,-1,-1,1,4,1,-2100,-1,-9999,MRD_x00_y01_z02,MRD_x00_y01_z02,None,ON,NORMAL +28,28,1,0,2,0,2,-73.75,-81.2,336.38,147.2,20,0.6,7,2,2,1,3,1,3,-1,-1,1,4,2,-2100,-1,-9999,MRD_x00_y02_z02,MRD_x00_y02_z02,None,ON,NORMAL +29,29,1,0,2,0,3,-73.75,-60.9,336.38,147.2,20,0.6,7,2,3,1,4,1,4,-1,-1,1,4,3,-2100,-1,-9999,MRD_x00_y03_z02,MRD_x00_y03_z02,None,ON,NORMAL +30,30,1,0,2,0,4,-73.75,-40.6,336.38,147.2,20,0.6,7,2,4,1,5,1,5,-1,-1,1,4,4,-2100,-1,-9999,MRD_x00_y04_z02,MRD_x00_y04_z02,None,ON,NORMAL +31,31,1,0,2,0,5,-73.75,-20.3,336.38,147.2,20,0.6,7,2,5,1,6,1,6,-1,-1,1,4,5,-2100,-1,-9999,MRD_x00_y05_z02,MRD_x00_y05_z02,None,ON,NORMAL +32,32,1,0,2,0,6,-73.75,0,336.38,147.2,20,0.6,7,2,6,1,7,1,7,-1,-1,1,4,6,-2100,-1,-9999,MRD_x00_y06_z02,MRD_x00_y06_z02,None,ON,NORMAL +33,33,1,0,2,0,7,-73.75,20.3,336.38,147.2,20,0.6,7,2,7,1,8,1,8,-1,-1,1,4,7,-2100,-1,-9999,MRD_x00_y07_z02,MRD_x00_y07_z02,None,ON,NORMAL +34,34,1,0,2,0,8,-73.75,40.6,336.38,147.2,20,0.6,7,2,8,1,9,1,9,-1,-1,1,4,8,-1900,-1,-9999,MRD_x00_y08_z02,MRD_x00_y08_z02,None,ON,NORMAL +35,35,1,0,2,0,9,-73.75,60.9,336.38,147.2,20,0.6,7,2,9,1,10,1,10,-1,-1,1,4,10,-1900,-1,-9999,MRD_x00_y09_z02,MRD_x00_y09_z02,None,ON,NORMAL +36,36,1,0,2,0,10,-73.75,81.2,336.38,147.2,20,0.6,7,2,10,1,11,1,11,-1,-1,1,4,11,-2100,-1,-9999,MRD_x00_y10_z02,MRD_x00_y10_z02,None,ON,NORMAL +37,37,1,0,2,0,11,-73.75,101.5,336.38,147.2,20,0.6,7,2,11,1,12,1,12,-1,-1,1,4,12,-2100,-1,-9999,MRD_x00_y11_z02,MRD_x00_y11_z02,None,ON,NORMAL +38,38,1,0,2,0,12,-73.75,121.8,336.38,147.2,20,0.6,7,2,12,1,13,1,13,-1,-1,1,4,13,-1900,-1,-9999,MRD_x00_y12_z02,MRD_x00_y12_z02,None,ON,NORMAL +39,39,1,0,2,1,0,73.75,-121.8,336.38,147.2,20,0.6,7,2,16,3,1,2,1,-1,-1,1,5,0,-2100,-1,-9999,MRD_x01_y00_z02,MRD_x01_y00_z02,None,ON,NORMAL +40,40,1,0,2,1,1,73.75,-101.5,336.38,147.2,20,0.6,7,2,17,3,2,2,2,-1,-1,1,5,1,-2100,-1,-9999,MRD_x01_y01_z02,MRD_x01_y01_z02,None,ON,NORMAL +41,41,1,0,2,1,2,73.75,-81.2,336.38,147.2,20,0.6,7,2,18,3,3,2,3,-1,-1,1,5,2,-1900,-1,-9999,MRD_x01_y02_z02,MRD_x01_y02_z02,None,ON,NORMAL +42,42,1,0,2,1,3,73.75,-60.9,336.38,147.2,20,0.6,7,2,19,3,4,2,4,-1,-1,1,5,3,-1900,-1,-9999,MRD_x01_y03_z02,MRD_x01_y03_z02,None,ON,NORMAL +43,43,1,0,2,1,4,73.75,-40.6,336.38,147.2,20,0.6,7,2,20,3,5,2,5,-1,-1,1,5,4,-2100,-1,-9999,MRD_x01_y04_z02,MRD_x01_y04_z02,None,ON,NORMAL +44,44,1,0,2,1,5,73.75,-20.3,336.38,147.2,20,0.6,7,2,21,3,6,2,6,-1,-1,1,5,5,-2100,-1,-9999,MRD_x01_y05_z02,MRD_x01_y05_z02,None,ON,NORMAL +45,45,1,0,2,1,6,73.75,0,336.38,147.2,20,0.6,7,2,22,3,7,2,7,-1,-1,1,5,6,-1900,-1,-9999,MRD_x01_y06_z02,MRD_x01_y06_z02,None,ON,NORMAL +46,46,1,0,2,1,7,73.75,20.3,336.38,147.2,20,0.6,7,2,23,3,8,2,8,-1,-1,1,5,7,-2100,-1,-9999,MRD_x01_y07_z02,MRD_x01_y07_z02,None,ON,NORMAL +47,47,1,0,2,1,8,73.75,40.6,336.38,147.2,20,0.6,7,2,24,3,9,2,9,-1,-1,1,5,8,-2100,-1,-9999,MRD_x01_y08_z02,MRD_x01_y08_z02,None,ON,NORMAL +48,48,1,0,2,1,9,73.75,60.9,336.38,147.2,20,0.6,7,2,25,3,10,2,10,-1,-1,1,5,9,-2100,-1,-9999,MRD_x01_y09_z02,MRD_x01_y09_z02,None,ON,NORMAL +49,49,1,0,2,1,10,73.75,81.2,336.38,147.2,20,0.6,7,2,26,3,11,2,11,-1,-1,1,5,10,-2100,-1,-9999,MRD_x01_y10_z02,MRD_x01_y10_z02,None,ON,NORMAL +50,50,1,0,2,1,11,73.75,101.5,336.38,147.2,20,0.6,7,2,27,3,12,2,12,-1,-1,1,5,11,-2100,-1,-9999,MRD_x01_y11_z02,MRD_x01_y11_z02,None,ON,NORMAL +51,51,1,0,2,1,12,73.75,121.8,336.38,147.2,20,0.6,7,2,28,3,13,2,13,-1,-1,1,5,12,-1900,-1,-9999,MRD_x01_y12_z02,MRD_x01_y12_z02,None,ON,NORMAL +52,52,1,1,3,0,0,-107.1,-65.25,348.84,15,130.2,1.3,8,5,0,4,1,3,1,-1,-1,1,6,0,-2000,-1,-9999,MRD_x00_y00_z03,MRD_x00_y00_z03,None,OFF,NORMAL +53,53,1,1,3,0,1,-91.8,-65.25,348.84,15,130.2,1.3,8,5,1,4,2,3,2,-1,-1,1,6,1,-2000,-1,-9999,MRD_x01_y00_z03,MRD_x01_y00_z03,None,ON,NORMAL +54,54,1,1,3,0,2,-76.5,-65.25,348.84,15,130.2,1.3,8,5,2,4,3,3,3,-1,-1,1,6,2,-2000,-1,-9999,MRD_x02_y00_z03,MRD_x02_y00_z03,None,ON,NORMAL +55,55,1,1,3,0,3,-61.2,-65.25,348.84,15,130.2,1.3,8,5,3,4,4,3,4,-1,-1,1,6,3,-2000,-1,-9999,MRD_x03_y00_z03,MRD_x03_y00_z03,None,ON,NORMAL +56,56,1,1,3,0,4,-45.9,-65.25,348.84,15,130.2,1.3,8,5,4,4,5,3,5,-1,-1,1,6,4,-2000,-1,-9999,MRD_x04_y00_z03,MRD_x04_y00_z03,None,ON,NORMAL +57,57,1,1,3,0,5,-30.6,-65.25,348.84,15,130.2,1.3,8,5,5,4,6,3,6,-1,-1,1,6,5,-2000,-1,-9999,MRD_x05_y00_z03,MRD_x05_y00_z03,None,ON,NORMAL +58,58,1,1,3,0,6,-15.3,-65.25,348.84,15,130.2,1.3,8,5,6,4,7,3,7,-1,-1,1,6,6,-2000,-1,-9999,MRD_x06_y00_z03,MRD_x06_y00_z03,None,ON,NORMAL +59,59,1,1,3,0,7,0,-65.25,348.84,15,130.2,1.3,8,5,7,4,8,3,8,-1,-1,1,6,7,-2000,-1,-9999,MRD_x07_y00_z03,MRD_x07_y00_z03,None,ON,NORMAL +60,60,1,1,3,0,8,15.3,-65.25,348.84,15,130.2,1.3,8,5,8,4,9,3,9,-1,-1,1,6,8,-2000,-1,-9999,MRD_x08_y00_z03,MRD_x08_y00_z03,None,ON,NORMAL +61,61,1,1,3,0,9,30.6,-65.25,348.84,15,130.2,1.3,8,5,9,4,10,3,10,-1,-1,1,6,9,-2000,-1,-9999,MRD_x09_y00_z03,MRD_x09_y00_z03,None,ON,NORMAL +62,62,1,1,3,0,10,45.9,-65.25,348.84,15,130.2,1.3,8,5,10,4,11,3,11,-1,-1,1,6,10,-2000,-1,-9999,MRD_x10_y00_z03,MRD_x10_y00_z03,None,ON,NORMAL +63,63,1,1,3,0,11,61.2,-65.25,348.84,15,130.2,1.3,8,5,11,4,12,3,12,-1,-1,1,6,11,-2000,-1,-9999,MRD_x11_y00_z03,MRD_x11_y00_z03,None,ON,NORMAL +64,64,1,1,3,0,12,76.5,-65.25,348.84,15,130.2,1.3,8,5,12,4,13,3,13,-1,-1,1,6,12,-2000,-1,-9999,MRD_x12_y00_z03,MRD_x12_y00_z03,None,ON,NORMAL +65,65,1,1,3,0,13,91.8,-65.25,348.84,15,130.2,1.3,8,5,13,4,14,3,14,-1,-1,1,6,13,-2000,-1,-9999,MRD_x13_y00_z03,MRD_x13_y00_z03,None,ON,NORMAL +66,66,1,1,3,0,14,107.1,-65.25,348.84,15,130.2,1.3,8,5,14,4,15,3,15,-1,-1,1,6,14,-1800,-1,-9999,MRD_x14_y00_z03,MRD_x14_y00_z03,None,ON,NORMAL +67,67,1,1,3,1,0,-107.1,65.25,348.84,15,130.2,1.3,8,5,16,6,1,4,1,-1,-1,1,7,0,-2200,-1,-9999,MRD_x00_y01_z03,MRD_x00_y01_z03,None,ON,NORMAL +68,68,1,1,3,1,1,-91.8,65.25,348.84,15,130.2,1.3,8,5,17,6,2,4,2,-1,-1,1,7,1,-2000,-1,-9999,MRD_x01_y01_z03,MRD_x01_y01_z03,None,ON,NORMAL +69,69,1,1,3,1,2,-76.5,65.25,348.84,15,130.2,1.3,8,5,18,6,3,4,3,-1,-1,1,7,2,-2000,-1,-9999,MRD_x02_y01_z03,MRD_x02_y01_z03,None,ON,NORMAL +70,70,1,1,3,1,3,-61.2,65.25,348.84,15,130.2,1.3,8,5,19,6,4,4,4,-1,-1,1,7,3,-2000,-1,-9999,MRD_x03_y01_z03,MRD_x03_y01_z03,None,ON,NORMAL +71,71,1,1,3,1,4,-45.9,65.25,348.84,15,130.2,1.3,8,5,20,6,5,4,5,-1,-1,1,7,4,-2000,-1,-9999,MRD_x04_y01_z03,MRD_x04_y01_z03,None,ON,NORMAL +72,72,1,1,3,1,5,-30.6,65.25,348.84,15,130.2,1.3,8,5,21,6,6,4,6,-1,-1,1,7,5,-2000,-1,-9999,MRD_x05_y01_z03,MRD_x05_y01_z03,None,ON,NORMAL +73,73,1,1,3,1,6,-15.3,65.25,348.84,15,130.2,1.3,8,5,22,6,7,4,7,-1,-1,1,7,6,-2000,-1,-9999,MRD_x06_y01_z03,MRD_x06_y01_z03,None,ON,NORMAL +74,74,1,1,3,1,7,0,65.25,348.84,15,130.2,1.3,8,5,23,6,8,4,8,-1,-1,1,7,7,-2000,-1,-9999,MRD_x07_y01_z03,MRD_x07_y01_z03,None,ON,NORMAL +75,75,1,1,3,1,8,15.3,65.25,348.84,15,130.2,1.3,8,5,24,6,9,4,9,-1,-1,1,7,8,-2000,-1,-9999,MRD_x08_y01_z03,MRD_x08_y01_z03,None,ON,NORMAL +76,76,1,1,3,1,9,30.6,65.25,348.84,15,130.2,1.3,8,5,25,6,10,4,10,-1,-1,1,7,9,-2000,-1,-9999,MRD_x09_y01_z03,MRD_x09_y01_z03,None,ON,NORMAL +77,77,1,1,3,1,10,45.9,65.25,348.84,15,130.2,1.3,8,5,26,6,11,4,11,-1,-1,1,7,10,-2000,-1,-9999,MRD_x10_y01_z03,MRD_x10_y01_z03,Currently using y1 z3 spare cableNone,ON,NORMAL +78,78,1,1,3,1,11,61.2,65.25,348.84,15,130.2,1.3,8,5,27,6,12,4,12,-1,-1,1,7,11,-2000,-1,-9999,MRD_x11_y01_z03,MRD_x11_y01_z03,None,ON,NORMAL +79,79,1,1,3,1,12,76.5,65.25,348.84,15,130.2,1.3,8,5,28,6,13,4,13,-1,-1,1,7,12,-2000,-1,-9999,MRD_x12_y01_z03,MRD_x12_y01_z03,None,ON,NORMAL +80,80,1,1,3,1,13,91.8,65.25,348.84,15,130.2,1.3,8,5,29,6,14,4,14,-1,-1,1,7,13,-2000,-1,-9999,MRD_x13_y01_z03,MRD_x13_y01_z03,None,ON,NORMAL +81,81,1,1,3,1,14,107.1,65.25,348.84,15,130.2,1.3,8,5,30,6,15,4,15,-1,-1,1,7,14,-2000,-1,-9999,MRD_x14_y01_z03,MRD_x14_y01_z03,None,ON,NORMAL +82,82,1,0,4,0,0,-73.75,-121.8,361.3,147.2,20,0.6,7,5,0,4,1,3,1,-1,-1,1,8,0,-2100,-1,-9999,MRD_x00_y00_z04,MRD_x00_y00_z04,None,ON,NORMAL +83,83,1,0,4,0,1,-73.75,-101.5,361.3,147.2,20,0.6,7,5,1,4,2,3,2,-1,-1,1,8,1,-2100,-1,-9999,MRD_x00_y01_z04,MRD_x00_y01_z04,None,ON,NORMAL +84,84,1,0,4,0,2,-73.75,-81.2,361.3,147.2,20,0.6,7,5,2,4,3,3,3,-1,-1,1,8,2,-2100,-1,-9999,MRD_x00_y02_z04,MRD_x00_y02_z04,None,ON,NORMAL +85,85,1,0,4,0,3,-73.75,-60.9,361.3,147.2,20,0.6,7,5,3,4,4,3,4,-1,-1,1,8,3,-2100,-1,-9999,MRD_x00_y03_z04,MRD_x00_y03_z04,None,ON,NORMAL +86,86,1,0,4,0,4,-73.75,-40.6,361.3,147.2,20,0.6,7,5,4,4,5,3,5,-1,-1,1,8,4,-2300,-1,-9999,MRD_x00_y04_z04,MRD_x00_y04_z04,None,ON,NORMAL +87,87,1,0,4,0,5,-73.75,-20.3,361.3,147.2,20,0.6,7,5,5,4,6,3,6,-1,-1,1,8,5,-2100,-1,-9999,MRD_x00_y05_z04,MRD_x00_y05_z04,None,ON,NORMAL +88,88,1,0,4,0,6,-73.75,0,361.3,147.2,20,0.6,7,5,6,4,7,3,7,-1,-1,1,8,6,-2100,-1,-9999,MRD_x00_y06_z04,MRD_x00_y06_z04,None,ON,NORMAL +89,89,1,0,4,0,7,-73.75,20.3,361.3,147.2,20,0.6,7,5,7,4,8,3,8,-1,-1,1,8,7,-2100,-1,-9999,MRD_x00_y07_z04,MRD_x00_y07_z04,None,ON,NORMAL +90,90,1,0,4,0,8,-73.75,40.6,361.3,147.2,20,0.6,7,5,8,4,9,3,9,-1,-1,1,8,8,-2100,-1,-9999,MRD_x00_y08_z04,MRD_x00_y08_z04,None,ON,NORMAL +91,91,1,0,4,0,9,-73.75,60.9,361.3,147.2,20,0.6,7,5,9,4,10,3,10,-1,-1,1,8,9,-2100,-1,-9999,MRD_x00_y09_z04,MRD_x00_y09_z04,None,ON,NORMAL +92,92,1,0,4,0,10,-73.75,81.2,361.3,147.2,20,0.6,7,5,10,4,11,3,11,-1,-1,1,8,10,-2100,-1,-9999,MRD_x00_y10_z04,MRD_x00_y10_z04,None,ON,NORMAL +93,93,1,0,4,0,11,-73.75,101.5,361.3,147.2,20,0.6,7,5,11,4,12,3,12,-1,-1,1,8,11,-2100,-1,-9999,MRD_x00_y11_z04,MRD_x00_y11_z04,None,ON,NORMAL +94,94,1,0,4,0,12,-73.75,121.8,361.3,147.2,20,0.6,7,5,12,4,13,3,13,-1,-1,1,8,12,-2300,-1,-9999,MRD_x00_y12_z04,MRD_x00_y12_z04,None,ON,NORMAL +95,95,1,0,4,1,0,73.75,-121.8,361.3,147.2,20,0.6,7,5,16,6,1,4,1,-1,-1,1,9,0,-2100,-1,-9999,MRD_x01_y00_z04,MRD_x01_y00_z04,None,ON,NORMAL +96,96,1,0,4,1,1,73.75,-101.5,361.3,147.2,20,0.6,7,5,17,6,2,4,2,-1,-1,1,9,1,-2100,-1,-9999,MRD_x01_y01_z04,MRD_x01_y01_z04,None,ON,NORMAL +97,97,1,0,4,1,2,73.75,-81.2,361.3,147.2,20,0.6,7,5,18,6,3,4,3,-1,-1,1,9,2,-2300,-1,-9999,MRD_x01_y02_z04,MRD_x01_y02_z04,None,ON,NORMAL +98,98,1,0,4,1,3,73.75,-60.9,361.3,147.2,20,0.6,7,5,19,6,4,4,4,-1,-1,1,9,3,-2300,-1,-9999,MRD_x01_y03_z04,MRD_x01_y03_z04,None,ON,NORMAL +99,99,1,0,4,1,4,73.75,-40.6,361.3,147.2,20,0.6,7,5,20,6,5,4,5,-1,-1,1,9,4,-2100,-1,-9999,MRD_x01_y04_z04,MRD_x01_y04_z04,None,ON,NORMAL +100,100,1,0,4,1,5,73.75,-20.3,361.3,147.2,20,0.6,7,5,21,6,6,4,6,-1,-1,1,9,5,-2100,-1,-9999,MRD_x01_y05_z04,MRD_x01_y05_z04,None,ON,NORMAL +101,101,1,0,4,1,6,73.75,0,361.3,147.2,20,0.6,7,5,22,6,7,4,7,-1,-1,1,9,6,-2100,-1,-9999,MRD_x01_y06_z04,MRD_x01_y06_z04,None,ON,NORMAL +102,102,1,0,4,1,7,73.75,20.3,361.3,147.2,20,0.6,7,5,23,6,8,4,8,-1,-1,1,9,7,-2100,-1,-9999,MRD_x01_y07_z04,MRD_x01_y07_z04,None,ON,NORMAL +103,103,1,0,4,1,8,73.75,40.6,361.3,147.2,20,0.6,7,5,24,6,9,4,9,-1,-1,1,9,8,-2100,-1,-9999,MRD_x01_y08_z04,MRD_x01_y08_z04,None,ON,NORMAL +104,104,1,0,4,1,9,73.75,60.9,361.3,147.2,20,0.6,7,5,25,6,10,4,10,-1,-1,1,9,9,-2100,-1,-9999,MRD_x01_y09_z04,MRD_x01_y09_z04,None,ON,NORMAL +105,105,1,0,4,1,10,73.75,81.2,361.3,147.2,20,0.6,7,5,26,6,11,4,11,-1,-1,1,9,10,-2100,-1,-9999,MRD_x01_y10_z04,MRD_x01_y10_z04,None,ON,NORMAL +106,106,1,0,4,1,11,73.75,101.5,361.3,147.2,20,0.6,7,5,27,6,12,4,12,-1,-1,1,9,11,-2100,-1,-9999,MRD_x01_y11_z04,MRD_x01_y11_z04,None,ON,NORMAL +107,107,1,0,4,1,12,73.75,121.8,361.3,147.2,20,0.6,7,5,28,6,13,4,13,-1,-1,1,9,12,-2100,-1,-9999,MRD_x01_y12_z04,MRD_x01_y12_z04,None,ON,NORMAL +108,108,1,1,5,0,0,-122.4,-65.25,373.76,15,130.2,1.3,8,8,0,7,1,5,1,-1,-1,1,10,0,-2200,-1,-9999,MRD_x00_y00_z05,MRD_x00_y00_z05,None,ON,NORMAL +109,109,1,1,5,0,1,-107.1,-65.25,373.76,15,130.2,1.3,8,8,1,7,2,5,2,-1,-1,1,10,1,-2200,-1,-9999,MRD_x01_y00_z05,MRD_x01_y00_z05,None,ON,NORMAL +110,110,1,1,5,0,2,-91.8,-65.25,373.76,15,130.2,1.3,8,8,2,7,3,5,3,-1,-1,1,10,2,-2000,-1,-9999,MRD_x02_y00_z05,MRD_x02_y00_z05,None,ON,NORMAL +111,111,1,1,5,0,3,-76.5,-65.25,373.76,15,130.2,1.3,8,8,7,7,8,5,4,-1,-1,1,10,3,-1500,-1,-9999,MRD_x03_y00_z05,MRD_x03_y00_z05,None,ON,NORMAL +112,112,1,1,5,0,4,-61.2,-65.25,373.76,15,130.2,1.3,8,8,3,7,4,5,5,-1,-1,1,10,4,-2000,-1,-9999,MRD_x04_y00_z05,MRD_x04_y00_z05,None,ON,NORMAL +113,113,1,1,5,0,5,-45.9,-65.25,373.76,15,130.2,1.3,8,8,4,7,5,5,6,-1,-1,1,10,5,-2000,-1,-9999,MRD_x05_y00_z05,MRD_x05_y00_z05,None,ON,NORMAL +114,114,1,1,5,0,6,-30.6,-65.25,373.76,15,130.2,1.3,8,8,6,7,7,5,7,-1,-1,1,10,6,-2000,-1,-9999,MRD_x06_y00_z05,MRD_x06_y00_z05,None,ON,NORMAL +115,115,1,1,5,0,7,-15.3,-65.25,373.76,15,130.2,1.3,8,8,5,7,6,5,8,-1,-1,1,10,7,-2000,-1,-9999,MRD_x07_y00_z05,MRD_x07_y00_z05,None,ON,NORMAL +116,116,1,1,5,0,8,0,-65.25,373.76,15,130.2,1.3,8,8,8,7,9,5,9,-1,-1,1,10,8,-2000,-1,-9999,MRD_x08_y00_z05,MRD_x08_y00_z05,None,ON,NORMAL +117,117,1,1,5,0,9,15.3,-65.25,373.76,15,130.2,1.3,8,8,14,7,15,5,10,-1,-1,1,10,9,-2000,-1,-9999,MRD_x09_y00_z05,MRD_x09_y00_z05,None,ON,NORMAL +118,118,1,1,5,0,10,30.6,-65.25,373.76,15,130.2,1.3,8,8,10,7,11,5,11,-1,-1,1,10,10,-2000,-1,-9999,MRD_x10_y00_z05,MRD_x10_y00_z05,None,ON,NORMAL +119,119,1,1,5,0,11,45.9,-65.25,373.76,15,130.2,1.3,8,8,11,7,12,5,12,-1,-1,1,10,11,-2000,-1,-9999,MRD_x11_y00_z05,MRD_x11_y00_z05,None,ON,NORMAL +120,120,1,1,5,0,12,61.2,-65.25,373.76,15,130.2,1.3,8,8,9,7,10,5,13,-1,-1,1,10,12,-2000,-1,-9999,MRD_x12_y00_z05,MRD_x12_y00_z05,Discriminator on slot 7 channel 13 has no NIM outputNone,ON,NORMAL +121,121,1,1,5,0,13,76.5,-65.25,373.76,15,130.2,1.3,8,8,12,7,13,5,14,-1,-1,1,10,13,-2000,-1,-9999,MRD_x13_y00_z05,MRD_x13_y00_z05,None,ON,NORMAL +122,122,1,1,5,0,14,91.8,-65.25,373.76,15,130.2,1.3,8,8,13,7,14,5,15,-1,-1,1,10,14,-2000,-1,-9999,MRD_x14_y00_z05,MRD_x14_y00_z05,None,ON,NORMAL +123,123,1,1,5,0,15,107.1,-65.25,373.76,15,130.2,1.3,8,8,15,7,16,5,16,-1,-1,1,5,14,-1500,-1,-9999,MRD_x15_y00_z05,MRD_x15_y00_z05,None,OFF,NORMAL +124,124,1,1,5,0,16,122.4,-65.25,373.76,15,130.2,1.3,8,17,15,16,16,5,17,-1,-1,1,4,14,-2200,-1,-9999,MRD_x16_y00_z05,MRD_x16_y00_z05,None,OFF,NORMAL +125,125,1,1,5,1,0,-122.4,65.25,373.76,15,130.2,1.3,8,8,16,9,1,6,1,-1,-1,1,11,0,-2000,-1,-9999,MRD_x00_y01_z05,MRD_x00_y01_z05,None,ON,NORMAL +126,126,1,1,5,1,1,-107.1,65.25,373.76,15,130.2,1.3,8,8,17,9,2,6,2,-1,-1,1,11,1,-2000,-1,-9999,MRD_x01_y01_z05,MRD_x01_y01_z05,possible dischargeNone,ON,NORMAL +127,127,1,1,5,1,2,-91.8,65.25,373.76,15,130.2,1.3,8,8,18,9,3,6,3,-1,-1,1,11,2,-2000,-1,-9999,MRD_x02_y01_z05,MRD_x02_y01_z05,None,ON,NORMAL +128,128,1,1,5,1,3,-76.5,65.25,373.76,15,130.2,1.3,8,8,19,9,4,6,4,-1,-1,1,11,3,-2000,-1,-9999,MRD_x03_y01_z05,MRD_x03_y01_z05,None,ON,NORMAL +129,129,1,1,5,1,4,-61.2,65.25,373.76,15,130.2,1.3,8,8,20,9,5,6,5,-1,-1,1,11,4,-1500,-1,-9999,MRD_x04_y01_z05,MRD_x04_y01_z05,None,ON,NORMAL +130,130,1,1,5,1,5,-45.9,65.25,373.76,15,130.2,1.3,8,8,21,9,6,6,6,-1,-1,1,11,5,-2000,-1,-9999,MRD_x05_y01_z05,MRD_x05_y01_z05,None,ON,NORMAL +131,131,1,1,5,1,6,-30.6,65.25,373.76,15,130.2,1.3,8,8,22,9,7,6,7,-1,-1,1,11,6,-2000,-1,-9999,MRD_x06_y01_z05,MRD_x06_y01_z05,None,OFF,NORMAL +132,132,1,1,5,1,7,-15.3,65.25,373.76,15,130.2,1.3,8,8,23,9,8,6,8,-1,-1,1,11,7,-2000,-1,-9999,MRD_x07_y01_z05,MRD_x07_y01_z05,None,ON,HOT +133,133,1,1,5,1,8,0,65.25,373.76,15,130.2,1.3,8,8,24,9,9,6,9,-1,-1,1,11,8,-2000,-1,-9999,MRD_x08_y01_z05,MRD_x08_y01_z05,None,OFF,NORMAL +134,134,1,1,5,1,9,15.3,65.25,373.76,15,130.2,1.3,8,8,25,9,10,6,10,-1,-1,1,11,9,-2000,-1,-9999,MRD_x09_y01_z05,MRD_x09_y01_z05,None,ON,NORMAL +135,135,1,1,5,1,10,30.6,65.25,373.76,15,130.2,1.3,8,8,26,9,11,6,11,-1,-1,1,11,10,-2000,-1,-9999,MRD_x10_y01_z05,MRD_x10_y01_z05,None,ON,NORMAL +136,136,1,1,5,1,11,45.9,65.25,373.76,15,130.2,1.3,8,8,27,9,12,6,12,-1,-1,1,11,11,-1800,-1,-9999,MRD_x11_y01_z05,MRD_x11_y01_z05,None,ON,NORMAL +137,137,1,1,5,1,12,61.2,65.25,373.76,15,130.2,1.3,8,8,28,9,13,6,13,-1,-1,1,11,12,-2000,-1,-9999,MRD_x12_y01_z05,MRD_x12_y01_z05,None,ON,NORMAL +138,138,1,1,5,1,13,76.5,65.25,373.76,15,130.2,1.3,8,8,29,9,14,6,14,-1,-1,1,11,13,-2000,-1,-9999,MRD_x13_y01_z05,MRD_x13_y01_z05,None,ON,NORMAL +139,139,1,1,5,1,14,91.8,65.25,373.76,15,130.2,1.3,8,8,30,9,15,6,15,-1,-1,1,11,14,-2000,-1,-9999,MRD_x14_y01_z05,MRD_x14_y01_z05,None,ON,NORMAL +140,140,1,1,5,1,15,107.1,65.25,373.76,15,130.2,1.3,8,8,31,9,16,6,16,-1,-1,1,11,15,-2000,-1,-9999,MRD_x15_y01_z05,MRD_x15_y01_z05,None,OFF,NORMAL +141,141,1,1,5,1,16,122.4,65.25,373.76,15,130.2,1.3,8,14,31,15,16,6,17,-1,-1,1,4,15,-2000,-1,-9999,MRD_x16_y01_z05,MRD_x16_y01_z05,Now uses y0 z5 spare; Rack 8 slot 18 channel 16 has no NIM output,OFF,NORMAL +142,142,1,0,6,0,0,-73.75,-121.8,386.22,147.2,20,0.6,7,8,0,7,1,5,1,-1,-1,1,12,0,-2100,-1,-9999,MRD_x00_y00_z06,MRD_x00_y00_z06,None,ON,NORMAL +143,143,1,0,6,0,1,-73.75,-101.5,386.22,147.2,20,0.6,7,8,1,7,2,5,2,-1,-1,1,12,1,-2100,-1,-9999,MRD_x00_y01_z06,MRD_x00_y01_z06,None,ON,NORMAL +144,144,1,0,6,0,2,-73.75,-81.2,386.22,147.2,20,0.6,7,8,2,7,3,5,3,-1,-1,1,12,2,-2100,-1,-9999,MRD_x00_y02_z06,MRD_x00_y02_z06,None,ON,NORMAL +145,145,1,0,6,0,3,-73.75,-60.9,386.22,147.2,20,0.6,7,8,3,7,4,5,4,-1,-1,1,12,3,-2100,-1,-9999,MRD_x00_y03_z06,MRD_x00_y03_z06,None,ON,NORMAL +146,146,1,0,6,0,4,-73.75,-40.6,386.22,147.2,20,0.6,7,8,4,7,5,5,5,-1,-1,1,12,4,-2100,-1,-9999,MRD_x00_y04_z06,MRD_x00_y04_z06,None,ON,NORMAL +147,147,1,0,6,0,5,-73.75,-20.3,386.22,147.2,20,0.6,7,8,5,7,6,5,6,-1,-1,1,12,5,-2100,-1,-9999,MRD_x00_y05_z06,MRD_x00_y05_z06,None,ON,NORMAL +148,148,1,0,6,0,6,-73.75,0,386.22,147.2,20,0.6,7,8,6,7,7,5,7,-1,-1,1,12,6,-2100,-1,-9999,MRD_x00_y06_z06,MRD_x00_y06_z06,None,ON,NORMAL +149,149,1,0,6,0,7,-73.75,20.3,386.22,147.2,20,0.6,7,8,7,7,8,5,8,-1,-1,1,12,7,-2100,-1,-9999,MRD_x00_y07_z06,MRD_x00_y07_z06,None,ON,NORMAL +150,150,1,0,6,0,8,-73.75,40.6,386.22,147.2,20,0.6,7,8,8,7,9,5,9,-1,-1,1,12,8,-2100,-1,-9999,MRD_x00_y08_z06,MRD_x00_y08_z06,None,ON,NORMAL +151,151,1,0,6,0,9,-73.75,60.9,386.22,147.2,20,0.6,7,8,9,7,10,5,10,-1,-1,1,12,9,-2100,-1,-9999,MRD_x00_y09_z06,MRD_x00_y09_z06,None,ON,NORMAL +152,152,1,0,6,0,10,-73.75,81.2,386.22,147.2,20,0.6,7,8,10,7,11,5,11,-1,-1,1,12,10,-2100,-1,-9999,MRD_x00_y10_z06,MRD_x00_y10_z06,None,ON,NORMAL +153,153,1,0,6,0,11,-73.75,101.5,386.22,147.2,20,0.6,7,8,11,7,12,5,12,-1,-1,1,12,11,-2100,-1,-9999,MRD_x00_y11_z06,MRD_x00_y11_z06,None,ON,NORMAL +154,154,1,0,6,0,12,-73.75,121.8,386.22,147.2,20,0.6,7,8,12,7,13,5,13,-1,-1,1,12,12,-2100,-1,-9999,MRD_x00_y12_z06,MRD_x00_y12_z06,None,ON,NORMAL +155,155,1,0,6,1,0,73.75,-121.8,386.22,147.2,20,0.6,7,8,16,9,1,6,1,-1,-1,1,13,0,-1900,-1,-9999,MRD_x01_y00_z06,MRD_x01_y00_z06,None,ON,NORMAL +156,156,1,0,6,1,1,73.75,-101.5,386.22,147.2,20,0.6,7,8,17,9,2,6,2,-1,-1,1,13,1,-2100,-1,-9999,MRD_x01_y01_z06,MRD_x01_y01_z06,None,ON,NORMAL +157,157,1,0,6,1,2,73.75,-81.2,386.22,147.2,20,0.6,7,8,18,9,3,6,3,-1,-1,1,13,2,-2100,-1,-9999,MRD_x01_y02_z06,MRD_x01_y02_z06,None,ON,NORMAL +158,158,1,0,6,1,3,73.75,-60.9,386.22,147.2,20,0.6,7,8,19,9,4,6,4,-1,-1,1,13,3,-2100,-1,-9999,MRD_x01_y03_z06,MRD_x01_y03_z06,None,ON,NORMAL +159,159,1,0,6,1,4,73.75,-40.6,386.22,147.2,20,0.6,7,8,20,9,5,6,5,-1,-1,1,13,4,-2100,-1,-9999,MRD_x01_y04_z06,MRD_x01_y04_z06,None,ON,NORMAL +160,160,1,0,6,1,5,73.75,-20.3,386.22,147.2,20,0.6,7,8,21,9,6,6,6,-1,-1,1,13,5,-2100,-1,-9999,MRD_x01_y05_z06,MRD_x01_y05_z06,None,ON,NORMAL +161,161,1,0,6,1,6,73.75,0,386.22,147.2,20,0.6,7,8,22,9,7,6,7,-1,-1,1,13,6,-2100,-1,-9999,MRD_x01_y06_z06,MRD_x01_y06_z06,None,ON,NORMAL +162,162,1,0,6,1,7,73.75,20.3,386.22,147.2,20,0.6,7,8,23,9,8,6,8,-1,-1,1,13,7,-2100,-1,-9999,MRD_x01_y07_z06,MRD_x01_y07_z06,None,ON,NORMAL +163,163,1,0,6,1,8,73.75,40.6,386.22,147.2,20,0.6,7,8,24,9,9,6,9,-1,-1,1,13,8,-2100,-1,-9999,MRD_x01_y08_z06,MRD_x01_y08_z06,None,ON,NORMAL +164,164,1,0,6,1,9,73.75,60.9,386.22,147.2,20,0.6,7,8,25,9,10,6,10,-1,-1,1,13,9,-1900,-1,-9999,MRD_x01_y09_z06,MRD_x01_y09_z06,None,ON,NORMAL +165,165,1,0,6,1,10,73.75,81.2,386.22,147.2,20,0.6,7,8,26,9,11,6,11,-1,-1,1,13,10,-2100,-1,-9999,MRD_x01_y10_z06,MRD_x01_y10_z06,None,ON,NORMAL +166,166,1,0,6,1,11,73.75,101.5,386.22,147.2,20,0.6,7,8,27,9,12,6,12,-1,-1,1,13,11,-2100,-1,-9999,MRD_x01_y11_z06,MRD_x01_y11_z06,None,ON,NORMAL +167,167,1,0,6,1,12,73.75,121.8,386.22,147.2,20,0.6,7,8,28,9,13,6,13,-1,-1,1,13,12,-2100,-1,-9999,MRD_x01_y12_z06,MRD_x01_y12_z06,None,ON,NORMAL +168,168,1,1,7,0,1,-121.8,-65.25,398.33,20,130.2,0.6,8,11,1,10,2,7,2,1,3,1,14,1,-1500,-1,-9999,MRD_x01_y00_z07,MRD_x01_y00_z07,None,ON,NORMAL +169,169,1,1,7,0,2,-101.5,-65.25,398.33,20,130.2,0.6,8,11,2,10,3,7,3,1,5,1,14,2,-1500,-1,-9999,MRD_x02_y00_z07,MRD_x02_y00_z07,None,ON,NORMAL +170,170,1,1,7,0,3,-81.2,-65.25,398.33,20,130.2,0.6,8,11,3,10,4,7,4,1,7,1,14,3,-1500,-1,-9999,MRD_x03_y00_z07,MRD_x03_y00_z07,None,ON,NORMAL +171,171,1,1,7,0,4,-60.9,-65.25,398.33,20,130.2,0.6,8,11,4,10,5,7,5,1,9,1,14,4,-1500,-1,-9999,MRD_x04_y00_z07,MRD_x04_y00_z07,None,ON,NORMAL +172,172,1,1,7,0,5,-40.6,-65.25,398.33,20,130.2,0.6,8,11,5,10,6,7,6,1,11,1,14,5,-1500,-1,-9999,MRD_x05_y00_z07,MRD_x05_y00_z07,None,ON,NORMAL +173,173,1,1,7,0,6,-20.3,-65.25,398.33,20,130.2,0.6,8,11,6,10,7,7,7,1,13,1,14,6,-1500,-1,-9999,MRD_x06_y00_z07,MRD_x06_y00_z07,None,ON,NORMAL +174,174,1,1,7,0,7,0,-65.25,398.33,20,130.2,0.6,8,11,7,10,8,7,8,12,2,1,14,7,-1500,-1,-9999,MRD_x07_y00_z07,MRD_x07_y00_z07,None,ON,NORMAL +175,175,1,1,7,0,8,20.3,-65.25,398.33,20,130.2,0.6,8,11,8,10,9,7,9,12,4,1,14,8,-1500,-1,-9999,MRD_x08_y00_z07,MRD_x08_y00_z07,None,ON,NORMAL +176,176,1,1,7,0,9,40.6,-65.25,398.33,20,130.2,0.6,8,11,9,10,10,7,10,12,6,1,14,9,-1500,-1,-9999,MRD_x09_y00_z07,MRD_x09_y00_z07,None,ON,NORMAL +177,177,1,1,7,0,10,60.9,-65.25,398.33,20,130.2,0.6,8,11,10,10,11,7,11,12,8,1,14,10,-1500,-1,-9999,MRD_x10_y00_z07,MRD_x10_y00_z07,None,ON,NORMAL +178,178,1,1,7,0,11,81.2,-65.25,398.33,20,130.2,0.6,8,11,11,10,12,7,12,12,10,1,14,11,-1500,-1,-9999,MRD_x11_y00_z07,MRD_x11_y00_z07,None,ON,NORMAL +179,179,1,1,7,0,12,101.5,-65.25,398.33,20,130.2,0.6,8,11,12,10,13,7,13,12,12,1,14,12,-1500,-1,-9999,MRD_x12_y00_z07,MRD_x12_y00_z07,None,ON,NORMAL +180,180,1,1,7,0,13,121.8,-65.25,398.33,20,130.2,0.6,8,11,13,10,14,7,14,12,14,1,14,13,-1500,-1,-9999,MRD_x13_y00_z07,MRD_x13_y00_z07,None,ON,NORMAL +181,181,1,1,7,1,1,-121.8,65.25,398.33,20,130.2,0.6,8,11,17,12,2,8,2,1,4,1,15,1,-1500,-1,-9999,MRD_x01_y01_z07,MRD_x01_y01_z07,None,ON,NORMAL +182,182,1,1,7,1,2,-101.5,65.25,398.33,20,130.2,0.6,8,11,18,12,3,8,3,1,6,1,15,2,-1500,-1,-9999,MRD_x02_y01_z07,MRD_x02_y01_z07,None,ON,NORMAL +183,183,1,1,7,1,3,-81.2,65.25,398.33,20,130.2,0.6,8,11,19,12,4,8,4,1,8,1,15,3,-1300,-1,-9999,MRD_x03_y01_z07,MRD_x03_y01_z07,None,ON,HOT +184,184,1,1,7,1,4,-60.9,65.25,398.33,20,130.2,0.6,8,11,20,12,5,8,5,1,10,1,15,4,-1500,-1,-9999,MRD_x04_y01_z07,MRD_x04_y01_z07,None,ON,NORMAL +185,185,1,1,7,1,5,-40.6,65.25,398.33,20,130.2,0.6,8,11,21,12,6,8,6,1,12,1,15,5,-2000,-1,-9999,MRD_x05_y01_z07,MRD_x05_y01_z07,None,ON,NORMAL +186,186,1,1,7,1,6,-20.3,65.25,398.33,20,130.2,0.6,8,11,22,12,7,8,7,1,14,1,15,6,-2000,-1,-9999,MRD_x06_y01_z07,MRD_x06_y01_z07,None,ON,NORMAL +187,187,1,1,7,1,7,0,65.25,398.33,20,130.2,0.6,8,11,23,12,8,8,8,12,1,1,15,7,-2000,-1,-9999,MRD_x07_y01_z07,MRD_x07_y01_z07,None,ON,NORMAL +188,188,1,1,7,1,8,20.3,65.25,398.33,20,130.2,0.6,8,11,24,12,9,8,9,12,3,1,15,8,-2000,-1,-9999,MRD_x08_y01_z07,MRD_x08_y01_z07,None,ON,NORMAL +189,189,1,1,7,1,9,40.6,65.25,398.33,20,130.2,0.6,8,11,25,12,10,8,10,12,5,1,15,9,-1500,-1,-9999,MRD_x09_y01_z07,MRD_x09_y01_z07,None,ON,NORMAL +190,190,1,1,7,1,10,60.9,65.25,398.33,20,130.2,0.6,8,11,26,12,11,8,11,12,7,1,15,10,-1500,-1,-9999,MRD_x10_y01_z07,MRD_x10_y01_z07,None,ON,NORMAL +191,191,1,1,7,1,11,81.2,65.25,398.33,20,130.2,0.6,8,11,27,12,12,8,12,12,9,1,15,11,-1500,-1,-9999,MRD_x11_y01_z07,MRD_x11_y01_z07,None,ON,HOT +192,192,1,1,7,1,12,101.5,65.25,398.33,20,130.2,0.6,8,11,28,12,13,8,13,12,11,1,15,12,-1500,-1,-9999,MRD_x12_y01_z07,MRD_x12_y01_z07,None,ON,NORMAL +193,193,1,1,7,1,13,121.8,65.25,398.33,20,130.2,0.6,8,11,29,12,14,8,14,12,13,1,15,13,-1500,-1,-9999,MRD_x13_y01_z07,MRD_x13_y01_z07,None,ON,NORMAL +194,194,1,0,8,0,0,-73.75,-121.8,410.44,147.2,20,0.6,7,11,0,10,1,7,1,-1,-1,1,0,0,2100,1,EMI 9939B,MRD_x00_y00_z08,MRD_x00_y00_z08,None,ON,NORMAL +195,195,1,0,8,0,1,-73.75,-101.5,410.44,147.2,20,0.6,7,11,1,10,2,7,2,-1,-1,1,0,1,2100,1,EMI 9939B,MRD_x00_y01_z08,MRD_x00_y01_z08,None,OFF,NORMAL +196,196,1,0,8,0,2,-73.75,-81.2,410.44,147.2,20,0.6,7,11,2,10,3,7,3,-1,-1,1,0,2,2100,1,EMI 9939B,MRD_x00_y02_z08,MRD_x00_y02_z08,None,ON,NORMAL +197,197,1,0,8,0,3,-73.75,-60.9,410.44,147.2,20,0.6,7,11,3,10,4,7,4,-1,-1,1,0,3,2100,1,EMI 9939B,MRD_x00_y03_z08,MRD_x00_y03_z08,None,ON,NORMAL +198,198,1,0,8,0,4,-73.75,-40.6,410.44,147.2,20,0.6,7,11,4,10,5,7,5,-1,-1,1,0,4,2100,1,EMI 9939B,MRD_x00_y04_z08,MRD_x00_y04_z08,None,ON,NORMAL +199,199,1,0,8,0,5,-73.75,-20.3,410.44,147.2,20,0.6,7,11,5,10,6,7,6,-1,-1,1,0,5,2100,1,EMI 9939B,MRD_x00_y05_z08,MRD_x00_y05_z08,None,ON,NORMAL +200,200,1,0,8,0,6,-73.75,0,410.44,147.2,20,0.6,7,11,6,10,7,7,7,-1,-1,1,0,6,2100,1,EMI 9939B,MRD_x00_y06_z08,MRD_x00_y06_z08,None,ON,NORMAL +201,201,1,0,8,0,7,-73.75,20.3,410.44,147.2,20,0.6,7,11,7,10,8,7,8,-1,-1,1,0,7,2100,1,EMI 9939B,MRD_x00_y07_z08,MRD_x00_y07_z08,None,ON,NORMAL +202,202,1,0,8,0,8,-73.75,40.6,410.44,147.2,20,0.6,7,11,8,10,9,7,9,-1,-1,1,0,8,2100,1,EMI 9939B,MRD_x00_y08_z08,MRD_x00_y08_z08,None,ON,NORMAL +203,203,1,0,8,0,9,-73.75,60.9,410.44,147.2,20,0.6,7,11,9,10,10,7,10,-1,-1,1,0,9,2100,1,EMI 9939B,MRD_x00_y09_z08,MRD_x00_y09_z08,None,ON,NORMAL +204,204,1,0,8,0,10,-73.75,81.2,410.44,147.2,20,0.6,7,11,10,10,11,7,11,-1,-1,1,0,10,2100,1,EMI 9939B,MRD_x00_y10_z08,MRD_x00_y10_z08,None,ON,NORMAL +205,205,1,0,8,0,11,-73.75,101.5,410.44,147.2,20,0.6,7,11,11,10,12,7,12,-1,-1,1,0,11,2100,1,EMI 9939B,MRD_x00_y11_z08,MRD_x00_y11_z08,None,ON,NORMAL +206,206,1,0,8,0,12,-73.75,121.8,410.44,147.2,20,0.6,7,11,12,10,13,7,13,-1,-1,1,0,12,2100,1,EMI 9939B,MRD_x00_y12_z08,MRD_x00_y12_z08,None,OFF,NORMAL +207,207,1,0,8,1,0,73.75,-121.8,410.44,147.2,20,0.6,7,11,16,12,1,8,1,-1,-1,1,1,13,2100,1,EMI 9939B,MRD_x01_y00_z08,MRD_x01_y00_z08,< HV 1-1-0 is brokenNone,ON,NORMAL +208,208,1,0,8,1,1,73.75,-101.5,410.44,147.2,20,0.6,7,11,17,12,2,8,2,-1,-1,1,1,1,2100,1,EMI 9939B,MRD_x01_y01_z08,MRD_x01_y01_z08,None,ON,NORMAL +209,209,1,0,8,1,2,73.75,-81.2,410.44,147.2,20,0.6,7,11,18,12,3,8,3,-1,-1,1,1,2,2100,1,EMI 9939B,MRD_x01_y02_z08,MRD_x01_y02_z08,None,ON,NORMAL +210,210,1,0,8,1,3,73.75,-60.9,410.44,147.2,20,0.6,7,11,19,12,4,8,4,-1,-1,1,1,3,2100,1,EMI 9939B,MRD_x01_y03_z08,MRD_x01_y03_z08,None,ON,NORMAL +211,211,1,0,8,1,4,73.75,-40.6,410.44,147.2,20,0.6,7,11,20,12,5,8,5,-1,-1,1,1,4,2100,1,EMI 9939B,MRD_x01_y04_z08,MRD_x01_y04_z08,None,ON,NORMAL +212,212,1,0,8,1,5,73.75,-20.3,410.44,147.2,20,0.6,7,11,21,12,6,8,6,-1,-1,1,1,5,2100,1,EMI 9939B,MRD_x01_y05_z08,MRD_x01_y05_z08,None,ON,NORMAL +213,213,1,0,8,1,6,73.75,0,410.44,147.2,20,0.6,7,11,22,12,7,8,7,-1,-1,1,1,6,2100,1,EMI 9939B,MRD_x01_y06_z08,MRD_x01_y06_z08,None,ON,NORMAL +214,214,1,0,8,1,7,73.75,20.3,410.44,147.2,20,0.6,7,11,23,12,8,8,8,-1,-1,1,1,7,2100,1,EMI 9939B,MRD_x01_y07_z08,MRD_x01_y07_z08,None,ON,NORMAL +215,215,1,0,8,1,8,73.75,40.6,410.44,147.2,20,0.6,7,11,24,12,9,8,9,-1,-1,1,1,8,2100,1,EMI 9939B,MRD_x01_y08_z08,MRD_x01_y08_z08,None,OFF,NORMAL +216,216,1,0,8,1,9,73.75,60.9,410.44,147.2,20,0.6,7,11,25,12,10,8,10,-1,-1,1,1,9,2100,1,EMI 9939B,MRD_x01_y09_z08,MRD_x01_y09_z08,None,ON,NORMAL +217,217,1,0,8,1,10,73.75,81.2,410.44,147.2,20,0.6,7,11,26,12,11,8,11,-1,-1,1,1,10,2100,1,EMI 9939B,MRD_x01_y10_z08,MRD_x01_y10_z08,None,OFF,NORMAL +218,218,1,0,8,1,11,73.75,101.5,410.44,147.2,20,0.6,7,11,27,12,12,8,12,-1,-1,1,1,11,2100,1,EMI 9939B,MRD_x01_y11_z08,MRD_x01_y11_z08,None,OFF,NORMAL +219,219,1,0,8,1,12,73.75,121.8,410.44,147.2,20,0.6,7,11,28,12,13,8,13,-1,-1,1,1,12,2100,1,EMI 9939B,MRD_x01_y12_z08,MRD_x01_y12_z08,None,ON,NORMAL +220,220,1,1,9,0,0,-142.1,-65.25,422.55,20,130.2,0.6,8,14,0,13,1,9,1,2,1,2,0,0,-1500,-1,-9999,MRD_x00_y00_z09,MRD_x00_y00_z09,None,ON,NORMAL +221,221,1,1,9,0,1,-121.8,-65.25,422.55,20,130.2,0.6,8,14,1,13,2,9,2,2,3,2,0,1,-1500,-1,-9999,MRD_x01_y00_z09,MRD_x01_y00_z09,None,ON,NORMAL +222,222,1,1,9,0,2,-101.5,-65.25,422.55,20,130.2,0.6,8,14,2,13,3,9,3,2,5,2,0,2,-1500,-1,-9999,MRD_x02_y00_z09,MRD_x02_y00_z09,None,ON,NORMAL +223,223,1,1,9,0,3,-81.2,-65.25,422.55,20,130.2,0.6,8,14,3,13,4,9,4,2,7,2,0,3,-1500,-1,-9999,MRD_x03_y00_z09,MRD_x03_y00_z09,None,ON,NORMAL +224,224,1,1,9,0,4,-60.9,-65.25,422.55,20,130.2,0.6,8,14,4,13,5,9,5,2,9,2,0,4,-1500,-1,-9999,MRD_x04_y00_z09,MRD_x04_y00_z09,None,OFF,NORMAL +225,225,1,1,9,0,5,-40.6,-65.25,422.55,20,130.2,0.6,8,14,5,13,6,9,6,2,11,2,0,5,-2000,-1,-9999,MRD_x05_y00_z09,MRD_x05_y00_z09,None,ON,NORMAL +226,226,1,1,9,0,6,-20.3,-65.25,422.55,20,130.2,0.6,8,14,6,13,7,9,7,2,13,2,0,6,-2000,-1,-9999,MRD_x06_y00_z09,MRD_x06_y00_z09,None,ON,NORMAL +227,227,1,1,9,0,7,0,-65.25,422.55,20,130.2,0.6,8,11,31,12,16,9,8,11,1,2,0,7,-2000,-1,-9999,MRD_x07_y00_z09,MRD_x07_y00_z09,Discriminator on rack 8 slot 13 channel 8 has no NIM outputNone,ON,NORMAL +228,228,1,1,9,0,8,20.3,-65.25,422.55,20,130.2,0.6,8,14,8,13,9,9,9,11,2,2,0,8,-2000,-1,-9999,MRD_x08_y00_z09,MRD_x08_y00_z09,None,ON,NORMAL +229,229,1,1,9,0,9,40.6,-65.25,422.55,20,130.2,0.6,8,14,9,13,10,9,10,11,3,2,0,9,-1500,-1,-9999,MRD_x09_y00_z09,MRD_x09_y00_z09,None,ON,NORMAL +230,230,1,1,9,0,10,60.9,-65.25,422.55,20,130.2,0.6,8,14,10,13,11,9,11,11,4,2,0,10,-1500,-1,-9999,MRD_x10_y00_z09,MRD_x10_y00_z09,None,ON,NORMAL +231,231,1,1,9,0,11,81.2,-65.25,422.55,20,130.2,0.6,8,14,11,13,12,9,12,11,5,2,0,11,-1500,-1,-9999,MRD_x11_y00_z09,MRD_x11_y00_z09,None,ON,NORMAL +232,232,1,1,9,0,12,101.5,-65.25,422.55,20,130.2,0.6,8,14,15,13,16,9,13,11,6,2,0,12,-1500,-1,-9999,MRD_x12_y00_z09,MRD_x12_y00_z09,slot 13 on this disc had a very high rate; shifted signal to slot 16None,ON,NORMAL +233,233,1,1,9,0,13,121.8,-65.25,422.55,20,130.2,0.6,8,14,13,13,14,9,14,11,7,2,0,13,-1500,-1,-9999,MRD_x13_y00_z09,MRD_x13_y00_z09,None,ON,NORMAL +234,234,1,1,9,0,14,142.1,-65.25,422.55,20,130.2,0.6,8,14,14,13,15,9,15,11,8,2,0,14,-1500,-1,-9999,MRD_x14_y00_z09,MRD_x14_y00_z09,None,ON,NORMAL +235,235,1,1,9,1,0,-142.1,65.25,422.55,20,130.2,0.6,8,14,16,15,1,10,1,2,2,2,1,0,-1500,-1,-9999,MRD_x00_y01_z09,MRD_x00_y01_z09,None,ON,NORMAL +236,236,1,1,9,1,1,-121.8,65.25,422.55,20,130.2,0.6,8,14,17,15,2,10,2,2,4,2,1,1,-1500,-1,-9999,MRD_x01_y01_z09,MRD_x01_y01_z09,None,ON,NORMAL +237,237,1,1,9,1,2,-101.5,65.25,422.55,20,130.2,0.6,8,14,18,15,3,10,3,2,6,2,1,2,-1300,-1,-9999,MRD_x02_y01_z09,MRD_x02_y01_z09,None,ON,NORMAL +238,238,1,1,9,1,3,-81.2,65.25,422.55,20,130.2,0.6,8,14,19,15,4,10,4,2,8,2,1,3,-1500,-1,-9999,MRD_x03_y01_z09,MRD_x03_y01_z09,None,ON,NORMAL +239,239,1,1,9,1,4,-60.9,65.25,422.55,20,130.2,0.6,8,14,20,15,5,10,5,2,10,2,1,4,-1500,-1,-9999,MRD_x04_y01_z09,MRD_x04_y01_z09,None,ON,NORMAL +240,240,1,1,9,1,5,-40.6,65.25,422.55,20,130.2,0.6,8,14,21,15,6,10,6,2,12,2,1,5,-1500,-1,-9999,MRD_x05_y01_z09,MRD_x05_y01_z09,None,ON,NORMAL +241,241,1,1,9,1,6,-20.3,65.25,422.55,20,130.2,0.6,8,14,22,15,7,10,7,2,14,2,1,6,-1500,-1,-9999,MRD_x06_y01_z09,MRD_x06_y01_z09,None,ON,NORMAL +242,242,1,1,9,1,7,0,65.25,422.55,20,130.2,0.6,8,14,23,15,8,10,8,12,18,2,1,7,-1500,-1,-9999,MRD_x07_y01_z09,MRD_x07_y01_z09,None,ON,NORMAL +243,243,1,1,9,1,8,20.3,65.25,422.55,20,130.2,0.6,8,14,24,15,9,10,9,12,20,2,1,8,-1500,-1,-9999,MRD_x08_y01_z09,MRD_x08_y01_z09,None,ON,NORMAL +244,244,1,1,9,1,9,40.6,65.25,422.55,20,130.2,0.6,8,14,25,15,10,10,10,12,22,2,1,9,-1500,-1,-9999,MRD_x09_y01_z09,MRD_x09_y01_z09,None,ON,NORMAL +245,245,1,1,9,1,10,60.9,65.25,422.55,20,130.2,0.6,8,14,26,15,11,10,11,12,24,2,1,10,-1500,-1,-9999,MRD_x10_y01_z09,MRD_x10_y01_z09,None,ON,NORMAL +246,246,1,1,9,1,11,81.2,65.25,422.55,20,130.2,0.6,8,14,27,15,12,10,12,12,26,2,1,11,-1500,-1,-9999,MRD_x11_y01_z09,MRD_x11_y01_z09,None,ON,NORMAL +247,247,1,1,9,1,12,101.5,65.25,422.55,20,130.2,0.6,8,14,28,15,13,10,13,12,28,2,1,12,-1500,-1,-9999,MRD_x12_y01_z09,MRD_x12_y01_z09,None,ON,NORMAL +248,248,1,1,9,1,13,121.8,65.25,422.55,20,130.2,0.6,8,14,29,15,14,10,14,12,30,2,1,13,-1500,-1,-9999,MRD_x13_y01_z09,MRD_x13_y01_z09,None,ON,NORMAL +249,249,1,1,9,1,14,142.1,65.25,422.55,20,130.2,0.6,8,14,30,15,15,10,15,12,32,2,1,14,-1500,-1,-9999,MRD_x14_y01_z09,MRD_x14_y01_z09,None,ON,NORMAL +250,250,1,0,10,0,0,-73.75,-121.8,434.66,147.2,20,0.6,7,19,0,18,1,9,1,-1,-1,2,2,0,-2100,-1,-9999,MRD_x00_y00_z10,MRD_x00_y00_z10,None,ON,NORMAL +251,251,1,0,10,0,1,-73.75,-101.5,434.66,147.2,20,0.6,7,19,1,18,2,9,2,-1,-1,2,2,1,-1600,-1,-9999,MRD_x00_y01_z10,MRD_x00_y01_z10,None,OFF,NORMAL +252,252,1,0,10,0,2,-73.75,-81.2,434.66,147.2,20,0.6,7,19,2,18,3,9,3,-1,-1,2,2,2,-2100,-1,-9999,MRD_x00_y02_z10,MRD_x00_y02_z10,None,ON,NORMAL +253,253,1,0,10,0,3,-73.75,-60.9,434.66,147.2,20,0.6,7,19,3,18,4,9,4,-1,-1,2,2,3,-2100,-1,-9999,MRD_x00_y03_z10,MRD_x00_y03_z10,None,ON,NORMAL +254,254,1,0,10,0,4,-73.75,-40.6,434.66,147.2,20,0.6,7,19,4,18,5,9,5,-1,-1,2,2,4,-2100,-1,-9999,MRD_x00_y04_z10,MRD_x00_y04_z10,None,OFF,NORMAL +255,255,1,0,10,0,5,-73.75,-20.3,434.66,147.2,20,0.6,7,19,5,18,6,9,6,-1,-1,2,2,5,-2100,-1,-9999,MRD_x00_y05_z10,MRD_x00_y05_z10,None,ON,NORMAL +256,256,1,0,10,0,6,-73.75,0,434.66,147.2,20,0.6,7,19,6,18,7,9,7,-1,-1,2,2,6,-2100,-1,-9999,MRD_x00_y06_z10,MRD_x00_y06_z10,None,ON,NORMAL +257,257,1,0,10,0,7,-73.75,20.3,434.66,147.2,20,0.6,7,19,7,18,8,9,8,-1,-1,2,2,7,-2100,-1,-9999,MRD_x00_y07_z10,MRD_x00_y07_z10,None,ON,NORMAL +258,258,1,0,10,0,8,-73.75,40.6,434.66,147.2,20,0.6,7,19,8,18,9,9,9,-1,-1,2,2,8,-1900,-1,-9999,MRD_x00_y08_z10,MRD_x00_y08_z10,None,ON,NORMAL +259,259,1,0,10,0,9,-73.75,60.9,434.66,147.2,20,0.6,7,19,9,18,10,9,10,-1,-1,2,2,9,-2100,-1,-9999,MRD_x00_y09_z10,MRD_x00_y09_z10,None,ON,NORMAL +260,260,1,0,10,0,10,-73.75,81.2,434.66,147.2,20,0.6,7,19,10,18,11,9,11,-1,-1,2,2,10,-2100,-1,-9999,MRD_x00_y10_z10,MRD_x00_y10_z10,None,OFF,NORMAL +261,261,1,0,10,0,11,-73.75,101.5,434.66,147.2,20,0.6,7,19,11,18,12,9,12,-1,-1,2,2,11,-2100,-1,-9999,MRD_x00_y11_z10,MRD_x00_y11_z10,Crate 2 card 3 ch11 is broken: nothing connectedNone,ON,NORMAL +262,262,1,0,10,0,12,-73.75,121.8,434.66,147.2,20,0.6,7,19,12,18,13,9,13,-1,-1,2,2,12,-2100,-1,-9999,MRD_x00_y12_z10,MRD_x00_y12_z10,None,ON,NORMAL +263,263,1,0,10,1,0,73.75,-121.8,434.66,147.2,20,0.6,7,19,16,20,1,10,1,-1,-1,2,3,0,-2100,-1,-9999,MRD_x01_y00_z10,MRD_x01_y00_z10,None,ON,NORMAL +264,264,1,0,10,1,1,73.75,-101.5,434.66,147.2,20,0.6,7,19,17,20,2,10,2,-1,-1,2,3,1,-1900,-1,-9999,MRD_x01_y01_z10,MRD_x01_y01_z10,None,ON,NORMAL +265,265,1,0,10,1,2,73.75,-81.2,434.66,147.2,20,0.6,7,19,18,20,3,10,3,-1,-1,2,3,2,-1600,-1,-9999,MRD_x01_y02_z10,MRD_x01_y02_z10,None,ON,NORMAL +266,266,1,0,10,1,3,73.75,-60.9,434.66,147.2,20,0.6,7,19,19,20,4,10,4,-1,-1,2,3,3,-1800,-1,-9999,MRD_x01_y03_z10,MRD_x01_y03_z10,None,ON,NORMAL +267,267,1,0,10,1,4,73.75,-40.6,434.66,147.2,20,0.6,7,19,20,20,5,10,5,-1,-1,2,3,4,-1800,-1,-9999,MRD_x01_y04_z10,MRD_x01_y04_z10,None,ON,NORMAL +268,268,1,0,10,1,5,73.75,-20.3,434.66,147.2,20,0.6,7,19,21,20,6,10,6,-1,-1,2,3,5,-2100,-1,-9999,MRD_x01_y05_z10,MRD_x01_y05_z10,None,ON,NORMAL +269,269,1,0,10,1,6,73.75,0,434.66,147.2,20,0.6,7,19,22,20,7,10,7,-1,-1,2,3,6,-2100,-1,-9999,MRD_x01_y06_z10,MRD_x01_y06_z10,None,ON,NORMAL +270,270,1,0,10,1,7,73.75,20.3,434.66,147.2,20,0.6,7,19,23,20,8,10,8,-1,-1,2,3,7,-1600,-1,-9999,MRD_x01_y07_z10,MRD_x01_y07_z10,None,ON,NORMAL +271,271,1,0,10,1,8,73.75,40.6,434.66,147.2,20,0.6,7,19,24,20,9,10,9,-1,-1,2,3,8,-2100,-1,-9999,MRD_x01_y08_z10,MRD_x01_y08_z10,None,OFF,HOT +272,272,1,0,10,1,9,73.75,60.9,434.66,147.2,20,0.6,7,19,25,20,10,10,10,-1,-1,2,3,9,-2100,-1,-9999,MRD_x01_y09_z10,MRD_x01_y09_z10,None,ON,NORMAL +273,273,1,0,10,1,10,73.75,81.2,434.66,147.2,20,0.6,7,19,26,20,11,10,11,-1,-1,2,3,10,-1600,-1,-9999,MRD_x01_y10_z10,MRD_x01_y10_z10,None,ON,NORMAL +274,274,1,0,10,1,11,73.75,101.5,434.66,147.2,20,0.6,7,19,27,20,12,10,12,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y11_z10,MRD_x01_y11_z10,None,ON,NORMAL +275,275,1,0,10,1,12,73.75,121.8,434.66,147.2,20,0.6,7,19,28,20,13,10,13,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y12_z10,MRD_x01_y12_z10,None,OFF,NORMAL +276,276,1,1,11,0,0,-142.1,-65.25,446.77,20,130.2,0.6,8,17,0,16,1,11,1,1,19,2,4,0,-1500,-1,-9999,MRD_x00_y00_z11,MRD_x00_y00_z11,None,ON,NORMAL +277,277,1,1,11,0,1,-121.8,-65.25,446.77,20,130.2,0.6,8,17,1,16,2,11,2,1,21,2,4,1,-1500,-1,-9999,MRD_x01_y00_z11,MRD_x01_y00_z11,None,ON,NORMAL +278,278,1,1,11,0,2,-101.5,-65.25,446.77,20,130.2,0.6,8,17,2,16,3,11,3,1,23,2,4,2,-1500,-1,-9999,MRD_x02_y00_z11,MRD_x02_y00_z11,None,ON,NORMAL +279,279,1,1,11,0,3,-81.2,-65.25,446.77,20,130.2,0.6,8,17,3,16,4,11,4,1,25,2,4,3,-1300,-1,-9999,MRD_x03_y00_z11,MRD_x03_y00_z11,None,ON,NORMAL +280,280,1,1,11,0,4,-60.9,-65.25,446.77,20,130.2,0.6,8,17,4,16,5,11,5,1,27,2,4,4,-1500,-1,-9999,MRD_x04_y00_z11,MRD_x04_y00_z11,None,ON,NORMAL +281,281,1,1,11,0,5,-40.6,-65.25,446.77,20,130.2,0.6,8,17,5,16,6,11,6,1,29,2,4,5,-1500,-1,-9999,MRD_x05_y00_z11,MRD_x05_y00_z11,None,ON,NORMAL +282,282,1,1,11,0,6,-20.3,-65.25,446.77,20,130.2,0.6,8,17,6,16,7,11,7,1,31,2,4,6,-1500,-1,-9999,MRD_x06_y00_z11,MRD_x06_y00_z11,None,ON,NORMAL +283,283,1,1,11,0,7,0,-65.25,446.77,20,130.2,0.6,8,17,7,16,8,11,8,12,17,2,4,7,-1500,-1,-9999,MRD_x07_y00_z11,MRD_x07_y00_z11,None,ON,NORMAL +284,284,1,1,11,0,8,20.3,-65.25,446.77,20,130.2,0.6,8,17,8,16,9,11,9,12,19,2,4,8,-1500,-1,-9999,MRD_x08_y00_z11,MRD_x08_y00_z11,None,ON,NORMAL +285,285,1,1,11,0,9,40.6,-65.25,446.77,20,130.2,0.6,8,17,9,16,10,11,10,12,21,2,4,9,-1300,-1,-9999,MRD_x09_y00_z11,MRD_x09_y00_z11,None,ON,NORMAL +286,286,1,1,11,0,10,60.9,-65.25,446.77,20,130.2,0.6,8,17,10,16,11,11,11,12,23,2,4,10,-1500,-1,-9999,MRD_x10_y00_z11,MRD_x10_y00_z11,None,ON,NORMAL +287,287,1,1,11,0,11,81.2,-65.25,446.77,20,130.2,0.6,8,17,11,16,12,11,12,12,25,2,4,11,-1500,-1,-9999,MRD_x11_y00_z11,MRD_x11_y00_z11,None,ON,NORMAL +288,288,1,1,11,0,12,101.5,-65.25,446.77,20,130.2,0.6,8,17,12,16,13,11,13,12,27,2,4,12,-1500,-1,-9999,MRD_x12_y00_z11,MRD_x12_y00_z11,None,ON,NORMAL +289,289,1,1,11,0,13,121.8,-65.25,446.77,20,130.2,0.6,8,17,13,16,14,11,14,12,29,2,4,13,-1500,-1,-9999,MRD_x13_y00_z11,MRD_x13_y00_z11,None,ON,NORMAL +290,290,1,1,11,0,14,142.1,-65.25,446.77,20,130.2,0.6,8,17,14,16,15,11,15,12,31,2,4,14,-1500,-1,-9999,MRD_x14_y00_z11,MRD_x14_y00_z11,None,ON,NORMAL +291,291,1,1,11,1,0,-142.1,65.25,446.77,20,130.2,0.6,8,17,16,18,1,12,1,1,20,2,5,0,-1500,-1,-9999,MRD_x00_y01_z11,MRD_x00_y01_z11,None,ON,HOT +292,292,1,1,11,1,1,-121.8,65.25,446.77,20,130.2,0.6,8,17,17,18,2,12,2,1,22,2,5,1,-1500,-1,-9999,MRD_x01_y01_z11,MRD_x01_y01_z11,None,ON,NORMAL +293,293,1,1,11,1,2,-101.5,65.25,446.77,20,130.2,0.6,8,17,18,18,3,12,3,1,24,2,5,3,-1500,-1,-9999,MRD_x02_y01_z11,MRD_x02_y01_z11,None,ON,HOT +294,294,1,1,11,1,3,-81.2,65.25,446.77,20,130.2,0.6,8,17,19,18,4,12,4,1,26,2,5,4,-1500,-1,-9999,MRD_x03_y01_z11,MRD_x03_y01_z11,None,ON,NORMAL +295,295,1,1,11,1,4,-60.9,65.25,446.77,20,130.2,0.6,8,17,20,18,5,12,5,1,28,2,5,5,-1500,-1,-9999,MRD_x04_y01_z11,MRD_x04_y01_z11,None,ON,NORMAL +296,296,1,1,11,1,5,-40.6,65.25,446.77,20,130.2,0.6,8,17,21,18,6,12,6,1,30,2,5,6,-1500,-1,-9999,MRD_x05_y01_z11,MRD_x05_y01_z11,None,ON,NORMAL +297,297,1,1,11,1,6,-20.3,65.25,446.77,20,130.2,0.6,8,17,22,18,7,12,7,1,32,2,5,7,-1500,-1,-9999,MRD_x06_y01_z11,MRD_x06_y01_z11,None,ON,HOT +298,298,1,1,11,1,7,0,65.25,446.77,20,130.2,0.6,8,17,23,18,8,12,8,10,1,2,5,8,-1500,-1,-9999,MRD_x07_y01_z11,MRD_x07_y01_z11,None,ON,HOT +299,299,1,1,11,1,8,20.3,65.25,446.77,20,130.2,0.6,8,17,24,18,9,12,9,10,2,2,5,9,-1500,-1,-9999,MRD_x08_y01_z11,MRD_x08_y01_z11,None,ON,NORMAL +300,300,1,1,11,1,9,40.6,65.25,446.77,20,130.2,0.6,8,17,25,18,10,12,10,10,3,2,5,10,-1300,-1,-9999,MRD_x09_y01_z11,MRD_x09_y01_z11,None,ON,HOT +301,301,1,1,11,1,10,60.9,65.25,446.77,20,130.2,0.6,8,17,26,18,11,12,11,10,4,2,5,11,-1300,-1,-9999,MRD_x10_y01_z11,MRD_x10_y01_z11,None,ON,NORMAL +302,302,1,1,11,1,11,81.2,65.25,446.77,20,130.2,0.6,8,17,27,18,12,12,12,10,5,2,5,12,-1300,-1,-9999,MRD_x11_y01_z11,MRD_x11_y01_z11,None,ON,NORMAL +303,303,1,1,11,1,12,101.5,65.25,446.77,20,130.2,0.6,8,17,28,18,13,12,13,10,6,2,5,13,-1300,-1,-9999,MRD_x12_y01_z11,MRD_x12_y01_z11,None,ON,NORMAL +304,304,1,1,11,1,13,121.8,65.25,446.77,20,130.2,0.6,8,17,29,18,14,12,14,10,7,2,5,14,-1500,-1,-9999,MRD_x13_y01_z11,MRD_x13_y01_z11,None,ON,HOT +305,305,1,1,11,1,14,142.1,65.25,446.77,20,130.2,0.6,8,17,30,18,15,12,15,10,8,2,5,14,-1500,-1,-9999,MRD_x14_y01_z11,MRD_x14_y01_z11,None,ON,NORMAL +306,306,1,0,12,0,0,-73.75,-121.8,458.88,147.2,20,0.6,7,22,0,21,1,11,1,-1,-1,2,6,0,-2100,-1,-9999,MRD_x00_y00_z12,MRD_x00_y00_z12,None,ON,NORMAL +307,307,1,0,12,0,1,-73.75,-101.5,458.88,147.2,20,0.6,7,22,1,21,2,11,2,-1,-1,2,6,1,-2100,-1,-9999,MRD_x00_y01_z12,MRD_x00_y01_z12,None,ON,NORMAL +308,308,1,0,12,0,2,-73.75,-81.2,458.88,147.2,20,0.6,7,22,2,21,3,11,3,-1,-1,2,6,2,-2100,-1,-9999,MRD_x00_y02_z12,MRD_x00_y02_z12,None,ON,NORMAL +309,309,1,0,12,0,3,-73.75,-60.9,458.88,147.2,20,0.6,7,22,3,21,4,11,4,-1,-1,2,6,3,-2100,-1,-9999,MRD_x00_y03_z12,MRD_x00_y03_z12,None,ON,NORMAL +310,310,1,0,12,0,4,-73.75,-40.6,458.88,147.2,20,0.6,7,22,4,21,5,11,5,-1,-1,2,6,4,-1900,-1,-9999,MRD_x00_y04_z12,MRD_x00_y04_z12,None,ON,NORMAL +311,311,1,0,12,0,5,-73.75,-20.3,458.88,147.2,20,0.6,7,22,5,21,6,11,6,-1,-1,2,6,5,-2100,-1,-9999,MRD_x00_y05_z12,MRD_x00_y05_z12,None,ON,NORMAL +312,312,1,0,12,0,6,-73.75,0,458.88,147.2,20,0.6,7,22,6,21,7,11,7,-1,-1,2,6,6,-1900,-1,-9999,MRD_x00_y06_z12,MRD_x00_y06_z12,None,ON,NORMAL +313,313,1,0,12,0,7,-73.75,20.3,458.88,147.2,20,0.6,7,22,7,21,8,11,8,-1,-1,2,6,7,-2100,-1,-9999,MRD_x00_y07_z12,MRD_x00_y07_z12,None,ON,NORMAL +314,314,1,0,12,0,8,-73.75,40.6,458.88,147.2,20,0.6,7,22,8,21,9,11,9,-1,-1,2,6,8,-2100,-1,-9999,MRD_x00_y08_z12,MRD_x00_y08_z12,None,ON,NORMAL +315,315,1,0,12,0,9,-73.75,60.9,458.88,147.2,20,0.6,7,22,9,21,10,11,10,-1,-1,2,6,9,-2100,-1,-9999,MRD_x00_y09_z12,MRD_x00_y09_z12,None,ON,NORMAL +316,316,1,0,12,0,10,-73.75,81.2,458.88,147.2,20,0.6,7,22,10,21,11,11,11,-1,-1,2,6,10,-2100,-1,-9999,MRD_x00_y10_z12,MRD_x00_y10_z12,None,ON,NORMAL +317,317,1,0,12,0,11,-73.75,101.5,458.88,147.2,20,0.6,7,22,11,21,12,11,12,-1,-1,2,6,11,-2100,-1,-9999,MRD_x00_y11_z12,MRD_x00_y11_z12,None,ON,NORMAL +318,318,1,0,12,0,12,-73.75,121.8,458.88,147.2,20,0.6,7,22,12,21,13,11,13,-1,-1,2,6,12,-2100,-1,-9999,MRD_x00_y12_z12,MRD_x00_y12_z12,None,ON,NORMAL +319,319,1,0,12,1,0,73.75,-121.8,458.88,147.2,20,0.6,7,22,16,23,1,12,1,-1,-1,2,7,0,-2100,-1,-9999,MRD_x01_y00_z12,MRD_x01_y00_z12,None,ON,NORMAL +320,320,1,0,12,1,1,73.75,-101.5,458.88,147.2,20,0.6,7,22,17,23,2,12,2,-1,-1,2,7,1,-2100,-1,-9999,MRD_x01_y01_z12,MRD_x01_y01_z12,None,ON,NORMAL +321,321,1,0,12,1,2,73.75,-81.2,458.88,147.2,20,0.6,7,22,18,23,3,12,3,-1,-1,2,7,2,-2100,-1,-9999,MRD_x01_y02_z12,MRD_x01_y02_z12,None,ON,NORMAL +322,322,1,0,12,1,3,73.75,-60.9,458.88,147.2,20,0.6,7,22,19,23,4,12,4,-1,-1,2,7,3,-2100,-1,-9999,MRD_x01_y03_z12,MRD_x01_y03_z12,None,ON,NORMAL +323,323,1,0,12,1,4,73.75,-40.6,458.88,147.2,20,0.6,7,22,20,23,5,12,5,-1,-1,2,7,4,-2100,-1,-9999,MRD_x01_y04_z12,MRD_x01_y04_z12,None,ON,NORMAL +324,324,1,0,12,1,5,73.75,-20.3,458.88,147.2,20,0.6,7,22,21,23,6,12,6,-1,-1,2,7,5,-2100,-1,-9999,MRD_x01_y05_z12,MRD_x01_y05_z12,None,ON,NORMAL +325,325,1,0,12,1,6,73.75,0,458.88,147.2,20,0.6,7,22,22,23,7,12,7,-1,-1,2,7,6,-2100,-1,-9999,MRD_x01_y06_z12,MRD_x01_y06_z12,None,OFF,NORMAL +326,326,1,0,12,1,7,73.75,20.3,458.88,147.2,20,0.6,7,22,23,23,8,12,8,-1,-1,2,7,7,-2100,-1,-9999,MRD_x01_y07_z12,MRD_x01_y07_z12,None,ON,NORMAL +327,327,1,0,12,1,8,73.75,40.6,458.88,147.2,20,0.6,7,22,24,23,9,12,9,-1,-1,2,7,8,-2100,-1,-9999,MRD_x01_y08_z12,MRD_x01_y08_z12,None,ON,NORMAL +328,328,1,0,12,1,9,73.75,60.9,458.88,147.2,20,0.6,7,22,25,23,10,12,10,-1,-1,2,7,9,-2100,-1,-9999,MRD_x01_y09_z12,MRD_x01_y09_z12,None,ON,NORMAL +329,329,1,0,12,1,10,73.75,81.2,458.88,147.2,20,0.6,7,22,26,23,11,12,11,-1,-1,2,7,10,-2100,-1,-9999,MRD_x01_y10_z12,MRD_x01_y10_z12,None,ON,NORMAL +330,330,1,0,12,1,11,73.75,101.5,458.88,147.2,20,0.6,7,22,27,23,12,12,12,-1,-1,2,7,11,-2100,-1,-9999,MRD_x01_y11_z12,MRD_x01_y11_z12,None,ON,NORMAL +331,331,1,0,12,1,12,73.75,121.8,458.88,147.2,20,0.6,7,22,28,23,13,12,13,-1,-1,2,7,12,-2100,-1,-9999,MRD_x01_y12_z12,MRD_x01_y12_z12,None,ON,NORMAL +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/FullMRDGeometry_2022_thru_03_2023_Runs_up_to_R4191.csv b/configfiles/LoadGeometry/FullMRDGeometry_2022_thru_03_2023_Runs_up_to_R4191.csv new file mode 100644 index 000000000..6c890bb57 --- /dev/null +++ b/configfiles/LoadGeometry/FullMRDGeometry_2022_thru_03_2023_Runs_up_to_R4191.csv @@ -0,0 +1,342 @@ +#,,0=FMV,0=horizontal,,0=left,from left to right,,,,,,,,,,,,,,#NAME?,#NAME?,,,,,,,,,,, +#,,1=MRD,1=vertical,,1=right,from bottom to top,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,0=bottom,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,1=top,,,,,,,,,,,,,,,,,,,,,,,,,,, +#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,channel_num,detector_system,orientation,layer,side,num,x_center,y_center,z_center,x_width,y_width,z_width,rack,TDC_slot,TDC_channel,discrim_slot,discrim_ch,patch_panel_row,patch_panel_col,amp_slot,amp_channel,hv_crate,hv_slot,hv_channel,nominal_HV,polarity,PMT_type,cable_label,paddle_label,notes,detector_status,noise +########################################,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,0,0,0,0,0,0,0,-198.699875,5.08,320,30.5,2,8,2,0,1,1,1,1,-1,-1,2,14,0,-1871,-1,EMI9815,MRD_x00_y00_z00,4SW,None,ON,NORMAL +1,1,0,0,0,0,1,0,-167.999875,5.08,320,30.5,2,8,2,1,1,2,1,2,-1,-1,2,14,1,-1838,-1,EMI9815,MRD_x00_y01_z00,U39,None,ON,NORMAL +2,2,0,0,0,0,2,0,-137.299875,5.08,320,30.5,2,8,2,2,1,3,1,3,-1,-1,2,14,2,-1793,-1,EMI9815,MRD_x00_y02_z00,U58 (or U38; bad writing),None,ON,NORMAL +3,3,0,0,0,0,3,0,-106.599875,5.08,320,30.5,2,8,2,3,1,4,1,4,-1,-1,2,14,3,-1806,-1,EMI9815,MRD_x00_y03_z00,U29,None,ON,NORMAL +4,4,0,0,0,0,4,0,-75.899875,5.08,320,30.5,2,8,2,4,1,5,1,5,-1,-1,2,14,4,-1865,-1,EMI9815,MRD_x00_y04_z00,14SW,None,ON,NORMAL +5,5,0,0,0,0,5,0,-45.199875,5.08,320,30.5,2,8,2,5,1,6,1,6,-1,-1,2,14,5,-1823,-1,EMI9815,MRD_x00_y05_z00,Unknown4,None,ON,NORMAL +6,6,0,0,0,0,6,0,-14.499875,5.08,320,30.5,2,8,2,6,1,7,1,7,-1,-1,2,14,6,-1798,-1,EMI9815,MRD_x00_y06_z00,U17,None,ON,NORMAL +7,7,0,0,0,0,7,0,16.200125,5.08,320,30.5,2,8,2,7,1,8,1,8,-1,-1,2,14,7,-1823,-1,EMI9815,MRD_x00_y07_z00,11SE,None,ON,NORMAL +8,8,0,0,0,0,8,0,46.900125,5.08,320,30.5,2,8,2,8,1,9,1,9,-1,-1,2,14,8,-1871,-1,EMI9815,MRD_x00_y08_z00,18SE,None,ON,NORMAL +9,9,0,0,0,0,9,0,77.600125,5.08,320,30.5,2,8,2,9,1,10,1,10,-1,-1,2,14,9,-1836,-1,EMI9815,MRD_x00_y09_z00,21SW,None,ON,NORMAL +10,10,0,0,0,0,10,0,108.300125,5.08,320,30.5,2,8,2,10,1,11,1,11,-1,-1,2,14,10,-1814,-1,EMI9815,MRD_x00_y10_z00,3SE,None,ON,NORMAL +11,11,0,0,0,0,11,0,139.000125,5.08,320,30.5,2,8,2,11,1,12,1,12,-1,-1,2,14,11,-1781,-1,EMI9815,MRD_x00_y11_z00,24SE,None,ON,NORMAL +12,12,0,0,0,0,12,0,169.700125,5.08,320,30.5,2,8,2,12,1,13,1,13,-1,-1,2,14,12,-1816,-1,EMI9815,MRD_x00_y12_z00,U25,None,ON,NORMAL +13,13,0,0,0,1,0,0,-198.064875,7.28,320,30.5,2,8,2,16,3,1,2,1,-1,-1,2,15,0,-1805,-1,EMI9815,MRD_x01_y00_z00,28SE,None,ON,NORMAL +14,14,0,0,0,1,1,0,-167.364875,7.28,320,30.5,2,8,2,17,3,2,2,2,-1,-1,2,15,1,-1818,-1,EMI9815,MRD_x01_y01_z00,31SE,None,ON,NORMAL +15,15,0,0,0,1,2,0,-136.664875,7.28,320,30.5,2,8,2,18,3,3,2,3,-1,-1,2,15,2,-1860,-1,EMI9815,MRD_x01_y02_z00,8SE,None,ON,NORMAL +16,16,0,0,0,1,3,0,-105.964875,7.28,320,30.5,2,8,2,19,3,4,2,4,-1,-1,2,15,3,-1780,-1,EMI9815,MRD_x01_y03_z00,11SW,None,ON,NORMAL +17,17,0,0,0,1,4,0,-75.264875,7.28,320,30.5,2,8,2,20,3,5,2,5,-1,-1,2,15,4,-1841,-1,EMI9815,MRD_x01_y04_z00,U34,None,ON,NORMAL +18,18,0,0,0,1,5,0,-44.564875,7.28,320,30.5,2,8,2,21,3,6,2,6,-1,-1,2,15,5,-1786,-1,EMI9815,MRD_x01_y05_z010,U36,None,ON,NORMAL +19,19,0,0,0,1,6,0,-13.864875,7.28,320,30.5,2,8,2,22,3,7,2,7,-1,-1,2,15,6,-1864,-1,EMI9815,MRD_x01_y06_z00,U40,None,ON,NORMAL +20,20,0,0,0,1,7,0,16.835125,7.28,320,30.5,2,8,2,23,3,8,2,8,-1,-1,2,15,7,-1858,-1,EMI9815,MRD_x01_y07_z00,Unknown5,None,ON,NORMAL +21,21,0,0,0,1,8,0,47.535125,7.28,320,30.5,2,8,2,24,3,9,2,9,-1,-1,2,15,8,-1876,-1,EMI9815,MRD_x01_y08_z00,27SE,None,ON,NORMAL +22,22,0,0,0,1,9,0,78.235125,7.28,320,30.5,2,8,2,25,3,10,2,10,-1,-1,2,15,9,-1806,-1,EMI9815,MRD_x01_y09_z00,Unknown2,None,ON,NORMAL +23,23,0,0,0,1,10,0,108.935125,7.28,320,30.5,2,8,2,26,3,11,2,11,-1,-1,2,15,10,-1853,-1,EMI9815,MRD_x01_y10_z00,10SW,None,ON,NORMAL +24,24,0,0,0,1,11,0,139.635125,7.28,320,30.5,2,8,2,27,3,12,2,12,-1,-1,2,15,11,-1860,-1,EMI9815,MRD_x01_y11_z00,Bill2,None,ON,NORMAL +25,25,0,0,0,1,12,0,170.335125,7.28,320,30.5,2,8,2,28,3,13,2,13,-1,-1,2,15,12,-1844,-1,EMI9815,MRD_x01_y12_z00,13SE,None,ON,NORMAL +26,26,1,0,2,0,0,-73.75,-121.8,336.38,147.2,20,0.6,7,2,0,1,1,1,1,-1,-1,1,4,0,-2100,-1,-9999,MRD_x00_y00_z02,MRD_x00_y00_z02,None,ON,NORMAL +27,27,1,0,2,0,1,-73.75,-101.5,336.38,147.2,20,0.6,7,2,1,1,2,1,2,-1,-1,1,4,1,-2100,-1,-9999,MRD_x00_y01_z02,MRD_x00_y01_z02,None,ON,NORMAL +28,28,1,0,2,0,2,-73.75,-81.2,336.38,147.2,20,0.6,7,2,2,1,3,1,3,-1,-1,1,4,2,-2100,-1,-9999,MRD_x00_y02_z02,MRD_x00_y02_z02,None,ON,NORMAL +29,29,1,0,2,0,3,-73.75,-60.9,336.38,147.2,20,0.6,7,2,3,1,4,1,4,-1,-1,1,4,3,-2100,-1,-9999,MRD_x00_y03_z02,MRD_x00_y03_z02,None,ON,NORMAL +30,30,1,0,2,0,4,-73.75,-40.6,336.38,147.2,20,0.6,7,2,4,1,5,1,5,-1,-1,1,4,4,-2100,-1,-9999,MRD_x00_y04_z02,MRD_x00_y04_z02,None,ON,NORMAL +31,31,1,0,2,0,5,-73.75,-20.3,336.38,147.2,20,0.6,7,2,5,1,6,1,6,-1,-1,1,4,5,-2100,-1,-9999,MRD_x00_y05_z02,MRD_x00_y05_z02,None,ON,NORMAL +32,32,1,0,2,0,6,-73.75,0,336.38,147.2,20,0.6,7,2,6,1,7,1,7,-1,-1,1,4,6,-2100,-1,-9999,MRD_x00_y06_z02,MRD_x00_y06_z02,None,ON,NORMAL +33,33,1,0,2,0,7,-73.75,20.3,336.38,147.2,20,0.6,7,2,7,1,8,1,8,-1,-1,1,4,7,-2100,-1,-9999,MRD_x00_y07_z02,MRD_x00_y07_z02,None,ON,NORMAL +34,34,1,0,2,0,8,-73.75,40.6,336.38,147.2,20,0.6,7,2,8,1,9,1,9,-1,-1,1,4,8,-1900,-1,-9999,MRD_x00_y08_z02,MRD_x00_y08_z02,None,ON,NORMAL +35,35,1,0,2,0,9,-73.75,60.9,336.38,147.2,20,0.6,7,2,9,1,10,1,10,-1,-1,1,4,10,-1900,-1,-9999,MRD_x00_y09_z02,MRD_x00_y09_z02,None,ON,NORMAL +36,36,1,0,2,0,10,-73.75,81.2,336.38,147.2,20,0.6,7,2,10,1,11,1,11,-1,-1,1,4,11,-2100,-1,-9999,MRD_x00_y10_z02,MRD_x00_y10_z02,None,ON,NORMAL +37,37,1,0,2,0,11,-73.75,101.5,336.38,147.2,20,0.6,7,2,11,1,12,1,12,-1,-1,1,4,12,-2100,-1,-9999,MRD_x00_y11_z02,MRD_x00_y11_z02,None,ON,NORMAL +38,38,1,0,2,0,12,-73.75,121.8,336.38,147.2,20,0.6,7,2,12,1,13,1,13,-1,-1,1,4,13,-1900,-1,-9999,MRD_x00_y12_z02,MRD_x00_y12_z02,None,ON,NORMAL +39,39,1,0,2,1,0,73.75,-121.8,336.38,147.2,20,0.6,7,2,16,3,1,2,1,-1,-1,1,5,0,-2100,-1,-9999,MRD_x01_y00_z02,MRD_x01_y00_z02,None,ON,NORMAL +40,40,1,0,2,1,1,73.75,-101.5,336.38,147.2,20,0.6,7,2,17,3,2,2,2,-1,-1,1,5,1,-2100,-1,-9999,MRD_x01_y01_z02,MRD_x01_y01_z02,None,ON,NORMAL +41,41,1,0,2,1,2,73.75,-81.2,336.38,147.2,20,0.6,7,2,18,3,3,2,3,-1,-1,1,5,2,-1900,-1,-9999,MRD_x01_y02_z02,MRD_x01_y02_z02,None,ON,NORMAL +42,42,1,0,2,1,3,73.75,-60.9,336.38,147.2,20,0.6,7,2,19,3,4,2,4,-1,-1,1,5,3,-1900,-1,-9999,MRD_x01_y03_z02,MRD_x01_y03_z02,None,ON,NORMAL +43,43,1,0,2,1,4,73.75,-40.6,336.38,147.2,20,0.6,7,2,20,3,5,2,5,-1,-1,1,5,4,-2100,-1,-9999,MRD_x01_y04_z02,MRD_x01_y04_z02,None,ON,NORMAL +44,44,1,0,2,1,5,73.75,-20.3,336.38,147.2,20,0.6,7,2,21,3,6,2,6,-1,-1,1,5,5,-2100,-1,-9999,MRD_x01_y05_z02,MRD_x01_y05_z02,None,ON,NORMAL +45,45,1,0,2,1,6,73.75,0,336.38,147.2,20,0.6,7,2,22,3,7,2,7,-1,-1,1,5,6,-1900,-1,-9999,MRD_x01_y06_z02,MRD_x01_y06_z02,None,ON,NORMAL +46,46,1,0,2,1,7,73.75,20.3,336.38,147.2,20,0.6,7,2,23,3,8,2,8,-1,-1,1,5,7,-2100,-1,-9999,MRD_x01_y07_z02,MRD_x01_y07_z02,None,ON,NORMAL +47,47,1,0,2,1,8,73.75,40.6,336.38,147.2,20,0.6,7,2,24,3,9,2,9,-1,-1,1,5,8,-2100,-1,-9999,MRD_x01_y08_z02,MRD_x01_y08_z02,None,ON,NORMAL +48,48,1,0,2,1,9,73.75,60.9,336.38,147.2,20,0.6,7,2,25,3,10,2,10,-1,-1,1,5,9,-2100,-1,-9999,MRD_x01_y09_z02,MRD_x01_y09_z02,None,ON,NORMAL +49,49,1,0,2,1,10,73.75,81.2,336.38,147.2,20,0.6,7,2,26,3,11,2,11,-1,-1,1,5,10,-2100,-1,-9999,MRD_x01_y10_z02,MRD_x01_y10_z02,None,ON,NORMAL +50,50,1,0,2,1,11,73.75,101.5,336.38,147.2,20,0.6,7,2,27,3,12,2,12,-1,-1,1,5,11,-2100,-1,-9999,MRD_x01_y11_z02,MRD_x01_y11_z02,None,ON,NORMAL +51,51,1,0,2,1,12,73.75,121.8,336.38,147.2,20,0.6,7,2,28,3,13,2,13,-1,-1,1,5,12,-1900,-1,-9999,MRD_x01_y12_z02,MRD_x01_y12_z02,None,OFF,NORMAL +52,52,1,1,3,0,0,-107.1,-65.25,348.84,15,130.2,1.3,8,5,0,4,1,3,1,-1,-1,1,6,0,-2000,-1,-9999,MRD_x00_y00_z03,MRD_x00_y00_z03,None,ON,NORMAL +53,53,1,1,3,0,1,-91.8,-65.25,348.84,15,130.2,1.3,8,5,1,4,2,3,2,-1,-1,1,6,1,-2000,-1,-9999,MRD_x01_y00_z03,MRD_x01_y00_z03,None,ON,NORMAL +54,54,1,1,3,0,2,-76.5,-65.25,348.84,15,130.2,1.3,8,5,2,4,3,3,3,-1,-1,1,6,2,-2000,-1,-9999,MRD_x02_y00_z03,MRD_x02_y00_z03,None,ON,NORMAL +55,55,1,1,3,0,3,-61.2,-65.25,348.84,15,130.2,1.3,8,5,3,4,4,3,4,-1,-1,1,6,3,-2000,-1,-9999,MRD_x03_y00_z03,MRD_x03_y00_z03,None,ON,NORMAL +56,56,1,1,3,0,4,-45.9,-65.25,348.84,15,130.2,1.3,8,5,4,4,5,3,5,-1,-1,1,6,4,-2000,-1,-9999,MRD_x04_y00_z03,MRD_x04_y00_z03,None,ON,NORMAL +57,57,1,1,3,0,5,-30.6,-65.25,348.84,15,130.2,1.3,8,5,5,4,6,3,6,-1,-1,1,6,5,-2000,-1,-9999,MRD_x05_y00_z03,MRD_x05_y00_z03,None,ON,NORMAL +58,58,1,1,3,0,6,-15.3,-65.25,348.84,15,130.2,1.3,8,5,6,4,7,3,7,-1,-1,1,6,6,-2000,-1,-9999,MRD_x06_y00_z03,MRD_x06_y00_z03,None,ON,NORMAL +59,59,1,1,3,0,7,0,-65.25,348.84,15,130.2,1.3,8,5,7,4,8,3,8,-1,-1,1,6,7,-2000,-1,-9999,MRD_x07_y00_z03,MRD_x07_y00_z03,None,ON,NORMAL +60,60,1,1,3,0,8,15.3,-65.25,348.84,15,130.2,1.3,8,5,8,4,9,3,9,-1,-1,1,6,8,-2000,-1,-9999,MRD_x08_y00_z03,MRD_x08_y00_z03,None,ON,NORMAL +61,61,1,1,3,0,9,30.6,-65.25,348.84,15,130.2,1.3,8,5,9,4,10,3,10,-1,-1,1,6,9,-2000,-1,-9999,MRD_x09_y00_z03,MRD_x09_y00_z03,None,ON,NORMAL +62,62,1,1,3,0,10,45.9,-65.25,348.84,15,130.2,1.3,8,5,10,4,11,3,11,-1,-1,1,6,10,-2000,-1,-9999,MRD_x10_y00_z03,MRD_x10_y00_z03,None,ON,NORMAL +63,63,1,1,3,0,11,61.2,-65.25,348.84,15,130.2,1.3,8,5,11,4,12,3,12,-1,-1,1,6,11,-2000,-1,-9999,MRD_x11_y00_z03,MRD_x11_y00_z03,None,ON,NORMAL +64,64,1,1,3,0,12,76.5,-65.25,348.84,15,130.2,1.3,8,5,12,4,13,3,13,-1,-1,1,6,12,-2000,-1,-9999,MRD_x12_y00_z03,MRD_x12_y00_z03,None,ON,NORMAL +65,65,1,1,3,0,13,91.8,-65.25,348.84,15,130.2,1.3,8,5,13,4,14,3,14,-1,-1,1,6,13,-2000,-1,-9999,MRD_x13_y00_z03,MRD_x13_y00_z03,None,ON,NORMAL +66,66,1,1,3,0,14,107.1,-65.25,348.84,15,130.2,1.3,8,5,14,4,15,3,15,-1,-1,1,6,14,-1800,-1,-9999,MRD_x14_y00_z03,MRD_x14_y00_z03,None,ON,NORMAL +67,67,1,1,3,1,0,-107.1,65.25,348.84,15,130.2,1.3,8,5,16,6,1,4,1,-1,-1,1,7,0,-2200,-1,-9999,MRD_x00_y01_z03,MRD_x00_y01_z03,None,ON,NORMAL +68,68,1,1,3,1,1,-91.8,65.25,348.84,15,130.2,1.3,8,5,17,6,2,4,2,-1,-1,1,7,1,-2000,-1,-9999,MRD_x01_y01_z03,MRD_x01_y01_z03,None,ON,NORMAL +69,69,1,1,3,1,2,-76.5,65.25,348.84,15,130.2,1.3,8,5,18,6,3,4,3,-1,-1,1,7,2,-2000,-1,-9999,MRD_x02_y01_z03,MRD_x02_y01_z03,None,ON,NORMAL +70,70,1,1,3,1,3,-61.2,65.25,348.84,15,130.2,1.3,8,5,19,6,4,4,4,-1,-1,1,7,3,-2000,-1,-9999,MRD_x03_y01_z03,MRD_x03_y01_z03,None,ON,NORMAL +71,71,1,1,3,1,4,-45.9,65.25,348.84,15,130.2,1.3,8,5,20,6,5,4,5,-1,-1,1,7,4,-2000,-1,-9999,MRD_x04_y01_z03,MRD_x04_y01_z03,None,ON,NORMAL +72,72,1,1,3,1,5,-30.6,65.25,348.84,15,130.2,1.3,8,5,21,6,6,4,6,-1,-1,1,7,5,-2000,-1,-9999,MRD_x05_y01_z03,MRD_x05_y01_z03,None,ON,NORMAL +73,73,1,1,3,1,6,-15.3,65.25,348.84,15,130.2,1.3,8,5,22,6,7,4,7,-1,-1,1,7,6,-2000,-1,-9999,MRD_x06_y01_z03,MRD_x06_y01_z03,None,ON,NORMAL +74,74,1,1,3,1,7,0,65.25,348.84,15,130.2,1.3,8,5,23,6,8,4,8,-1,-1,1,7,7,-2000,-1,-9999,MRD_x07_y01_z03,MRD_x07_y01_z03,None,ON,NORMAL +75,75,1,1,3,1,8,15.3,65.25,348.84,15,130.2,1.3,8,5,24,6,9,4,9,-1,-1,1,7,8,-2000,-1,-9999,MRD_x08_y01_z03,MRD_x08_y01_z03,None,ON,NORMAL +76,76,1,1,3,1,9,30.6,65.25,348.84,15,130.2,1.3,8,5,25,6,10,4,10,-1,-1,1,7,9,-2000,-1,-9999,MRD_x09_y01_z03,MRD_x09_y01_z03,None,ON,HOT +77,77,1,1,3,1,10,45.9,65.25,348.84,15,130.2,1.3,8,5,26,6,11,4,11,-1,-1,1,7,10,-2000,-1,-9999,MRD_x10_y01_z03,MRD_x10_y01_z03,Currently using y1 z3 spare cableNone,ON,NORMAL +78,78,1,1,3,1,11,61.2,65.25,348.84,15,130.2,1.3,8,5,27,6,12,4,12,-1,-1,1,7,11,-2000,-1,-9999,MRD_x11_y01_z03,MRD_x11_y01_z03,None,ON,HOT +79,79,1,1,3,1,12,76.5,65.25,348.84,15,130.2,1.3,8,5,28,6,13,4,13,-1,-1,1,7,12,-2000,-1,-9999,MRD_x12_y01_z03,MRD_x12_y01_z03,None,ON,NORMAL +80,80,1,1,3,1,13,91.8,65.25,348.84,15,130.2,1.3,8,5,29,6,14,4,14,-1,-1,1,7,13,-2000,-1,-9999,MRD_x13_y01_z03,MRD_x13_y01_z03,None,ON,NORMAL +81,81,1,1,3,1,14,107.1,65.25,348.84,15,130.2,1.3,8,5,30,6,15,4,15,-1,-1,1,7,14,-2000,-1,-9999,MRD_x14_y01_z03,MRD_x14_y01_z03,None,ON,NORMAL +82,82,1,0,4,0,0,-73.75,-121.8,361.3,147.2,20,0.6,7,5,0,4,1,3,1,-1,-1,1,8,0,-2100,-1,-9999,MRD_x00_y00_z04,MRD_x00_y00_z04,None,ON,NORMAL +83,83,1,0,4,0,1,-73.75,-101.5,361.3,147.2,20,0.6,7,5,1,4,2,3,2,-1,-1,1,8,1,-2100,-1,-9999,MRD_x00_y01_z04,MRD_x00_y01_z04,None,ON,NORMAL +84,84,1,0,4,0,2,-73.75,-81.2,361.3,147.2,20,0.6,7,5,2,4,3,3,3,-1,-1,1,8,2,-2100,-1,-9999,MRD_x00_y02_z04,MRD_x00_y02_z04,None,ON,NORMAL +85,85,1,0,4,0,3,-73.75,-60.9,361.3,147.2,20,0.6,7,5,3,4,4,3,4,-1,-1,1,8,3,-2100,-1,-9999,MRD_x00_y03_z04,MRD_x00_y03_z04,None,ON,NORMAL +86,86,1,0,4,0,4,-73.75,-40.6,361.3,147.2,20,0.6,7,5,4,4,5,3,5,-1,-1,1,8,4,-2300,-1,-9999,MRD_x00_y04_z04,MRD_x00_y04_z04,None,ON,NORMAL +87,87,1,0,4,0,5,-73.75,-20.3,361.3,147.2,20,0.6,7,5,5,4,6,3,6,-1,-1,1,8,5,-2100,-1,-9999,MRD_x00_y05_z04,MRD_x00_y05_z04,None,ON,NORMAL +88,88,1,0,4,0,6,-73.75,0,361.3,147.2,20,0.6,7,5,6,4,7,3,7,-1,-1,1,8,6,-2100,-1,-9999,MRD_x00_y06_z04,MRD_x00_y06_z04,None,ON,NORMAL +89,89,1,0,4,0,7,-73.75,20.3,361.3,147.2,20,0.6,7,5,7,4,8,3,8,-1,-1,1,8,7,-2100,-1,-9999,MRD_x00_y07_z04,MRD_x00_y07_z04,None,ON,NORMAL +90,90,1,0,4,0,8,-73.75,40.6,361.3,147.2,20,0.6,7,5,8,4,9,3,9,-1,-1,1,8,8,-2100,-1,-9999,MRD_x00_y08_z04,MRD_x00_y08_z04,None,ON,NORMAL +91,91,1,0,4,0,9,-73.75,60.9,361.3,147.2,20,0.6,7,5,9,4,10,3,10,-1,-1,1,8,9,-2100,-1,-9999,MRD_x00_y09_z04,MRD_x00_y09_z04,None,ON,NORMAL +92,92,1,0,4,0,10,-73.75,81.2,361.3,147.2,20,0.6,7,5,10,4,11,3,11,-1,-1,1,8,10,-2100,-1,-9999,MRD_x00_y10_z04,MRD_x00_y10_z04,None,ON,NORMAL +93,93,1,0,4,0,11,-73.75,101.5,361.3,147.2,20,0.6,7,5,11,4,12,3,12,-1,-1,1,8,11,-2100,-1,-9999,MRD_x00_y11_z04,MRD_x00_y11_z04,None,ON,NORMAL +94,94,1,0,4,0,12,-73.75,121.8,361.3,147.2,20,0.6,7,5,12,4,13,3,13,-1,-1,1,8,12,-2300,-1,-9999,MRD_x00_y12_z04,MRD_x00_y12_z04,None,ON,NORMAL +95,95,1,0,4,1,0,73.75,-121.8,361.3,147.2,20,0.6,7,5,16,6,1,4,1,-1,-1,1,9,0,-2100,-1,-9999,MRD_x01_y00_z04,MRD_x01_y00_z04,None,ON,NORMAL +96,96,1,0,4,1,1,73.75,-101.5,361.3,147.2,20,0.6,7,5,17,6,2,4,2,-1,-1,1,9,1,-2100,-1,-9999,MRD_x01_y01_z04,MRD_x01_y01_z04,None,ON,NORMAL +97,97,1,0,4,1,2,73.75,-81.2,361.3,147.2,20,0.6,7,5,18,6,3,4,3,-1,-1,1,9,2,-2300,-1,-9999,MRD_x01_y02_z04,MRD_x01_y02_z04,None,ON,NORMAL +98,98,1,0,4,1,3,73.75,-60.9,361.3,147.2,20,0.6,7,5,19,6,4,4,4,-1,-1,1,9,3,-2300,-1,-9999,MRD_x01_y03_z04,MRD_x01_y03_z04,None,ON,NORMAL +99,99,1,0,4,1,4,73.75,-40.6,361.3,147.2,20,0.6,7,5,20,6,5,4,5,-1,-1,1,9,4,-2100,-1,-9999,MRD_x01_y04_z04,MRD_x01_y04_z04,None,ON,NORMAL +100,100,1,0,4,1,5,73.75,-20.3,361.3,147.2,20,0.6,7,5,21,6,6,4,6,-1,-1,1,9,5,-2100,-1,-9999,MRD_x01_y05_z04,MRD_x01_y05_z04,None,ON,NORMAL +101,101,1,0,4,1,6,73.75,0,361.3,147.2,20,0.6,7,5,22,6,7,4,7,-1,-1,1,9,6,-2100,-1,-9999,MRD_x01_y06_z04,MRD_x01_y06_z04,None,ON,NORMAL +102,102,1,0,4,1,7,73.75,20.3,361.3,147.2,20,0.6,7,5,23,6,8,4,8,-1,-1,1,9,7,-2100,-1,-9999,MRD_x01_y07_z04,MRD_x01_y07_z04,None,ON,NORMAL +103,103,1,0,4,1,8,73.75,40.6,361.3,147.2,20,0.6,7,5,24,6,9,4,9,-1,-1,1,9,8,-2100,-1,-9999,MRD_x01_y08_z04,MRD_x01_y08_z04,None,ON,NORMAL +104,104,1,0,4,1,9,73.75,60.9,361.3,147.2,20,0.6,7,5,25,6,10,4,10,-1,-1,1,9,9,-2100,-1,-9999,MRD_x01_y09_z04,MRD_x01_y09_z04,None,ON,NORMAL +105,105,1,0,4,1,10,73.75,81.2,361.3,147.2,20,0.6,7,5,26,6,11,4,11,-1,-1,1,9,10,-2100,-1,-9999,MRD_x01_y10_z04,MRD_x01_y10_z04,None,ON,NORMAL +106,106,1,0,4,1,11,73.75,101.5,361.3,147.2,20,0.6,7,5,27,6,12,4,12,-1,-1,1,9,11,-2100,-1,-9999,MRD_x01_y11_z04,MRD_x01_y11_z04,None,ON,NORMAL +107,107,1,0,4,1,12,73.75,121.8,361.3,147.2,20,0.6,7,5,28,6,13,4,13,-1,-1,1,9,12,-2100,-1,-9999,MRD_x01_y12_z04,MRD_x01_y12_z04,None,ON,NORMAL +108,108,1,1,5,0,0,-122.4,-65.25,373.76,15,130.2,1.3,8,8,0,7,1,5,1,-1,-1,1,10,0,-2200,-1,-9999,MRD_x00_y00_z05,MRD_x00_y00_z05,None,ON,NORMAL +109,109,1,1,5,0,1,-107.1,-65.25,373.76,15,130.2,1.3,8,8,1,7,2,5,2,-1,-1,1,10,1,-2200,-1,-9999,MRD_x01_y00_z05,MRD_x01_y00_z05,None,ON,HOT +110,110,1,1,5,0,2,-91.8,-65.25,373.76,15,130.2,1.3,8,8,2,7,3,5,3,-1,-1,1,10,2,-2000,-1,-9999,MRD_x02_y00_z05,MRD_x02_y00_z05,None,ON,NORMAL +111,111,1,1,5,0,3,-76.5,-65.25,373.76,15,130.2,1.3,8,8,7,7,8,5,4,-1,-1,1,10,3,-1500,-1,-9999,MRD_x03_y00_z05,MRD_x03_y00_z05,None,ON,NORMAL +112,112,1,1,5,0,4,-61.2,-65.25,373.76,15,130.2,1.3,8,8,3,7,4,5,5,-1,-1,1,10,4,-2000,-1,-9999,MRD_x04_y00_z05,MRD_x04_y00_z05,None,ON,NORMAL +113,113,1,1,5,0,5,-45.9,-65.25,373.76,15,130.2,1.3,8,8,4,7,5,5,6,-1,-1,1,10,5,-2000,-1,-9999,MRD_x05_y00_z05,MRD_x05_y00_z05,None,ON,NORMAL +114,114,1,1,5,0,6,-30.6,-65.25,373.76,15,130.2,1.3,8,8,6,7,7,5,7,-1,-1,1,10,6,-2000,-1,-9999,MRD_x06_y00_z05,MRD_x06_y00_z05,None,ON,NORMAL +115,115,1,1,5,0,7,-15.3,-65.25,373.76,15,130.2,1.3,8,8,5,7,6,5,8,-1,-1,1,10,7,-2000,-1,-9999,MRD_x07_y00_z05,MRD_x07_y00_z05,None,ON,HOT +116,116,1,1,5,0,8,0,-65.25,373.76,15,130.2,1.3,8,8,8,7,9,5,9,-1,-1,1,10,8,-2000,-1,-9999,MRD_x08_y00_z05,MRD_x08_y00_z05,None,ON,NORMAL +117,117,1,1,5,0,9,15.3,-65.25,373.76,15,130.2,1.3,8,8,14,7,15,5,10,-1,-1,1,10,9,-2000,-1,-9999,MRD_x09_y00_z05,MRD_x09_y00_z05,None,ON,NORMAL +118,118,1,1,5,0,10,30.6,-65.25,373.76,15,130.2,1.3,8,8,10,7,11,5,11,-1,-1,1,10,10,-2000,-1,-9999,MRD_x10_y00_z05,MRD_x10_y00_z05,None,ON,NORMAL +119,119,1,1,5,0,11,45.9,-65.25,373.76,15,130.2,1.3,8,8,11,7,12,5,12,-1,-1,1,10,11,-2000,-1,-9999,MRD_x11_y00_z05,MRD_x11_y00_z05,None,ON,NORMAL +120,120,1,1,5,0,12,61.2,-65.25,373.76,15,130.2,1.3,8,8,9,7,10,5,13,-1,-1,1,10,12,-2000,-1,-9999,MRD_x12_y00_z05,MRD_x12_y00_z05,Discriminator on slot 7 channel 13 has no NIM outputNone,ON,NORMAL +121,121,1,1,5,0,13,76.5,-65.25,373.76,15,130.2,1.3,8,8,12,7,13,5,14,-1,-1,1,10,13,-2000,-1,-9999,MRD_x13_y00_z05,MRD_x13_y00_z05,None,ON,NORMAL +122,122,1,1,5,0,14,91.8,-65.25,373.76,15,130.2,1.3,8,8,13,7,14,5,15,-1,-1,1,10,14,-2000,-1,-9999,MRD_x14_y00_z05,MRD_x14_y00_z05,None,ON,NORMAL +123,123,1,1,5,0,15,107.1,-65.25,373.76,15,130.2,1.3,8,8,15,7,16,5,16,-1,-1,1,5,14,-1500,-1,-9999,MRD_x15_y00_z05,MRD_x15_y00_z05,None,OFF,NORMAL +124,124,1,1,5,0,16,122.4,-65.25,373.76,15,130.2,1.3,8,17,15,16,16,5,17,-1,-1,1,4,14,-2200,-1,-9999,MRD_x16_y00_z05,MRD_x16_y00_z05,None,OFF,NORMAL +125,125,1,1,5,1,0,-122.4,65.25,373.76,15,130.2,1.3,8,8,16,9,1,6,1,-1,-1,1,11,0,-2000,-1,-9999,MRD_x00_y01_z05,MRD_x00_y01_z05,None,ON,NORMAL +126,126,1,1,5,1,1,-107.1,65.25,373.76,15,130.2,1.3,8,8,17,9,2,6,2,-1,-1,1,11,1,-2000,-1,-9999,MRD_x01_y01_z05,MRD_x01_y01_z05,possible dischargeNone,ON,NORMAL +127,127,1,1,5,1,2,-91.8,65.25,373.76,15,130.2,1.3,8,8,18,9,3,6,3,-1,-1,1,11,2,-2000,-1,-9999,MRD_x02_y01_z05,MRD_x02_y01_z05,None,ON,NORMAL +128,128,1,1,5,1,3,-76.5,65.25,373.76,15,130.2,1.3,8,8,19,9,4,6,4,-1,-1,1,11,3,-2000,-1,-9999,MRD_x03_y01_z05,MRD_x03_y01_z05,None,ON,NORMAL +129,129,1,1,5,1,4,-61.2,65.25,373.76,15,130.2,1.3,8,8,20,9,5,6,5,-1,-1,1,11,4,-1500,-1,-9999,MRD_x04_y01_z05,MRD_x04_y01_z05,None,ON,NORMAL +130,130,1,1,5,1,5,-45.9,65.25,373.76,15,130.2,1.3,8,8,21,9,6,6,6,-1,-1,1,11,5,-2000,-1,-9999,MRD_x05_y01_z05,MRD_x05_y01_z05,None,ON,NORMAL +131,131,1,1,5,1,6,-30.6,65.25,373.76,15,130.2,1.3,8,8,22,9,7,6,7,-1,-1,1,11,6,-2000,-1,-9999,MRD_x06_y01_z05,MRD_x06_y01_z05,None,ON,NORMAL +132,132,1,1,5,1,7,-15.3,65.25,373.76,15,130.2,1.3,8,8,23,9,8,6,8,-1,-1,1,11,7,-2000,-1,-9999,MRD_x07_y01_z05,MRD_x07_y01_z05,None,ON,NORMAL +133,133,1,1,5,1,8,0,65.25,373.76,15,130.2,1.3,8,8,24,9,9,6,9,-1,-1,1,11,8,-2000,-1,-9999,MRD_x08_y01_z05,MRD_x08_y01_z05,None,ON,NORMAL +134,134,1,1,5,1,9,15.3,65.25,373.76,15,130.2,1.3,8,8,25,9,10,6,10,-1,-1,1,11,9,-2000,-1,-9999,MRD_x09_y01_z05,MRD_x09_y01_z05,None,ON,NORMAL +135,135,1,1,5,1,10,30.6,65.25,373.76,15,130.2,1.3,8,8,26,9,11,6,11,-1,-1,1,11,10,-2000,-1,-9999,MRD_x10_y01_z05,MRD_x10_y01_z05,None,ON,NORMAL +136,136,1,1,5,1,11,45.9,65.25,373.76,15,130.2,1.3,8,8,27,9,12,6,12,-1,-1,1,11,11,-1800,-1,-9999,MRD_x11_y01_z05,MRD_x11_y01_z05,None,ON,NORMAL +137,137,1,1,5,1,12,61.2,65.25,373.76,15,130.2,1.3,8,8,28,9,13,6,13,-1,-1,1,11,12,-2000,-1,-9999,MRD_x12_y01_z05,MRD_x12_y01_z05,None,ON,NORMAL +138,138,1,1,5,1,13,76.5,65.25,373.76,15,130.2,1.3,8,8,29,9,14,6,14,-1,-1,1,11,13,-2000,-1,-9999,MRD_x13_y01_z05,MRD_x13_y01_z05,None,ON,NORMAL +139,139,1,1,5,1,14,91.8,65.25,373.76,15,130.2,1.3,8,8,30,9,15,6,15,-1,-1,1,11,14,-2000,-1,-9999,MRD_x14_y01_z05,MRD_x14_y01_z05,None,ON,NORMAL +140,140,1,1,5,1,15,107.1,65.25,373.76,15,130.2,1.3,8,8,31,9,16,6,16,-1,-1,1,11,15,-2000,-1,-9999,MRD_x15_y01_z05,MRD_x15_y01_z05,None,OFF,NORMAL +141,141,1,1,5,1,16,122.4,65.25,373.76,15,130.2,1.3,8,14,31,15,16,6,17,-1,-1,1,4,15,-2000,-1,-9999,MRD_x16_y01_z05,MRD_x16_y01_z05,Now uses y0 z5 spare; Rack 8 slot 18 channel 16 has no NIM output,OFF,NORMAL +142,142,1,0,6,0,0,-73.75,-121.8,386.22,147.2,20,0.6,7,8,0,7,1,5,1,-1,-1,1,12,0,-2100,-1,-9999,MRD_x00_y00_z06,MRD_x00_y00_z06,None,ON,NORMAL +143,143,1,0,6,0,1,-73.75,-101.5,386.22,147.2,20,0.6,7,8,1,7,2,5,2,-1,-1,1,12,1,-2100,-1,-9999,MRD_x00_y01_z06,MRD_x00_y01_z06,None,ON,NORMAL +144,144,1,0,6,0,2,-73.75,-81.2,386.22,147.2,20,0.6,7,8,2,7,3,5,3,-1,-1,1,12,2,-2100,-1,-9999,MRD_x00_y02_z06,MRD_x00_y02_z06,None,ON,NORMAL +145,145,1,0,6,0,3,-73.75,-60.9,386.22,147.2,20,0.6,7,8,3,7,4,5,4,-1,-1,1,12,3,-2100,-1,-9999,MRD_x00_y03_z06,MRD_x00_y03_z06,None,ON,NORMAL +146,146,1,0,6,0,4,-73.75,-40.6,386.22,147.2,20,0.6,7,8,4,7,5,5,5,-1,-1,1,12,4,-2100,-1,-9999,MRD_x00_y04_z06,MRD_x00_y04_z06,None,ON,NORMAL +147,147,1,0,6,0,5,-73.75,-20.3,386.22,147.2,20,0.6,7,8,5,7,6,5,6,-1,-1,1,12,5,-2100,-1,-9999,MRD_x00_y05_z06,MRD_x00_y05_z06,None,ON,NORMAL +148,148,1,0,6,0,6,-73.75,0,386.22,147.2,20,0.6,7,8,6,7,7,5,7,-1,-1,1,12,6,-2100,-1,-9999,MRD_x00_y06_z06,MRD_x00_y06_z06,None,ON,NORMAL +149,149,1,0,6,0,7,-73.75,20.3,386.22,147.2,20,0.6,7,8,7,7,8,5,8,-1,-1,1,12,7,-2100,-1,-9999,MRD_x00_y07_z06,MRD_x00_y07_z06,None,ON,NORMAL +150,150,1,0,6,0,8,-73.75,40.6,386.22,147.2,20,0.6,7,8,8,7,9,5,9,-1,-1,1,12,8,-2100,-1,-9999,MRD_x00_y08_z06,MRD_x00_y08_z06,None,ON,NORMAL +151,151,1,0,6,0,9,-73.75,60.9,386.22,147.2,20,0.6,7,8,9,7,10,5,10,-1,-1,1,12,9,-2100,-1,-9999,MRD_x00_y09_z06,MRD_x00_y09_z06,None,ON,NORMAL +152,152,1,0,6,0,10,-73.75,81.2,386.22,147.2,20,0.6,7,8,10,7,11,5,11,-1,-1,1,12,10,-2100,-1,-9999,MRD_x00_y10_z06,MRD_x00_y10_z06,None,ON,NORMAL +153,153,1,0,6,0,11,-73.75,101.5,386.22,147.2,20,0.6,7,8,11,7,12,5,12,-1,-1,1,12,11,-2100,-1,-9999,MRD_x00_y11_z06,MRD_x00_y11_z06,None,ON,NORMAL +154,154,1,0,6,0,12,-73.75,121.8,386.22,147.2,20,0.6,7,8,12,7,13,5,13,-1,-1,1,12,12,-2100,-1,-9999,MRD_x00_y12_z06,MRD_x00_y12_z06,None,ON,NORMAL +155,155,1,0,6,1,0,73.75,-121.8,386.22,147.2,20,0.6,7,8,16,9,1,6,1,-1,-1,1,13,0,-1900,-1,-9999,MRD_x01_y00_z06,MRD_x01_y00_z06,None,ON,NORMAL +156,156,1,0,6,1,1,73.75,-101.5,386.22,147.2,20,0.6,7,8,17,9,2,6,2,-1,-1,1,13,1,-2100,-1,-9999,MRD_x01_y01_z06,MRD_x01_y01_z06,None,ON,NORMAL +157,157,1,0,6,1,2,73.75,-81.2,386.22,147.2,20,0.6,7,8,18,9,3,6,3,-1,-1,1,13,2,-2100,-1,-9999,MRD_x01_y02_z06,MRD_x01_y02_z06,None,ON,HOT +158,158,1,0,6,1,3,73.75,-60.9,386.22,147.2,20,0.6,7,8,19,9,4,6,4,-1,-1,1,13,3,-2100,-1,-9999,MRD_x01_y03_z06,MRD_x01_y03_z06,None,ON,NORMAL +159,159,1,0,6,1,4,73.75,-40.6,386.22,147.2,20,0.6,7,8,20,9,5,6,5,-1,-1,1,13,4,-2100,-1,-9999,MRD_x01_y04_z06,MRD_x01_y04_z06,None,ON,NORMAL +160,160,1,0,6,1,5,73.75,-20.3,386.22,147.2,20,0.6,7,8,21,9,6,6,6,-1,-1,1,13,5,-2100,-1,-9999,MRD_x01_y05_z06,MRD_x01_y05_z06,None,ON,NORMAL +161,161,1,0,6,1,6,73.75,0,386.22,147.2,20,0.6,7,8,22,9,7,6,7,-1,-1,1,13,6,-2100,-1,-9999,MRD_x01_y06_z06,MRD_x01_y06_z06,None,ON,NORMAL +162,162,1,0,6,1,7,73.75,20.3,386.22,147.2,20,0.6,7,8,23,9,8,6,8,-1,-1,1,13,7,-2100,-1,-9999,MRD_x01_y07_z06,MRD_x01_y07_z06,None,ON,NORMAL +163,163,1,0,6,1,8,73.75,40.6,386.22,147.2,20,0.6,7,8,24,9,9,6,9,-1,-1,1,13,8,-2100,-1,-9999,MRD_x01_y08_z06,MRD_x01_y08_z06,None,ON,NORMAL +164,164,1,0,6,1,9,73.75,60.9,386.22,147.2,20,0.6,7,8,25,9,10,6,10,-1,-1,1,13,9,-1900,-1,-9999,MRD_x01_y09_z06,MRD_x01_y09_z06,None,ON,NORMAL +165,165,1,0,6,1,10,73.75,81.2,386.22,147.2,20,0.6,7,8,26,9,11,6,11,-1,-1,1,13,10,-2100,-1,-9999,MRD_x01_y10_z06,MRD_x01_y10_z06,None,ON,NORMAL +166,166,1,0,6,1,11,73.75,101.5,386.22,147.2,20,0.6,7,8,27,9,12,6,12,-1,-1,1,13,11,-2100,-1,-9999,MRD_x01_y11_z06,MRD_x01_y11_z06,None,ON,NORMAL +167,167,1,0,6,1,12,73.75,121.8,386.22,147.2,20,0.6,7,8,28,9,13,6,13,-1,-1,1,13,12,-2100,-1,-9999,MRD_x01_y12_z06,MRD_x01_y12_z06,None,ON,NORMAL +168,168,1,1,7,0,1,-121.8,-65.25,398.33,20,130.2,0.6,8,11,1,10,2,7,2,1,3,1,14,1,-1500,-1,-9999,MRD_x01_y00_z07,MRD_x01_y00_z07,None,ON,NORMAL +169,169,1,1,7,0,2,-101.5,-65.25,398.33,20,130.2,0.6,8,11,2,10,3,7,3,1,5,1,14,2,-1500,-1,-9999,MRD_x02_y00_z07,MRD_x02_y00_z07,None,ON,NORMAL +170,170,1,1,7,0,3,-81.2,-65.25,398.33,20,130.2,0.6,8,11,3,10,4,7,4,1,7,1,14,3,-1500,-1,-9999,MRD_x03_y00_z07,MRD_x03_y00_z07,None,ON,NORMAL +171,171,1,1,7,0,4,-60.9,-65.25,398.33,20,130.2,0.6,8,11,4,10,5,7,5,1,9,1,14,4,-1500,-1,-9999,MRD_x04_y00_z07,MRD_x04_y00_z07,None,ON,NORMAL +172,172,1,1,7,0,5,-40.6,-65.25,398.33,20,130.2,0.6,8,11,5,10,6,7,6,1,11,1,14,5,-1500,-1,-9999,MRD_x05_y00_z07,MRD_x05_y00_z07,None,ON,NORMAL +173,173,1,1,7,0,6,-20.3,-65.25,398.33,20,130.2,0.6,8,11,6,10,7,7,7,1,13,1,14,6,-1500,-1,-9999,MRD_x06_y00_z07,MRD_x06_y00_z07,None,ON,NORMAL +174,174,1,1,7,0,7,0,-65.25,398.33,20,130.2,0.6,8,11,7,10,8,7,8,12,2,1,14,7,-1500,-1,-9999,MRD_x07_y00_z07,MRD_x07_y00_z07,None,ON,NORMAL +175,175,1,1,7,0,8,20.3,-65.25,398.33,20,130.2,0.6,8,11,8,10,9,7,9,12,4,1,14,8,-1500,-1,-9999,MRD_x08_y00_z07,MRD_x08_y00_z07,None,ON,NORMAL +176,176,1,1,7,0,9,40.6,-65.25,398.33,20,130.2,0.6,8,11,9,10,10,7,10,12,6,1,14,9,-1500,-1,-9999,MRD_x09_y00_z07,MRD_x09_y00_z07,None,ON,NORMAL +177,177,1,1,7,0,10,60.9,-65.25,398.33,20,130.2,0.6,8,11,10,10,11,7,11,12,8,1,14,10,-1500,-1,-9999,MRD_x10_y00_z07,MRD_x10_y00_z07,None,ON,NORMAL +178,178,1,1,7,0,11,81.2,-65.25,398.33,20,130.2,0.6,8,11,11,10,12,7,12,12,10,1,14,11,-1500,-1,-9999,MRD_x11_y00_z07,MRD_x11_y00_z07,None,ON,NORMAL +179,179,1,1,7,0,12,101.5,-65.25,398.33,20,130.2,0.6,8,11,12,10,13,7,13,12,12,1,14,12,-1500,-1,-9999,MRD_x12_y00_z07,MRD_x12_y00_z07,None,ON,NORMAL +180,180,1,1,7,0,13,121.8,-65.25,398.33,20,130.2,0.6,8,11,13,10,14,7,14,12,14,1,14,13,-1500,-1,-9999,MRD_x13_y00_z07,MRD_x13_y00_z07,None,ON,NORMAL +181,181,1,1,7,1,1,-121.8,65.25,398.33,20,130.2,0.6,8,11,17,12,2,8,2,1,4,1,15,1,-1500,-1,-9999,MRD_x01_y01_z07,MRD_x01_y01_z07,None,ON,NORMAL +182,182,1,1,7,1,2,-101.5,65.25,398.33,20,130.2,0.6,8,11,18,12,3,8,3,1,6,1,15,2,-1500,-1,-9999,MRD_x02_y01_z07,MRD_x02_y01_z07,None,ON,NORMAL +183,183,1,1,7,1,3,-81.2,65.25,398.33,20,130.2,0.6,8,11,19,12,4,8,4,1,8,1,15,3,-1300,-1,-9999,MRD_x03_y01_z07,MRD_x03_y01_z07,None,ON,HOT +184,184,1,1,7,1,4,-60.9,65.25,398.33,20,130.2,0.6,8,11,20,12,5,8,5,1,10,1,15,4,-1500,-1,-9999,MRD_x04_y01_z07,MRD_x04_y01_z07,None,ON,NORMAL +185,185,1,1,7,1,5,-40.6,65.25,398.33,20,130.2,0.6,8,11,21,12,6,8,6,1,12,1,15,5,-2000,-1,-9999,MRD_x05_y01_z07,MRD_x05_y01_z07,None,ON,NORMAL +186,186,1,1,7,1,6,-20.3,65.25,398.33,20,130.2,0.6,8,11,22,12,7,8,7,1,14,1,15,6,-2000,-1,-9999,MRD_x06_y01_z07,MRD_x06_y01_z07,None,ON,NORMAL +187,187,1,1,7,1,7,0,65.25,398.33,20,130.2,0.6,8,11,23,12,8,8,8,12,1,1,15,7,-2000,-1,-9999,MRD_x07_y01_z07,MRD_x07_y01_z07,None,ON,NORMAL +188,188,1,1,7,1,8,20.3,65.25,398.33,20,130.2,0.6,8,11,24,12,9,8,9,12,3,1,15,8,-2000,-1,-9999,MRD_x08_y01_z07,MRD_x08_y01_z07,None,ON,NORMAL +189,189,1,1,7,1,9,40.6,65.25,398.33,20,130.2,0.6,8,11,25,12,10,8,10,12,5,1,15,9,-1500,-1,-9999,MRD_x09_y01_z07,MRD_x09_y01_z07,None,ON,NORMAL +190,190,1,1,7,1,10,60.9,65.25,398.33,20,130.2,0.6,8,11,26,12,11,8,11,12,7,1,15,10,-1500,-1,-9999,MRD_x10_y01_z07,MRD_x10_y01_z07,None,ON,NORMAL +191,191,1,1,7,1,11,81.2,65.25,398.33,20,130.2,0.6,8,11,27,12,12,8,12,12,9,1,15,11,-1500,-1,-9999,MRD_x11_y01_z07,MRD_x11_y01_z07,None,ON,NORMAL +192,192,1,1,7,1,12,101.5,65.25,398.33,20,130.2,0.6,8,11,28,12,13,8,13,12,11,1,15,12,-1500,-1,-9999,MRD_x12_y01_z07,MRD_x12_y01_z07,None,ON,NORMAL +193,193,1,1,7,1,13,121.8,65.25,398.33,20,130.2,0.6,8,11,29,12,14,8,14,12,13,1,15,13,-1500,-1,-9999,MRD_x13_y01_z07,MRD_x13_y01_z07,None,ON,NORMAL +194,194,1,0,8,0,0,-73.75,-121.8,410.44,147.2,20,0.6,7,11,0,10,1,7,1,-1,-1,1,0,0,2100,1,EMI 9939B,MRD_x00_y00_z08,MRD_x00_y00_z08,None,ON,NORMAL +195,195,1,0,8,0,1,-73.75,-101.5,410.44,147.2,20,0.6,7,11,1,10,2,7,2,-1,-1,1,0,1,2100,1,EMI 9939B,MRD_x00_y01_z08,MRD_x00_y01_z08,None,OFF,NORMAL +196,196,1,0,8,0,2,-73.75,-81.2,410.44,147.2,20,0.6,7,11,2,10,3,7,3,-1,-1,1,0,2,2100,1,EMI 9939B,MRD_x00_y02_z08,MRD_x00_y02_z08,None,ON,NORMAL +197,197,1,0,8,0,3,-73.75,-60.9,410.44,147.2,20,0.6,7,11,3,10,4,7,4,-1,-1,1,0,3,2100,1,EMI 9939B,MRD_x00_y03_z08,MRD_x00_y03_z08,None,ON,NORMAL +198,198,1,0,8,0,4,-73.75,-40.6,410.44,147.2,20,0.6,7,11,4,10,5,7,5,-1,-1,1,0,4,2100,1,EMI 9939B,MRD_x00_y04_z08,MRD_x00_y04_z08,None,ON,NORMAL +199,199,1,0,8,0,5,-73.75,-20.3,410.44,147.2,20,0.6,7,11,5,10,6,7,6,-1,-1,1,0,5,2100,1,EMI 9939B,MRD_x00_y05_z08,MRD_x00_y05_z08,None,ON,NORMAL +200,200,1,0,8,0,6,-73.75,0,410.44,147.2,20,0.6,7,11,6,10,7,7,7,-1,-1,1,0,6,2100,1,EMI 9939B,MRD_x00_y06_z08,MRD_x00_y06_z08,None,ON,NORMAL +201,201,1,0,8,0,7,-73.75,20.3,410.44,147.2,20,0.6,7,11,7,10,8,7,8,-1,-1,1,0,7,2100,1,EMI 9939B,MRD_x00_y07_z08,MRD_x00_y07_z08,None,ON,NORMAL +202,202,1,0,8,0,8,-73.75,40.6,410.44,147.2,20,0.6,7,11,8,10,9,7,9,-1,-1,1,0,8,2100,1,EMI 9939B,MRD_x00_y08_z08,MRD_x00_y08_z08,None,ON,NORMAL +203,203,1,0,8,0,9,-73.75,60.9,410.44,147.2,20,0.6,7,11,9,10,10,7,10,-1,-1,1,0,9,2100,1,EMI 9939B,MRD_x00_y09_z08,MRD_x00_y09_z08,None,ON,NORMAL +204,204,1,0,8,0,10,-73.75,81.2,410.44,147.2,20,0.6,7,11,10,10,11,7,11,-1,-1,1,0,10,2100,1,EMI 9939B,MRD_x00_y10_z08,MRD_x00_y10_z08,None,ON,NORMAL +205,205,1,0,8,0,11,-73.75,101.5,410.44,147.2,20,0.6,7,11,11,10,12,7,12,-1,-1,1,0,11,2100,1,EMI 9939B,MRD_x00_y11_z08,MRD_x00_y11_z08,None,ON,NORMAL +206,206,1,0,8,0,12,-73.75,121.8,410.44,147.2,20,0.6,7,11,12,10,13,7,13,-1,-1,1,0,12,2100,1,EMI 9939B,MRD_x00_y12_z08,MRD_x00_y12_z08,None,ON,NORMAL +207,207,1,0,8,1,0,73.75,-121.8,410.44,147.2,20,0.6,7,11,16,12,1,8,1,-1,-1,1,1,13,2100,1,EMI 9939B,MRD_x01_y00_z08,MRD_x01_y00_z08,< HV 1-1-0 is brokenNone,ON,NORMAL +208,208,1,0,8,1,1,73.75,-101.5,410.44,147.2,20,0.6,7,11,17,12,2,8,2,-1,-1,1,1,1,2100,1,EMI 9939B,MRD_x01_y01_z08,MRD_x01_y01_z08,None,ON,NORMAL +209,209,1,0,8,1,2,73.75,-81.2,410.44,147.2,20,0.6,7,11,18,12,3,8,3,-1,-1,1,1,2,2100,1,EMI 9939B,MRD_x01_y02_z08,MRD_x01_y02_z08,None,ON,NORMAL +210,210,1,0,8,1,3,73.75,-60.9,410.44,147.2,20,0.6,7,11,19,12,4,8,4,-1,-1,1,1,3,2100,1,EMI 9939B,MRD_x01_y03_z08,MRD_x01_y03_z08,None,ON,NORMAL +211,211,1,0,8,1,4,73.75,-40.6,410.44,147.2,20,0.6,7,11,20,12,5,8,5,-1,-1,1,1,4,2100,1,EMI 9939B,MRD_x01_y04_z08,MRD_x01_y04_z08,None,ON,NORMAL +212,212,1,0,8,1,5,73.75,-20.3,410.44,147.2,20,0.6,7,11,21,12,6,8,6,-1,-1,1,1,5,2100,1,EMI 9939B,MRD_x01_y05_z08,MRD_x01_y05_z08,None,ON,HOT +213,213,1,0,8,1,6,73.75,0,410.44,147.2,20,0.6,7,11,22,12,7,8,7,-1,-1,1,1,6,2100,1,EMI 9939B,MRD_x01_y06_z08,MRD_x01_y06_z08,None,ON,NORMAL +214,214,1,0,8,1,7,73.75,20.3,410.44,147.2,20,0.6,7,11,23,12,8,8,8,-1,-1,1,1,7,2100,1,EMI 9939B,MRD_x01_y07_z08,MRD_x01_y07_z08,None,ON,NORMAL +215,215,1,0,8,1,8,73.75,40.6,410.44,147.2,20,0.6,7,11,24,12,9,8,9,-1,-1,1,1,8,2100,1,EMI 9939B,MRD_x01_y08_z08,MRD_x01_y08_z08,None,OFF,NORMAL +216,216,1,0,8,1,9,73.75,60.9,410.44,147.2,20,0.6,7,11,25,12,10,8,10,-1,-1,1,1,9,2100,1,EMI 9939B,MRD_x01_y09_z08,MRD_x01_y09_z08,None,ON,NORMAL +217,217,1,0,8,1,10,73.75,81.2,410.44,147.2,20,0.6,7,11,26,12,11,8,11,-1,-1,1,1,10,2100,1,EMI 9939B,MRD_x01_y10_z08,MRD_x01_y10_z08,None,OFF,NORMAL +218,218,1,0,8,1,11,73.75,101.5,410.44,147.2,20,0.6,7,11,27,12,12,8,12,-1,-1,1,1,11,2100,1,EMI 9939B,MRD_x01_y11_z08,MRD_x01_y11_z08,None,OFF,NORMAL +219,219,1,0,8,1,12,73.75,121.8,410.44,147.2,20,0.6,7,11,28,12,13,8,13,-1,-1,1,1,12,2100,1,EMI 9939B,MRD_x01_y12_z08,MRD_x01_y12_z08,None,ON,NORMAL +220,220,1,1,9,0,0,-142.1,-65.25,422.55,20,130.2,0.6,8,14,0,13,1,9,1,2,1,2,0,0,-1500,-1,-9999,MRD_x00_y00_z09,MRD_x00_y00_z09,None,ON,NORMAL +221,221,1,1,9,0,1,-121.8,-65.25,422.55,20,130.2,0.6,8,14,1,13,2,9,2,2,3,2,0,1,-1500,-1,-9999,MRD_x01_y00_z09,MRD_x01_y00_z09,None,ON,NORMAL +222,222,1,1,9,0,2,-101.5,-65.25,422.55,20,130.2,0.6,8,14,2,13,3,9,3,2,5,2,0,2,-1500,-1,-9999,MRD_x02_y00_z09,MRD_x02_y00_z09,None,ON,NORMAL +223,223,1,1,9,0,3,-81.2,-65.25,422.55,20,130.2,0.6,8,14,3,13,4,9,4,2,7,2,0,3,-1500,-1,-9999,MRD_x03_y00_z09,MRD_x03_y00_z09,None,ON,NORMAL +224,224,1,1,9,0,4,-60.9,-65.25,422.55,20,130.2,0.6,8,14,4,13,5,9,5,2,9,2,0,4,-1500,-1,-9999,MRD_x04_y00_z09,MRD_x04_y00_z09,None,OFF,NORMAL +225,225,1,1,9,0,5,-40.6,-65.25,422.55,20,130.2,0.6,8,14,5,13,6,9,6,2,11,2,0,5,-2000,-1,-9999,MRD_x05_y00_z09,MRD_x05_y00_z09,None,ON,NORMAL +226,226,1,1,9,0,6,-20.3,-65.25,422.55,20,130.2,0.6,8,14,6,13,7,9,7,2,13,2,0,6,-2000,-1,-9999,MRD_x06_y00_z09,MRD_x06_y00_z09,None,ON,NORMAL +227,227,1,1,9,0,7,0,-65.25,422.55,20,130.2,0.6,8,11,31,12,16,9,8,11,1,2,0,7,-2000,-1,-9999,MRD_x07_y00_z09,MRD_x07_y00_z09,Discriminator on rack 8 slot 13 channel 8 has no NIM outputNone,ON,NORMAL +228,228,1,1,9,0,8,20.3,-65.25,422.55,20,130.2,0.6,8,14,8,13,9,9,9,11,2,2,0,8,-2000,-1,-9999,MRD_x08_y00_z09,MRD_x08_y00_z09,None,ON,NORMAL +229,229,1,1,9,0,9,40.6,-65.25,422.55,20,130.2,0.6,8,14,9,13,10,9,10,11,3,2,0,9,-1500,-1,-9999,MRD_x09_y00_z09,MRD_x09_y00_z09,None,ON,NORMAL +230,230,1,1,9,0,10,60.9,-65.25,422.55,20,130.2,0.6,8,14,10,13,11,9,11,11,4,2,0,10,-1500,-1,-9999,MRD_x10_y00_z09,MRD_x10_y00_z09,None,ON,NORMAL +231,231,1,1,9,0,11,81.2,-65.25,422.55,20,130.2,0.6,8,14,11,13,12,9,12,11,5,2,0,11,-1500,-1,-9999,MRD_x11_y00_z09,MRD_x11_y00_z09,None,ON,NORMAL +232,232,1,1,9,0,12,101.5,-65.25,422.55,20,130.2,0.6,8,14,15,13,16,9,13,11,6,2,0,12,-1500,-1,-9999,MRD_x12_y00_z09,MRD_x12_y00_z09,slot 13 on this disc had a very high rate; shifted signal to slot 16None,ON,NORMAL +233,233,1,1,9,0,13,121.8,-65.25,422.55,20,130.2,0.6,8,14,13,13,14,9,14,11,7,2,0,13,-1500,-1,-9999,MRD_x13_y00_z09,MRD_x13_y00_z09,None,ON,NORMAL +234,234,1,1,9,0,14,142.1,-65.25,422.55,20,130.2,0.6,8,14,14,13,15,9,15,11,8,2,0,14,-1500,-1,-9999,MRD_x14_y00_z09,MRD_x14_y00_z09,None,ON,NORMAL +235,235,1,1,9,1,0,-142.1,65.25,422.55,20,130.2,0.6,8,14,16,15,1,10,1,2,2,2,1,0,-1500,-1,-9999,MRD_x00_y01_z09,MRD_x00_y01_z09,None,ON,NORMAL +236,236,1,1,9,1,1,-121.8,65.25,422.55,20,130.2,0.6,8,14,17,15,2,10,2,2,4,2,1,1,-1500,-1,-9999,MRD_x01_y01_z09,MRD_x01_y01_z09,None,ON,NORMAL +237,237,1,1,9,1,2,-101.5,65.25,422.55,20,130.2,0.6,8,14,18,15,3,10,3,2,6,2,1,2,-1300,-1,-9999,MRD_x02_y01_z09,MRD_x02_y01_z09,None,ON,NORMAL +238,238,1,1,9,1,3,-81.2,65.25,422.55,20,130.2,0.6,8,14,19,15,4,10,4,2,8,2,1,3,-1500,-1,-9999,MRD_x03_y01_z09,MRD_x03_y01_z09,None,ON,NORMAL +239,239,1,1,9,1,4,-60.9,65.25,422.55,20,130.2,0.6,8,14,20,15,5,10,5,2,10,2,1,4,-1500,-1,-9999,MRD_x04_y01_z09,MRD_x04_y01_z09,None,ON,NORMAL +240,240,1,1,9,1,5,-40.6,65.25,422.55,20,130.2,0.6,8,14,21,15,6,10,6,2,12,2,1,5,-1500,-1,-9999,MRD_x05_y01_z09,MRD_x05_y01_z09,None,ON,NORMAL +241,241,1,1,9,1,6,-20.3,65.25,422.55,20,130.2,0.6,8,14,22,15,7,10,7,2,14,2,1,6,-1500,-1,-9999,MRD_x06_y01_z09,MRD_x06_y01_z09,None,ON,NORMAL +242,242,1,1,9,1,7,0,65.25,422.55,20,130.2,0.6,8,14,23,15,8,10,8,12,18,2,1,7,-1500,-1,-9999,MRD_x07_y01_z09,MRD_x07_y01_z09,None,ON,NORMAL +243,243,1,1,9,1,8,20.3,65.25,422.55,20,130.2,0.6,8,14,24,15,9,10,9,12,20,2,1,8,-1500,-1,-9999,MRD_x08_y01_z09,MRD_x08_y01_z09,None,ON,NORMAL +244,244,1,1,9,1,9,40.6,65.25,422.55,20,130.2,0.6,8,14,25,15,10,10,10,12,22,2,1,9,-1500,-1,-9999,MRD_x09_y01_z09,MRD_x09_y01_z09,None,ON,NORMAL +245,245,1,1,9,1,10,60.9,65.25,422.55,20,130.2,0.6,8,14,26,15,11,10,11,12,24,2,1,10,-1500,-1,-9999,MRD_x10_y01_z09,MRD_x10_y01_z09,None,ON,NORMAL +246,246,1,1,9,1,11,81.2,65.25,422.55,20,130.2,0.6,8,14,27,15,12,10,12,12,26,2,1,11,-1500,-1,-9999,MRD_x11_y01_z09,MRD_x11_y01_z09,None,ON,NORMAL +247,247,1,1,9,1,12,101.5,65.25,422.55,20,130.2,0.6,8,14,28,15,13,10,13,12,28,2,1,12,-1500,-1,-9999,MRD_x12_y01_z09,MRD_x12_y01_z09,None,ON,NORMAL +248,248,1,1,9,1,13,121.8,65.25,422.55,20,130.2,0.6,8,14,29,15,14,10,14,12,30,2,1,13,-1500,-1,-9999,MRD_x13_y01_z09,MRD_x13_y01_z09,None,ON,NORMAL +249,249,1,1,9,1,14,142.1,65.25,422.55,20,130.2,0.6,8,14,30,15,15,10,15,12,32,2,1,14,-1500,-1,-9999,MRD_x14_y01_z09,MRD_x14_y01_z09,None,ON,HOT +250,250,1,0,10,0,0,-73.75,-121.8,434.66,147.2,20,0.6,7,19,0,18,1,9,1,-1,-1,2,2,0,-2100,-1,-9999,MRD_x00_y00_z10,MRD_x00_y00_z10,None,ON,NORMAL +251,251,1,0,10,0,1,-73.75,-101.5,434.66,147.2,20,0.6,7,19,1,18,2,9,2,-1,-1,2,2,1,-1600,-1,-9999,MRD_x00_y01_z10,MRD_x00_y01_z10,None,OFF,NORMAL +252,252,1,0,10,0,2,-73.75,-81.2,434.66,147.2,20,0.6,7,19,2,18,3,9,3,-1,-1,2,2,2,-2100,-1,-9999,MRD_x00_y02_z10,MRD_x00_y02_z10,None,ON,NORMAL +253,253,1,0,10,0,3,-73.75,-60.9,434.66,147.2,20,0.6,7,19,3,18,4,9,4,-1,-1,2,2,3,-2100,-1,-9999,MRD_x00_y03_z10,MRD_x00_y03_z10,None,ON,NORMAL +254,254,1,0,10,0,4,-73.75,-40.6,434.66,147.2,20,0.6,7,19,4,18,5,9,5,-1,-1,2,2,4,-2100,-1,-9999,MRD_x00_y04_z10,MRD_x00_y04_z10,None,OFF,NORMAL +255,255,1,0,10,0,5,-73.75,-20.3,434.66,147.2,20,0.6,7,19,5,18,6,9,6,-1,-1,2,2,5,-2100,-1,-9999,MRD_x00_y05_z10,MRD_x00_y05_z10,None,ON,NORMAL +256,256,1,0,10,0,6,-73.75,0,434.66,147.2,20,0.6,7,19,6,18,7,9,7,-1,-1,2,2,6,-2100,-1,-9999,MRD_x00_y06_z10,MRD_x00_y06_z10,None,ON,NORMAL +257,257,1,0,10,0,7,-73.75,20.3,434.66,147.2,20,0.6,7,19,7,18,8,9,8,-1,-1,2,2,7,-2100,-1,-9999,MRD_x00_y07_z10,MRD_x00_y07_z10,None,ON,NORMAL +258,258,1,0,10,0,8,-73.75,40.6,434.66,147.2,20,0.6,7,19,8,18,9,9,9,-1,-1,2,2,8,-1900,-1,-9999,MRD_x00_y08_z10,MRD_x00_y08_z10,None,ON,NORMAL +259,259,1,0,10,0,9,-73.75,60.9,434.66,147.2,20,0.6,7,19,9,18,10,9,10,-1,-1,2,2,9,-2100,-1,-9999,MRD_x00_y09_z10,MRD_x00_y09_z10,None,ON,NORMAL +260,260,1,0,10,0,10,-73.75,81.2,434.66,147.2,20,0.6,7,19,10,18,11,9,11,-1,-1,2,2,10,-2100,-1,-9999,MRD_x00_y10_z10,MRD_x00_y10_z10,None,OFF,NORMAL +261,261,1,0,10,0,11,-73.75,101.5,434.66,147.2,20,0.6,7,19,11,18,12,9,12,-1,-1,2,2,11,-2100,-1,-9999,MRD_x00_y11_z10,MRD_x00_y11_z10,Crate 2 card 3 ch11 is broken: nothing connectedNone,ON,NORMAL +262,262,1,0,10,0,12,-73.75,121.8,434.66,147.2,20,0.6,7,19,12,18,13,9,13,-1,-1,2,2,12,-2100,-1,-9999,MRD_x00_y12_z10,MRD_x00_y12_z10,None,ON,NORMAL +263,263,1,0,10,1,0,73.75,-121.8,434.66,147.2,20,0.6,7,19,16,20,1,10,1,-1,-1,2,3,0,-2100,-1,-9999,MRD_x01_y00_z10,MRD_x01_y00_z10,None,ON,HOT +264,264,1,0,10,1,1,73.75,-101.5,434.66,147.2,20,0.6,7,19,17,20,2,10,2,-1,-1,2,3,1,-1900,-1,-9999,MRD_x01_y01_z10,MRD_x01_y01_z10,None,ON,NORMAL +265,265,1,0,10,1,2,73.75,-81.2,434.66,147.2,20,0.6,7,19,18,20,3,10,3,-1,-1,2,3,2,-1600,-1,-9999,MRD_x01_y02_z10,MRD_x01_y02_z10,None,ON,NORMAL +266,266,1,0,10,1,3,73.75,-60.9,434.66,147.2,20,0.6,7,19,19,20,4,10,4,-1,-1,2,3,3,-1800,-1,-9999,MRD_x01_y03_z10,MRD_x01_y03_z10,None,ON,NORMAL +267,267,1,0,10,1,4,73.75,-40.6,434.66,147.2,20,0.6,7,19,20,20,5,10,5,-1,-1,2,3,4,-1800,-1,-9999,MRD_x01_y04_z10,MRD_x01_y04_z10,None,ON,NORMAL +268,268,1,0,10,1,5,73.75,-20.3,434.66,147.2,20,0.6,7,19,21,20,6,10,6,-1,-1,2,3,5,-2100,-1,-9999,MRD_x01_y05_z10,MRD_x01_y05_z10,None,ON,NORMAL +269,269,1,0,10,1,6,73.75,0,434.66,147.2,20,0.6,7,19,22,20,7,10,7,-1,-1,2,3,6,-2100,-1,-9999,MRD_x01_y06_z10,MRD_x01_y06_z10,None,ON,NORMAL +270,270,1,0,10,1,7,73.75,20.3,434.66,147.2,20,0.6,7,19,23,20,8,10,8,-1,-1,2,3,7,-1600,-1,-9999,MRD_x01_y07_z10,MRD_x01_y07_z10,None,ON,NORMAL +271,271,1,0,10,1,8,73.75,40.6,434.66,147.2,20,0.6,7,19,24,20,9,10,9,-1,-1,2,3,8,-2100,-1,-9999,MRD_x01_y08_z10,MRD_x01_y08_z10,None,OFF,HOT +272,272,1,0,10,1,9,73.75,60.9,434.66,147.2,20,0.6,7,19,25,20,10,10,10,-1,-1,2,3,9,-2100,-1,-9999,MRD_x01_y09_z10,MRD_x01_y09_z10,None,ON,HOT +273,273,1,0,10,1,10,73.75,81.2,434.66,147.2,20,0.6,7,19,26,20,11,10,11,-1,-1,2,3,10,-1600,-1,-9999,MRD_x01_y10_z10,MRD_x01_y10_z10,None,ON,NORMAL +274,274,1,0,10,1,11,73.75,101.5,434.66,147.2,20,0.6,7,19,27,20,12,10,12,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y11_z10,MRD_x01_y11_z10,None,ON,HOT +275,275,1,0,10,1,12,73.75,121.8,434.66,147.2,20,0.6,7,19,28,20,13,10,13,-1,-1,2,3,13,-2100,-1,-9999,MRD_x01_y12_z10,MRD_x01_y12_z10,None,OFF,NORMAL +276,276,1,1,11,0,0,-142.1,-65.25,446.77,20,130.2,0.6,8,17,0,16,1,11,1,1,19,2,4,0,-1500,-1,-9999,MRD_x00_y00_z11,MRD_x00_y00_z11,None,ON,HOT +277,277,1,1,11,0,1,-121.8,-65.25,446.77,20,130.2,0.6,8,17,1,16,2,11,2,1,21,2,4,1,-1500,-1,-9999,MRD_x01_y00_z11,MRD_x01_y00_z11,None,ON,NORMAL +278,278,1,1,11,0,2,-101.5,-65.25,446.77,20,130.2,0.6,8,17,2,16,3,11,3,1,23,2,4,2,-1500,-1,-9999,MRD_x02_y00_z11,MRD_x02_y00_z11,None,ON,NORMAL +279,279,1,1,11,0,3,-81.2,-65.25,446.77,20,130.2,0.6,8,17,3,16,4,11,4,1,25,2,4,3,-1300,-1,-9999,MRD_x03_y00_z11,MRD_x03_y00_z11,None,ON,NORMAL +280,280,1,1,11,0,4,-60.9,-65.25,446.77,20,130.2,0.6,8,17,4,16,5,11,5,1,27,2,4,4,-1500,-1,-9999,MRD_x04_y00_z11,MRD_x04_y00_z11,None,ON,NORMAL +281,281,1,1,11,0,5,-40.6,-65.25,446.77,20,130.2,0.6,8,17,5,16,6,11,6,1,29,2,4,5,-1500,-1,-9999,MRD_x05_y00_z11,MRD_x05_y00_z11,None,ON,NORMAL +282,282,1,1,11,0,6,-20.3,-65.25,446.77,20,130.2,0.6,8,17,6,16,7,11,7,1,31,2,4,6,-1500,-1,-9999,MRD_x06_y00_z11,MRD_x06_y00_z11,None,ON,NORMAL +283,283,1,1,11,0,7,0,-65.25,446.77,20,130.2,0.6,8,17,7,16,8,11,8,12,17,2,4,7,-1500,-1,-9999,MRD_x07_y00_z11,MRD_x07_y00_z11,None,ON,HOT +284,284,1,1,11,0,8,20.3,-65.25,446.77,20,130.2,0.6,8,17,8,16,9,11,9,12,19,2,4,8,-1500,-1,-9999,MRD_x08_y00_z11,MRD_x08_y00_z11,None,ON,NORMAL +285,285,1,1,11,0,9,40.6,-65.25,446.77,20,130.2,0.6,8,17,9,16,10,11,10,12,21,2,4,9,-1300,-1,-9999,MRD_x09_y00_z11,MRD_x09_y00_z11,None,ON,NORMAL +286,286,1,1,11,0,10,60.9,-65.25,446.77,20,130.2,0.6,8,17,10,16,11,11,11,12,23,2,4,10,-1500,-1,-9999,MRD_x10_y00_z11,MRD_x10_y00_z11,None,ON,NORMAL +287,287,1,1,11,0,11,81.2,-65.25,446.77,20,130.2,0.6,8,17,11,16,12,11,12,12,25,2,4,11,-1500,-1,-9999,MRD_x11_y00_z11,MRD_x11_y00_z11,None,ON,NORMAL +288,288,1,1,11,0,12,101.5,-65.25,446.77,20,130.2,0.6,8,17,12,16,13,11,13,12,27,2,4,12,-1500,-1,-9999,MRD_x12_y00_z11,MRD_x12_y00_z11,None,ON,NORMAL +289,289,1,1,11,0,13,121.8,-65.25,446.77,20,130.2,0.6,8,17,13,16,14,11,14,12,29,2,4,13,-1500,-1,-9999,MRD_x13_y00_z11,MRD_x13_y00_z11,None,ON,NORMAL +290,290,1,1,11,0,14,142.1,-65.25,446.77,20,130.2,0.6,8,17,14,16,15,11,15,12,31,2,4,14,-1500,-1,-9999,MRD_x14_y00_z11,MRD_x14_y00_z11,None,ON,NORMAL +291,291,1,1,11,1,0,-142.1,65.25,446.77,20,130.2,0.6,8,17,16,18,1,12,1,1,20,2,5,0,-1500,-1,-9999,MRD_x00_y01_z11,MRD_x00_y01_z11,None,ON,NORMAL +292,292,1,1,11,1,1,-121.8,65.25,446.77,20,130.2,0.6,8,17,17,18,2,12,2,1,22,2,5,1,-1500,-1,-9999,MRD_x01_y01_z11,MRD_x01_y01_z11,None,ON,NORMAL +293,293,1,1,11,1,2,-101.5,65.25,446.77,20,130.2,0.6,8,17,18,18,3,12,3,1,24,2,5,3,-1500,-1,-9999,MRD_x02_y01_z11,MRD_x02_y01_z11,None,ON,NORMAL +294,294,1,1,11,1,3,-81.2,65.25,446.77,20,130.2,0.6,8,17,19,18,4,12,4,1,26,2,5,4,-1500,-1,-9999,MRD_x03_y01_z11,MRD_x03_y01_z11,None,ON,NORMAL +295,295,1,1,11,1,4,-60.9,65.25,446.77,20,130.2,0.6,8,17,20,18,5,12,5,1,28,2,5,5,-1500,-1,-9999,MRD_x04_y01_z11,MRD_x04_y01_z11,None,ON,NORMAL +296,296,1,1,11,1,5,-40.6,65.25,446.77,20,130.2,0.6,8,17,21,18,6,12,6,1,30,2,5,6,-1500,-1,-9999,MRD_x05_y01_z11,MRD_x05_y01_z11,None,ON,NORMAL +297,297,1,1,11,1,6,-20.3,65.25,446.77,20,130.2,0.6,8,17,22,18,7,12,7,1,32,2,5,7,-1500,-1,-9999,MRD_x06_y01_z11,MRD_x06_y01_z11,None,ON,NORMAL +298,298,1,1,11,1,7,0,65.25,446.77,20,130.2,0.6,8,17,23,18,8,12,8,10,1,2,5,8,-1500,-1,-9999,MRD_x07_y01_z11,MRD_x07_y01_z11,None,ON,NORMAL +299,299,1,1,11,1,8,20.3,65.25,446.77,20,130.2,0.6,8,17,24,18,9,12,9,10,2,2,5,9,-1500,-1,-9999,MRD_x08_y01_z11,MRD_x08_y01_z11,None,ON,NORMAL +300,300,1,1,11,1,9,40.6,65.25,446.77,20,130.2,0.6,8,17,25,18,10,12,10,10,3,2,5,10,-1300,-1,-9999,MRD_x09_y01_z11,MRD_x09_y01_z11,None,ON,NORMAL +301,301,1,1,11,1,10,60.9,65.25,446.77,20,130.2,0.6,8,17,26,18,11,12,11,10,4,2,5,11,-1300,-1,-9999,MRD_x10_y01_z11,MRD_x10_y01_z11,None,ON,NORMAL +302,302,1,1,11,1,11,81.2,65.25,446.77,20,130.2,0.6,8,17,27,18,12,12,12,10,5,2,5,12,-1300,-1,-9999,MRD_x11_y01_z11,MRD_x11_y01_z11,None,ON,NORMAL +303,303,1,1,11,1,12,101.5,65.25,446.77,20,130.2,0.6,8,17,28,18,13,12,13,10,6,2,5,13,-1300,-1,-9999,MRD_x12_y01_z11,MRD_x12_y01_z11,None,ON,NORMAL +304,304,1,1,11,1,13,121.8,65.25,446.77,20,130.2,0.6,8,17,29,18,14,12,14,10,7,2,5,14,-1500,-1,-9999,MRD_x13_y01_z11,MRD_x13_y01_z11,None,ON,NORMAL +305,305,1,1,11,1,14,142.1,65.25,446.77,20,130.2,0.6,8,17,30,18,15,12,15,10,8,2,5,14,-1500,-1,-9999,MRD_x14_y01_z11,MRD_x14_y01_z11,None,ON,NORMAL +306,306,1,0,12,0,0,-73.75,-121.8,458.88,147.2,20,0.6,7,22,0,21,1,11,1,-1,-1,2,6,0,-2100,-1,-9999,MRD_x00_y00_z12,MRD_x00_y00_z12,None,ON,NORMAL +307,307,1,0,12,0,1,-73.75,-101.5,458.88,147.2,20,0.6,7,22,1,21,2,11,2,-1,-1,2,6,1,-2100,-1,-9999,MRD_x00_y01_z12,MRD_x00_y01_z12,None,ON,NORMAL +308,308,1,0,12,0,2,-73.75,-81.2,458.88,147.2,20,0.6,7,22,2,21,3,11,3,-1,-1,2,6,2,-2100,-1,-9999,MRD_x00_y02_z12,MRD_x00_y02_z12,None,ON,NORMAL +309,309,1,0,12,0,3,-73.75,-60.9,458.88,147.2,20,0.6,7,22,3,21,4,11,4,-1,-1,2,6,3,-2100,-1,-9999,MRD_x00_y03_z12,MRD_x00_y03_z12,None,ON,NORMAL +310,310,1,0,12,0,4,-73.75,-40.6,458.88,147.2,20,0.6,7,22,4,21,5,11,5,-1,-1,2,6,4,-1900,-1,-9999,MRD_x00_y04_z12,MRD_x00_y04_z12,None,ON,NORMAL +311,311,1,0,12,0,5,-73.75,-20.3,458.88,147.2,20,0.6,7,22,5,21,6,11,6,-1,-1,2,6,5,-2100,-1,-9999,MRD_x00_y05_z12,MRD_x00_y05_z12,None,ON,NORMAL +312,312,1,0,12,0,6,-73.75,0,458.88,147.2,20,0.6,7,22,6,21,7,11,7,-1,-1,2,6,6,-1900,-1,-9999,MRD_x00_y06_z12,MRD_x00_y06_z12,None,ON,NORMAL +313,313,1,0,12,0,7,-73.75,20.3,458.88,147.2,20,0.6,7,22,7,21,8,11,8,-1,-1,2,6,7,-2100,-1,-9999,MRD_x00_y07_z12,MRD_x00_y07_z12,None,ON,NORMAL +314,314,1,0,12,0,8,-73.75,40.6,458.88,147.2,20,0.6,7,22,8,21,9,11,9,-1,-1,2,6,8,-2100,-1,-9999,MRD_x00_y08_z12,MRD_x00_y08_z12,None,ON,NORMAL +315,315,1,0,12,0,9,-73.75,60.9,458.88,147.2,20,0.6,7,22,9,21,10,11,10,-1,-1,2,6,9,-2100,-1,-9999,MRD_x00_y09_z12,MRD_x00_y09_z12,None,ON,NORMAL +316,316,1,0,12,0,10,-73.75,81.2,458.88,147.2,20,0.6,7,22,10,21,11,11,11,-1,-1,2,6,10,-2100,-1,-9999,MRD_x00_y10_z12,MRD_x00_y10_z12,None,ON,NORMAL +317,317,1,0,12,0,11,-73.75,101.5,458.88,147.2,20,0.6,7,22,11,21,12,11,12,-1,-1,2,6,11,-2100,-1,-9999,MRD_x00_y11_z12,MRD_x00_y11_z12,None,ON,NORMAL +318,318,1,0,12,0,12,-73.75,121.8,458.88,147.2,20,0.6,7,22,12,21,13,11,13,-1,-1,2,6,12,-2100,-1,-9999,MRD_x00_y12_z12,MRD_x00_y12_z12,None,ON,NORMAL +319,319,1,0,12,1,0,73.75,-121.8,458.88,147.2,20,0.6,7,22,16,23,1,12,1,-1,-1,2,7,0,-2100,-1,-9999,MRD_x01_y00_z12,MRD_x01_y00_z12,None,OFF,NORMAL +320,320,1,0,12,1,1,73.75,-101.5,458.88,147.2,20,0.6,7,22,17,23,2,12,2,-1,-1,2,7,1,-2100,-1,-9999,MRD_x01_y01_z12,MRD_x01_y01_z12,None,ON,NORMAL +321,321,1,0,12,1,2,73.75,-81.2,458.88,147.2,20,0.6,7,22,18,23,3,12,3,-1,-1,2,7,2,-2100,-1,-9999,MRD_x01_y02_z12,MRD_x01_y02_z12,None,ON,NORMAL +322,322,1,0,12,1,3,73.75,-60.9,458.88,147.2,20,0.6,7,22,19,23,4,12,4,-1,-1,2,7,3,-2100,-1,-9999,MRD_x01_y03_z12,MRD_x01_y03_z12,None,ON,NORMAL +323,323,1,0,12,1,4,73.75,-40.6,458.88,147.2,20,0.6,7,22,20,23,5,12,5,-1,-1,2,7,4,-2100,-1,-9999,MRD_x01_y04_z12,MRD_x01_y04_z12,None,ON,NORMAL +324,324,1,0,12,1,5,73.75,-20.3,458.88,147.2,20,0.6,7,22,21,23,6,12,6,-1,-1,2,7,5,-2100,-1,-9999,MRD_x01_y05_z12,MRD_x01_y05_z12,None,ON,NORMAL +325,325,1,0,12,1,6,73.75,0,458.88,147.2,20,0.6,7,22,22,23,7,12,7,-1,-1,2,7,6,-2100,-1,-9999,MRD_x01_y06_z12,MRD_x01_y06_z12,None,ON,NORMAL +326,326,1,0,12,1,7,73.75,20.3,458.88,147.2,20,0.6,7,22,23,23,8,12,8,-1,-1,2,7,7,-2100,-1,-9999,MRD_x01_y07_z12,MRD_x01_y07_z12,None,ON,NORMAL +327,327,1,0,12,1,8,73.75,40.6,458.88,147.2,20,0.6,7,22,24,23,9,12,9,-1,-1,2,7,8,-2100,-1,-9999,MRD_x01_y08_z12,MRD_x01_y08_z12,None,ON,NORMAL +328,328,1,0,12,1,9,73.75,60.9,458.88,147.2,20,0.6,7,22,25,23,10,12,10,-1,-1,2,7,9,-2100,-1,-9999,MRD_x01_y09_z12,MRD_x01_y09_z12,None,ON,NORMAL +329,329,1,0,12,1,10,73.75,81.2,458.88,147.2,20,0.6,7,22,26,23,11,12,11,-1,-1,2,7,10,-2100,-1,-9999,MRD_x01_y10_z12,MRD_x01_y10_z12,None,ON,NORMAL +330,330,1,0,12,1,11,73.75,101.5,458.88,147.2,20,0.6,7,22,27,23,12,12,12,-1,-1,2,7,11,-2100,-1,-9999,MRD_x01_y11_z12,MRD_x01_y11_z12,None,ON,NORMAL +331,331,1,0,12,1,12,73.75,121.8,458.88,147.2,20,0.6,7,22,28,23,13,12,13,-1,-1,2,7,12,-2100,-1,-9999,MRD_x01_y12_z12,MRD_x01_y12_z12,None,ON,NORMAL +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/FullTankPMTGeometry.csv b/configfiles/LoadGeometry/FullTankPMTGeometry.csv index 25a857ccf..c1a84129c 100755 --- a/configfiles/LoadGeometry/FullTankPMTGeometry.csv +++ b/configfiles/LoadGeometry/FullTankPMTGeometry.csv @@ -7,13 +7,13 @@ DATA_START,,,,,,,,,,,,,,,,,,,,,,,,, 334,334,Bottom,0,-0.7754244,-1.6939623,1.50832364,0,1,0,LUX,S1,ON,6,3,6,0,2,2,11,3,-999,-999,-999,-9999,ok (low rate) 335,335,Bottom,0,-0.445549,-1.6939623,1.80215489,0,1,0,LUX,S4,ON,6,4,6,0,3,2,11,4,-999,-999,-999,-9999,ok (noisy) 336,336,Bottom,0,-0.57756,-1.6852488,1.30996145,0,1,0,LUX,W4,ON,6,5,6,0,4,2,13,1,-999,-999,-999,-9999,ok (noisy) -337,337,Bottom,0,0.19125292,-1.6939623,2.46046266,0,1,0,LUX,N4,ON,6,6,6,0,5,2,13,2,-999,-999,-999,-9999,ok +337,337,Bottom,0,0.19125292,-1.6939623,2.46046266,0,1,0,LUX,N4,OFF,6,6,6,0,5,2,13,2,-999,-999,-999,-9999,ok 338,338,Bottom,0,0.0766569,-1.6939623,1.92087346,0,1,0,LUX,S2,ON,6,7,6,0,6,2,19,1,-999,-999,-999,-9999,ok (noisy) 339,339,Bottom,0,-0.3190719,-1.6939623,2.31759783,0,1,0,LUX,E3,ON,6,8,6,0,7,2,13,4,-999,-999,-999,-9999,ok (low rate) 340,340,Bottom,0,0.38911731,-1.6906278,2.26210047,0,1,0,LUX,E4,ON,6,9,6,0,8,2,14,1,-999,-999,-999,-9999,ok (noisy) 341,341,Bottom,0,-0.1212075,-1.6939623,2.11923565,0,1,0,LUX,S5,ON,6,10,6,0,9,2,14,2,-999,-999,-999,-9999,ok (noisy) 342,342,Bottom,0,-0.1882051,-1.6956896,0.91420765,0,1,0,LUX,N5,OFF,6,11,6,0,10,2,14,3,-999,-999,-999,-9999,ok (low rate) -343,343,Bottom,0,0.14804416,-1.6939623,1.20706832,0,1,0,LUX,W3,ON,6,12,6,0,11,2,14,4,-999,-999,-999,-9999,ok (noisy) +343,343,Bottom,0,0.14804416,-1.6939623,1.20706832,0,1,0,LUX,W3,OFF,6,12,6,0,11,2,14,4,-999,-999,-999,-9999,ok (noisy) 344,344,Bottom,0,-0.0498202,-1.6939623,1.40543051,0,1,0,LUX,W1,ON,7,1,6,0,12,2,19,2,-999,-999,-999,-9999,ok (noisy) 345,345,Bottom,0,0.34590855,-1.6986855,1.00870613,0,1,0,LUX,E5,OFF,7,2,6,0,13,2,15,2,-999,-999,-999,-9999,no signal 346,346,Bottom,0,-0.3860695,-1.6939623,1.11256984,0,1,0,LUX,E1,OFF,7,3,6,0,14,2,15,3,-999,-999,-999,-9999,ok (noisy) @@ -28,8 +28,8 @@ DATA_START,,,,,,,,,,,,,,,,,,,,,,,,, 355,355,Top,9,-0.4780203,1.33364449,2.36496633,0,-1,0,ETEL,127,ON,5,4,6,2,3,2,6,4,-999,-999,-999,-9999,ok 356,356,Top,9,-0.6793047,1.33439206,2.15757157,0,-1,0,ETEL,117,ON,5,5,6,2,4,2,9,1,-999,-999,-999,-9999,ok (noisy) 357,357,Top,9,-0.8158105,1.33006131,1.54452182,0,-1,0,ETEL,701,ON,5,6,6,2,5,2,9,2,-999,-999,-999,-9999,ok -358,358,Top,9,-0.685076,1.33006131,1.21748748,0,-1,0,ETEL,704,ON,5,7,6,2,6,2,9,3,-999,-999,-999,-9999,ok -359,359,Top,9,-0.1511486,1.33006131,0.86777977,0,-1,0,ETEL,719,ON,5,8,6,2,7,2,9,4,-999,-999,-999,-9999,ok +358,358,Top,9,-0.685076,1.33006131,1.21748748,0,-1,0,ETEL,704,OFF,5,7,6,2,6,2,9,3,-999,-999,-999,-9999,ok +359,359,Top,9,-0.1511486,1.33006131,0.86777977,0,-1,0,ETEL,719,OFF,5,8,6,2,7,2,9,4,-999,-999,-999,-9999,ok 360,360,Top,9,-0.4686274,1.33464118,1.0145482,0,-1,0,ETEL,105,ON,5,9,6,2,8,2,10,1,-999,-999,-999,-9999,ok 361,361,Top,9,0.48350228,1.33312054,1.00330305,0,-1,0,ETEL,703,ON,5,10,6,2,9,2,10,2,-999,-999,-999,-9999,ok 362,362,Top,9,0.81463341,1.33006131,1.53766317,0,-1,0,ETEL,119,ON,5,11,6,2,10,2,10,3,-999,-999,-999,-9999,ok @@ -78,7 +78,7 @@ DATA_START,,,,,,,,,,,,,,,,,,,,,,,,, 405,405,Barrel,8,0.54989219,0.01038878,2.6087467,-0.3773816,0.00035279,-0.9260398,Watchman,NB0114,ON,13,1,6,6,1,3,15,2,-999,-999,-999,-9999,ok 406,406,Barrel,8,0.27324662,-0.3994107,2.79745653,-0.3773816,0.00035279,-0.9260398,Hamamatsu,SQ0391,ON,13,10,6,6,2,3,15,3,-999,-999,-999,-9999,ok 407,407,Barrel,8,0.59832632,-0.402122,2.65563198,-0.3773816,0.00035279,-0.9260398,Hamamatsu,SQ0383,ON,13,11,6,6,3,3,15,4,-999,-999,-999,-9999,ok -408,408,Barrel,1,-0.593424,-0.8609753,2.65680163,0.38530308,0.00451611,-0.9227789,Hamamatsu,SQ0388,ON,13,2,6,6,4,3,18,1,-999,-999,-999,-9999,ok +408,408,Barrel,1,-0.593424,-0.8609753,2.65680163,0.38530308,0.00451611,-0.9227789,Hamamatsu,SQ0388,OFF,13,2,6,6,4,3,18,1,-999,-999,-999,-9999,ok 409,409,Barrel,1,-0.5836122,-0.4120414,2.66279671,0.38530308,0.00451611,-0.9227789,Hamamatsu,SQ0393,ON,13,3,6,6,5,3,18,2,-999,-999,-999,-9999,ok 410,410,Barrel,1,-0.2689693,0.45754046,2.79763283,0.38530308,0.00451611,-0.9227789,Hamamatsu,SQ0389,ON,13,4,6,6,6,3,18,3,-999,-999,-999,-9999,ok 411,411,Barrel,1,-0.5885181,0.45754046,2.65979917,0.38530308,0.00451611,-0.9227789,Hamamatsu,SQ0384,ON,13,5,6,6,7,3,18,4,-999,-999,-999,-9999,ok @@ -86,7 +86,7 @@ DATA_START,,,,,,,,,,,,,,,,,,,,,,,,, 413,413,Barrel,8,0.59832632,0.45792182,2.65563198,-0.3773816,0.00035279,-0.9260398,Hamamatsu,SQ0386,ON,13,7,6,6,9,3,19,2,-999,-999,-999,-9999,ok 414,414,Barrel,8,0.26276376,-0.8369909,2.79610581,-0.3773816,0.00035279,-0.9260398,Hamamatsu,SQ0390,ON,13,8,6,6,10,3,19,3,-999,-999,-999,-9999,ok 415,415,Barrel,8,0.26800519,0.45792182,2.79678117,-0.3773816,0.00035279,-0.9260398,Hamamatsu,SQ0387,ON,13,9,6,6,11,3,19,4,-999,-999,-999,-9999,ok -416,416,Barrel,3,-1.0413511,0.86344388,1.40794291,0.9222563,-0.0025943,0.3865435,Watchboy,3,ON,1,1,5,7,0,1,4,1,-999,-999,-999,-9999,ok +416,416,Barrel,3,-1.0413511,0.86344388,1.40794291,0.9222563,-0.0025943,0.3865435,Watchboy,3,OFF,1,1,5,7,0,1,4,1,-999,-999,-999,-9999,ok 417,417,Barrel,2,-1.0470203,-1.2853838,1.93673598,0.92372753,0.00187934,-0.3830443,Watchboy,15,ON,1,2,5,7,1,1,4,2,-999,-999,-999,-9999,ok 418,418,Barrel,3,-0.9317383,-1.2922401,1.14479123,0.92372753,0.00187934,-0.3830443,Watchboy,7,ON,1,3,5,7,2,1,4,3,-999,-999,-999,-9999,ok 419,419,Barrel,3,-1.0370936,-0.8573284,1.40051511,0.92372753,0.00187934,-0.3830443,Watchboy,34,ON,1,4,5,7,3,1,4,4,-999,-999,-999,-9999,ok @@ -134,4 +134,4 @@ DATA_START,,,,,,,,,,,,,,,,,,,,,,,,, 461,461,Barrel,8,0.54989219,0.86309907,2.6087467,-0.3773816,0.00035279,-0.9260398,Watchboy,47,ON,4,10,6,9,13,2,5,2,-999,-999,-999,-9999,ok 462,462,Barrel,8,0.26489847,0.01038878,2.72413225,-0.3773816,0.00035279,-0.9260398,Watchboy,12,ON,4,11,6,9,14,2,5,3,-999,-999,-999,-9999,ok (noisy) 463,463,Barrel,1,-0.5454545,0.00990167,2.60815843,0.38530308,0.00451611,-0.9227789,Watchboy,16,ON,4,12,6,9,15,2,5,4,-999,-999,-999,-9999,ok -DATA_END,,,,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file +DATA_END,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/configfiles/LoadGeometry/LAPPDGeometry.csv b/configfiles/LoadGeometry/LAPPDGeometry.csv index 4fec97347..df2b434c8 100644 --- a/configfiles/LoadGeometry/LAPPDGeometry.csv +++ b/configfiles/LoadGeometry/LAPPDGeometry.csv @@ -1,1445 +1,1445 @@ -LEGEND_LINE -detector_num,detector_position_x,detector_position_y,detector_position_z,detector_direction_x,detector_direction_y,detector_direction_z,detector_type,detector_status,channel_num,channel_position_x,channel_position_y,channel_position_z,channel_strip_side,channel_strip_num,channel_signal_crate,channel_signal_card,channel_signal_channel,channel_level2_crate,channel_level2_card,channel_level2_channel,channel_hv_crate,channel_hv_card,channel_hv_channel,channel_status - -DATA_START -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,0,100,-300,0,0,0,0,0,1,0,0,32669,0,0,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,1,100,-290,0,0,1,0,0,2,0,0,32669,0,0,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,2,100,-280,0,0,2,0,0,3,0,0,32669,0,0,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,3,100,-270,0,0,3,0,0,4,0,0,32669,0,1,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,4,100,-260,0,0,4,0,0,5,0,0,32669,0,1,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,5,100,-250,0,0,5,0,0,6,0,0,32669,0,1,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,6,100,-240,0,0,6,0,0,7,0,0,32669,0,1,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,7,100,-230,0,0,7,0,0,8,0,0,32669,0,2,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,8,100,-220,0,0,8,0,0,9,0,0,32669,0,2,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,9,100,-210,0,0,9,0,0,10,0,0,32669,0,2,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,10,100,-200,0,0,10,0,0,11,0,0,32669,0,2,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,11,100,-190,0,0,11,0,0,12,0,0,32669,0,3,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,12,100,-180,0,0,12,0,0,13,0,0,32669,0,3,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,13,100,-170,0,0,13,0,0,14,0,0,32669,0,3,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,14,100,-160,0,0,14,0,0,15,0,0,32669,0,3,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,15,100,-150,0,0,15,0,0,16,0,0,32669,0,4,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,16,100,-140,0,0,16,0,0,17,0,0,32669,0,4,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,17,100,-130,0,0,17,0,0,18,0,0,32669,0,4,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,18,100,-120,0,0,18,0,0,19,0,0,32669,0,4,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,19,100,-110,0,0,19,0,0,20,0,0,32669,0,5,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,20,100,-100,0,0,20,0,0,21,0,0,32669,0,5,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,21,100,-90,0,0,21,0,0,22,0,0,32669,0,5,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,22,100,-80,0,0,22,0,0,23,0,0,32669,0,5,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,23,100,-70,0,0,23,0,0,24,0,0,32669,0,6,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,24,100,-60,0,0,24,0,0,25,0,0,32669,0,6,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,25,100,-50,0,0,25,0,0,26,0,0,32669,0,6,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,26,100,-40,0,0,26,0,0,27,0,0,32669,0,6,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,27,100,-30,0,0,27,0,0,28,0,0,32669,0,7,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,28,100,-20,0,0,28,0,0,29,0,0,32669,0,7,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,29,100,-10,0,0,29,0,1,0,0,0,32669,0,7,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,30,-100,-300,0,1,0,0,1,1,0,0,32669,0,7,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,31,-100,-290,0,1,1,0,1,2,0,0,32669,0,8,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,32,-100,-280,0,1,2,0,1,3,0,0,32669,0,8,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,33,-100,-270,0,1,3,0,1,4,0,0,32669,0,8,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,34,-100,-260,0,1,4,0,1,5,0,0,32669,0,8,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,35,-100,-250,0,1,5,0,1,6,0,0,32669,0,9,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,36,-100,-240,0,1,6,0,1,7,0,0,32669,0,9,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,37,-100,-230,0,1,7,0,1,8,0,0,32669,0,9,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,38,-100,-220,0,1,8,0,1,9,0,0,32669,0,9,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,39,-100,-210,0,1,9,0,1,10,0,0,32669,1,0,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,40,-100,-200,0,1,10,0,1,11,0,0,32669,1,0,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,41,-100,-190,0,1,11,0,1,12,0,0,32669,1,0,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,42,-100,-180,0,1,12,0,1,13,0,0,32669,1,0,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,43,-100,-170,0,1,13,0,1,14,0,0,32669,1,1,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,44,-100,-160,0,1,14,0,1,15,0,0,32669,1,1,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,45,-100,-150,0,1,15,0,1,16,0,0,32669,1,1,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,46,-100,-140,0,1,16,0,1,17,0,0,32669,1,1,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,47,-100,-130,0,1,17,0,1,18,0,0,32669,1,2,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,48,-100,-120,0,1,18,0,1,19,0,0,32669,1,2,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,49,-100,-110,0,1,19,0,1,20,0,0,32669,1,2,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,50,-100,-100,0,1,20,0,1,21,0,0,32669,1,2,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,51,-100,-90,0,1,21,0,1,22,0,0,32669,1,3,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,52,-100,-80,0,1,22,0,1,23,0,0,32669,1,3,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,53,-100,-70,0,1,23,0,1,24,0,0,32669,1,3,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,54,-100,-60,0,1,24,0,1,25,0,0,32669,1,3,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,55,-100,-50,0,1,25,0,1,26,0,0,32669,1,4,0,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,56,-100,-40,0,1,26,0,1,27,0,0,32669,1,4,1,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,57,-100,-30,0,1,27,0,1,28,0,0,32669,1,4,2,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,58,-100,-20,0,1,28,0,1,29,0,0,32669,1,4,3,ON -0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,59,-100,-10,0,1,29,0,2,0,0,0,32669,1,5,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,60,100,-300,0,0,0,0,2,1,0,0,32669,1,5,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,61,100,-290,0,0,1,0,2,2,0,0,32669,1,5,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,62,100,-280,0,0,2,0,2,3,0,0,32669,1,5,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,63,100,-270,0,0,3,0,2,4,0,0,32669,1,6,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,64,100,-260,0,0,4,0,2,5,0,0,32669,1,6,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,65,100,-250,0,0,5,0,2,6,0,0,32669,1,6,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,66,100,-240,0,0,6,0,2,7,0,0,32669,1,6,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,67,100,-230,0,0,7,0,2,8,0,0,32669,1,7,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,68,100,-220,0,0,8,0,2,9,0,0,32669,1,7,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,69,100,-210,0,0,9,0,2,10,0,0,32669,1,7,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,70,100,-200,0,0,10,0,2,11,0,0,32669,1,7,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,71,100,-190,0,0,11,0,2,12,0,0,32669,1,8,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,72,100,-180,0,0,12,0,2,13,0,0,32669,1,8,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,73,100,-170,0,0,13,0,2,14,0,0,32669,1,8,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,74,100,-160,0,0,14,0,2,15,0,0,32669,1,8,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,75,100,-150,0,0,15,0,2,16,0,0,32669,1,9,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,76,100,-140,0,0,16,0,2,17,0,0,32669,1,9,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,77,100,-130,0,0,17,0,2,18,0,0,32669,1,9,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,78,100,-120,0,0,18,0,2,19,0,0,32669,1,9,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,79,100,-110,0,0,19,0,2,20,0,0,32669,2,0,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,80,100,-100,0,0,20,0,2,21,0,0,32669,2,0,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,81,100,-90,0,0,21,0,2,22,0,0,32669,2,0,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,82,100,-80,0,0,22,0,2,23,0,0,32669,2,0,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,83,100,-70,0,0,23,0,2,24,0,0,32669,2,1,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,84,100,-60,0,0,24,0,2,25,0,0,32669,2,1,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,85,100,-50,0,0,25,0,2,26,0,0,32669,2,1,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,86,100,-40,0,0,26,0,2,27,0,0,32669,2,1,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,87,100,-30,0,0,27,0,2,28,0,0,32669,2,2,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,88,100,-20,0,0,28,0,2,29,0,0,32669,2,2,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,89,100,-10,0,0,29,0,3,0,0,0,32669,2,2,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,90,-100,-300,0,1,0,0,3,1,0,0,32669,2,2,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,91,-100,-290,0,1,1,0,3,2,0,0,32669,2,3,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,92,-100,-280,0,1,2,0,3,3,0,0,32669,2,3,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,93,-100,-270,0,1,3,0,3,4,0,0,32669,2,3,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,94,-100,-260,0,1,4,0,3,5,0,0,32669,2,3,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,95,-100,-250,0,1,5,0,3,6,0,0,32669,2,4,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,96,-100,-240,0,1,6,0,3,7,0,0,32669,2,4,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,97,-100,-230,0,1,7,0,3,8,0,0,32669,2,4,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,98,-100,-220,0,1,8,0,3,9,0,0,32669,2,4,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,99,-100,-210,0,1,9,0,3,10,0,0,32669,2,5,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,100,-100,-200,0,1,10,0,3,11,0,0,32669,2,5,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,101,-100,-190,0,1,11,0,3,12,0,0,32669,2,5,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,102,-100,-180,0,1,12,0,3,13,0,0,32669,2,5,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,103,-100,-170,0,1,13,0,3,14,0,0,32669,2,6,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,104,-100,-160,0,1,14,0,3,15,0,0,32669,2,6,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,105,-100,-150,0,1,15,0,3,16,0,0,32669,2,6,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,106,-100,-140,0,1,16,0,3,17,0,0,32669,2,6,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,107,-100,-130,0,1,17,0,3,18,0,0,32669,2,7,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,108,-100,-120,0,1,18,0,3,19,0,0,32669,2,7,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,109,-100,-110,0,1,19,0,3,20,0,0,32669,2,7,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,110,-100,-100,0,1,20,0,3,21,0,0,32669,2,7,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,111,-100,-90,0,1,21,0,3,22,0,0,32669,2,8,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,112,-100,-80,0,1,22,0,3,23,0,0,32669,2,8,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,113,-100,-70,0,1,23,0,3,24,0,0,32669,2,8,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,114,-100,-60,0,1,24,0,3,25,0,0,32669,2,8,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,115,-100,-50,0,1,25,0,3,26,0,0,32669,2,9,0,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,116,-100,-40,0,1,26,0,3,27,0,0,32669,2,9,1,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,117,-100,-30,0,1,27,0,3,28,0,0,32669,2,9,2,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,118,-100,-20,0,1,28,0,3,29,0,0,32669,2,9,3,ON -1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,119,-100,-10,0,1,29,0,4,0,0,0,32669,3,0,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,120,100,-300,0,0,0,0,4,1,0,0,32669,3,0,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,121,100,-290,0,0,1,0,4,2,0,0,32669,3,0,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,122,100,-280,0,0,2,0,4,3,0,0,32669,3,0,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,123,100,-270,0,0,3,0,4,4,0,0,32669,3,1,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,124,100,-260,0,0,4,0,4,5,0,0,32669,3,1,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,125,100,-250,0,0,5,0,4,6,0,0,32669,3,1,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,126,100,-240,0,0,6,0,4,7,0,0,32669,3,1,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,127,100,-230,0,0,7,0,4,8,0,0,32669,3,2,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,128,100,-220,0,0,8,0,4,9,0,0,32669,3,2,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,129,100,-210,0,0,9,0,4,10,0,0,32669,3,2,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,130,100,-200,0,0,10,0,4,11,0,0,32669,3,2,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,131,100,-190,0,0,11,0,4,12,0,0,32669,3,3,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,132,100,-180,0,0,12,0,4,13,0,0,32669,3,3,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,133,100,-170,0,0,13,0,4,14,0,0,32669,3,3,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,134,100,-160,0,0,14,0,4,15,0,0,32669,3,3,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,135,100,-150,0,0,15,0,4,16,0,0,32669,3,4,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,136,100,-140,0,0,16,0,4,17,0,0,32669,3,4,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,137,100,-130,0,0,17,0,4,18,0,0,32669,3,4,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,138,100,-120,0,0,18,0,4,19,0,0,32669,3,4,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,139,100,-110,0,0,19,0,4,20,0,0,32669,3,5,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,140,100,-100,0,0,20,0,4,21,0,0,32669,3,5,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,141,100,-90,0,0,21,0,4,22,0,0,32669,3,5,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,142,100,-80,0,0,22,0,4,23,0,0,32669,3,5,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,143,100,-70,0,0,23,0,4,24,0,0,32669,3,6,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,144,100,-60,0,0,24,0,4,25,0,0,32669,3,6,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,145,100,-50,0,0,25,0,4,26,0,0,32669,3,6,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,146,100,-40,0,0,26,0,4,27,0,0,32669,3,6,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,147,100,-30,0,0,27,0,4,28,0,0,32669,3,7,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,148,100,-20,0,0,28,0,4,29,0,0,32669,3,7,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,149,100,-10,0,0,29,0,5,0,0,0,32669,3,7,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,150,-100,-300,0,1,0,0,5,1,0,0,32669,3,7,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,151,-100,-290,0,1,1,0,5,2,0,0,32669,3,8,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,152,-100,-280,0,1,2,0,5,3,0,0,32669,3,8,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,153,-100,-270,0,1,3,0,5,4,0,0,32669,3,8,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,154,-100,-260,0,1,4,0,5,5,0,0,32669,3,8,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,155,-100,-250,0,1,5,0,5,6,0,0,32669,3,9,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,156,-100,-240,0,1,6,0,5,7,0,0,32669,3,9,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,157,-100,-230,0,1,7,0,5,8,0,0,32669,3,9,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,158,-100,-220,0,1,8,0,5,9,0,0,32669,3,9,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,159,-100,-210,0,1,9,0,5,10,0,0,32669,4,0,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,160,-100,-200,0,1,10,0,5,11,0,0,32669,4,0,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,161,-100,-190,0,1,11,0,5,12,0,0,32669,4,0,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,162,-100,-180,0,1,12,0,5,13,0,0,32669,4,0,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,163,-100,-170,0,1,13,0,5,14,0,0,32669,4,1,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,164,-100,-160,0,1,14,0,5,15,0,0,32669,4,1,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,165,-100,-150,0,1,15,0,5,16,0,0,32669,4,1,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,166,-100,-140,0,1,16,0,5,17,0,0,32669,4,1,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,167,-100,-130,0,1,17,0,5,18,0,0,32669,4,2,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,168,-100,-120,0,1,18,0,5,19,0,0,32669,4,2,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,169,-100,-110,0,1,19,0,5,20,0,0,32669,4,2,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,170,-100,-100,0,1,20,0,5,21,0,0,32669,4,2,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,171,-100,-90,0,1,21,0,5,22,0,0,32669,4,3,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,172,-100,-80,0,1,22,0,5,23,0,0,32669,4,3,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,173,-100,-70,0,1,23,0,5,24,0,0,32669,4,3,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,174,-100,-60,0,1,24,0,5,25,0,0,32669,4,3,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,175,-100,-50,0,1,25,0,5,26,0,0,32669,4,4,0,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,176,-100,-40,0,1,26,0,5,27,0,0,32669,4,4,1,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,177,-100,-30,0,1,27,0,5,28,0,0,32669,4,4,2,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,178,-100,-20,0,1,28,0,5,29,0,0,32669,4,4,3,ON -2,0,0.637851,0.404,0,0,1,lappd_v1,ON,179,-100,-10,0,1,29,0,6,0,0,0,32669,4,5,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,180,100,-300,0,0,0,0,6,1,0,0,32669,4,5,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,181,100,-290,0,0,1,0,6,2,0,0,32669,4,5,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,182,100,-280,0,0,2,0,6,3,0,0,32669,4,5,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,183,100,-270,0,0,3,0,6,4,0,0,32669,4,6,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,184,100,-260,0,0,4,0,6,5,0,0,32669,4,6,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,185,100,-250,0,0,5,0,6,6,0,0,32669,4,6,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,186,100,-240,0,0,6,0,6,7,0,0,32669,4,6,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,187,100,-230,0,0,7,0,6,8,0,0,32669,4,7,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,188,100,-220,0,0,8,0,6,9,0,0,32669,4,7,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,189,100,-210,0,0,9,0,6,10,0,0,32669,4,7,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,190,100,-200,0,0,10,0,6,11,0,0,32669,4,7,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,191,100,-190,0,0,11,0,6,12,0,0,32669,4,8,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,192,100,-180,0,0,12,0,6,13,0,0,32669,4,8,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,193,100,-170,0,0,13,0,6,14,0,0,32669,4,8,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,194,100,-160,0,0,14,0,6,15,0,0,32669,4,8,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,195,100,-150,0,0,15,0,6,16,0,0,32669,4,9,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,196,100,-140,0,0,16,0,6,17,0,0,32669,4,9,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,197,100,-130,0,0,17,0,6,18,0,0,32669,4,9,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,198,100,-120,0,0,18,0,6,19,0,0,32669,4,9,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,199,100,-110,0,0,19,0,6,20,0,0,32669,5,0,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,200,100,-100,0,0,20,0,6,21,0,0,32669,5,0,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,201,100,-90,0,0,21,0,6,22,0,0,32669,5,0,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,202,100,-80,0,0,22,0,6,23,0,0,32669,5,0,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,203,100,-70,0,0,23,0,6,24,0,0,32669,5,1,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,204,100,-60,0,0,24,0,6,25,0,0,32669,5,1,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,205,100,-50,0,0,25,0,6,26,0,0,32669,5,1,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,206,100,-40,0,0,26,0,6,27,0,0,32669,5,1,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,207,100,-30,0,0,27,0,6,28,0,0,32669,5,2,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,208,100,-20,0,0,28,0,6,29,0,0,32669,5,2,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,209,100,-10,0,0,29,0,7,0,0,0,32669,5,2,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,210,-100,-300,0,1,0,0,7,1,0,0,32669,5,2,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,211,-100,-290,0,1,1,0,7,2,0,0,32669,5,3,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,212,-100,-280,0,1,2,0,7,3,0,0,32669,5,3,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,213,-100,-270,0,1,3,0,7,4,0,0,32669,5,3,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,214,-100,-260,0,1,4,0,7,5,0,0,32669,5,3,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,215,-100,-250,0,1,5,0,7,6,0,0,32669,5,4,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,216,-100,-240,0,1,6,0,7,7,0,0,32669,5,4,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,217,-100,-230,0,1,7,0,7,8,0,0,32669,5,4,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,218,-100,-220,0,1,8,0,7,9,0,0,32669,5,4,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,219,-100,-210,0,1,9,0,7,10,0,0,32669,5,5,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,220,-100,-200,0,1,10,0,7,11,0,0,32669,5,5,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,221,-100,-190,0,1,11,0,7,12,0,0,32669,5,5,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,222,-100,-180,0,1,12,0,7,13,0,0,32669,5,5,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,223,-100,-170,0,1,13,0,7,14,0,0,32669,5,6,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,224,-100,-160,0,1,14,0,7,15,0,0,32669,5,6,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,225,-100,-150,0,1,15,0,7,16,0,0,32669,5,6,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,226,-100,-140,0,1,16,0,7,17,0,0,32669,5,6,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,227,-100,-130,0,1,17,0,7,18,0,0,32669,5,7,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,228,-100,-120,0,1,18,0,7,19,0,0,32669,5,7,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,229,-100,-110,0,1,19,0,7,20,0,0,32669,5,7,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,230,-100,-100,0,1,20,0,7,21,0,0,32669,5,7,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,231,-100,-90,0,1,21,0,7,22,0,0,32669,5,8,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,232,-100,-80,0,1,22,0,7,23,0,0,32669,5,8,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,233,-100,-70,0,1,23,0,7,24,0,0,32669,5,8,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,234,-100,-60,0,1,24,0,7,25,0,0,32669,5,8,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,235,-100,-50,0,1,25,0,7,26,0,0,32669,5,9,0,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,236,-100,-40,0,1,26,0,7,27,0,0,32669,5,9,1,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,237,-100,-30,0,1,27,0,7,28,0,0,32669,5,9,2,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,238,-100,-20,0,1,28,0,7,29,0,0,32669,5,9,3,ON -3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,239,-100,-10,0,1,29,0,8,0,0,1,32669,6,0,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,240,100,-300,0,0,0,0,8,1,0,1,32669,6,0,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,241,100,-290,0,0,1,0,8,2,0,1,32669,6,0,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,242,100,-280,0,0,2,0,8,3,0,1,32669,6,0,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,243,100,-270,0,0,3,0,8,4,0,1,32669,6,1,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,244,100,-260,0,0,4,0,8,5,0,1,32669,6,1,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,245,100,-250,0,0,5,0,8,6,0,1,32669,6,1,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,246,100,-240,0,0,6,0,8,7,0,1,32669,6,1,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,247,100,-230,0,0,7,0,8,8,0,1,32669,6,2,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,248,100,-220,0,0,8,0,8,9,0,1,32669,6,2,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,249,100,-210,0,0,9,0,8,10,0,1,32669,6,2,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,250,100,-200,0,0,10,0,8,11,0,1,32669,6,2,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,251,100,-190,0,0,11,0,8,12,0,1,32669,6,3,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,252,100,-180,0,0,12,0,8,13,0,1,32669,6,3,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,253,100,-170,0,0,13,0,8,14,0,1,32669,6,3,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,254,100,-160,0,0,14,0,8,15,0,1,32669,6,3,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,255,100,-150,0,0,15,0,8,16,0,1,32669,6,4,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,256,100,-140,0,0,16,0,8,17,0,1,32669,6,4,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,257,100,-130,0,0,17,0,8,18,0,1,32669,6,4,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,258,100,-120,0,0,18,0,8,19,0,1,32669,6,4,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,259,100,-110,0,0,19,0,8,20,0,1,32669,6,5,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,260,100,-100,0,0,20,0,8,21,0,1,32669,6,5,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,261,100,-90,0,0,21,0,8,22,0,1,32669,6,5,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,262,100,-80,0,0,22,0,8,23,0,1,32669,6,5,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,263,100,-70,0,0,23,0,8,24,0,1,32669,6,6,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,264,100,-60,0,0,24,0,8,25,0,1,32669,6,6,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,265,100,-50,0,0,25,0,8,26,0,1,32669,6,6,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,266,100,-40,0,0,26,0,8,27,0,1,32669,6,6,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,267,100,-30,0,0,27,0,8,28,0,1,32669,6,7,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,268,100,-20,0,0,28,0,8,29,0,1,32669,6,7,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,269,100,-10,0,0,29,0,9,0,0,1,32669,6,7,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,270,-100,-300,0,1,0,0,9,1,0,1,32669,6,7,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,271,-100,-290,0,1,1,0,9,2,0,1,32669,6,8,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,272,-100,-280,0,1,2,0,9,3,0,1,32669,6,8,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,273,-100,-270,0,1,3,0,9,4,0,1,32669,6,8,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,274,-100,-260,0,1,4,0,9,5,0,1,32669,6,8,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,275,-100,-250,0,1,5,0,9,6,0,1,32669,6,9,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,276,-100,-240,0,1,6,0,9,7,0,1,32669,6,9,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,277,-100,-230,0,1,7,0,9,8,0,1,32669,6,9,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,278,-100,-220,0,1,8,0,9,9,0,1,32669,6,9,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,279,-100,-210,0,1,9,0,9,10,0,1,32669,7,0,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,280,-100,-200,0,1,10,0,9,11,0,1,32669,7,0,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,281,-100,-190,0,1,11,0,9,12,0,1,32669,7,0,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,282,-100,-180,0,1,12,0,9,13,0,1,32669,7,0,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,283,-100,-170,0,1,13,0,9,14,0,1,32669,7,1,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,284,-100,-160,0,1,14,0,9,15,0,1,32669,7,1,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,285,-100,-150,0,1,15,0,9,16,0,1,32669,7,1,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,286,-100,-140,0,1,16,0,9,17,0,1,32669,7,1,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,287,-100,-130,0,1,17,0,9,18,0,1,32669,7,2,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,288,-100,-120,0,1,18,0,9,19,0,1,32669,7,2,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,289,-100,-110,0,1,19,0,9,20,0,1,32669,7,2,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,290,-100,-100,0,1,20,0,9,21,0,1,32669,7,2,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,291,-100,-90,0,1,21,0,9,22,0,1,32669,7,3,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,292,-100,-80,0,1,22,0,9,23,0,1,32669,7,3,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,293,-100,-70,0,1,23,0,9,24,0,1,32669,7,3,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,294,-100,-60,0,1,24,0,9,25,0,1,32669,7,3,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,295,-100,-50,0,1,25,0,9,26,0,1,32669,7,4,0,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,296,-100,-40,0,1,26,0,9,27,0,1,32669,7,4,1,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,297,-100,-30,0,1,27,0,9,28,0,1,32669,7,4,2,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,298,-100,-20,0,1,28,0,9,29,0,1,32669,7,4,3,ON -4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,299,-100,-10,0,1,29,0,10,0,0,1,32669,7,5,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,300,100,-300,0,0,0,0,10,1,0,1,32669,7,5,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,301,100,-290,0,0,1,0,10,2,0,1,32669,7,5,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,302,100,-280,0,0,2,0,10,3,0,1,32669,7,5,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,303,100,-270,0,0,3,0,10,4,0,1,32669,7,6,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,304,100,-260,0,0,4,0,10,5,0,1,32669,7,6,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,305,100,-250,0,0,5,0,10,6,0,1,32669,7,6,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,306,100,-240,0,0,6,0,10,7,0,1,32669,7,6,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,307,100,-230,0,0,7,0,10,8,0,1,32669,7,7,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,308,100,-220,0,0,8,0,10,9,0,1,32669,7,7,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,309,100,-210,0,0,9,0,10,10,0,1,32669,7,7,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,310,100,-200,0,0,10,0,10,11,0,1,32669,7,7,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,311,100,-190,0,0,11,0,10,12,0,1,32669,7,8,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,312,100,-180,0,0,12,0,10,13,0,1,32669,7,8,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,313,100,-170,0,0,13,0,10,14,0,1,32669,7,8,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,314,100,-160,0,0,14,0,10,15,0,1,32669,7,8,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,315,100,-150,0,0,15,0,10,16,0,1,32669,7,9,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,316,100,-140,0,0,16,0,10,17,0,1,32669,7,9,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,317,100,-130,0,0,17,0,10,18,0,1,32669,7,9,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,318,100,-120,0,0,18,0,10,19,0,1,32669,7,9,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,319,100,-110,0,0,19,0,10,20,0,1,32669,8,0,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,320,100,-100,0,0,20,0,10,21,0,1,32669,8,0,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,321,100,-90,0,0,21,0,10,22,0,1,32669,8,0,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,322,100,-80,0,0,22,0,10,23,0,1,32669,8,0,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,323,100,-70,0,0,23,0,10,24,0,1,32669,8,1,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,324,100,-60,0,0,24,0,10,25,0,1,32669,8,1,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,325,100,-50,0,0,25,0,10,26,0,1,32669,8,1,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,326,100,-40,0,0,26,0,10,27,0,1,32669,8,1,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,327,100,-30,0,0,27,0,10,28,0,1,32669,8,2,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,328,100,-20,0,0,28,0,10,29,0,1,32669,8,2,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,329,100,-10,0,0,29,0,11,0,0,1,32669,8,2,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,330,-100,-300,0,1,0,0,11,1,0,1,32669,8,2,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,331,-100,-290,0,1,1,0,11,2,0,1,32669,8,3,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,332,-100,-280,0,1,2,0,11,3,0,1,32669,8,3,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,333,-100,-270,0,1,3,0,11,4,0,1,32669,8,3,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,334,-100,-260,0,1,4,0,11,5,0,1,32669,8,3,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,335,-100,-250,0,1,5,0,11,6,0,1,32669,8,4,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,336,-100,-240,0,1,6,0,11,7,0,1,32669,8,4,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,337,-100,-230,0,1,7,0,11,8,0,1,32669,8,4,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,338,-100,-220,0,1,8,0,11,9,0,1,32669,8,4,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,339,-100,-210,0,1,9,0,11,10,0,1,32669,8,5,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,340,-100,-200,0,1,10,0,11,11,0,1,32669,8,5,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,341,-100,-190,0,1,11,0,11,12,0,1,32669,8,5,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,342,-100,-180,0,1,12,0,11,13,0,1,32669,8,5,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,343,-100,-170,0,1,13,0,11,14,0,1,32669,8,6,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,344,-100,-160,0,1,14,0,11,15,0,1,32669,8,6,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,345,-100,-150,0,1,15,0,11,16,0,1,32669,8,6,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,346,-100,-140,0,1,16,0,11,17,0,1,32669,8,6,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,347,-100,-130,0,1,17,0,11,18,0,1,32669,8,7,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,348,-100,-120,0,1,18,0,11,19,0,1,32669,8,7,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,349,-100,-110,0,1,19,0,11,20,0,1,32669,8,7,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,350,-100,-100,0,1,20,0,11,21,0,1,32669,8,7,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,351,-100,-90,0,1,21,0,11,22,0,1,32669,8,8,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,352,-100,-80,0,1,22,0,11,23,0,1,32669,8,8,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,353,-100,-70,0,1,23,0,11,24,0,1,32669,8,8,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,354,-100,-60,0,1,24,0,11,25,0,1,32669,8,8,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,355,-100,-50,0,1,25,0,11,26,0,1,32669,8,9,0,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,356,-100,-40,0,1,26,0,11,27,0,1,32669,8,9,1,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,357,-100,-30,0,1,27,0,11,28,0,1,32669,8,9,2,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,358,-100,-20,0,1,28,0,11,29,0,1,32669,8,9,3,ON -5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,359,-100,-10,0,1,29,0,12,0,0,1,32669,9,0,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,360,100,-300,0,0,0,0,12,1,0,1,32669,9,0,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,361,100,-290,0,0,1,0,12,2,0,1,32669,9,0,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,362,100,-280,0,0,2,0,12,3,0,1,32669,9,0,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,363,100,-270,0,0,3,0,12,4,0,1,32669,9,1,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,364,100,-260,0,0,4,0,12,5,0,1,32669,9,1,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,365,100,-250,0,0,5,0,12,6,0,1,32669,9,1,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,366,100,-240,0,0,6,0,12,7,0,1,32669,9,1,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,367,100,-230,0,0,7,0,12,8,0,1,32669,9,2,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,368,100,-220,0,0,8,0,12,9,0,1,32669,9,2,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,369,100,-210,0,0,9,0,12,10,0,1,32669,9,2,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,370,100,-200,0,0,10,0,12,11,0,1,32669,9,2,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,371,100,-190,0,0,11,0,12,12,0,1,32669,9,3,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,372,100,-180,0,0,12,0,12,13,0,1,32669,9,3,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,373,100,-170,0,0,13,0,12,14,0,1,32669,9,3,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,374,100,-160,0,0,14,0,12,15,0,1,32669,9,3,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,375,100,-150,0,0,15,0,12,16,0,1,32669,9,4,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,376,100,-140,0,0,16,0,12,17,0,1,32669,9,4,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,377,100,-130,0,0,17,0,12,18,0,1,32669,9,4,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,378,100,-120,0,0,18,0,12,19,0,1,32669,9,4,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,379,100,-110,0,0,19,0,12,20,0,1,32669,9,5,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,380,100,-100,0,0,20,0,12,21,0,1,32669,9,5,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,381,100,-90,0,0,21,0,12,22,0,1,32669,9,5,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,382,100,-80,0,0,22,0,12,23,0,1,32669,9,5,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,383,100,-70,0,0,23,0,12,24,0,1,32669,9,6,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,384,100,-60,0,0,24,0,12,25,0,1,32669,9,6,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,385,100,-50,0,0,25,0,12,26,0,1,32669,9,6,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,386,100,-40,0,0,26,0,12,27,0,1,32669,9,6,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,387,100,-30,0,0,27,0,12,28,0,1,32669,9,7,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,388,100,-20,0,0,28,0,12,29,0,1,32669,9,7,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,389,100,-10,0,0,29,0,13,0,0,1,32669,9,7,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,390,-100,-300,0,1,0,0,13,1,0,1,32669,9,7,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,391,-100,-290,0,1,1,0,13,2,0,1,32669,9,8,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,392,-100,-280,0,1,2,0,13,3,0,1,32669,9,8,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,393,-100,-270,0,1,3,0,13,4,0,1,32669,9,8,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,394,-100,-260,0,1,4,0,13,5,0,1,32669,9,8,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,395,-100,-250,0,1,5,0,13,6,0,1,32669,9,9,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,396,-100,-240,0,1,6,0,13,7,0,1,32669,9,9,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,397,-100,-230,0,1,7,0,13,8,0,1,32669,9,9,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,398,-100,-220,0,1,8,0,13,9,0,1,32669,9,9,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,399,-100,-210,0,1,9,0,13,10,0,1,32669,10,0,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,400,-100,-200,0,1,10,0,13,11,0,1,32669,10,0,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,401,-100,-190,0,1,11,0,13,12,0,1,32669,10,0,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,402,-100,-180,0,1,12,0,13,13,0,1,32669,10,0,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,403,-100,-170,0,1,13,0,13,14,0,1,32669,10,1,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,404,-100,-160,0,1,14,0,13,15,0,1,32669,10,1,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,405,-100,-150,0,1,15,0,13,16,0,1,32669,10,1,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,406,-100,-140,0,1,16,0,13,17,0,1,32669,10,1,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,407,-100,-130,0,1,17,0,13,18,0,1,32669,10,2,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,408,-100,-120,0,1,18,0,13,19,0,1,32669,10,2,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,409,-100,-110,0,1,19,0,13,20,0,1,32669,10,2,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,410,-100,-100,0,1,20,0,13,21,0,1,32669,10,2,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,411,-100,-90,0,1,21,0,13,22,0,1,32669,10,3,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,412,-100,-80,0,1,22,0,13,23,0,1,32669,10,3,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,413,-100,-70,0,1,23,0,13,24,0,1,32669,10,3,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,414,-100,-60,0,1,24,0,13,25,0,1,32669,10,3,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,415,-100,-50,0,1,25,0,13,26,0,1,32669,10,4,0,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,416,-100,-40,0,1,26,0,13,27,0,1,32669,10,4,1,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,417,-100,-30,0,1,27,0,13,28,0,1,32669,10,4,2,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,418,-100,-20,0,1,28,0,13,29,0,1,32669,10,4,3,ON -6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,419,-100,-10,0,1,29,0,14,0,0,1,32669,10,5,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,420,100,-300,0,0,0,0,14,1,0,1,32669,10,5,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,421,100,-290,0,0,1,0,14,2,0,1,32669,10,5,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,422,100,-280,0,0,2,0,14,3,0,1,32669,10,5,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,423,100,-270,0,0,3,0,14,4,0,1,32669,10,6,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,424,100,-260,0,0,4,0,14,5,0,1,32669,10,6,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,425,100,-250,0,0,5,0,14,6,0,1,32669,10,6,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,426,100,-240,0,0,6,0,14,7,0,1,32669,10,6,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,427,100,-230,0,0,7,0,14,8,0,1,32669,10,7,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,428,100,-220,0,0,8,0,14,9,0,1,32669,10,7,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,429,100,-210,0,0,9,0,14,10,0,1,32669,10,7,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,430,100,-200,0,0,10,0,14,11,0,1,32669,10,7,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,431,100,-190,0,0,11,0,14,12,0,1,32669,10,8,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,432,100,-180,0,0,12,0,14,13,0,1,32669,10,8,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,433,100,-170,0,0,13,0,14,14,0,1,32669,10,8,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,434,100,-160,0,0,14,0,14,15,0,1,32669,10,8,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,435,100,-150,0,0,15,0,14,16,0,1,32669,10,9,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,436,100,-140,0,0,16,0,14,17,0,1,32669,10,9,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,437,100,-130,0,0,17,0,14,18,0,1,32669,10,9,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,438,100,-120,0,0,18,0,14,19,0,1,32669,10,9,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,439,100,-110,0,0,19,0,14,20,0,1,32669,11,0,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,440,100,-100,0,0,20,0,14,21,0,1,32669,11,0,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,441,100,-90,0,0,21,0,14,22,0,1,32669,11,0,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,442,100,-80,0,0,22,0,14,23,0,1,32669,11,0,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,443,100,-70,0,0,23,0,14,24,0,1,32669,11,1,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,444,100,-60,0,0,24,0,14,25,0,1,32669,11,1,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,445,100,-50,0,0,25,0,14,26,0,1,32669,11,1,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,446,100,-40,0,0,26,0,14,27,0,1,32669,11,1,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,447,100,-30,0,0,27,0,14,28,0,1,32669,11,2,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,448,100,-20,0,0,28,0,14,29,0,1,32669,11,2,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,449,100,-10,0,0,29,0,15,0,0,1,32669,11,2,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,450,-100,-300,0,1,0,0,15,1,0,1,32669,11,2,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,451,-100,-290,0,1,1,0,15,2,0,1,32669,11,3,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,452,-100,-280,0,1,2,0,15,3,0,1,32669,11,3,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,453,-100,-270,0,1,3,0,15,4,0,1,32669,11,3,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,454,-100,-260,0,1,4,0,15,5,0,1,32669,11,3,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,455,-100,-250,0,1,5,0,15,6,0,1,32669,11,4,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,456,-100,-240,0,1,6,0,15,7,0,1,32669,11,4,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,457,-100,-230,0,1,7,0,15,8,0,1,32669,11,4,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,458,-100,-220,0,1,8,0,15,9,0,1,32669,11,4,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,459,-100,-210,0,1,9,0,15,10,0,1,32669,11,5,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,460,-100,-200,0,1,10,0,15,11,0,1,32669,11,5,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,461,-100,-190,0,1,11,0,15,12,0,1,32669,11,5,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,462,-100,-180,0,1,12,0,15,13,0,1,32669,11,5,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,463,-100,-170,0,1,13,0,15,14,0,1,32669,11,6,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,464,-100,-160,0,1,14,0,15,15,0,1,32669,11,6,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,465,-100,-150,0,1,15,0,15,16,0,1,32669,11,6,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,466,-100,-140,0,1,16,0,15,17,0,1,32669,11,6,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,467,-100,-130,0,1,17,0,15,18,0,1,32669,11,7,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,468,-100,-120,0,1,18,0,15,19,0,1,32669,11,7,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,469,-100,-110,0,1,19,0,15,20,0,1,32669,11,7,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,470,-100,-100,0,1,20,0,15,21,0,1,32669,11,7,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,471,-100,-90,0,1,21,0,15,22,0,1,32669,11,8,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,472,-100,-80,0,1,22,0,15,23,0,1,32669,11,8,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,473,-100,-70,0,1,23,0,15,24,0,1,32669,11,8,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,474,-100,-60,0,1,24,0,15,25,0,1,32669,11,8,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,475,-100,-50,0,1,25,0,15,26,0,1,32669,11,9,0,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,476,-100,-40,0,1,26,0,15,27,0,1,32669,11,9,1,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,477,-100,-30,0,1,27,0,15,28,0,1,32669,11,9,2,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,478,-100,-20,0,1,28,0,15,29,0,1,32669,11,9,3,ON -7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,479,-100,-10,0,1,29,0,16,0,0,2,32669,12,0,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,480,100,-300,0,0,0,0,16,1,0,2,32669,12,0,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,481,100,-290,0,0,1,0,16,2,0,2,32669,12,0,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,482,100,-280,0,0,2,0,16,3,0,2,32669,12,0,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,483,100,-270,0,0,3,0,16,4,0,2,32669,12,1,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,484,100,-260,0,0,4,0,16,5,0,2,32669,12,1,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,485,100,-250,0,0,5,0,16,6,0,2,32669,12,1,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,486,100,-240,0,0,6,0,16,7,0,2,32669,12,1,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,487,100,-230,0,0,7,0,16,8,0,2,32669,12,2,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,488,100,-220,0,0,8,0,16,9,0,2,32669,12,2,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,489,100,-210,0,0,9,0,16,10,0,2,32669,12,2,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,490,100,-200,0,0,10,0,16,11,0,2,32669,12,2,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,491,100,-190,0,0,11,0,16,12,0,2,32669,12,3,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,492,100,-180,0,0,12,0,16,13,0,2,32669,12,3,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,493,100,-170,0,0,13,0,16,14,0,2,32669,12,3,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,494,100,-160,0,0,14,0,16,15,0,2,32669,12,3,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,495,100,-150,0,0,15,0,16,16,0,2,32669,12,4,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,496,100,-140,0,0,16,0,16,17,0,2,32669,12,4,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,497,100,-130,0,0,17,0,16,18,0,2,32669,12,4,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,498,100,-120,0,0,18,0,16,19,0,2,32669,12,4,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,499,100,-110,0,0,19,0,16,20,0,2,32669,12,5,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,500,100,-100,0,0,20,0,16,21,0,2,32669,12,5,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,501,100,-90,0,0,21,0,16,22,0,2,32669,12,5,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,502,100,-80,0,0,22,0,16,23,0,2,32669,12,5,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,503,100,-70,0,0,23,0,16,24,0,2,32669,12,6,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,504,100,-60,0,0,24,0,16,25,0,2,32669,12,6,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,505,100,-50,0,0,25,0,16,26,0,2,32669,12,6,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,506,100,-40,0,0,26,0,16,27,0,2,32669,12,6,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,507,100,-30,0,0,27,0,16,28,0,2,32669,12,7,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,508,100,-20,0,0,28,0,16,29,0,2,32669,12,7,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,509,100,-10,0,0,29,0,17,0,0,2,32669,12,7,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,510,-100,-300,0,1,0,0,17,1,0,2,32669,12,7,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,511,-100,-290,0,1,1,0,17,2,0,2,32669,12,8,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,512,-100,-280,0,1,2,0,17,3,0,2,32669,12,8,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,513,-100,-270,0,1,3,0,17,4,0,2,32669,12,8,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,514,-100,-260,0,1,4,0,17,5,0,2,32669,12,8,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,515,-100,-250,0,1,5,0,17,6,0,2,32669,12,9,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,516,-100,-240,0,1,6,0,17,7,0,2,32669,12,9,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,517,-100,-230,0,1,7,0,17,8,0,2,32669,12,9,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,518,-100,-220,0,1,8,0,17,9,0,2,32669,12,9,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,519,-100,-210,0,1,9,0,17,10,0,2,32669,13,0,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,520,-100,-200,0,1,10,0,17,11,0,2,32669,13,0,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,521,-100,-190,0,1,11,0,17,12,0,2,32669,13,0,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,522,-100,-180,0,1,12,0,17,13,0,2,32669,13,0,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,523,-100,-170,0,1,13,0,17,14,0,2,32669,13,1,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,524,-100,-160,0,1,14,0,17,15,0,2,32669,13,1,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,525,-100,-150,0,1,15,0,17,16,0,2,32669,13,1,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,526,-100,-140,0,1,16,0,17,17,0,2,32669,13,1,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,527,-100,-130,0,1,17,0,17,18,0,2,32669,13,2,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,528,-100,-120,0,1,18,0,17,19,0,2,32669,13,2,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,529,-100,-110,0,1,19,0,17,20,0,2,32669,13,2,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,530,-100,-100,0,1,20,0,17,21,0,2,32669,13,2,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,531,-100,-90,0,1,21,0,17,22,0,2,32669,13,3,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,532,-100,-80,0,1,22,0,17,23,0,2,32669,13,3,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,533,-100,-70,0,1,23,0,17,24,0,2,32669,13,3,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,534,-100,-60,0,1,24,0,17,25,0,2,32669,13,3,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,535,-100,-50,0,1,25,0,17,26,0,2,32669,13,4,0,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,536,-100,-40,0,1,26,0,17,27,0,2,32669,13,4,1,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,537,-100,-30,0,1,27,0,17,28,0,2,32669,13,4,2,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,538,-100,-20,0,1,28,0,17,29,0,2,32669,13,4,3,ON -8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,539,-100,-10,0,1,29,0,18,0,0,2,32669,13,5,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,540,100,-300,0,0,0,0,18,1,0,2,32669,13,5,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,541,100,-290,0,0,1,0,18,2,0,2,32669,13,5,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,542,100,-280,0,0,2,0,18,3,0,2,32669,13,5,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,543,100,-270,0,0,3,0,18,4,0,2,32669,13,6,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,544,100,-260,0,0,4,0,18,5,0,2,32669,13,6,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,545,100,-250,0,0,5,0,18,6,0,2,32669,13,6,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,546,100,-240,0,0,6,0,18,7,0,2,32669,13,6,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,547,100,-230,0,0,7,0,18,8,0,2,32669,13,7,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,548,100,-220,0,0,8,0,18,9,0,2,32669,13,7,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,549,100,-210,0,0,9,0,18,10,0,2,32669,13,7,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,550,100,-200,0,0,10,0,18,11,0,2,32669,13,7,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,551,100,-190,0,0,11,0,18,12,0,2,32669,13,8,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,552,100,-180,0,0,12,0,18,13,0,2,32669,13,8,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,553,100,-170,0,0,13,0,18,14,0,2,32669,13,8,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,554,100,-160,0,0,14,0,18,15,0,2,32669,13,8,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,555,100,-150,0,0,15,0,18,16,0,2,32669,13,9,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,556,100,-140,0,0,16,0,18,17,0,2,32669,13,9,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,557,100,-130,0,0,17,0,18,18,0,2,32669,13,9,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,558,100,-120,0,0,18,0,18,19,0,2,32669,13,9,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,559,100,-110,0,0,19,0,18,20,0,2,32669,14,0,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,560,100,-100,0,0,20,0,18,21,0,2,32669,14,0,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,561,100,-90,0,0,21,0,18,22,0,2,32669,14,0,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,562,100,-80,0,0,22,0,18,23,0,2,32669,14,0,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,563,100,-70,0,0,23,0,18,24,0,2,32669,14,1,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,564,100,-60,0,0,24,0,18,25,0,2,32669,14,1,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,565,100,-50,0,0,25,0,18,26,0,2,32669,14,1,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,566,100,-40,0,0,26,0,18,27,0,2,32669,14,1,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,567,100,-30,0,0,27,0,18,28,0,2,32669,14,2,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,568,100,-20,0,0,28,0,18,29,0,2,32669,14,2,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,569,100,-10,0,0,29,0,19,0,0,2,32669,14,2,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,570,-100,-300,0,1,0,0,19,1,0,2,32669,14,2,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,571,-100,-290,0,1,1,0,19,2,0,2,32669,14,3,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,572,-100,-280,0,1,2,0,19,3,0,2,32669,14,3,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,573,-100,-270,0,1,3,0,19,4,0,2,32669,14,3,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,574,-100,-260,0,1,4,0,19,5,0,2,32669,14,3,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,575,-100,-250,0,1,5,0,19,6,0,2,32669,14,4,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,576,-100,-240,0,1,6,0,19,7,0,2,32669,14,4,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,577,-100,-230,0,1,7,0,19,8,0,2,32669,14,4,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,578,-100,-220,0,1,8,0,19,9,0,2,32669,14,4,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,579,-100,-210,0,1,9,0,19,10,0,2,32669,14,5,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,580,-100,-200,0,1,10,0,19,11,0,2,32669,14,5,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,581,-100,-190,0,1,11,0,19,12,0,2,32669,14,5,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,582,-100,-180,0,1,12,0,19,13,0,2,32669,14,5,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,583,-100,-170,0,1,13,0,19,14,0,2,32669,14,6,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,584,-100,-160,0,1,14,0,19,15,0,2,32669,14,6,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,585,-100,-150,0,1,15,0,19,16,0,2,32669,14,6,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,586,-100,-140,0,1,16,0,19,17,0,2,32669,14,6,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,587,-100,-130,0,1,17,0,19,18,0,2,32669,14,7,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,588,-100,-120,0,1,18,0,19,19,0,2,32669,14,7,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,589,-100,-110,0,1,19,0,19,20,0,2,32669,14,7,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,590,-100,-100,0,1,20,0,19,21,0,2,32669,14,7,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,591,-100,-90,0,1,21,0,19,22,0,2,32669,14,8,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,592,-100,-80,0,1,22,0,19,23,0,2,32669,14,8,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,593,-100,-70,0,1,23,0,19,24,0,2,32669,14,8,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,594,-100,-60,0,1,24,0,19,25,0,2,32669,14,8,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,595,-100,-50,0,1,25,0,19,26,0,2,32669,14,9,0,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,596,-100,-40,0,1,26,0,19,27,0,2,32669,14,9,1,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,597,-100,-30,0,1,27,0,19,28,0,2,32669,14,9,2,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,598,-100,-20,0,1,28,0,19,29,0,2,32669,14,9,3,ON -9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,599,-100,-10,0,1,29,1,0,0,0,2,32669,15,0,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,600,100,-300,0,0,0,1,0,1,0,2,32669,15,0,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,601,100,-290,0,0,1,1,0,2,0,2,32669,15,0,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,602,100,-280,0,0,2,1,0,3,0,2,32669,15,0,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,603,100,-270,0,0,3,1,0,4,0,2,32669,15,1,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,604,100,-260,0,0,4,1,0,5,0,2,32669,15,1,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,605,100,-250,0,0,5,1,0,6,0,2,32669,15,1,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,606,100,-240,0,0,6,1,0,7,0,2,32669,15,1,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,607,100,-230,0,0,7,1,0,8,0,2,32669,15,2,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,608,100,-220,0,0,8,1,0,9,0,2,32669,15,2,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,609,100,-210,0,0,9,1,0,10,0,2,32669,15,2,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,610,100,-200,0,0,10,1,0,11,0,2,32669,15,2,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,611,100,-190,0,0,11,1,0,12,0,2,32669,15,3,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,612,100,-180,0,0,12,1,0,13,0,2,32669,15,3,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,613,100,-170,0,0,13,1,0,14,0,2,32669,15,3,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,614,100,-160,0,0,14,1,0,15,0,2,32669,15,3,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,615,100,-150,0,0,15,1,0,16,0,2,32669,15,4,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,616,100,-140,0,0,16,1,0,17,0,2,32669,15,4,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,617,100,-130,0,0,17,1,0,18,0,2,32669,15,4,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,618,100,-120,0,0,18,1,0,19,0,2,32669,15,4,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,619,100,-110,0,0,19,1,0,20,0,2,32669,15,5,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,620,100,-100,0,0,20,1,0,21,0,2,32669,15,5,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,621,100,-90,0,0,21,1,0,22,0,2,32669,15,5,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,622,100,-80,0,0,22,1,0,23,0,2,32669,15,5,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,623,100,-70,0,0,23,1,0,24,0,2,32669,15,6,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,624,100,-60,0,0,24,1,0,25,0,2,32669,15,6,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,625,100,-50,0,0,25,1,0,26,0,2,32669,15,6,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,626,100,-40,0,0,26,1,0,27,0,2,32669,15,6,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,627,100,-30,0,0,27,1,0,28,0,2,32669,15,7,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,628,100,-20,0,0,28,1,0,29,0,2,32669,15,7,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,629,100,-10,0,0,29,1,1,0,0,2,32669,15,7,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,630,-100,-300,0,1,0,1,1,1,0,2,32669,15,7,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,631,-100,-290,0,1,1,1,1,2,0,2,32669,15,8,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,632,-100,-280,0,1,2,1,1,3,0,2,32669,15,8,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,633,-100,-270,0,1,3,1,1,4,0,2,32669,15,8,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,634,-100,-260,0,1,4,1,1,5,0,2,32669,15,8,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,635,-100,-250,0,1,5,1,1,6,0,2,32669,15,9,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,636,-100,-240,0,1,6,1,1,7,0,2,32669,15,9,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,637,-100,-230,0,1,7,1,1,8,0,2,32669,15,9,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,638,-100,-220,0,1,8,1,1,9,0,2,32669,15,9,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,639,-100,-210,0,1,9,1,1,10,0,2,32669,16,0,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,640,-100,-200,0,1,10,1,1,11,0,2,32669,16,0,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,641,-100,-190,0,1,11,1,1,12,0,2,32669,16,0,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,642,-100,-180,0,1,12,1,1,13,0,2,32669,16,0,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,643,-100,-170,0,1,13,1,1,14,0,2,32669,16,1,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,644,-100,-160,0,1,14,1,1,15,0,2,32669,16,1,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,645,-100,-150,0,1,15,1,1,16,0,2,32669,16,1,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,646,-100,-140,0,1,16,1,1,17,0,2,32669,16,1,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,647,-100,-130,0,1,17,1,1,18,0,2,32669,16,2,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,648,-100,-120,0,1,18,1,1,19,0,2,32669,16,2,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,649,-100,-110,0,1,19,1,1,20,0,2,32669,16,2,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,650,-100,-100,0,1,20,1,1,21,0,2,32669,16,2,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,651,-100,-90,0,1,21,1,1,22,0,2,32669,16,3,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,652,-100,-80,0,1,22,1,1,23,0,2,32669,16,3,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,653,-100,-70,0,1,23,1,1,24,0,2,32669,16,3,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,654,-100,-60,0,1,24,1,1,25,0,2,32669,16,3,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,655,-100,-50,0,1,25,1,1,26,0,2,32669,16,4,0,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,656,-100,-40,0,1,26,1,1,27,0,2,32669,16,4,1,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,657,-100,-30,0,1,27,1,1,28,0,2,32669,16,4,2,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,658,-100,-20,0,1,28,1,1,29,0,2,32669,16,4,3,ON -10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,659,-100,-10,0,1,29,1,2,0,0,2,32669,16,5,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,660,100,-300,0,0,0,1,2,1,0,2,32669,16,5,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,661,100,-290,0,0,1,1,2,2,0,2,32669,16,5,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,662,100,-280,0,0,2,1,2,3,0,2,32669,16,5,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,663,100,-270,0,0,3,1,2,4,0,2,32669,16,6,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,664,100,-260,0,0,4,1,2,5,0,2,32669,16,6,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,665,100,-250,0,0,5,1,2,6,0,2,32669,16,6,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,666,100,-240,0,0,6,1,2,7,0,2,32669,16,6,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,667,100,-230,0,0,7,1,2,8,0,2,32669,16,7,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,668,100,-220,0,0,8,1,2,9,0,2,32669,16,7,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,669,100,-210,0,0,9,1,2,10,0,2,32669,16,7,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,670,100,-200,0,0,10,1,2,11,0,2,32669,16,7,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,671,100,-190,0,0,11,1,2,12,0,2,32669,16,8,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,672,100,-180,0,0,12,1,2,13,0,2,32669,16,8,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,673,100,-170,0,0,13,1,2,14,0,2,32669,16,8,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,674,100,-160,0,0,14,1,2,15,0,2,32669,16,8,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,675,100,-150,0,0,15,1,2,16,0,2,32669,16,9,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,676,100,-140,0,0,16,1,2,17,0,2,32669,16,9,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,677,100,-130,0,0,17,1,2,18,0,2,32669,16,9,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,678,100,-120,0,0,18,1,2,19,0,2,32669,16,9,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,679,100,-110,0,0,19,1,2,20,0,2,32669,17,0,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,680,100,-100,0,0,20,1,2,21,0,2,32669,17,0,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,681,100,-90,0,0,21,1,2,22,0,2,32669,17,0,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,682,100,-80,0,0,22,1,2,23,0,2,32669,17,0,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,683,100,-70,0,0,23,1,2,24,0,2,32669,17,1,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,684,100,-60,0,0,24,1,2,25,0,2,32669,17,1,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,685,100,-50,0,0,25,1,2,26,0,2,32669,17,1,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,686,100,-40,0,0,26,1,2,27,0,2,32669,17,1,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,687,100,-30,0,0,27,1,2,28,0,2,32669,17,2,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,688,100,-20,0,0,28,1,2,29,0,2,32669,17,2,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,689,100,-10,0,0,29,1,3,0,0,2,32669,17,2,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,690,-100,-300,0,1,0,1,3,1,0,2,32669,17,2,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,691,-100,-290,0,1,1,1,3,2,0,2,32669,17,3,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,692,-100,-280,0,1,2,1,3,3,0,2,32669,17,3,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,693,-100,-270,0,1,3,1,3,4,0,2,32669,17,3,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,694,-100,-260,0,1,4,1,3,5,0,2,32669,17,3,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,695,-100,-250,0,1,5,1,3,6,0,2,32669,17,4,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,696,-100,-240,0,1,6,1,3,7,0,2,32669,17,4,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,697,-100,-230,0,1,7,1,3,8,0,2,32669,17,4,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,698,-100,-220,0,1,8,1,3,9,0,2,32669,17,4,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,699,-100,-210,0,1,9,1,3,10,0,2,32669,17,5,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,700,-100,-200,0,1,10,1,3,11,0,2,32669,17,5,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,701,-100,-190,0,1,11,1,3,12,0,2,32669,17,5,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,702,-100,-180,0,1,12,1,3,13,0,2,32669,17,5,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,703,-100,-170,0,1,13,1,3,14,0,2,32669,17,6,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,704,-100,-160,0,1,14,1,3,15,0,2,32669,17,6,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,705,-100,-150,0,1,15,1,3,16,0,2,32669,17,6,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,706,-100,-140,0,1,16,1,3,17,0,2,32669,17,6,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,707,-100,-130,0,1,17,1,3,18,0,2,32669,17,7,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,708,-100,-120,0,1,18,1,3,19,0,2,32669,17,7,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,709,-100,-110,0,1,19,1,3,20,0,2,32669,17,7,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,710,-100,-100,0,1,20,1,3,21,0,2,32669,17,7,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,711,-100,-90,0,1,21,1,3,22,0,2,32669,17,8,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,712,-100,-80,0,1,22,1,3,23,0,2,32669,17,8,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,713,-100,-70,0,1,23,1,3,24,0,2,32669,17,8,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,714,-100,-60,0,1,24,1,3,25,0,2,32669,17,8,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,715,-100,-50,0,1,25,1,3,26,0,2,32669,17,9,0,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,716,-100,-40,0,1,26,1,3,27,0,2,32669,17,9,1,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,717,-100,-30,0,1,27,1,3,28,0,2,32669,17,9,2,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,718,-100,-20,0,1,28,1,3,29,0,2,32669,17,9,3,ON -11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,719,-100,-10,0,1,29,1,4,0,0,3,32669,18,0,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,720,100,-300,0,0,0,1,4,1,0,3,32669,18,0,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,721,100,-290,0,0,1,1,4,2,0,3,32669,18,0,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,722,100,-280,0,0,2,1,4,3,0,3,32669,18,0,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,723,100,-270,0,0,3,1,4,4,0,3,32669,18,1,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,724,100,-260,0,0,4,1,4,5,0,3,32669,18,1,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,725,100,-250,0,0,5,1,4,6,0,3,32669,18,1,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,726,100,-240,0,0,6,1,4,7,0,3,32669,18,1,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,727,100,-230,0,0,7,1,4,8,0,3,32669,18,2,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,728,100,-220,0,0,8,1,4,9,0,3,32669,18,2,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,729,100,-210,0,0,9,1,4,10,0,3,32669,18,2,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,730,100,-200,0,0,10,1,4,11,0,3,32669,18,2,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,731,100,-190,0,0,11,1,4,12,0,3,32669,18,3,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,732,100,-180,0,0,12,1,4,13,0,3,32669,18,3,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,733,100,-170,0,0,13,1,4,14,0,3,32669,18,3,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,734,100,-160,0,0,14,1,4,15,0,3,32669,18,3,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,735,100,-150,0,0,15,1,4,16,0,3,32669,18,4,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,736,100,-140,0,0,16,1,4,17,0,3,32669,18,4,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,737,100,-130,0,0,17,1,4,18,0,3,32669,18,4,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,738,100,-120,0,0,18,1,4,19,0,3,32669,18,4,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,739,100,-110,0,0,19,1,4,20,0,3,32669,18,5,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,740,100,-100,0,0,20,1,4,21,0,3,32669,18,5,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,741,100,-90,0,0,21,1,4,22,0,3,32669,18,5,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,742,100,-80,0,0,22,1,4,23,0,3,32669,18,5,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,743,100,-70,0,0,23,1,4,24,0,3,32669,18,6,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,744,100,-60,0,0,24,1,4,25,0,3,32669,18,6,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,745,100,-50,0,0,25,1,4,26,0,3,32669,18,6,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,746,100,-40,0,0,26,1,4,27,0,3,32669,18,6,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,747,100,-30,0,0,27,1,4,28,0,3,32669,18,7,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,748,100,-20,0,0,28,1,4,29,0,3,32669,18,7,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,749,100,-10,0,0,29,1,5,0,0,3,32669,18,7,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,750,-100,-300,0,1,0,1,5,1,0,3,32669,18,7,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,751,-100,-290,0,1,1,1,5,2,0,3,32669,18,8,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,752,-100,-280,0,1,2,1,5,3,0,3,32669,18,8,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,753,-100,-270,0,1,3,1,5,4,0,3,32669,18,8,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,754,-100,-260,0,1,4,1,5,5,0,3,32669,18,8,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,755,-100,-250,0,1,5,1,5,6,0,3,32669,18,9,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,756,-100,-240,0,1,6,1,5,7,0,3,32669,18,9,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,757,-100,-230,0,1,7,1,5,8,0,3,32669,18,9,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,758,-100,-220,0,1,8,1,5,9,0,3,32669,18,9,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,759,-100,-210,0,1,9,1,5,10,0,3,32669,19,0,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,760,-100,-200,0,1,10,1,5,11,0,3,32669,19,0,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,761,-100,-190,0,1,11,1,5,12,0,3,32669,19,0,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,762,-100,-180,0,1,12,1,5,13,0,3,32669,19,0,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,763,-100,-170,0,1,13,1,5,14,0,3,32669,19,1,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,764,-100,-160,0,1,14,1,5,15,0,3,32669,19,1,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,765,-100,-150,0,1,15,1,5,16,0,3,32669,19,1,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,766,-100,-140,0,1,16,1,5,17,0,3,32669,19,1,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,767,-100,-130,0,1,17,1,5,18,0,3,32669,19,2,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,768,-100,-120,0,1,18,1,5,19,0,3,32669,19,2,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,769,-100,-110,0,1,19,1,5,20,0,3,32669,19,2,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,770,-100,-100,0,1,20,1,5,21,0,3,32669,19,2,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,771,-100,-90,0,1,21,1,5,22,0,3,32669,19,3,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,772,-100,-80,0,1,22,1,5,23,0,3,32669,19,3,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,773,-100,-70,0,1,23,1,5,24,0,3,32669,19,3,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,774,-100,-60,0,1,24,1,5,25,0,3,32669,19,3,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,775,-100,-50,0,1,25,1,5,26,0,3,32669,19,4,0,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,776,-100,-40,0,1,26,1,5,27,0,3,32669,19,4,1,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,777,-100,-30,0,1,27,1,5,28,0,3,32669,19,4,2,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,778,-100,-20,0,1,28,1,5,29,0,3,32669,19,4,3,ON -12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,779,-100,-10,0,1,29,1,6,0,0,3,32669,19,5,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,780,100,-300,0,0,0,1,6,1,0,3,32669,19,5,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,781,100,-290,0,0,1,1,6,2,0,3,32669,19,5,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,782,100,-280,0,0,2,1,6,3,0,3,32669,19,5,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,783,100,-270,0,0,3,1,6,4,0,3,32669,19,6,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,784,100,-260,0,0,4,1,6,5,0,3,32669,19,6,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,785,100,-250,0,0,5,1,6,6,0,3,32669,19,6,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,786,100,-240,0,0,6,1,6,7,0,3,32669,19,6,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,787,100,-230,0,0,7,1,6,8,0,3,32669,19,7,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,788,100,-220,0,0,8,1,6,9,0,3,32669,19,7,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,789,100,-210,0,0,9,1,6,10,0,3,32669,19,7,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,790,100,-200,0,0,10,1,6,11,0,3,32669,19,7,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,791,100,-190,0,0,11,1,6,12,0,3,32669,19,8,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,792,100,-180,0,0,12,1,6,13,0,3,32669,19,8,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,793,100,-170,0,0,13,1,6,14,0,3,32669,19,8,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,794,100,-160,0,0,14,1,6,15,0,3,32669,19,8,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,795,100,-150,0,0,15,1,6,16,0,3,32669,19,9,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,796,100,-140,0,0,16,1,6,17,0,3,32669,19,9,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,797,100,-130,0,0,17,1,6,18,0,3,32669,19,9,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,798,100,-120,0,0,18,1,6,19,0,3,32669,19,9,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,799,100,-110,0,0,19,1,6,20,0,3,32669,20,0,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,800,100,-100,0,0,20,1,6,21,0,3,32669,20,0,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,801,100,-90,0,0,21,1,6,22,0,3,32669,20,0,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,802,100,-80,0,0,22,1,6,23,0,3,32669,20,0,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,803,100,-70,0,0,23,1,6,24,0,3,32669,20,1,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,804,100,-60,0,0,24,1,6,25,0,3,32669,20,1,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,805,100,-50,0,0,25,1,6,26,0,3,32669,20,1,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,806,100,-40,0,0,26,1,6,27,0,3,32669,20,1,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,807,100,-30,0,0,27,1,6,28,0,3,32669,20,2,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,808,100,-20,0,0,28,1,6,29,0,3,32669,20,2,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,809,100,-10,0,0,29,1,7,0,0,3,32669,20,2,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,810,-100,-300,0,1,0,1,7,1,0,3,32669,20,2,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,811,-100,-290,0,1,1,1,7,2,0,3,32669,20,3,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,812,-100,-280,0,1,2,1,7,3,0,3,32669,20,3,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,813,-100,-270,0,1,3,1,7,4,0,3,32669,20,3,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,814,-100,-260,0,1,4,1,7,5,0,3,32669,20,3,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,815,-100,-250,0,1,5,1,7,6,0,3,32669,20,4,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,816,-100,-240,0,1,6,1,7,7,0,3,32669,20,4,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,817,-100,-230,0,1,7,1,7,8,0,3,32669,20,4,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,818,-100,-220,0,1,8,1,7,9,0,3,32669,20,4,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,819,-100,-210,0,1,9,1,7,10,0,3,32669,20,5,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,820,-100,-200,0,1,10,1,7,11,0,3,32669,20,5,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,821,-100,-190,0,1,11,1,7,12,0,3,32669,20,5,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,822,-100,-180,0,1,12,1,7,13,0,3,32669,20,5,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,823,-100,-170,0,1,13,1,7,14,0,3,32669,20,6,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,824,-100,-160,0,1,14,1,7,15,0,3,32669,20,6,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,825,-100,-150,0,1,15,1,7,16,0,3,32669,20,6,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,826,-100,-140,0,1,16,1,7,17,0,3,32669,20,6,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,827,-100,-130,0,1,17,1,7,18,0,3,32669,20,7,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,828,-100,-120,0,1,18,1,7,19,0,3,32669,20,7,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,829,-100,-110,0,1,19,1,7,20,0,3,32669,20,7,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,830,-100,-100,0,1,20,1,7,21,0,3,32669,20,7,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,831,-100,-90,0,1,21,1,7,22,0,3,32669,20,8,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,832,-100,-80,0,1,22,1,7,23,0,3,32669,20,8,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,833,-100,-70,0,1,23,1,7,24,0,3,32669,20,8,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,834,-100,-60,0,1,24,1,7,25,0,3,32669,20,8,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,835,-100,-50,0,1,25,1,7,26,0,3,32669,20,9,0,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,836,-100,-40,0,1,26,1,7,27,0,3,32669,20,9,1,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,837,-100,-30,0,1,27,1,7,28,0,3,32669,20,9,2,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,838,-100,-20,0,1,28,1,7,29,0,3,32669,20,9,3,ON -13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,839,-100,-10,0,1,29,1,8,0,0,3,32669,21,0,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,840,100,-300,0,0,0,1,8,1,0,3,32669,21,0,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,841,100,-290,0,0,1,1,8,2,0,3,32669,21,0,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,842,100,-280,0,0,2,1,8,3,0,3,32669,21,0,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,843,100,-270,0,0,3,1,8,4,0,3,32669,21,1,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,844,100,-260,0,0,4,1,8,5,0,3,32669,21,1,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,845,100,-250,0,0,5,1,8,6,0,3,32669,21,1,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,846,100,-240,0,0,6,1,8,7,0,3,32669,21,1,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,847,100,-230,0,0,7,1,8,8,0,3,32669,21,2,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,848,100,-220,0,0,8,1,8,9,0,3,32669,21,2,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,849,100,-210,0,0,9,1,8,10,0,3,32669,21,2,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,850,100,-200,0,0,10,1,8,11,0,3,32669,21,2,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,851,100,-190,0,0,11,1,8,12,0,3,32669,21,3,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,852,100,-180,0,0,12,1,8,13,0,3,32669,21,3,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,853,100,-170,0,0,13,1,8,14,0,3,32669,21,3,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,854,100,-160,0,0,14,1,8,15,0,3,32669,21,3,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,855,100,-150,0,0,15,1,8,16,0,3,32669,21,4,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,856,100,-140,0,0,16,1,8,17,0,3,32669,21,4,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,857,100,-130,0,0,17,1,8,18,0,3,32669,21,4,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,858,100,-120,0,0,18,1,8,19,0,3,32669,21,4,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,859,100,-110,0,0,19,1,8,20,0,3,32669,21,5,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,860,100,-100,0,0,20,1,8,21,0,3,32669,21,5,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,861,100,-90,0,0,21,1,8,22,0,3,32669,21,5,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,862,100,-80,0,0,22,1,8,23,0,3,32669,21,5,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,863,100,-70,0,0,23,1,8,24,0,3,32669,21,6,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,864,100,-60,0,0,24,1,8,25,0,3,32669,21,6,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,865,100,-50,0,0,25,1,8,26,0,3,32669,21,6,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,866,100,-40,0,0,26,1,8,27,0,3,32669,21,6,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,867,100,-30,0,0,27,1,8,28,0,3,32669,21,7,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,868,100,-20,0,0,28,1,8,29,0,3,32669,21,7,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,869,100,-10,0,0,29,1,9,0,0,3,32669,21,7,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,870,-100,-300,0,1,0,1,9,1,0,3,32669,21,7,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,871,-100,-290,0,1,1,1,9,2,0,3,32669,21,8,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,872,-100,-280,0,1,2,1,9,3,0,3,32669,21,8,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,873,-100,-270,0,1,3,1,9,4,0,3,32669,21,8,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,874,-100,-260,0,1,4,1,9,5,0,3,32669,21,8,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,875,-100,-250,0,1,5,1,9,6,0,3,32669,21,9,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,876,-100,-240,0,1,6,1,9,7,0,3,32669,21,9,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,877,-100,-230,0,1,7,1,9,8,0,3,32669,21,9,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,878,-100,-220,0,1,8,1,9,9,0,3,32669,21,9,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,879,-100,-210,0,1,9,1,9,10,0,3,32669,22,0,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,880,-100,-200,0,1,10,1,9,11,0,3,32669,22,0,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,881,-100,-190,0,1,11,1,9,12,0,3,32669,22,0,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,882,-100,-180,0,1,12,1,9,13,0,3,32669,22,0,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,883,-100,-170,0,1,13,1,9,14,0,3,32669,22,1,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,884,-100,-160,0,1,14,1,9,15,0,3,32669,22,1,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,885,-100,-150,0,1,15,1,9,16,0,3,32669,22,1,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,886,-100,-140,0,1,16,1,9,17,0,3,32669,22,1,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,887,-100,-130,0,1,17,1,9,18,0,3,32669,22,2,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,888,-100,-120,0,1,18,1,9,19,0,3,32669,22,2,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,889,-100,-110,0,1,19,1,9,20,0,3,32669,22,2,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,890,-100,-100,0,1,20,1,9,21,0,3,32669,22,2,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,891,-100,-90,0,1,21,1,9,22,0,3,32669,22,3,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,892,-100,-80,0,1,22,1,9,23,0,3,32669,22,3,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,893,-100,-70,0,1,23,1,9,24,0,3,32669,22,3,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,894,-100,-60,0,1,24,1,9,25,0,3,32669,22,3,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,895,-100,-50,0,1,25,1,9,26,0,3,32669,22,4,0,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,896,-100,-40,0,1,26,1,9,27,0,3,32669,22,4,1,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,897,-100,-30,0,1,27,1,9,28,0,3,32669,22,4,2,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,898,-100,-20,0,1,28,1,9,29,0,3,32669,22,4,3,ON -14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,899,-100,-10,0,1,29,1,10,0,0,3,32669,22,5,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,900,100,-300,0,0,0,1,10,1,0,3,32669,22,5,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,901,100,-290,0,0,1,1,10,2,0,3,32669,22,5,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,902,100,-280,0,0,2,1,10,3,0,3,32669,22,5,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,903,100,-270,0,0,3,1,10,4,0,3,32669,22,6,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,904,100,-260,0,0,4,1,10,5,0,3,32669,22,6,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,905,100,-250,0,0,5,1,10,6,0,3,32669,22,6,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,906,100,-240,0,0,6,1,10,7,0,3,32669,22,6,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,907,100,-230,0,0,7,1,10,8,0,3,32669,22,7,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,908,100,-220,0,0,8,1,10,9,0,3,32669,22,7,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,909,100,-210,0,0,9,1,10,10,0,3,32669,22,7,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,910,100,-200,0,0,10,1,10,11,0,3,32669,22,7,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,911,100,-190,0,0,11,1,10,12,0,3,32669,22,8,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,912,100,-180,0,0,12,1,10,13,0,3,32669,22,8,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,913,100,-170,0,0,13,1,10,14,0,3,32669,22,8,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,914,100,-160,0,0,14,1,10,15,0,3,32669,22,8,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,915,100,-150,0,0,15,1,10,16,0,3,32669,22,9,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,916,100,-140,0,0,16,1,10,17,0,3,32669,22,9,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,917,100,-130,0,0,17,1,10,18,0,3,32669,22,9,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,918,100,-120,0,0,18,1,10,19,0,3,32669,22,9,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,919,100,-110,0,0,19,1,10,20,0,3,32669,23,0,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,920,100,-100,0,0,20,1,10,21,0,3,32669,23,0,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,921,100,-90,0,0,21,1,10,22,0,3,32669,23,0,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,922,100,-80,0,0,22,1,10,23,0,3,32669,23,0,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,923,100,-70,0,0,23,1,10,24,0,3,32669,23,1,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,924,100,-60,0,0,24,1,10,25,0,3,32669,23,1,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,925,100,-50,0,0,25,1,10,26,0,3,32669,23,1,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,926,100,-40,0,0,26,1,10,27,0,3,32669,23,1,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,927,100,-30,0,0,27,1,10,28,0,3,32669,23,2,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,928,100,-20,0,0,28,1,10,29,0,3,32669,23,2,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,929,100,-10,0,0,29,1,11,0,0,3,32669,23,2,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,930,-100,-300,0,1,0,1,11,1,0,3,32669,23,2,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,931,-100,-290,0,1,1,1,11,2,0,3,32669,23,3,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,932,-100,-280,0,1,2,1,11,3,0,3,32669,23,3,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,933,-100,-270,0,1,3,1,11,4,0,3,32669,23,3,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,934,-100,-260,0,1,4,1,11,5,0,3,32669,23,3,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,935,-100,-250,0,1,5,1,11,6,0,3,32669,23,4,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,936,-100,-240,0,1,6,1,11,7,0,3,32669,23,4,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,937,-100,-230,0,1,7,1,11,8,0,3,32669,23,4,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,938,-100,-220,0,1,8,1,11,9,0,3,32669,23,4,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,939,-100,-210,0,1,9,1,11,10,0,3,32669,23,5,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,940,-100,-200,0,1,10,1,11,11,0,3,32669,23,5,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,941,-100,-190,0,1,11,1,11,12,0,3,32669,23,5,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,942,-100,-180,0,1,12,1,11,13,0,3,32669,23,5,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,943,-100,-170,0,1,13,1,11,14,0,3,32669,23,6,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,944,-100,-160,0,1,14,1,11,15,0,3,32669,23,6,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,945,-100,-150,0,1,15,1,11,16,0,3,32669,23,6,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,946,-100,-140,0,1,16,1,11,17,0,3,32669,23,6,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,947,-100,-130,0,1,17,1,11,18,0,3,32669,23,7,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,948,-100,-120,0,1,18,1,11,19,0,3,32669,23,7,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,949,-100,-110,0,1,19,1,11,20,0,3,32669,23,7,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,950,-100,-100,0,1,20,1,11,21,0,3,32669,23,7,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,951,-100,-90,0,1,21,1,11,22,0,3,32669,23,8,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,952,-100,-80,0,1,22,1,11,23,0,3,32669,23,8,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,953,-100,-70,0,1,23,1,11,24,0,3,32669,23,8,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,954,-100,-60,0,1,24,1,11,25,0,3,32669,23,8,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,955,-100,-50,0,1,25,1,11,26,0,3,32669,23,9,0,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,956,-100,-40,0,1,26,1,11,27,0,3,32669,23,9,1,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,957,-100,-30,0,1,27,1,11,28,0,3,32669,23,9,2,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,958,-100,-20,0,1,28,1,11,29,0,3,32669,23,9,3,ON -15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,959,-100,-10,0,1,29,1,12,0,0,4,32669,24,0,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,960,100,-300,0,0,0,1,12,1,0,4,32669,24,0,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,961,100,-290,0,0,1,1,12,2,0,4,32669,24,0,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,962,100,-280,0,0,2,1,12,3,0,4,32669,24,0,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,963,100,-270,0,0,3,1,12,4,0,4,32669,24,1,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,964,100,-260,0,0,4,1,12,5,0,4,32669,24,1,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,965,100,-250,0,0,5,1,12,6,0,4,32669,24,1,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,966,100,-240,0,0,6,1,12,7,0,4,32669,24,1,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,967,100,-230,0,0,7,1,12,8,0,4,32669,24,2,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,968,100,-220,0,0,8,1,12,9,0,4,32669,24,2,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,969,100,-210,0,0,9,1,12,10,0,4,32669,24,2,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,970,100,-200,0,0,10,1,12,11,0,4,32669,24,2,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,971,100,-190,0,0,11,1,12,12,0,4,32669,24,3,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,972,100,-180,0,0,12,1,12,13,0,4,32669,24,3,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,973,100,-170,0,0,13,1,12,14,0,4,32669,24,3,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,974,100,-160,0,0,14,1,12,15,0,4,32669,24,3,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,975,100,-150,0,0,15,1,12,16,0,4,32669,24,4,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,976,100,-140,0,0,16,1,12,17,0,4,32669,24,4,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,977,100,-130,0,0,17,1,12,18,0,4,32669,24,4,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,978,100,-120,0,0,18,1,12,19,0,4,32669,24,4,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,979,100,-110,0,0,19,1,12,20,0,4,32669,24,5,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,980,100,-100,0,0,20,1,12,21,0,4,32669,24,5,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,981,100,-90,0,0,21,1,12,22,0,4,32669,24,5,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,982,100,-80,0,0,22,1,12,23,0,4,32669,24,5,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,983,100,-70,0,0,23,1,12,24,0,4,32669,24,6,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,984,100,-60,0,0,24,1,12,25,0,4,32669,24,6,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,985,100,-50,0,0,25,1,12,26,0,4,32669,24,6,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,986,100,-40,0,0,26,1,12,27,0,4,32669,24,6,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,987,100,-30,0,0,27,1,12,28,0,4,32669,24,7,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,988,100,-20,0,0,28,1,12,29,0,4,32669,24,7,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,989,100,-10,0,0,29,1,13,0,0,4,32669,24,7,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,990,-100,-300,0,1,0,1,13,1,0,4,32669,24,7,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,991,-100,-290,0,1,1,1,13,2,0,4,32669,24,8,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,992,-100,-280,0,1,2,1,13,3,0,4,32669,24,8,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,993,-100,-270,0,1,3,1,13,4,0,4,32669,24,8,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,994,-100,-260,0,1,4,1,13,5,0,4,32669,24,8,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,995,-100,-250,0,1,5,1,13,6,0,4,32669,24,9,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,996,-100,-240,0,1,6,1,13,7,0,4,32669,24,9,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,997,-100,-230,0,1,7,1,13,8,0,4,32669,24,9,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,998,-100,-220,0,1,8,1,13,9,0,4,32669,24,9,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,999,-100,-210,0,1,9,1,13,10,0,4,32669,25,0,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1000,-100,-200,0,1,10,1,13,11,0,4,32669,25,0,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1001,-100,-190,0,1,11,1,13,12,0,4,32669,25,0,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1002,-100,-180,0,1,12,1,13,13,0,4,32669,25,0,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1003,-100,-170,0,1,13,1,13,14,0,4,32669,25,1,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1004,-100,-160,0,1,14,1,13,15,0,4,32669,25,1,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1005,-100,-150,0,1,15,1,13,16,0,4,32669,25,1,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1006,-100,-140,0,1,16,1,13,17,0,4,32669,25,1,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1007,-100,-130,0,1,17,1,13,18,0,4,32669,25,2,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1008,-100,-120,0,1,18,1,13,19,0,4,32669,25,2,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1009,-100,-110,0,1,19,1,13,20,0,4,32669,25,2,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1010,-100,-100,0,1,20,1,13,21,0,4,32669,25,2,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1011,-100,-90,0,1,21,1,13,22,0,4,32669,25,3,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1012,-100,-80,0,1,22,1,13,23,0,4,32669,25,3,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1013,-100,-70,0,1,23,1,13,24,0,4,32669,25,3,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1014,-100,-60,0,1,24,1,13,25,0,4,32669,25,3,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1015,-100,-50,0,1,25,1,13,26,0,4,32669,25,4,0,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1016,-100,-40,0,1,26,1,13,27,0,4,32669,25,4,1,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1017,-100,-30,0,1,27,1,13,28,0,4,32669,25,4,2,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1018,-100,-20,0,1,28,1,13,29,0,4,32669,25,4,3,ON -16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1019,-100,-10,0,1,29,1,14,0,0,4,32669,25,5,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1020,100,-300,0,0,0,1,14,1,0,4,32669,25,5,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1021,100,-290,0,0,1,1,14,2,0,4,32669,25,5,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1022,100,-280,0,0,2,1,14,3,0,4,32669,25,5,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1023,100,-270,0,0,3,1,14,4,0,4,32669,25,6,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1024,100,-260,0,0,4,1,14,5,0,4,32669,25,6,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1025,100,-250,0,0,5,1,14,6,0,4,32669,25,6,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1026,100,-240,0,0,6,1,14,7,0,4,32669,25,6,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1027,100,-230,0,0,7,1,14,8,0,4,32669,25,7,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1028,100,-220,0,0,8,1,14,9,0,4,32669,25,7,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1029,100,-210,0,0,9,1,14,10,0,4,32669,25,7,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1030,100,-200,0,0,10,1,14,11,0,4,32669,25,7,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1031,100,-190,0,0,11,1,14,12,0,4,32669,25,8,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1032,100,-180,0,0,12,1,14,13,0,4,32669,25,8,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1033,100,-170,0,0,13,1,14,14,0,4,32669,25,8,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1034,100,-160,0,0,14,1,14,15,0,4,32669,25,8,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1035,100,-150,0,0,15,1,14,16,0,4,32669,25,9,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1036,100,-140,0,0,16,1,14,17,0,4,32669,25,9,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1037,100,-130,0,0,17,1,14,18,0,4,32669,25,9,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1038,100,-120,0,0,18,1,14,19,0,4,32669,25,9,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1039,100,-110,0,0,19,1,14,20,0,4,32669,26,0,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1040,100,-100,0,0,20,1,14,21,0,4,32669,26,0,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1041,100,-90,0,0,21,1,14,22,0,4,32669,26,0,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1042,100,-80,0,0,22,1,14,23,0,4,32669,26,0,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1043,100,-70,0,0,23,1,14,24,0,4,32669,26,1,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1044,100,-60,0,0,24,1,14,25,0,4,32669,26,1,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1045,100,-50,0,0,25,1,14,26,0,4,32669,26,1,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1046,100,-40,0,0,26,1,14,27,0,4,32669,26,1,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1047,100,-30,0,0,27,1,14,28,0,4,32669,26,2,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1048,100,-20,0,0,28,1,14,29,0,4,32669,26,2,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1049,100,-10,0,0,29,1,15,0,0,4,32669,26,2,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1050,-100,-300,0,1,0,1,15,1,0,4,32669,26,2,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1051,-100,-290,0,1,1,1,15,2,0,4,32669,26,3,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1052,-100,-280,0,1,2,1,15,3,0,4,32669,26,3,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1053,-100,-270,0,1,3,1,15,4,0,4,32669,26,3,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1054,-100,-260,0,1,4,1,15,5,0,4,32669,26,3,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1055,-100,-250,0,1,5,1,15,6,0,4,32669,26,4,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1056,-100,-240,0,1,6,1,15,7,0,4,32669,26,4,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1057,-100,-230,0,1,7,1,15,8,0,4,32669,26,4,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1058,-100,-220,0,1,8,1,15,9,0,4,32669,26,4,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1059,-100,-210,0,1,9,1,15,10,0,4,32669,26,5,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1060,-100,-200,0,1,10,1,15,11,0,4,32669,26,5,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1061,-100,-190,0,1,11,1,15,12,0,4,32669,26,5,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1062,-100,-180,0,1,12,1,15,13,0,4,32669,26,5,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1063,-100,-170,0,1,13,1,15,14,0,4,32669,26,6,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1064,-100,-160,0,1,14,1,15,15,0,4,32669,26,6,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1065,-100,-150,0,1,15,1,15,16,0,4,32669,26,6,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1066,-100,-140,0,1,16,1,15,17,0,4,32669,26,6,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1067,-100,-130,0,1,17,1,15,18,0,4,32669,26,7,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1068,-100,-120,0,1,18,1,15,19,0,4,32669,26,7,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1069,-100,-110,0,1,19,1,15,20,0,4,32669,26,7,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1070,-100,-100,0,1,20,1,15,21,0,4,32669,26,7,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1071,-100,-90,0,1,21,1,15,22,0,4,32669,26,8,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1072,-100,-80,0,1,22,1,15,23,0,4,32669,26,8,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1073,-100,-70,0,1,23,1,15,24,0,4,32669,26,8,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1074,-100,-60,0,1,24,1,15,25,0,4,32669,26,8,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1075,-100,-50,0,1,25,1,15,26,0,4,32669,26,9,0,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1076,-100,-40,0,1,26,1,15,27,0,4,32669,26,9,1,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1077,-100,-30,0,1,27,1,15,28,0,4,32669,26,9,2,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1078,-100,-20,0,1,28,1,15,29,0,4,32669,26,9,3,ON -17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1079,-100,-10,0,1,29,1,16,0,0,4,32669,27,0,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1080,100,-300,0,0,0,1,16,1,0,4,32669,27,0,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1081,100,-290,0,0,1,1,16,2,0,4,32669,27,0,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1082,100,-280,0,0,2,1,16,3,0,4,32669,27,0,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1083,100,-270,0,0,3,1,16,4,0,4,32669,27,1,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1084,100,-260,0,0,4,1,16,5,0,4,32669,27,1,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1085,100,-250,0,0,5,1,16,6,0,4,32669,27,1,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1086,100,-240,0,0,6,1,16,7,0,4,32669,27,1,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1087,100,-230,0,0,7,1,16,8,0,4,32669,27,2,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1088,100,-220,0,0,8,1,16,9,0,4,32669,27,2,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1089,100,-210,0,0,9,1,16,10,0,4,32669,27,2,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1090,100,-200,0,0,10,1,16,11,0,4,32669,27,2,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1091,100,-190,0,0,11,1,16,12,0,4,32669,27,3,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1092,100,-180,0,0,12,1,16,13,0,4,32669,27,3,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1093,100,-170,0,0,13,1,16,14,0,4,32669,27,3,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1094,100,-160,0,0,14,1,16,15,0,4,32669,27,3,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1095,100,-150,0,0,15,1,16,16,0,4,32669,27,4,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1096,100,-140,0,0,16,1,16,17,0,4,32669,27,4,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1097,100,-130,0,0,17,1,16,18,0,4,32669,27,4,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1098,100,-120,0,0,18,1,16,19,0,4,32669,27,4,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1099,100,-110,0,0,19,1,16,20,0,4,32669,27,5,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1100,100,-100,0,0,20,1,16,21,0,4,32669,27,5,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1101,100,-90,0,0,21,1,16,22,0,4,32669,27,5,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1102,100,-80,0,0,22,1,16,23,0,4,32669,27,5,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1103,100,-70,0,0,23,1,16,24,0,4,32669,27,6,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1104,100,-60,0,0,24,1,16,25,0,4,32669,27,6,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1105,100,-50,0,0,25,1,16,26,0,4,32669,27,6,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1106,100,-40,0,0,26,1,16,27,0,4,32669,27,6,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1107,100,-30,0,0,27,1,16,28,0,4,32669,27,7,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1108,100,-20,0,0,28,1,16,29,0,4,32669,27,7,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1109,100,-10,0,0,29,1,17,0,0,4,32669,27,7,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1110,-100,-300,0,1,0,1,17,1,0,4,32669,27,7,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1111,-100,-290,0,1,1,1,17,2,0,4,32669,27,8,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1112,-100,-280,0,1,2,1,17,3,0,4,32669,27,8,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1113,-100,-270,0,1,3,1,17,4,0,4,32669,27,8,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1114,-100,-260,0,1,4,1,17,5,0,4,32669,27,8,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1115,-100,-250,0,1,5,1,17,6,0,4,32669,27,9,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1116,-100,-240,0,1,6,1,17,7,0,4,32669,27,9,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1117,-100,-230,0,1,7,1,17,8,0,4,32669,27,9,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1118,-100,-220,0,1,8,1,17,9,0,4,32669,27,9,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1119,-100,-210,0,1,9,1,17,10,0,4,32669,28,0,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1120,-100,-200,0,1,10,1,17,11,0,4,32669,28,0,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1121,-100,-190,0,1,11,1,17,12,0,4,32669,28,0,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1122,-100,-180,0,1,12,1,17,13,0,4,32669,28,0,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1123,-100,-170,0,1,13,1,17,14,0,4,32669,28,1,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1124,-100,-160,0,1,14,1,17,15,0,4,32669,28,1,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1125,-100,-150,0,1,15,1,17,16,0,4,32669,28,1,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1126,-100,-140,0,1,16,1,17,17,0,4,32669,28,1,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1127,-100,-130,0,1,17,1,17,18,0,4,32669,28,2,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1128,-100,-120,0,1,18,1,17,19,0,4,32669,28,2,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1129,-100,-110,0,1,19,1,17,20,0,4,32669,28,2,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1130,-100,-100,0,1,20,1,17,21,0,4,32669,28,2,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1131,-100,-90,0,1,21,1,17,22,0,4,32669,28,3,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1132,-100,-80,0,1,22,1,17,23,0,4,32669,28,3,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1133,-100,-70,0,1,23,1,17,24,0,4,32669,28,3,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1134,-100,-60,0,1,24,1,17,25,0,4,32669,28,3,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1135,-100,-50,0,1,25,1,17,26,0,4,32669,28,4,0,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1136,-100,-40,0,1,26,1,17,27,0,4,32669,28,4,1,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1137,-100,-30,0,1,27,1,17,28,0,4,32669,28,4,2,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1138,-100,-20,0,1,28,1,17,29,0,4,32669,28,4,3,ON -18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1139,-100,-10,0,1,29,1,18,0,0,4,32669,28,5,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1140,100,-300,0,0,0,1,18,1,0,4,32669,28,5,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1141,100,-290,0,0,1,1,18,2,0,4,32669,28,5,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1142,100,-280,0,0,2,1,18,3,0,4,32669,28,5,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1143,100,-270,0,0,3,1,18,4,0,4,32669,28,6,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1144,100,-260,0,0,4,1,18,5,0,4,32669,28,6,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1145,100,-250,0,0,5,1,18,6,0,4,32669,28,6,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1146,100,-240,0,0,6,1,18,7,0,4,32669,28,6,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1147,100,-230,0,0,7,1,18,8,0,4,32669,28,7,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1148,100,-220,0,0,8,1,18,9,0,4,32669,28,7,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1149,100,-210,0,0,9,1,18,10,0,4,32669,28,7,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1150,100,-200,0,0,10,1,18,11,0,4,32669,28,7,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1151,100,-190,0,0,11,1,18,12,0,4,32669,28,8,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1152,100,-180,0,0,12,1,18,13,0,4,32669,28,8,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1153,100,-170,0,0,13,1,18,14,0,4,32669,28,8,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1154,100,-160,0,0,14,1,18,15,0,4,32669,28,8,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1155,100,-150,0,0,15,1,18,16,0,4,32669,28,9,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1156,100,-140,0,0,16,1,18,17,0,4,32669,28,9,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1157,100,-130,0,0,17,1,18,18,0,4,32669,28,9,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1158,100,-120,0,0,18,1,18,19,0,4,32669,28,9,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1159,100,-110,0,0,19,1,18,20,0,4,32669,29,0,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1160,100,-100,0,0,20,1,18,21,0,4,32669,29,0,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1161,100,-90,0,0,21,1,18,22,0,4,32669,29,0,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1162,100,-80,0,0,22,1,18,23,0,4,32669,29,0,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1163,100,-70,0,0,23,1,18,24,0,4,32669,29,1,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1164,100,-60,0,0,24,1,18,25,0,4,32669,29,1,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1165,100,-50,0,0,25,1,18,26,0,4,32669,29,1,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1166,100,-40,0,0,26,1,18,27,0,4,32669,29,1,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1167,100,-30,0,0,27,1,18,28,0,4,32669,29,2,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1168,100,-20,0,0,28,1,18,29,0,4,32669,29,2,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1169,100,-10,0,0,29,1,19,0,0,4,32669,29,2,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1170,-100,-300,0,1,0,1,19,1,0,4,32669,29,2,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1171,-100,-290,0,1,1,1,19,2,0,4,32669,29,3,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1172,-100,-280,0,1,2,1,19,3,0,4,32669,29,3,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1173,-100,-270,0,1,3,1,19,4,0,4,32669,29,3,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1174,-100,-260,0,1,4,1,19,5,0,4,32669,29,3,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1175,-100,-250,0,1,5,1,19,6,0,4,32669,29,4,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1176,-100,-240,0,1,6,1,19,7,0,4,32669,29,4,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1177,-100,-230,0,1,7,1,19,8,0,4,32669,29,4,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1178,-100,-220,0,1,8,1,19,9,0,4,32669,29,4,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1179,-100,-210,0,1,9,1,19,10,0,4,32669,29,5,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1180,-100,-200,0,1,10,1,19,11,0,4,32669,29,5,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1181,-100,-190,0,1,11,1,19,12,0,4,32669,29,5,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1182,-100,-180,0,1,12,1,19,13,0,4,32669,29,5,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1183,-100,-170,0,1,13,1,19,14,0,4,32669,29,6,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1184,-100,-160,0,1,14,1,19,15,0,4,32669,29,6,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1185,-100,-150,0,1,15,1,19,16,0,4,32669,29,6,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1186,-100,-140,0,1,16,1,19,17,0,4,32669,29,6,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1187,-100,-130,0,1,17,1,19,18,0,4,32669,29,7,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1188,-100,-120,0,1,18,1,19,19,0,4,32669,29,7,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1189,-100,-110,0,1,19,1,19,20,0,4,32669,29,7,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1190,-100,-100,0,1,20,1,19,21,0,4,32669,29,7,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1191,-100,-90,0,1,21,1,19,22,0,4,32669,29,8,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1192,-100,-80,0,1,22,1,19,23,0,4,32669,29,8,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1193,-100,-70,0,1,23,1,19,24,0,4,32669,29,8,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1194,-100,-60,0,1,24,1,19,25,0,4,32669,29,8,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1195,-100,-50,0,1,25,1,19,26,0,4,32669,29,9,0,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1196,-100,-40,0,1,26,1,19,27,0,4,32669,29,9,1,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1197,-100,-30,0,1,27,1,19,28,0,4,32669,29,9,2,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1198,-100,-20,0,1,28,1,19,29,0,4,32669,29,9,3,ON -19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1199,-100,-10,0,1,29,2,0,0,0,5,32669,30,0,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1200,100,-300,0,0,0,2,0,1,0,5,32669,30,0,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1201,100,-290,0,0,1,2,0,2,0,5,32669,30,0,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1202,100,-280,0,0,2,2,0,3,0,5,32669,30,0,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1203,100,-270,0,0,3,2,0,4,0,5,32669,30,1,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1204,100,-260,0,0,4,2,0,5,0,5,32669,30,1,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1205,100,-250,0,0,5,2,0,6,0,5,32669,30,1,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1206,100,-240,0,0,6,2,0,7,0,5,32669,30,1,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1207,100,-230,0,0,7,2,0,8,0,5,32669,30,2,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1208,100,-220,0,0,8,2,0,9,0,5,32669,30,2,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1209,100,-210,0,0,9,2,0,10,0,5,32669,30,2,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1210,100,-200,0,0,10,2,0,11,0,5,32669,30,2,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1211,100,-190,0,0,11,2,0,12,0,5,32669,30,3,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1212,100,-180,0,0,12,2,0,13,0,5,32669,30,3,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1213,100,-170,0,0,13,2,0,14,0,5,32669,30,3,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1214,100,-160,0,0,14,2,0,15,0,5,32669,30,3,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1215,100,-150,0,0,15,2,0,16,0,5,32669,30,4,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1216,100,-140,0,0,16,2,0,17,0,5,32669,30,4,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1217,100,-130,0,0,17,2,0,18,0,5,32669,30,4,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1218,100,-120,0,0,18,2,0,19,0,5,32669,30,4,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1219,100,-110,0,0,19,2,0,20,0,5,32669,30,5,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1220,100,-100,0,0,20,2,0,21,0,5,32669,30,5,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1221,100,-90,0,0,21,2,0,22,0,5,32669,30,5,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1222,100,-80,0,0,22,2,0,23,0,5,32669,30,5,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1223,100,-70,0,0,23,2,0,24,0,5,32669,30,6,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1224,100,-60,0,0,24,2,0,25,0,5,32669,30,6,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1225,100,-50,0,0,25,2,0,26,0,5,32669,30,6,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1226,100,-40,0,0,26,2,0,27,0,5,32669,30,6,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1227,100,-30,0,0,27,2,0,28,0,5,32669,30,7,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1228,100,-20,0,0,28,2,0,29,0,5,32669,30,7,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1229,100,-10,0,0,29,2,1,0,0,5,32669,30,7,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1230,-100,-300,0,1,0,2,1,1,0,5,32669,30,7,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1231,-100,-290,0,1,1,2,1,2,0,5,32669,30,8,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1232,-100,-280,0,1,2,2,1,3,0,5,32669,30,8,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1233,-100,-270,0,1,3,2,1,4,0,5,32669,30,8,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1234,-100,-260,0,1,4,2,1,5,0,5,32669,30,8,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1235,-100,-250,0,1,5,2,1,6,0,5,32669,30,9,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1236,-100,-240,0,1,6,2,1,7,0,5,32669,30,9,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1237,-100,-230,0,1,7,2,1,8,0,5,32669,30,9,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1238,-100,-220,0,1,8,2,1,9,0,5,32669,30,9,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1239,-100,-210,0,1,9,2,1,10,0,5,32669,31,0,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1240,-100,-200,0,1,10,2,1,11,0,5,32669,31,0,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1241,-100,-190,0,1,11,2,1,12,0,5,32669,31,0,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1242,-100,-180,0,1,12,2,1,13,0,5,32669,31,0,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1243,-100,-170,0,1,13,2,1,14,0,5,32669,31,1,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1244,-100,-160,0,1,14,2,1,15,0,5,32669,31,1,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1245,-100,-150,0,1,15,2,1,16,0,5,32669,31,1,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1246,-100,-140,0,1,16,2,1,17,0,5,32669,31,1,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1247,-100,-130,0,1,17,2,1,18,0,5,32669,31,2,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1248,-100,-120,0,1,18,2,1,19,0,5,32669,31,2,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1249,-100,-110,0,1,19,2,1,20,0,5,32669,31,2,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1250,-100,-100,0,1,20,2,1,21,0,5,32669,31,2,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1251,-100,-90,0,1,21,2,1,22,0,5,32669,31,3,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1252,-100,-80,0,1,22,2,1,23,0,5,32669,31,3,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1253,-100,-70,0,1,23,2,1,24,0,5,32669,31,3,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1254,-100,-60,0,1,24,2,1,25,0,5,32669,31,3,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1255,-100,-50,0,1,25,2,1,26,0,5,32669,31,4,0,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1256,-100,-40,0,1,26,2,1,27,0,5,32669,31,4,1,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1257,-100,-30,0,1,27,2,1,28,0,5,32669,31,4,2,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1258,-100,-20,0,1,28,2,1,29,0,5,32669,31,4,3,ON -20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1259,-100,-10,0,1,29,2,2,0,0,5,32669,31,5,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1260,100,-300,0,0,0,2,2,1,0,5,32669,31,5,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1261,100,-290,0,0,1,2,2,2,0,5,32669,31,5,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1262,100,-280,0,0,2,2,2,3,0,5,32669,31,5,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1263,100,-270,0,0,3,2,2,4,0,5,32669,31,6,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1264,100,-260,0,0,4,2,2,5,0,5,32669,31,6,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1265,100,-250,0,0,5,2,2,6,0,5,32669,31,6,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1266,100,-240,0,0,6,2,2,7,0,5,32669,31,6,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1267,100,-230,0,0,7,2,2,8,0,5,32669,31,7,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1268,100,-220,0,0,8,2,2,9,0,5,32669,31,7,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1269,100,-210,0,0,9,2,2,10,0,5,32669,31,7,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1270,100,-200,0,0,10,2,2,11,0,5,32669,31,7,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1271,100,-190,0,0,11,2,2,12,0,5,32669,31,8,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1272,100,-180,0,0,12,2,2,13,0,5,32669,31,8,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1273,100,-170,0,0,13,2,2,14,0,5,32669,31,8,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1274,100,-160,0,0,14,2,2,15,0,5,32669,31,8,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1275,100,-150,0,0,15,2,2,16,0,5,32669,31,9,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1276,100,-140,0,0,16,2,2,17,0,5,32669,31,9,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1277,100,-130,0,0,17,2,2,18,0,5,32669,31,9,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1278,100,-120,0,0,18,2,2,19,0,5,32669,31,9,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1279,100,-110,0,0,19,2,2,20,0,5,32669,32,0,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1280,100,-100,0,0,20,2,2,21,0,5,32669,32,0,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1281,100,-90,0,0,21,2,2,22,0,5,32669,32,0,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1282,100,-80,0,0,22,2,2,23,0,5,32669,32,0,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1283,100,-70,0,0,23,2,2,24,0,5,32669,32,1,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1284,100,-60,0,0,24,2,2,25,0,5,32669,32,1,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1285,100,-50,0,0,25,2,2,26,0,5,32669,32,1,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1286,100,-40,0,0,26,2,2,27,0,5,32669,32,1,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1287,100,-30,0,0,27,2,2,28,0,5,32669,32,2,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1288,100,-20,0,0,28,2,2,29,0,5,32669,32,2,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1289,100,-10,0,0,29,2,3,0,0,5,32669,32,2,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1290,-100,-300,0,1,0,2,3,1,0,5,32669,32,2,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1291,-100,-290,0,1,1,2,3,2,0,5,32669,32,3,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1292,-100,-280,0,1,2,2,3,3,0,5,32669,32,3,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1293,-100,-270,0,1,3,2,3,4,0,5,32669,32,3,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1294,-100,-260,0,1,4,2,3,5,0,5,32669,32,3,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1295,-100,-250,0,1,5,2,3,6,0,5,32669,32,4,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1296,-100,-240,0,1,6,2,3,7,0,5,32669,32,4,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1297,-100,-230,0,1,7,2,3,8,0,5,32669,32,4,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1298,-100,-220,0,1,8,2,3,9,0,5,32669,32,4,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1299,-100,-210,0,1,9,2,3,10,0,5,32669,32,5,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1300,-100,-200,0,1,10,2,3,11,0,5,32669,32,5,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1301,-100,-190,0,1,11,2,3,12,0,5,32669,32,5,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1302,-100,-180,0,1,12,2,3,13,0,5,32669,32,5,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1303,-100,-170,0,1,13,2,3,14,0,5,32669,32,6,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1304,-100,-160,0,1,14,2,3,15,0,5,32669,32,6,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1305,-100,-150,0,1,15,2,3,16,0,5,32669,32,6,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1306,-100,-140,0,1,16,2,3,17,0,5,32669,32,6,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1307,-100,-130,0,1,17,2,3,18,0,5,32669,32,7,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1308,-100,-120,0,1,18,2,3,19,0,5,32669,32,7,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1309,-100,-110,0,1,19,2,3,20,0,5,32669,32,7,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1310,-100,-100,0,1,20,2,3,21,0,5,32669,32,7,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1311,-100,-90,0,1,21,2,3,22,0,5,32669,32,8,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1312,-100,-80,0,1,22,2,3,23,0,5,32669,32,8,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1313,-100,-70,0,1,23,2,3,24,0,5,32669,32,8,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1314,-100,-60,0,1,24,2,3,25,0,5,32669,32,8,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1315,-100,-50,0,1,25,2,3,26,0,5,32669,32,9,0,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1316,-100,-40,0,1,26,2,3,27,0,5,32669,32,9,1,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1317,-100,-30,0,1,27,2,3,28,0,5,32669,32,9,2,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1318,-100,-20,0,1,28,2,3,29,0,5,32669,32,9,3,ON -21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1319,-100,-10,0,1,29,2,4,0,0,5,32669,33,0,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1320,100,-300,0,0,0,2,4,1,0,5,32669,33,0,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1321,100,-290,0,0,1,2,4,2,0,5,32669,33,0,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1322,100,-280,0,0,2,2,4,3,0,5,32669,33,0,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1323,100,-270,0,0,3,2,4,4,0,5,32669,33,1,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1324,100,-260,0,0,4,2,4,5,0,5,32669,33,1,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1325,100,-250,0,0,5,2,4,6,0,5,32669,33,1,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1326,100,-240,0,0,6,2,4,7,0,5,32669,33,1,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1327,100,-230,0,0,7,2,4,8,0,5,32669,33,2,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1328,100,-220,0,0,8,2,4,9,0,5,32669,33,2,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1329,100,-210,0,0,9,2,4,10,0,5,32669,33,2,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1330,100,-200,0,0,10,2,4,11,0,5,32669,33,2,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1331,100,-190,0,0,11,2,4,12,0,5,32669,33,3,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1332,100,-180,0,0,12,2,4,13,0,5,32669,33,3,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1333,100,-170,0,0,13,2,4,14,0,5,32669,33,3,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1334,100,-160,0,0,14,2,4,15,0,5,32669,33,3,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1335,100,-150,0,0,15,2,4,16,0,5,32669,33,4,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1336,100,-140,0,0,16,2,4,17,0,5,32669,33,4,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1337,100,-130,0,0,17,2,4,18,0,5,32669,33,4,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1338,100,-120,0,0,18,2,4,19,0,5,32669,33,4,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1339,100,-110,0,0,19,2,4,20,0,5,32669,33,5,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1340,100,-100,0,0,20,2,4,21,0,5,32669,33,5,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1341,100,-90,0,0,21,2,4,22,0,5,32669,33,5,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1342,100,-80,0,0,22,2,4,23,0,5,32669,33,5,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1343,100,-70,0,0,23,2,4,24,0,5,32669,33,6,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1344,100,-60,0,0,24,2,4,25,0,5,32669,33,6,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1345,100,-50,0,0,25,2,4,26,0,5,32669,33,6,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1346,100,-40,0,0,26,2,4,27,0,5,32669,33,6,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1347,100,-30,0,0,27,2,4,28,0,5,32669,33,7,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1348,100,-20,0,0,28,2,4,29,0,5,32669,33,7,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1349,100,-10,0,0,29,2,5,0,0,5,32669,33,7,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1350,-100,-300,0,1,0,2,5,1,0,5,32669,33,7,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1351,-100,-290,0,1,1,2,5,2,0,5,32669,33,8,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1352,-100,-280,0,1,2,2,5,3,0,5,32669,33,8,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1353,-100,-270,0,1,3,2,5,4,0,5,32669,33,8,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1354,-100,-260,0,1,4,2,5,5,0,5,32669,33,8,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1355,-100,-250,0,1,5,2,5,6,0,5,32669,33,9,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1356,-100,-240,0,1,6,2,5,7,0,5,32669,33,9,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1357,-100,-230,0,1,7,2,5,8,0,5,32669,33,9,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1358,-100,-220,0,1,8,2,5,9,0,5,32669,33,9,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1359,-100,-210,0,1,9,2,5,10,0,5,32669,34,0,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1360,-100,-200,0,1,10,2,5,11,0,5,32669,34,0,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1361,-100,-190,0,1,11,2,5,12,0,5,32669,34,0,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1362,-100,-180,0,1,12,2,5,13,0,5,32669,34,0,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1363,-100,-170,0,1,13,2,5,14,0,5,32669,34,1,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1364,-100,-160,0,1,14,2,5,15,0,5,32669,34,1,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1365,-100,-150,0,1,15,2,5,16,0,5,32669,34,1,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1366,-100,-140,0,1,16,2,5,17,0,5,32669,34,1,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1367,-100,-130,0,1,17,2,5,18,0,5,32669,34,2,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1368,-100,-120,0,1,18,2,5,19,0,5,32669,34,2,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1369,-100,-110,0,1,19,2,5,20,0,5,32669,34,2,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1370,-100,-100,0,1,20,2,5,21,0,5,32669,34,2,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1371,-100,-90,0,1,21,2,5,22,0,5,32669,34,3,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1372,-100,-80,0,1,22,2,5,23,0,5,32669,34,3,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1373,-100,-70,0,1,23,2,5,24,0,5,32669,34,3,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1374,-100,-60,0,1,24,2,5,25,0,5,32669,34,3,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1375,-100,-50,0,1,25,2,5,26,0,5,32669,34,4,0,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1376,-100,-40,0,1,26,2,5,27,0,5,32669,34,4,1,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1377,-100,-30,0,1,27,2,5,28,0,5,32669,34,4,2,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1378,-100,-20,0,1,28,2,5,29,0,5,32669,34,4,3,ON -22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1379,-100,-10,0,1,29,2,6,0,0,5,32669,34,5,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1380,100,-300,0,0,0,2,6,1,0,5,32669,34,5,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1381,100,-290,0,0,1,2,6,2,0,5,32669,34,5,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1382,100,-280,0,0,2,2,6,3,0,5,32669,34,5,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1383,100,-270,0,0,3,2,6,4,0,5,32669,34,6,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1384,100,-260,0,0,4,2,6,5,0,5,32669,34,6,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1385,100,-250,0,0,5,2,6,6,0,5,32669,34,6,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1386,100,-240,0,0,6,2,6,7,0,5,32669,34,6,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1387,100,-230,0,0,7,2,6,8,0,5,32669,34,7,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1388,100,-220,0,0,8,2,6,9,0,5,32669,34,7,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1389,100,-210,0,0,9,2,6,10,0,5,32669,34,7,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1390,100,-200,0,0,10,2,6,11,0,5,32669,34,7,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1391,100,-190,0,0,11,2,6,12,0,5,32669,34,8,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1392,100,-180,0,0,12,2,6,13,0,5,32669,34,8,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1393,100,-170,0,0,13,2,6,14,0,5,32669,34,8,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1394,100,-160,0,0,14,2,6,15,0,5,32669,34,8,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1395,100,-150,0,0,15,2,6,16,0,5,32669,34,9,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1396,100,-140,0,0,16,2,6,17,0,5,32669,34,9,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1397,100,-130,0,0,17,2,6,18,0,5,32669,34,9,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1398,100,-120,0,0,18,2,6,19,0,5,32669,34,9,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1399,100,-110,0,0,19,2,6,20,0,5,32669,35,0,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1400,100,-100,0,0,20,2,6,21,0,5,32669,35,0,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1401,100,-90,0,0,21,2,6,22,0,5,32669,35,0,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1402,100,-80,0,0,22,2,6,23,0,5,32669,35,0,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1403,100,-70,0,0,23,2,6,24,0,5,32669,35,1,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1404,100,-60,0,0,24,2,6,25,0,5,32669,35,1,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1405,100,-50,0,0,25,2,6,26,0,5,32669,35,1,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1406,100,-40,0,0,26,2,6,27,0,5,32669,35,1,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1407,100,-30,0,0,27,2,6,28,0,5,32669,35,2,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1408,100,-20,0,0,28,2,6,29,0,5,32669,35,2,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1409,100,-10,0,0,29,2,7,0,0,5,32669,35,2,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1410,-100,-300,0,1,0,2,7,1,0,5,32669,35,2,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1411,-100,-290,0,1,1,2,7,2,0,5,32669,35,3,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1412,-100,-280,0,1,2,2,7,3,0,5,32669,35,3,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1413,-100,-270,0,1,3,2,7,4,0,5,32669,35,3,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1414,-100,-260,0,1,4,2,7,5,0,5,32669,35,3,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1415,-100,-250,0,1,5,2,7,6,0,5,32669,35,4,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1416,-100,-240,0,1,6,2,7,7,0,5,32669,35,4,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1417,-100,-230,0,1,7,2,7,8,0,5,32669,35,4,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1418,-100,-220,0,1,8,2,7,9,0,5,32669,35,4,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1419,-100,-210,0,1,9,2,7,10,0,5,32669,35,5,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1420,-100,-200,0,1,10,2,7,11,0,5,32669,35,5,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1421,-100,-190,0,1,11,2,7,12,0,5,32669,35,5,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1422,-100,-180,0,1,12,2,7,13,0,5,32669,35,5,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1423,-100,-170,0,1,13,2,7,14,0,5,32669,35,6,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1424,-100,-160,0,1,14,2,7,15,0,5,32669,35,6,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1425,-100,-150,0,1,15,2,7,16,0,5,32669,35,6,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1426,-100,-140,0,1,16,2,7,17,0,5,32669,35,6,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1427,-100,-130,0,1,17,2,7,18,0,5,32669,35,7,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1428,-100,-120,0,1,18,2,7,19,0,5,32669,35,7,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1429,-100,-110,0,1,19,2,7,20,0,5,32669,35,7,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1430,-100,-100,0,1,20,2,7,21,0,5,32669,35,7,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1431,-100,-90,0,1,21,2,7,22,0,5,32669,35,8,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1432,-100,-80,0,1,22,2,7,23,0,5,32669,35,8,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1433,-100,-70,0,1,23,2,7,24,0,5,32669,35,8,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1434,-100,-60,0,1,24,2,7,25,0,5,32669,35,8,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1435,-100,-50,0,1,25,2,7,26,0,5,32669,35,9,0,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1436,-100,-40,0,1,26,2,7,27,0,5,32669,35,9,1,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1437,-100,-30,0,1,27,2,7,28,0,5,32669,35,9,2,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1438,-100,-20,0,1,28,2,7,29,0,5,32669,35,9,3,ON -23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1439,-100,-10,0,1,29,2,8,0,0,6,32669,36,0,0,ON -DATA_END +LEGEND_LINE,,,,,,,,,,,,,,,,,,,,,,,, +detector_num,detector_position_x,detector_position_y,detector_position_z,detector_direction_x,detector_direction_y,detector_direction_z,detector_type,detector_status,channel_num,channel_position_x,channel_position_y,channel_position_z,channel_strip_side,channel_strip_num,channel_signal_crate,channel_signal_card,channel_signal_channel,channel_level2_crate,channel_level2_card,channel_level2_channel,channel_hv_crate,channel_hv_card,channel_hv_channel,channel_status +,,,,,,,,,,,,,,,,,,,,,,,, +DATA_START,,,,,,,,,,,,,,,,,,,,,,,, +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,4,100,-300,0,0,0,0,0,1,0,0,32669,0,0,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,3,100,-290,0,0,1,0,0,2,0,0,32669,0,0,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,2,100,-280,0,0,2,0,0,3,0,0,32669,0,0,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,1,100,-270,0,0,3,0,0,4,0,0,32669,0,1,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,0,100,-260,0,0,4,0,0,5,0,0,32669,0,1,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,11,100,-250,0,0,5,0,0,6,0,0,32669,0,1,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,10,100,-240,0,0,6,0,0,7,0,0,32669,0,1,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,9,100,-230,0,0,7,0,0,8,0,0,32669,0,2,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,8,100,-220,0,0,8,0,0,9,0,0,32669,0,2,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,7,100,-210,0,0,9,0,0,10,0,0,32669,0,2,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,6,100,-200,0,0,10,0,0,11,0,0,32669,0,2,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,17,100,-190,0,0,11,0,0,12,0,0,32669,0,3,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,16,100,-180,0,0,12,0,0,13,0,0,32669,0,3,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,15,100,-170,0,0,13,0,0,14,0,0,32669,0,3,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,14,100,-160,0,0,14,0,0,15,0,0,32669,0,3,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,43,100,-150,0,0,15,0,0,16,0,0,32669,0,4,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,42,100,-140,0,0,16,0,0,17,0,0,32669,0,4,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,53,100,-130,0,0,17,0,0,18,0,0,32669,0,4,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,52,100,-120,0,0,18,0,0,19,0,0,32669,0,4,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,51,100,-110,0,0,19,0,0,20,0,0,32669,0,5,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,50,100,-100,0,0,20,0,0,21,0,0,32669,0,5,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,49,100,-90,0,0,21,0,0,22,0,0,32669,0,5,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,48,100,-80,0,0,22,0,0,23,0,0,32669,0,5,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,59,100,-70,0,0,23,0,0,24,0,0,32669,0,6,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,58,100,-60,0,0,24,0,0,25,0,0,32669,0,6,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,57,100,-50,0,0,25,0,0,26,0,0,32669,0,6,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,56,100,-40,0,0,26,0,0,27,0,0,32669,0,6,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,55,100,-30,0,0,27,0,0,28,0,0,32669,0,7,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,54,100,-20,0,0,28,0,0,29,0,0,32669,0,7,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,34,100,-10,0,0,29,0,1,0,0,0,32669,0,7,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,5,-100,-300,0,1,0,0,1,1,0,0,32669,0,7,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,24,-100,-290,0,1,1,0,1,2,0,0,32669,0,8,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,25,-100,-280,0,1,2,0,1,3,0,0,32669,0,8,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,26,-100,-270,0,1,3,0,1,4,0,0,32669,0,8,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,27,-100,-260,0,1,4,0,1,5,0,0,32669,0,8,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,28,-100,-250,0,1,5,0,1,6,0,0,32669,0,9,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,29,-100,-240,0,1,6,0,1,7,0,0,32669,0,9,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,18,-100,-230,0,1,7,0,1,8,0,0,32669,0,9,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,19,-100,-220,0,1,8,0,1,9,0,0,32669,0,9,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,20,-100,-210,0,1,9,0,1,10,0,0,32669,1,0,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,21,-100,-200,0,1,10,0,1,11,0,0,32669,1,0,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,22,-100,-190,0,1,11,0,1,12,0,0,32669,1,0,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,23,-100,-180,0,1,12,0,1,13,0,0,32669,1,0,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,12,-100,-170,0,1,13,0,1,14,0,0,32669,1,1,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,13,-100,-160,0,1,14,0,1,15,0,0,32669,1,1,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,44,-100,-150,0,1,15,0,1,16,0,0,32669,1,1,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,45,-100,-140,0,1,16,0,1,17,0,0,32669,1,1,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,46,-100,-130,0,1,17,0,1,18,0,0,32669,1,2,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,47,-100,-120,0,1,18,0,1,19,0,0,32669,1,2,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,36,-100,-110,0,1,19,0,1,20,0,0,32669,1,2,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,37,-100,-100,0,1,20,0,1,21,0,0,32669,1,2,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,38,-100,-90,0,1,21,0,1,22,0,0,32669,1,3,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,39,-100,-80,0,1,22,0,1,23,0,0,32669,1,3,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,40,-100,-70,0,1,23,0,1,24,0,0,32669,1,3,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,41,-100,-60,0,1,24,0,1,25,0,0,32669,1,3,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,30,-100,-50,0,1,25,0,1,26,0,0,32669,1,4,0,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,31,-100,-40,0,1,26,0,1,27,0,0,32669,1,4,1,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,32,-100,-30,0,1,27,0,1,28,0,0,32669,1,4,2,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,33,-100,-20,0,1,28,0,1,29,0,0,32669,1,4,3,ON +0,0,-0.927149,0.404,0,0,1,lappd_v1,ON,35,-100,-10,0,1,29,0,2,0,0,0,32669,1,5,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,60,100,-300,0,0,0,0,2,1,0,0,32669,1,5,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,61,100,-290,0,0,1,0,2,2,0,0,32669,1,5,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,62,100,-280,0,0,2,0,2,3,0,0,32669,1,5,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,63,100,-270,0,0,3,0,2,4,0,0,32669,1,6,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,64,100,-260,0,0,4,0,2,5,0,0,32669,1,6,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,65,100,-250,0,0,5,0,2,6,0,0,32669,1,6,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,66,100,-240,0,0,6,0,2,7,0,0,32669,1,6,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,67,100,-230,0,0,7,0,2,8,0,0,32669,1,7,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,68,100,-220,0,0,8,0,2,9,0,0,32669,1,7,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,69,100,-210,0,0,9,0,2,10,0,0,32669,1,7,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,70,100,-200,0,0,10,0,2,11,0,0,32669,1,7,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,71,100,-190,0,0,11,0,2,12,0,0,32669,1,8,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,72,100,-180,0,0,12,0,2,13,0,0,32669,1,8,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,73,100,-170,0,0,13,0,2,14,0,0,32669,1,8,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,74,100,-160,0,0,14,0,2,15,0,0,32669,1,8,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,75,100,-150,0,0,15,0,2,16,0,0,32669,1,9,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,76,100,-140,0,0,16,0,2,17,0,0,32669,1,9,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,77,100,-130,0,0,17,0,2,18,0,0,32669,1,9,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,78,100,-120,0,0,18,0,2,19,0,0,32669,1,9,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,79,100,-110,0,0,19,0,2,20,0,0,32669,2,0,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,80,100,-100,0,0,20,0,2,21,0,0,32669,2,0,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,81,100,-90,0,0,21,0,2,22,0,0,32669,2,0,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,82,100,-80,0,0,22,0,2,23,0,0,32669,2,0,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,83,100,-70,0,0,23,0,2,24,0,0,32669,2,1,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,84,100,-60,0,0,24,0,2,25,0,0,32669,2,1,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,85,100,-50,0,0,25,0,2,26,0,0,32669,2,1,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,86,100,-40,0,0,26,0,2,27,0,0,32669,2,1,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,87,100,-30,0,0,27,0,2,28,0,0,32669,2,2,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,88,100,-20,0,0,28,0,2,29,0,0,32669,2,2,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,89,100,-10,0,0,29,0,3,0,0,0,32669,2,2,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,90,-100,-300,0,1,0,0,3,1,0,0,32669,2,2,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,91,-100,-290,0,1,1,0,3,2,0,0,32669,2,3,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,92,-100,-280,0,1,2,0,3,3,0,0,32669,2,3,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,93,-100,-270,0,1,3,0,3,4,0,0,32669,2,3,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,94,-100,-260,0,1,4,0,3,5,0,0,32669,2,3,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,95,-100,-250,0,1,5,0,3,6,0,0,32669,2,4,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,96,-100,-240,0,1,6,0,3,7,0,0,32669,2,4,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,97,-100,-230,0,1,7,0,3,8,0,0,32669,2,4,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,98,-100,-220,0,1,8,0,3,9,0,0,32669,2,4,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,99,-100,-210,0,1,9,0,3,10,0,0,32669,2,5,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,100,-100,-200,0,1,10,0,3,11,0,0,32669,2,5,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,101,-100,-190,0,1,11,0,3,12,0,0,32669,2,5,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,102,-100,-180,0,1,12,0,3,13,0,0,32669,2,5,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,103,-100,-170,0,1,13,0,3,14,0,0,32669,2,6,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,104,-100,-160,0,1,14,0,3,15,0,0,32669,2,6,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,105,-100,-150,0,1,15,0,3,16,0,0,32669,2,6,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,106,-100,-140,0,1,16,0,3,17,0,0,32669,2,6,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,107,-100,-130,0,1,17,0,3,18,0,0,32669,2,7,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,108,-100,-120,0,1,18,0,3,19,0,0,32669,2,7,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,109,-100,-110,0,1,19,0,3,20,0,0,32669,2,7,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,110,-100,-100,0,1,20,0,3,21,0,0,32669,2,7,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,111,-100,-90,0,1,21,0,3,22,0,0,32669,2,8,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,112,-100,-80,0,1,22,0,3,23,0,0,32669,2,8,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,113,-100,-70,0,1,23,0,3,24,0,0,32669,2,8,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,114,-100,-60,0,1,24,0,3,25,0,0,32669,2,8,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,115,-100,-50,0,1,25,0,3,26,0,0,32669,2,9,0,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,116,-100,-40,0,1,26,0,3,27,0,0,32669,2,9,1,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,117,-100,-30,0,1,27,0,3,28,0,0,32669,2,9,2,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,118,-100,-20,0,1,28,0,3,29,0,0,32669,2,9,3,ON +1,0,-0.144649,0.404,0,0,1,lappd_v1,ON,119,-100,-10,0,1,29,0,4,0,0,0,32669,3,0,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,120,100,-300,0,0,0,0,4,1,0,0,32669,3,0,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,121,100,-290,0,0,1,0,4,2,0,0,32669,3,0,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,122,100,-280,0,0,2,0,4,3,0,0,32669,3,0,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,123,100,-270,0,0,3,0,4,4,0,0,32669,3,1,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,124,100,-260,0,0,4,0,4,5,0,0,32669,3,1,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,125,100,-250,0,0,5,0,4,6,0,0,32669,3,1,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,126,100,-240,0,0,6,0,4,7,0,0,32669,3,1,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,127,100,-230,0,0,7,0,4,8,0,0,32669,3,2,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,128,100,-220,0,0,8,0,4,9,0,0,32669,3,2,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,129,100,-210,0,0,9,0,4,10,0,0,32669,3,2,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,130,100,-200,0,0,10,0,4,11,0,0,32669,3,2,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,131,100,-190,0,0,11,0,4,12,0,0,32669,3,3,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,132,100,-180,0,0,12,0,4,13,0,0,32669,3,3,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,133,100,-170,0,0,13,0,4,14,0,0,32669,3,3,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,134,100,-160,0,0,14,0,4,15,0,0,32669,3,3,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,135,100,-150,0,0,15,0,4,16,0,0,32669,3,4,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,136,100,-140,0,0,16,0,4,17,0,0,32669,3,4,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,137,100,-130,0,0,17,0,4,18,0,0,32669,3,4,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,138,100,-120,0,0,18,0,4,19,0,0,32669,3,4,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,139,100,-110,0,0,19,0,4,20,0,0,32669,3,5,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,140,100,-100,0,0,20,0,4,21,0,0,32669,3,5,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,141,100,-90,0,0,21,0,4,22,0,0,32669,3,5,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,142,100,-80,0,0,22,0,4,23,0,0,32669,3,5,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,143,100,-70,0,0,23,0,4,24,0,0,32669,3,6,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,144,100,-60,0,0,24,0,4,25,0,0,32669,3,6,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,145,100,-50,0,0,25,0,4,26,0,0,32669,3,6,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,146,100,-40,0,0,26,0,4,27,0,0,32669,3,6,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,147,100,-30,0,0,27,0,4,28,0,0,32669,3,7,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,148,100,-20,0,0,28,0,4,29,0,0,32669,3,7,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,149,100,-10,0,0,29,0,5,0,0,0,32669,3,7,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,150,-100,-300,0,1,0,0,5,1,0,0,32669,3,7,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,151,-100,-290,0,1,1,0,5,2,0,0,32669,3,8,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,152,-100,-280,0,1,2,0,5,3,0,0,32669,3,8,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,153,-100,-270,0,1,3,0,5,4,0,0,32669,3,8,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,154,-100,-260,0,1,4,0,5,5,0,0,32669,3,8,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,155,-100,-250,0,1,5,0,5,6,0,0,32669,3,9,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,156,-100,-240,0,1,6,0,5,7,0,0,32669,3,9,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,157,-100,-230,0,1,7,0,5,8,0,0,32669,3,9,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,158,-100,-220,0,1,8,0,5,9,0,0,32669,3,9,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,159,-100,-210,0,1,9,0,5,10,0,0,32669,4,0,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,160,-100,-200,0,1,10,0,5,11,0,0,32669,4,0,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,161,-100,-190,0,1,11,0,5,12,0,0,32669,4,0,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,162,-100,-180,0,1,12,0,5,13,0,0,32669,4,0,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,163,-100,-170,0,1,13,0,5,14,0,0,32669,4,1,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,164,-100,-160,0,1,14,0,5,15,0,0,32669,4,1,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,165,-100,-150,0,1,15,0,5,16,0,0,32669,4,1,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,166,-100,-140,0,1,16,0,5,17,0,0,32669,4,1,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,167,-100,-130,0,1,17,0,5,18,0,0,32669,4,2,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,168,-100,-120,0,1,18,0,5,19,0,0,32669,4,2,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,169,-100,-110,0,1,19,0,5,20,0,0,32669,4,2,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,170,-100,-100,0,1,20,0,5,21,0,0,32669,4,2,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,171,-100,-90,0,1,21,0,5,22,0,0,32669,4,3,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,172,-100,-80,0,1,22,0,5,23,0,0,32669,4,3,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,173,-100,-70,0,1,23,0,5,24,0,0,32669,4,3,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,174,-100,-60,0,1,24,0,5,25,0,0,32669,4,3,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,175,-100,-50,0,1,25,0,5,26,0,0,32669,4,4,0,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,176,-100,-40,0,1,26,0,5,27,0,0,32669,4,4,1,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,177,-100,-30,0,1,27,0,5,28,0,0,32669,4,4,2,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,178,-100,-20,0,1,28,0,5,29,0,0,32669,4,4,3,ON +2,0,0.637851,0.404,0,0,1,lappd_v1,ON,179,-100,-10,0,1,29,0,6,0,0,0,32669,4,5,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,180,100,-300,0,0,0,0,6,1,0,0,32669,4,5,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,181,100,-290,0,0,1,0,6,2,0,0,32669,4,5,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,182,100,-280,0,0,2,0,6,3,0,0,32669,4,5,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,183,100,-270,0,0,3,0,6,4,0,0,32669,4,6,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,184,100,-260,0,0,4,0,6,5,0,0,32669,4,6,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,185,100,-250,0,0,5,0,6,6,0,0,32669,4,6,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,186,100,-240,0,0,6,0,6,7,0,0,32669,4,6,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,187,100,-230,0,0,7,0,6,8,0,0,32669,4,7,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,188,100,-220,0,0,8,0,6,9,0,0,32669,4,7,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,189,100,-210,0,0,9,0,6,10,0,0,32669,4,7,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,190,100,-200,0,0,10,0,6,11,0,0,32669,4,7,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,191,100,-190,0,0,11,0,6,12,0,0,32669,4,8,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,192,100,-180,0,0,12,0,6,13,0,0,32669,4,8,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,193,100,-170,0,0,13,0,6,14,0,0,32669,4,8,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,194,100,-160,0,0,14,0,6,15,0,0,32669,4,8,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,195,100,-150,0,0,15,0,6,16,0,0,32669,4,9,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,196,100,-140,0,0,16,0,6,17,0,0,32669,4,9,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,197,100,-130,0,0,17,0,6,18,0,0,32669,4,9,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,198,100,-120,0,0,18,0,6,19,0,0,32669,4,9,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,199,100,-110,0,0,19,0,6,20,0,0,32669,5,0,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,200,100,-100,0,0,20,0,6,21,0,0,32669,5,0,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,201,100,-90,0,0,21,0,6,22,0,0,32669,5,0,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,202,100,-80,0,0,22,0,6,23,0,0,32669,5,0,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,203,100,-70,0,0,23,0,6,24,0,0,32669,5,1,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,204,100,-60,0,0,24,0,6,25,0,0,32669,5,1,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,205,100,-50,0,0,25,0,6,26,0,0,32669,5,1,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,206,100,-40,0,0,26,0,6,27,0,0,32669,5,1,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,207,100,-30,0,0,27,0,6,28,0,0,32669,5,2,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,208,100,-20,0,0,28,0,6,29,0,0,32669,5,2,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,209,100,-10,0,0,29,0,7,0,0,0,32669,5,2,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,210,-100,-300,0,1,0,0,7,1,0,0,32669,5,2,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,211,-100,-290,0,1,1,0,7,2,0,0,32669,5,3,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,212,-100,-280,0,1,2,0,7,3,0,0,32669,5,3,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,213,-100,-270,0,1,3,0,7,4,0,0,32669,5,3,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,214,-100,-260,0,1,4,0,7,5,0,0,32669,5,3,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,215,-100,-250,0,1,5,0,7,6,0,0,32669,5,4,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,216,-100,-240,0,1,6,0,7,7,0,0,32669,5,4,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,217,-100,-230,0,1,7,0,7,8,0,0,32669,5,4,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,218,-100,-220,0,1,8,0,7,9,0,0,32669,5,4,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,219,-100,-210,0,1,9,0,7,10,0,0,32669,5,5,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,220,-100,-200,0,1,10,0,7,11,0,0,32669,5,5,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,221,-100,-190,0,1,11,0,7,12,0,0,32669,5,5,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,222,-100,-180,0,1,12,0,7,13,0,0,32669,5,5,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,223,-100,-170,0,1,13,0,7,14,0,0,32669,5,6,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,224,-100,-160,0,1,14,0,7,15,0,0,32669,5,6,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,225,-100,-150,0,1,15,0,7,16,0,0,32669,5,6,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,226,-100,-140,0,1,16,0,7,17,0,0,32669,5,6,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,227,-100,-130,0,1,17,0,7,18,0,0,32669,5,7,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,228,-100,-120,0,1,18,0,7,19,0,0,32669,5,7,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,229,-100,-110,0,1,19,0,7,20,0,0,32669,5,7,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,230,-100,-100,0,1,20,0,7,21,0,0,32669,5,7,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,231,-100,-90,0,1,21,0,7,22,0,0,32669,5,8,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,232,-100,-80,0,1,22,0,7,23,0,0,32669,5,8,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,233,-100,-70,0,1,23,0,7,24,0,0,32669,5,8,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,234,-100,-60,0,1,24,0,7,25,0,0,32669,5,8,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,235,-100,-50,0,1,25,0,7,26,0,0,32669,5,9,0,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,236,-100,-40,0,1,26,0,7,27,0,0,32669,5,9,1,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,237,-100,-30,0,1,27,0,7,28,0,0,32669,5,9,2,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,238,-100,-20,0,1,28,0,7,29,0,0,32669,5,9,3,ON +3,0.902975,-0.927149,0.778025,-0.707107,0,0.707107,lappd_v1,ON,239,-100,-10,0,1,29,0,8,0,0,1,32669,6,0,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,240,100,-300,0,0,0,0,8,1,0,1,32669,6,0,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,241,100,-290,0,0,1,0,8,2,0,1,32669,6,0,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,242,100,-280,0,0,2,0,8,3,0,1,32669,6,0,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,243,100,-270,0,0,3,0,8,4,0,1,32669,6,1,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,244,100,-260,0,0,4,0,8,5,0,1,32669,6,1,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,245,100,-250,0,0,5,0,8,6,0,1,32669,6,1,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,246,100,-240,0,0,6,0,8,7,0,1,32669,6,1,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,247,100,-230,0,0,7,0,8,8,0,1,32669,6,2,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,248,100,-220,0,0,8,0,8,9,0,1,32669,6,2,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,249,100,-210,0,0,9,0,8,10,0,1,32669,6,2,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,250,100,-200,0,0,10,0,8,11,0,1,32669,6,2,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,251,100,-190,0,0,11,0,8,12,0,1,32669,6,3,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,252,100,-180,0,0,12,0,8,13,0,1,32669,6,3,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,253,100,-170,0,0,13,0,8,14,0,1,32669,6,3,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,254,100,-160,0,0,14,0,8,15,0,1,32669,6,3,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,255,100,-150,0,0,15,0,8,16,0,1,32669,6,4,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,256,100,-140,0,0,16,0,8,17,0,1,32669,6,4,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,257,100,-130,0,0,17,0,8,18,0,1,32669,6,4,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,258,100,-120,0,0,18,0,8,19,0,1,32669,6,4,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,259,100,-110,0,0,19,0,8,20,0,1,32669,6,5,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,260,100,-100,0,0,20,0,8,21,0,1,32669,6,5,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,261,100,-90,0,0,21,0,8,22,0,1,32669,6,5,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,262,100,-80,0,0,22,0,8,23,0,1,32669,6,5,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,263,100,-70,0,0,23,0,8,24,0,1,32669,6,6,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,264,100,-60,0,0,24,0,8,25,0,1,32669,6,6,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,265,100,-50,0,0,25,0,8,26,0,1,32669,6,6,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,266,100,-40,0,0,26,0,8,27,0,1,32669,6,6,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,267,100,-30,0,0,27,0,8,28,0,1,32669,6,7,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,268,100,-20,0,0,28,0,8,29,0,1,32669,6,7,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,269,100,-10,0,0,29,0,9,0,0,1,32669,6,7,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,270,-100,-300,0,1,0,0,9,1,0,1,32669,6,7,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,271,-100,-290,0,1,1,0,9,2,0,1,32669,6,8,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,272,-100,-280,0,1,2,0,9,3,0,1,32669,6,8,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,273,-100,-270,0,1,3,0,9,4,0,1,32669,6,8,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,274,-100,-260,0,1,4,0,9,5,0,1,32669,6,8,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,275,-100,-250,0,1,5,0,9,6,0,1,32669,6,9,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,276,-100,-240,0,1,6,0,9,7,0,1,32669,6,9,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,277,-100,-230,0,1,7,0,9,8,0,1,32669,6,9,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,278,-100,-220,0,1,8,0,9,9,0,1,32669,6,9,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,279,-100,-210,0,1,9,0,9,10,0,1,32669,7,0,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,280,-100,-200,0,1,10,0,9,11,0,1,32669,7,0,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,281,-100,-190,0,1,11,0,9,12,0,1,32669,7,0,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,282,-100,-180,0,1,12,0,9,13,0,1,32669,7,0,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,283,-100,-170,0,1,13,0,9,14,0,1,32669,7,1,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,284,-100,-160,0,1,14,0,9,15,0,1,32669,7,1,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,285,-100,-150,0,1,15,0,9,16,0,1,32669,7,1,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,286,-100,-140,0,1,16,0,9,17,0,1,32669,7,1,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,287,-100,-130,0,1,17,0,9,18,0,1,32669,7,2,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,288,-100,-120,0,1,18,0,9,19,0,1,32669,7,2,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,289,-100,-110,0,1,19,0,9,20,0,1,32669,7,2,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,290,-100,-100,0,1,20,0,9,21,0,1,32669,7,2,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,291,-100,-90,0,1,21,0,9,22,0,1,32669,7,3,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,292,-100,-80,0,1,22,0,9,23,0,1,32669,7,3,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,293,-100,-70,0,1,23,0,9,24,0,1,32669,7,3,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,294,-100,-60,0,1,24,0,9,25,0,1,32669,7,3,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,295,-100,-50,0,1,25,0,9,26,0,1,32669,7,4,0,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,296,-100,-40,0,1,26,0,9,27,0,1,32669,7,4,1,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,297,-100,-30,0,1,27,0,9,28,0,1,32669,7,4,2,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,298,-100,-20,0,1,28,0,9,29,0,1,32669,7,4,3,ON +4,0.902975,-0.144649,0.778025,-0.707107,0,0.707107,lappd_v1,ON,299,-100,-10,0,1,29,0,10,0,0,1,32669,7,5,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,300,100,-300,0,0,0,0,10,1,0,1,32669,7,5,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,301,100,-290,0,0,1,0,10,2,0,1,32669,7,5,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,302,100,-280,0,0,2,0,10,3,0,1,32669,7,5,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,303,100,-270,0,0,3,0,10,4,0,1,32669,7,6,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,304,100,-260,0,0,4,0,10,5,0,1,32669,7,6,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,305,100,-250,0,0,5,0,10,6,0,1,32669,7,6,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,306,100,-240,0,0,6,0,10,7,0,1,32669,7,6,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,307,100,-230,0,0,7,0,10,8,0,1,32669,7,7,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,308,100,-220,0,0,8,0,10,9,0,1,32669,7,7,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,309,100,-210,0,0,9,0,10,10,0,1,32669,7,7,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,310,100,-200,0,0,10,0,10,11,0,1,32669,7,7,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,311,100,-190,0,0,11,0,10,12,0,1,32669,7,8,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,312,100,-180,0,0,12,0,10,13,0,1,32669,7,8,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,313,100,-170,0,0,13,0,10,14,0,1,32669,7,8,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,314,100,-160,0,0,14,0,10,15,0,1,32669,7,8,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,315,100,-150,0,0,15,0,10,16,0,1,32669,7,9,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,316,100,-140,0,0,16,0,10,17,0,1,32669,7,9,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,317,100,-130,0,0,17,0,10,18,0,1,32669,7,9,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,318,100,-120,0,0,18,0,10,19,0,1,32669,7,9,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,319,100,-110,0,0,19,0,10,20,0,1,32669,8,0,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,320,100,-100,0,0,20,0,10,21,0,1,32669,8,0,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,321,100,-90,0,0,21,0,10,22,0,1,32669,8,0,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,322,100,-80,0,0,22,0,10,23,0,1,32669,8,0,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,323,100,-70,0,0,23,0,10,24,0,1,32669,8,1,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,324,100,-60,0,0,24,0,10,25,0,1,32669,8,1,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,325,100,-50,0,0,25,0,10,26,0,1,32669,8,1,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,326,100,-40,0,0,26,0,10,27,0,1,32669,8,1,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,327,100,-30,0,0,27,0,10,28,0,1,32669,8,2,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,328,100,-20,0,0,28,0,10,29,0,1,32669,8,2,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,329,100,-10,0,0,29,0,11,0,0,1,32669,8,2,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,330,-100,-300,0,1,0,0,11,1,0,1,32669,8,2,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,331,-100,-290,0,1,1,0,11,2,0,1,32669,8,3,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,332,-100,-280,0,1,2,0,11,3,0,1,32669,8,3,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,333,-100,-270,0,1,3,0,11,4,0,1,32669,8,3,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,334,-100,-260,0,1,4,0,11,5,0,1,32669,8,3,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,335,-100,-250,0,1,5,0,11,6,0,1,32669,8,4,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,336,-100,-240,0,1,6,0,11,7,0,1,32669,8,4,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,337,-100,-230,0,1,7,0,11,8,0,1,32669,8,4,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,338,-100,-220,0,1,8,0,11,9,0,1,32669,8,4,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,339,-100,-210,0,1,9,0,11,10,0,1,32669,8,5,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,340,-100,-200,0,1,10,0,11,11,0,1,32669,8,5,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,341,-100,-190,0,1,11,0,11,12,0,1,32669,8,5,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,342,-100,-180,0,1,12,0,11,13,0,1,32669,8,5,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,343,-100,-170,0,1,13,0,11,14,0,1,32669,8,6,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,344,-100,-160,0,1,14,0,11,15,0,1,32669,8,6,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,345,-100,-150,0,1,15,0,11,16,0,1,32669,8,6,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,346,-100,-140,0,1,16,0,11,17,0,1,32669,8,6,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,347,-100,-130,0,1,17,0,11,18,0,1,32669,8,7,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,348,-100,-120,0,1,18,0,11,19,0,1,32669,8,7,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,349,-100,-110,0,1,19,0,11,20,0,1,32669,8,7,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,350,-100,-100,0,1,20,0,11,21,0,1,32669,8,7,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,351,-100,-90,0,1,21,0,11,22,0,1,32669,8,8,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,352,-100,-80,0,1,22,0,11,23,0,1,32669,8,8,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,353,-100,-70,0,1,23,0,11,24,0,1,32669,8,8,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,354,-100,-60,0,1,24,0,11,25,0,1,32669,8,8,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,355,-100,-50,0,1,25,0,11,26,0,1,32669,8,9,0,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,356,-100,-40,0,1,26,0,11,27,0,1,32669,8,9,1,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,357,-100,-30,0,1,27,0,11,28,0,1,32669,8,9,2,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,358,-100,-20,0,1,28,0,11,29,0,1,32669,8,9,3,ON +5,0.902975,0.637851,0.778025,-0.707107,0,0.707107,lappd_v1,ON,359,-100,-10,0,1,29,0,12,0,0,1,32669,9,0,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,360,100,-300,0,0,0,0,12,1,0,1,32669,9,0,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,361,100,-290,0,0,1,0,12,2,0,1,32669,9,0,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,362,100,-280,0,0,2,0,12,3,0,1,32669,9,0,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,363,100,-270,0,0,3,0,12,4,0,1,32669,9,1,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,364,100,-260,0,0,4,0,12,5,0,1,32669,9,1,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,365,100,-250,0,0,5,0,12,6,0,1,32669,9,1,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,366,100,-240,0,0,6,0,12,7,0,1,32669,9,1,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,367,100,-230,0,0,7,0,12,8,0,1,32669,9,2,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,368,100,-220,0,0,8,0,12,9,0,1,32669,9,2,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,369,100,-210,0,0,9,0,12,10,0,1,32669,9,2,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,370,100,-200,0,0,10,0,12,11,0,1,32669,9,2,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,371,100,-190,0,0,11,0,12,12,0,1,32669,9,3,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,372,100,-180,0,0,12,0,12,13,0,1,32669,9,3,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,373,100,-170,0,0,13,0,12,14,0,1,32669,9,3,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,374,100,-160,0,0,14,0,12,15,0,1,32669,9,3,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,375,100,-150,0,0,15,0,12,16,0,1,32669,9,4,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,376,100,-140,0,0,16,0,12,17,0,1,32669,9,4,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,377,100,-130,0,0,17,0,12,18,0,1,32669,9,4,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,378,100,-120,0,0,18,0,12,19,0,1,32669,9,4,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,379,100,-110,0,0,19,0,12,20,0,1,32669,9,5,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,380,100,-100,0,0,20,0,12,21,0,1,32669,9,5,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,381,100,-90,0,0,21,0,12,22,0,1,32669,9,5,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,382,100,-80,0,0,22,0,12,23,0,1,32669,9,5,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,383,100,-70,0,0,23,0,12,24,0,1,32669,9,6,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,384,100,-60,0,0,24,0,12,25,0,1,32669,9,6,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,385,100,-50,0,0,25,0,12,26,0,1,32669,9,6,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,386,100,-40,0,0,26,0,12,27,0,1,32669,9,6,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,387,100,-30,0,0,27,0,12,28,0,1,32669,9,7,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,388,100,-20,0,0,28,0,12,29,0,1,32669,9,7,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,389,100,-10,0,0,29,0,13,0,0,1,32669,9,7,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,390,-100,-300,0,1,0,0,13,1,0,1,32669,9,7,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,391,-100,-290,0,1,1,0,13,2,0,1,32669,9,8,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,392,-100,-280,0,1,2,0,13,3,0,1,32669,9,8,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,393,-100,-270,0,1,3,0,13,4,0,1,32669,9,8,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,394,-100,-260,0,1,4,0,13,5,0,1,32669,9,8,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,395,-100,-250,0,1,5,0,13,6,0,1,32669,9,9,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,396,-100,-240,0,1,6,0,13,7,0,1,32669,9,9,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,397,-100,-230,0,1,7,0,13,8,0,1,32669,9,9,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,398,-100,-220,0,1,8,0,13,9,0,1,32669,9,9,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,399,-100,-210,0,1,9,0,13,10,0,1,32669,10,0,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,400,-100,-200,0,1,10,0,13,11,0,1,32669,10,0,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,401,-100,-190,0,1,11,0,13,12,0,1,32669,10,0,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,402,-100,-180,0,1,12,0,13,13,0,1,32669,10,0,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,403,-100,-170,0,1,13,0,13,14,0,1,32669,10,1,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,404,-100,-160,0,1,14,0,13,15,0,1,32669,10,1,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,405,-100,-150,0,1,15,0,13,16,0,1,32669,10,1,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,406,-100,-140,0,1,16,0,13,17,0,1,32669,10,1,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,407,-100,-130,0,1,17,0,13,18,0,1,32669,10,2,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,408,-100,-120,0,1,18,0,13,19,0,1,32669,10,2,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,409,-100,-110,0,1,19,0,13,20,0,1,32669,10,2,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,410,-100,-100,0,1,20,0,13,21,0,1,32669,10,2,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,411,-100,-90,0,1,21,0,13,22,0,1,32669,10,3,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,412,-100,-80,0,1,22,0,13,23,0,1,32669,10,3,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,413,-100,-70,0,1,23,0,13,24,0,1,32669,10,3,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,414,-100,-60,0,1,24,0,13,25,0,1,32669,10,3,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,415,-100,-50,0,1,25,0,13,26,0,1,32669,10,4,0,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,416,-100,-40,0,1,26,0,13,27,0,1,32669,10,4,1,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,417,-100,-30,0,1,27,0,13,28,0,1,32669,10,4,2,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,418,-100,-20,0,1,28,0,13,29,0,1,32669,10,4,3,ON +6,1.277,-0.927149,1.681,-1,0,0,lappd_v1,ON,419,-100,-10,0,1,29,0,14,0,0,1,32669,10,5,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,420,100,-300,0,0,0,0,14,1,0,1,32669,10,5,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,421,100,-290,0,0,1,0,14,2,0,1,32669,10,5,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,422,100,-280,0,0,2,0,14,3,0,1,32669,10,5,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,423,100,-270,0,0,3,0,14,4,0,1,32669,10,6,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,424,100,-260,0,0,4,0,14,5,0,1,32669,10,6,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,425,100,-250,0,0,5,0,14,6,0,1,32669,10,6,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,426,100,-240,0,0,6,0,14,7,0,1,32669,10,6,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,427,100,-230,0,0,7,0,14,8,0,1,32669,10,7,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,428,100,-220,0,0,8,0,14,9,0,1,32669,10,7,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,429,100,-210,0,0,9,0,14,10,0,1,32669,10,7,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,430,100,-200,0,0,10,0,14,11,0,1,32669,10,7,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,431,100,-190,0,0,11,0,14,12,0,1,32669,10,8,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,432,100,-180,0,0,12,0,14,13,0,1,32669,10,8,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,433,100,-170,0,0,13,0,14,14,0,1,32669,10,8,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,434,100,-160,0,0,14,0,14,15,0,1,32669,10,8,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,435,100,-150,0,0,15,0,14,16,0,1,32669,10,9,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,436,100,-140,0,0,16,0,14,17,0,1,32669,10,9,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,437,100,-130,0,0,17,0,14,18,0,1,32669,10,9,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,438,100,-120,0,0,18,0,14,19,0,1,32669,10,9,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,439,100,-110,0,0,19,0,14,20,0,1,32669,11,0,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,440,100,-100,0,0,20,0,14,21,0,1,32669,11,0,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,441,100,-90,0,0,21,0,14,22,0,1,32669,11,0,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,442,100,-80,0,0,22,0,14,23,0,1,32669,11,0,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,443,100,-70,0,0,23,0,14,24,0,1,32669,11,1,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,444,100,-60,0,0,24,0,14,25,0,1,32669,11,1,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,445,100,-50,0,0,25,0,14,26,0,1,32669,11,1,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,446,100,-40,0,0,26,0,14,27,0,1,32669,11,1,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,447,100,-30,0,0,27,0,14,28,0,1,32669,11,2,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,448,100,-20,0,0,28,0,14,29,0,1,32669,11,2,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,449,100,-10,0,0,29,0,15,0,0,1,32669,11,2,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,450,-100,-300,0,1,0,0,15,1,0,1,32669,11,2,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,451,-100,-290,0,1,1,0,15,2,0,1,32669,11,3,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,452,-100,-280,0,1,2,0,15,3,0,1,32669,11,3,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,453,-100,-270,0,1,3,0,15,4,0,1,32669,11,3,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,454,-100,-260,0,1,4,0,15,5,0,1,32669,11,3,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,455,-100,-250,0,1,5,0,15,6,0,1,32669,11,4,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,456,-100,-240,0,1,6,0,15,7,0,1,32669,11,4,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,457,-100,-230,0,1,7,0,15,8,0,1,32669,11,4,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,458,-100,-220,0,1,8,0,15,9,0,1,32669,11,4,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,459,-100,-210,0,1,9,0,15,10,0,1,32669,11,5,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,460,-100,-200,0,1,10,0,15,11,0,1,32669,11,5,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,461,-100,-190,0,1,11,0,15,12,0,1,32669,11,5,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,462,-100,-180,0,1,12,0,15,13,0,1,32669,11,5,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,463,-100,-170,0,1,13,0,15,14,0,1,32669,11,6,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,464,-100,-160,0,1,14,0,15,15,0,1,32669,11,6,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,465,-100,-150,0,1,15,0,15,16,0,1,32669,11,6,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,466,-100,-140,0,1,16,0,15,17,0,1,32669,11,6,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,467,-100,-130,0,1,17,0,15,18,0,1,32669,11,7,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,468,-100,-120,0,1,18,0,15,19,0,1,32669,11,7,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,469,-100,-110,0,1,19,0,15,20,0,1,32669,11,7,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,470,-100,-100,0,1,20,0,15,21,0,1,32669,11,7,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,471,-100,-90,0,1,21,0,15,22,0,1,32669,11,8,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,472,-100,-80,0,1,22,0,15,23,0,1,32669,11,8,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,473,-100,-70,0,1,23,0,15,24,0,1,32669,11,8,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,474,-100,-60,0,1,24,0,15,25,0,1,32669,11,8,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,475,-100,-50,0,1,25,0,15,26,0,1,32669,11,9,0,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,476,-100,-40,0,1,26,0,15,27,0,1,32669,11,9,1,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,477,-100,-30,0,1,27,0,15,28,0,1,32669,11,9,2,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,478,-100,-20,0,1,28,0,15,29,0,1,32669,11,9,3,ON +7,1.277,-0.144649,1.681,-1,0,0,lappd_v1,ON,479,-100,-10,0,1,29,0,16,0,0,2,32669,12,0,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,480,100,-300,0,0,0,0,16,1,0,2,32669,12,0,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,481,100,-290,0,0,1,0,16,2,0,2,32669,12,0,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,482,100,-280,0,0,2,0,16,3,0,2,32669,12,0,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,483,100,-270,0,0,3,0,16,4,0,2,32669,12,1,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,484,100,-260,0,0,4,0,16,5,0,2,32669,12,1,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,485,100,-250,0,0,5,0,16,6,0,2,32669,12,1,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,486,100,-240,0,0,6,0,16,7,0,2,32669,12,1,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,487,100,-230,0,0,7,0,16,8,0,2,32669,12,2,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,488,100,-220,0,0,8,0,16,9,0,2,32669,12,2,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,489,100,-210,0,0,9,0,16,10,0,2,32669,12,2,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,490,100,-200,0,0,10,0,16,11,0,2,32669,12,2,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,491,100,-190,0,0,11,0,16,12,0,2,32669,12,3,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,492,100,-180,0,0,12,0,16,13,0,2,32669,12,3,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,493,100,-170,0,0,13,0,16,14,0,2,32669,12,3,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,494,100,-160,0,0,14,0,16,15,0,2,32669,12,3,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,495,100,-150,0,0,15,0,16,16,0,2,32669,12,4,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,496,100,-140,0,0,16,0,16,17,0,2,32669,12,4,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,497,100,-130,0,0,17,0,16,18,0,2,32669,12,4,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,498,100,-120,0,0,18,0,16,19,0,2,32669,12,4,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,499,100,-110,0,0,19,0,16,20,0,2,32669,12,5,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,500,100,-100,0,0,20,0,16,21,0,2,32669,12,5,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,501,100,-90,0,0,21,0,16,22,0,2,32669,12,5,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,502,100,-80,0,0,22,0,16,23,0,2,32669,12,5,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,503,100,-70,0,0,23,0,16,24,0,2,32669,12,6,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,504,100,-60,0,0,24,0,16,25,0,2,32669,12,6,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,505,100,-50,0,0,25,0,16,26,0,2,32669,12,6,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,506,100,-40,0,0,26,0,16,27,0,2,32669,12,6,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,507,100,-30,0,0,27,0,16,28,0,2,32669,12,7,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,508,100,-20,0,0,28,0,16,29,0,2,32669,12,7,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,509,100,-10,0,0,29,0,17,0,0,2,32669,12,7,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,510,-100,-300,0,1,0,0,17,1,0,2,32669,12,7,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,511,-100,-290,0,1,1,0,17,2,0,2,32669,12,8,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,512,-100,-280,0,1,2,0,17,3,0,2,32669,12,8,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,513,-100,-270,0,1,3,0,17,4,0,2,32669,12,8,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,514,-100,-260,0,1,4,0,17,5,0,2,32669,12,8,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,515,-100,-250,0,1,5,0,17,6,0,2,32669,12,9,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,516,-100,-240,0,1,6,0,17,7,0,2,32669,12,9,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,517,-100,-230,0,1,7,0,17,8,0,2,32669,12,9,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,518,-100,-220,0,1,8,0,17,9,0,2,32669,12,9,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,519,-100,-210,0,1,9,0,17,10,0,2,32669,13,0,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,520,-100,-200,0,1,10,0,17,11,0,2,32669,13,0,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,521,-100,-190,0,1,11,0,17,12,0,2,32669,13,0,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,522,-100,-180,0,1,12,0,17,13,0,2,32669,13,0,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,523,-100,-170,0,1,13,0,17,14,0,2,32669,13,1,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,524,-100,-160,0,1,14,0,17,15,0,2,32669,13,1,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,525,-100,-150,0,1,15,0,17,16,0,2,32669,13,1,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,526,-100,-140,0,1,16,0,17,17,0,2,32669,13,1,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,527,-100,-130,0,1,17,0,17,18,0,2,32669,13,2,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,528,-100,-120,0,1,18,0,17,19,0,2,32669,13,2,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,529,-100,-110,0,1,19,0,17,20,0,2,32669,13,2,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,530,-100,-100,0,1,20,0,17,21,0,2,32669,13,2,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,531,-100,-90,0,1,21,0,17,22,0,2,32669,13,3,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,532,-100,-80,0,1,22,0,17,23,0,2,32669,13,3,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,533,-100,-70,0,1,23,0,17,24,0,2,32669,13,3,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,534,-100,-60,0,1,24,0,17,25,0,2,32669,13,3,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,535,-100,-50,0,1,25,0,17,26,0,2,32669,13,4,0,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,536,-100,-40,0,1,26,0,17,27,0,2,32669,13,4,1,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,537,-100,-30,0,1,27,0,17,28,0,2,32669,13,4,2,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,538,-100,-20,0,1,28,0,17,29,0,2,32669,13,4,3,ON +8,1.277,0.637851,1.681,-1,0,0,lappd_v1,ON,539,-100,-10,0,1,29,0,18,0,0,2,32669,13,5,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,540,100,-300,0,0,0,0,18,1,0,2,32669,13,5,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,541,100,-290,0,0,1,0,18,2,0,2,32669,13,5,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,542,100,-280,0,0,2,0,18,3,0,2,32669,13,5,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,543,100,-270,0,0,3,0,18,4,0,2,32669,13,6,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,544,100,-260,0,0,4,0,18,5,0,2,32669,13,6,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,545,100,-250,0,0,5,0,18,6,0,2,32669,13,6,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,546,100,-240,0,0,6,0,18,7,0,2,32669,13,6,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,547,100,-230,0,0,7,0,18,8,0,2,32669,13,7,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,548,100,-220,0,0,8,0,18,9,0,2,32669,13,7,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,549,100,-210,0,0,9,0,18,10,0,2,32669,13,7,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,550,100,-200,0,0,10,0,18,11,0,2,32669,13,7,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,551,100,-190,0,0,11,0,18,12,0,2,32669,13,8,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,552,100,-180,0,0,12,0,18,13,0,2,32669,13,8,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,553,100,-170,0,0,13,0,18,14,0,2,32669,13,8,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,554,100,-160,0,0,14,0,18,15,0,2,32669,13,8,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,555,100,-150,0,0,15,0,18,16,0,2,32669,13,9,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,556,100,-140,0,0,16,0,18,17,0,2,32669,13,9,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,557,100,-130,0,0,17,0,18,18,0,2,32669,13,9,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,558,100,-120,0,0,18,0,18,19,0,2,32669,13,9,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,559,100,-110,0,0,19,0,18,20,0,2,32669,14,0,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,560,100,-100,0,0,20,0,18,21,0,2,32669,14,0,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,561,100,-90,0,0,21,0,18,22,0,2,32669,14,0,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,562,100,-80,0,0,22,0,18,23,0,2,32669,14,0,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,563,100,-70,0,0,23,0,18,24,0,2,32669,14,1,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,564,100,-60,0,0,24,0,18,25,0,2,32669,14,1,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,565,100,-50,0,0,25,0,18,26,0,2,32669,14,1,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,566,100,-40,0,0,26,0,18,27,0,2,32669,14,1,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,567,100,-30,0,0,27,0,18,28,0,2,32669,14,2,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,568,100,-20,0,0,28,0,18,29,0,2,32669,14,2,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,569,100,-10,0,0,29,0,19,0,0,2,32669,14,2,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,570,-100,-300,0,1,0,0,19,1,0,2,32669,14,2,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,571,-100,-290,0,1,1,0,19,2,0,2,32669,14,3,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,572,-100,-280,0,1,2,0,19,3,0,2,32669,14,3,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,573,-100,-270,0,1,3,0,19,4,0,2,32669,14,3,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,574,-100,-260,0,1,4,0,19,5,0,2,32669,14,3,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,575,-100,-250,0,1,5,0,19,6,0,2,32669,14,4,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,576,-100,-240,0,1,6,0,19,7,0,2,32669,14,4,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,577,-100,-230,0,1,7,0,19,8,0,2,32669,14,4,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,578,-100,-220,0,1,8,0,19,9,0,2,32669,14,4,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,579,-100,-210,0,1,9,0,19,10,0,2,32669,14,5,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,580,-100,-200,0,1,10,0,19,11,0,2,32669,14,5,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,581,-100,-190,0,1,11,0,19,12,0,2,32669,14,5,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,582,-100,-180,0,1,12,0,19,13,0,2,32669,14,5,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,583,-100,-170,0,1,13,0,19,14,0,2,32669,14,6,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,584,-100,-160,0,1,14,0,19,15,0,2,32669,14,6,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,585,-100,-150,0,1,15,0,19,16,0,2,32669,14,6,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,586,-100,-140,0,1,16,0,19,17,0,2,32669,14,6,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,587,-100,-130,0,1,17,0,19,18,0,2,32669,14,7,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,588,-100,-120,0,1,18,0,19,19,0,2,32669,14,7,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,589,-100,-110,0,1,19,0,19,20,0,2,32669,14,7,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,590,-100,-100,0,1,20,0,19,21,0,2,32669,14,7,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,591,-100,-90,0,1,21,0,19,22,0,2,32669,14,8,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,592,-100,-80,0,1,22,0,19,23,0,2,32669,14,8,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,593,-100,-70,0,1,23,0,19,24,0,2,32669,14,8,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,594,-100,-60,0,1,24,0,19,25,0,2,32669,14,8,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,595,-100,-50,0,1,25,0,19,26,0,2,32669,14,9,0,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,596,-100,-40,0,1,26,0,19,27,0,2,32669,14,9,1,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,597,-100,-30,0,1,27,0,19,28,0,2,32669,14,9,2,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,598,-100,-20,0,1,28,0,19,29,0,2,32669,14,9,3,ON +9,0.902975,-0.927149,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,599,-100,-10,0,1,29,1,0,0,0,2,32669,15,0,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,600,100,-300,0,0,0,1,0,1,0,2,32669,15,0,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,601,100,-290,0,0,1,1,0,2,0,2,32669,15,0,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,602,100,-280,0,0,2,1,0,3,0,2,32669,15,0,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,603,100,-270,0,0,3,1,0,4,0,2,32669,15,1,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,604,100,-260,0,0,4,1,0,5,0,2,32669,15,1,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,605,100,-250,0,0,5,1,0,6,0,2,32669,15,1,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,606,100,-240,0,0,6,1,0,7,0,2,32669,15,1,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,607,100,-230,0,0,7,1,0,8,0,2,32669,15,2,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,608,100,-220,0,0,8,1,0,9,0,2,32669,15,2,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,609,100,-210,0,0,9,1,0,10,0,2,32669,15,2,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,610,100,-200,0,0,10,1,0,11,0,2,32669,15,2,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,611,100,-190,0,0,11,1,0,12,0,2,32669,15,3,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,612,100,-180,0,0,12,1,0,13,0,2,32669,15,3,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,613,100,-170,0,0,13,1,0,14,0,2,32669,15,3,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,614,100,-160,0,0,14,1,0,15,0,2,32669,15,3,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,615,100,-150,0,0,15,1,0,16,0,2,32669,15,4,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,616,100,-140,0,0,16,1,0,17,0,2,32669,15,4,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,617,100,-130,0,0,17,1,0,18,0,2,32669,15,4,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,618,100,-120,0,0,18,1,0,19,0,2,32669,15,4,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,619,100,-110,0,0,19,1,0,20,0,2,32669,15,5,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,620,100,-100,0,0,20,1,0,21,0,2,32669,15,5,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,621,100,-90,0,0,21,1,0,22,0,2,32669,15,5,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,622,100,-80,0,0,22,1,0,23,0,2,32669,15,5,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,623,100,-70,0,0,23,1,0,24,0,2,32669,15,6,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,624,100,-60,0,0,24,1,0,25,0,2,32669,15,6,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,625,100,-50,0,0,25,1,0,26,0,2,32669,15,6,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,626,100,-40,0,0,26,1,0,27,0,2,32669,15,6,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,627,100,-30,0,0,27,1,0,28,0,2,32669,15,7,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,628,100,-20,0,0,28,1,0,29,0,2,32669,15,7,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,629,100,-10,0,0,29,1,1,0,0,2,32669,15,7,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,630,-100,-300,0,1,0,1,1,1,0,2,32669,15,7,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,631,-100,-290,0,1,1,1,1,2,0,2,32669,15,8,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,632,-100,-280,0,1,2,1,1,3,0,2,32669,15,8,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,633,-100,-270,0,1,3,1,1,4,0,2,32669,15,8,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,634,-100,-260,0,1,4,1,1,5,0,2,32669,15,8,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,635,-100,-250,0,1,5,1,1,6,0,2,32669,15,9,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,636,-100,-240,0,1,6,1,1,7,0,2,32669,15,9,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,637,-100,-230,0,1,7,1,1,8,0,2,32669,15,9,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,638,-100,-220,0,1,8,1,1,9,0,2,32669,15,9,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,639,-100,-210,0,1,9,1,1,10,0,2,32669,16,0,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,640,-100,-200,0,1,10,1,1,11,0,2,32669,16,0,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,641,-100,-190,0,1,11,1,1,12,0,2,32669,16,0,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,642,-100,-180,0,1,12,1,1,13,0,2,32669,16,0,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,643,-100,-170,0,1,13,1,1,14,0,2,32669,16,1,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,644,-100,-160,0,1,14,1,1,15,0,2,32669,16,1,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,645,-100,-150,0,1,15,1,1,16,0,2,32669,16,1,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,646,-100,-140,0,1,16,1,1,17,0,2,32669,16,1,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,647,-100,-130,0,1,17,1,1,18,0,2,32669,16,2,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,648,-100,-120,0,1,18,1,1,19,0,2,32669,16,2,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,649,-100,-110,0,1,19,1,1,20,0,2,32669,16,2,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,650,-100,-100,0,1,20,1,1,21,0,2,32669,16,2,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,651,-100,-90,0,1,21,1,1,22,0,2,32669,16,3,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,652,-100,-80,0,1,22,1,1,23,0,2,32669,16,3,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,653,-100,-70,0,1,23,1,1,24,0,2,32669,16,3,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,654,-100,-60,0,1,24,1,1,25,0,2,32669,16,3,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,655,-100,-50,0,1,25,1,1,26,0,2,32669,16,4,0,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,656,-100,-40,0,1,26,1,1,27,0,2,32669,16,4,1,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,657,-100,-30,0,1,27,1,1,28,0,2,32669,16,4,2,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,658,-100,-20,0,1,28,1,1,29,0,2,32669,16,4,3,ON +10,0.902975,-0.144649,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,659,-100,-10,0,1,29,1,2,0,0,2,32669,16,5,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,660,100,-300,0,0,0,1,2,1,0,2,32669,16,5,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,661,100,-290,0,0,1,1,2,2,0,2,32669,16,5,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,662,100,-280,0,0,2,1,2,3,0,2,32669,16,5,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,663,100,-270,0,0,3,1,2,4,0,2,32669,16,6,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,664,100,-260,0,0,4,1,2,5,0,2,32669,16,6,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,665,100,-250,0,0,5,1,2,6,0,2,32669,16,6,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,666,100,-240,0,0,6,1,2,7,0,2,32669,16,6,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,667,100,-230,0,0,7,1,2,8,0,2,32669,16,7,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,668,100,-220,0,0,8,1,2,9,0,2,32669,16,7,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,669,100,-210,0,0,9,1,2,10,0,2,32669,16,7,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,670,100,-200,0,0,10,1,2,11,0,2,32669,16,7,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,671,100,-190,0,0,11,1,2,12,0,2,32669,16,8,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,672,100,-180,0,0,12,1,2,13,0,2,32669,16,8,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,673,100,-170,0,0,13,1,2,14,0,2,32669,16,8,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,674,100,-160,0,0,14,1,2,15,0,2,32669,16,8,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,675,100,-150,0,0,15,1,2,16,0,2,32669,16,9,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,676,100,-140,0,0,16,1,2,17,0,2,32669,16,9,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,677,100,-130,0,0,17,1,2,18,0,2,32669,16,9,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,678,100,-120,0,0,18,1,2,19,0,2,32669,16,9,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,679,100,-110,0,0,19,1,2,20,0,2,32669,17,0,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,680,100,-100,0,0,20,1,2,21,0,2,32669,17,0,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,681,100,-90,0,0,21,1,2,22,0,2,32669,17,0,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,682,100,-80,0,0,22,1,2,23,0,2,32669,17,0,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,683,100,-70,0,0,23,1,2,24,0,2,32669,17,1,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,684,100,-60,0,0,24,1,2,25,0,2,32669,17,1,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,685,100,-50,0,0,25,1,2,26,0,2,32669,17,1,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,686,100,-40,0,0,26,1,2,27,0,2,32669,17,1,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,687,100,-30,0,0,27,1,2,28,0,2,32669,17,2,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,688,100,-20,0,0,28,1,2,29,0,2,32669,17,2,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,689,100,-10,0,0,29,1,3,0,0,2,32669,17,2,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,690,-100,-300,0,1,0,1,3,1,0,2,32669,17,2,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,691,-100,-290,0,1,1,1,3,2,0,2,32669,17,3,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,692,-100,-280,0,1,2,1,3,3,0,2,32669,17,3,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,693,-100,-270,0,1,3,1,3,4,0,2,32669,17,3,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,694,-100,-260,0,1,4,1,3,5,0,2,32669,17,3,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,695,-100,-250,0,1,5,1,3,6,0,2,32669,17,4,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,696,-100,-240,0,1,6,1,3,7,0,2,32669,17,4,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,697,-100,-230,0,1,7,1,3,8,0,2,32669,17,4,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,698,-100,-220,0,1,8,1,3,9,0,2,32669,17,4,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,699,-100,-210,0,1,9,1,3,10,0,2,32669,17,5,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,700,-100,-200,0,1,10,1,3,11,0,2,32669,17,5,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,701,-100,-190,0,1,11,1,3,12,0,2,32669,17,5,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,702,-100,-180,0,1,12,1,3,13,0,2,32669,17,5,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,703,-100,-170,0,1,13,1,3,14,0,2,32669,17,6,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,704,-100,-160,0,1,14,1,3,15,0,2,32669,17,6,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,705,-100,-150,0,1,15,1,3,16,0,2,32669,17,6,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,706,-100,-140,0,1,16,1,3,17,0,2,32669,17,6,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,707,-100,-130,0,1,17,1,3,18,0,2,32669,17,7,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,708,-100,-120,0,1,18,1,3,19,0,2,32669,17,7,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,709,-100,-110,0,1,19,1,3,20,0,2,32669,17,7,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,710,-100,-100,0,1,20,1,3,21,0,2,32669,17,7,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,711,-100,-90,0,1,21,1,3,22,0,2,32669,17,8,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,712,-100,-80,0,1,22,1,3,23,0,2,32669,17,8,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,713,-100,-70,0,1,23,1,3,24,0,2,32669,17,8,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,714,-100,-60,0,1,24,1,3,25,0,2,32669,17,8,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,715,-100,-50,0,1,25,1,3,26,0,2,32669,17,9,0,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,716,-100,-40,0,1,26,1,3,27,0,2,32669,17,9,1,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,717,-100,-30,0,1,27,1,3,28,0,2,32669,17,9,2,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,718,-100,-20,0,1,28,1,3,29,0,2,32669,17,9,3,ON +11,0.902975,0.637851,2.58398,-0.707107,0,-0.707107,lappd_v1,ON,719,-100,-10,0,1,29,1,4,0,0,3,32669,18,0,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,720,100,-300,0,0,0,1,4,1,0,3,32669,18,0,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,721,100,-290,0,0,1,1,4,2,0,3,32669,18,0,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,722,100,-280,0,0,2,1,4,3,0,3,32669,18,0,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,723,100,-270,0,0,3,1,4,4,0,3,32669,18,1,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,724,100,-260,0,0,4,1,4,5,0,3,32669,18,1,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,725,100,-250,0,0,5,1,4,6,0,3,32669,18,1,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,726,100,-240,0,0,6,1,4,7,0,3,32669,18,1,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,727,100,-230,0,0,7,1,4,8,0,3,32669,18,2,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,728,100,-220,0,0,8,1,4,9,0,3,32669,18,2,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,729,100,-210,0,0,9,1,4,10,0,3,32669,18,2,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,730,100,-200,0,0,10,1,4,11,0,3,32669,18,2,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,731,100,-190,0,0,11,1,4,12,0,3,32669,18,3,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,732,100,-180,0,0,12,1,4,13,0,3,32669,18,3,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,733,100,-170,0,0,13,1,4,14,0,3,32669,18,3,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,734,100,-160,0,0,14,1,4,15,0,3,32669,18,3,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,735,100,-150,0,0,15,1,4,16,0,3,32669,18,4,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,736,100,-140,0,0,16,1,4,17,0,3,32669,18,4,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,737,100,-130,0,0,17,1,4,18,0,3,32669,18,4,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,738,100,-120,0,0,18,1,4,19,0,3,32669,18,4,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,739,100,-110,0,0,19,1,4,20,0,3,32669,18,5,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,740,100,-100,0,0,20,1,4,21,0,3,32669,18,5,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,741,100,-90,0,0,21,1,4,22,0,3,32669,18,5,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,742,100,-80,0,0,22,1,4,23,0,3,32669,18,5,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,743,100,-70,0,0,23,1,4,24,0,3,32669,18,6,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,744,100,-60,0,0,24,1,4,25,0,3,32669,18,6,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,745,100,-50,0,0,25,1,4,26,0,3,32669,18,6,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,746,100,-40,0,0,26,1,4,27,0,3,32669,18,6,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,747,100,-30,0,0,27,1,4,28,0,3,32669,18,7,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,748,100,-20,0,0,28,1,4,29,0,3,32669,18,7,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,749,100,-10,0,0,29,1,5,0,0,3,32669,18,7,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,750,-100,-300,0,1,0,1,5,1,0,3,32669,18,7,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,751,-100,-290,0,1,1,1,5,2,0,3,32669,18,8,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,752,-100,-280,0,1,2,1,5,3,0,3,32669,18,8,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,753,-100,-270,0,1,3,1,5,4,0,3,32669,18,8,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,754,-100,-260,0,1,4,1,5,5,0,3,32669,18,8,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,755,-100,-250,0,1,5,1,5,6,0,3,32669,18,9,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,756,-100,-240,0,1,6,1,5,7,0,3,32669,18,9,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,757,-100,-230,0,1,7,1,5,8,0,3,32669,18,9,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,758,-100,-220,0,1,8,1,5,9,0,3,32669,18,9,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,759,-100,-210,0,1,9,1,5,10,0,3,32669,19,0,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,760,-100,-200,0,1,10,1,5,11,0,3,32669,19,0,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,761,-100,-190,0,1,11,1,5,12,0,3,32669,19,0,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,762,-100,-180,0,1,12,1,5,13,0,3,32669,19,0,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,763,-100,-170,0,1,13,1,5,14,0,3,32669,19,1,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,764,-100,-160,0,1,14,1,5,15,0,3,32669,19,1,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,765,-100,-150,0,1,15,1,5,16,0,3,32669,19,1,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,766,-100,-140,0,1,16,1,5,17,0,3,32669,19,1,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,767,-100,-130,0,1,17,1,5,18,0,3,32669,19,2,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,768,-100,-120,0,1,18,1,5,19,0,3,32669,19,2,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,769,-100,-110,0,1,19,1,5,20,0,3,32669,19,2,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,770,-100,-100,0,1,20,1,5,21,0,3,32669,19,2,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,771,-100,-90,0,1,21,1,5,22,0,3,32669,19,3,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,772,-100,-80,0,1,22,1,5,23,0,3,32669,19,3,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,773,-100,-70,0,1,23,1,5,24,0,3,32669,19,3,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,774,-100,-60,0,1,24,1,5,25,0,3,32669,19,3,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,775,-100,-50,0,1,25,1,5,26,0,3,32669,19,4,0,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,776,-100,-40,0,1,26,1,5,27,0,3,32669,19,4,1,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,777,-100,-30,0,1,27,1,5,28,0,3,32669,19,4,2,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,778,-100,-20,0,1,28,1,5,29,0,3,32669,19,4,3,ON +12,0,-0.927149,2.958,0,0,-1,lappd_v1,ON,779,-100,-10,0,1,29,1,6,0,0,3,32669,19,5,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,780,100,-300,0,0,0,1,6,1,0,3,32669,19,5,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,781,100,-290,0,0,1,1,6,2,0,3,32669,19,5,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,782,100,-280,0,0,2,1,6,3,0,3,32669,19,5,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,783,100,-270,0,0,3,1,6,4,0,3,32669,19,6,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,784,100,-260,0,0,4,1,6,5,0,3,32669,19,6,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,785,100,-250,0,0,5,1,6,6,0,3,32669,19,6,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,786,100,-240,0,0,6,1,6,7,0,3,32669,19,6,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,787,100,-230,0,0,7,1,6,8,0,3,32669,19,7,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,788,100,-220,0,0,8,1,6,9,0,3,32669,19,7,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,789,100,-210,0,0,9,1,6,10,0,3,32669,19,7,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,790,100,-200,0,0,10,1,6,11,0,3,32669,19,7,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,791,100,-190,0,0,11,1,6,12,0,3,32669,19,8,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,792,100,-180,0,0,12,1,6,13,0,3,32669,19,8,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,793,100,-170,0,0,13,1,6,14,0,3,32669,19,8,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,794,100,-160,0,0,14,1,6,15,0,3,32669,19,8,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,795,100,-150,0,0,15,1,6,16,0,3,32669,19,9,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,796,100,-140,0,0,16,1,6,17,0,3,32669,19,9,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,797,100,-130,0,0,17,1,6,18,0,3,32669,19,9,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,798,100,-120,0,0,18,1,6,19,0,3,32669,19,9,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,799,100,-110,0,0,19,1,6,20,0,3,32669,20,0,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,800,100,-100,0,0,20,1,6,21,0,3,32669,20,0,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,801,100,-90,0,0,21,1,6,22,0,3,32669,20,0,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,802,100,-80,0,0,22,1,6,23,0,3,32669,20,0,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,803,100,-70,0,0,23,1,6,24,0,3,32669,20,1,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,804,100,-60,0,0,24,1,6,25,0,3,32669,20,1,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,805,100,-50,0,0,25,1,6,26,0,3,32669,20,1,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,806,100,-40,0,0,26,1,6,27,0,3,32669,20,1,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,807,100,-30,0,0,27,1,6,28,0,3,32669,20,2,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,808,100,-20,0,0,28,1,6,29,0,3,32669,20,2,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,809,100,-10,0,0,29,1,7,0,0,3,32669,20,2,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,810,-100,-300,0,1,0,1,7,1,0,3,32669,20,2,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,811,-100,-290,0,1,1,1,7,2,0,3,32669,20,3,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,812,-100,-280,0,1,2,1,7,3,0,3,32669,20,3,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,813,-100,-270,0,1,3,1,7,4,0,3,32669,20,3,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,814,-100,-260,0,1,4,1,7,5,0,3,32669,20,3,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,815,-100,-250,0,1,5,1,7,6,0,3,32669,20,4,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,816,-100,-240,0,1,6,1,7,7,0,3,32669,20,4,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,817,-100,-230,0,1,7,1,7,8,0,3,32669,20,4,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,818,-100,-220,0,1,8,1,7,9,0,3,32669,20,4,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,819,-100,-210,0,1,9,1,7,10,0,3,32669,20,5,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,820,-100,-200,0,1,10,1,7,11,0,3,32669,20,5,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,821,-100,-190,0,1,11,1,7,12,0,3,32669,20,5,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,822,-100,-180,0,1,12,1,7,13,0,3,32669,20,5,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,823,-100,-170,0,1,13,1,7,14,0,3,32669,20,6,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,824,-100,-160,0,1,14,1,7,15,0,3,32669,20,6,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,825,-100,-150,0,1,15,1,7,16,0,3,32669,20,6,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,826,-100,-140,0,1,16,1,7,17,0,3,32669,20,6,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,827,-100,-130,0,1,17,1,7,18,0,3,32669,20,7,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,828,-100,-120,0,1,18,1,7,19,0,3,32669,20,7,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,829,-100,-110,0,1,19,1,7,20,0,3,32669,20,7,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,830,-100,-100,0,1,20,1,7,21,0,3,32669,20,7,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,831,-100,-90,0,1,21,1,7,22,0,3,32669,20,8,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,832,-100,-80,0,1,22,1,7,23,0,3,32669,20,8,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,833,-100,-70,0,1,23,1,7,24,0,3,32669,20,8,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,834,-100,-60,0,1,24,1,7,25,0,3,32669,20,8,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,835,-100,-50,0,1,25,1,7,26,0,3,32669,20,9,0,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,836,-100,-40,0,1,26,1,7,27,0,3,32669,20,9,1,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,837,-100,-30,0,1,27,1,7,28,0,3,32669,20,9,2,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,838,-100,-20,0,1,28,1,7,29,0,3,32669,20,9,3,ON +13,0,-0.144649,2.958,0,0,-1,lappd_v1,ON,839,-100,-10,0,1,29,1,8,0,0,3,32669,21,0,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,840,100,-300,0,0,0,1,8,1,0,3,32669,21,0,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,841,100,-290,0,0,1,1,8,2,0,3,32669,21,0,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,842,100,-280,0,0,2,1,8,3,0,3,32669,21,0,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,843,100,-270,0,0,3,1,8,4,0,3,32669,21,1,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,844,100,-260,0,0,4,1,8,5,0,3,32669,21,1,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,845,100,-250,0,0,5,1,8,6,0,3,32669,21,1,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,846,100,-240,0,0,6,1,8,7,0,3,32669,21,1,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,847,100,-230,0,0,7,1,8,8,0,3,32669,21,2,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,848,100,-220,0,0,8,1,8,9,0,3,32669,21,2,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,849,100,-210,0,0,9,1,8,10,0,3,32669,21,2,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,850,100,-200,0,0,10,1,8,11,0,3,32669,21,2,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,851,100,-190,0,0,11,1,8,12,0,3,32669,21,3,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,852,100,-180,0,0,12,1,8,13,0,3,32669,21,3,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,853,100,-170,0,0,13,1,8,14,0,3,32669,21,3,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,854,100,-160,0,0,14,1,8,15,0,3,32669,21,3,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,855,100,-150,0,0,15,1,8,16,0,3,32669,21,4,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,856,100,-140,0,0,16,1,8,17,0,3,32669,21,4,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,857,100,-130,0,0,17,1,8,18,0,3,32669,21,4,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,858,100,-120,0,0,18,1,8,19,0,3,32669,21,4,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,859,100,-110,0,0,19,1,8,20,0,3,32669,21,5,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,860,100,-100,0,0,20,1,8,21,0,3,32669,21,5,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,861,100,-90,0,0,21,1,8,22,0,3,32669,21,5,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,862,100,-80,0,0,22,1,8,23,0,3,32669,21,5,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,863,100,-70,0,0,23,1,8,24,0,3,32669,21,6,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,864,100,-60,0,0,24,1,8,25,0,3,32669,21,6,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,865,100,-50,0,0,25,1,8,26,0,3,32669,21,6,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,866,100,-40,0,0,26,1,8,27,0,3,32669,21,6,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,867,100,-30,0,0,27,1,8,28,0,3,32669,21,7,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,868,100,-20,0,0,28,1,8,29,0,3,32669,21,7,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,869,100,-10,0,0,29,1,9,0,0,3,32669,21,7,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,870,-100,-300,0,1,0,1,9,1,0,3,32669,21,7,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,871,-100,-290,0,1,1,1,9,2,0,3,32669,21,8,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,872,-100,-280,0,1,2,1,9,3,0,3,32669,21,8,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,873,-100,-270,0,1,3,1,9,4,0,3,32669,21,8,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,874,-100,-260,0,1,4,1,9,5,0,3,32669,21,8,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,875,-100,-250,0,1,5,1,9,6,0,3,32669,21,9,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,876,-100,-240,0,1,6,1,9,7,0,3,32669,21,9,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,877,-100,-230,0,1,7,1,9,8,0,3,32669,21,9,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,878,-100,-220,0,1,8,1,9,9,0,3,32669,21,9,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,879,-100,-210,0,1,9,1,9,10,0,3,32669,22,0,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,880,-100,-200,0,1,10,1,9,11,0,3,32669,22,0,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,881,-100,-190,0,1,11,1,9,12,0,3,32669,22,0,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,882,-100,-180,0,1,12,1,9,13,0,3,32669,22,0,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,883,-100,-170,0,1,13,1,9,14,0,3,32669,22,1,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,884,-100,-160,0,1,14,1,9,15,0,3,32669,22,1,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,885,-100,-150,0,1,15,1,9,16,0,3,32669,22,1,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,886,-100,-140,0,1,16,1,9,17,0,3,32669,22,1,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,887,-100,-130,0,1,17,1,9,18,0,3,32669,22,2,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,888,-100,-120,0,1,18,1,9,19,0,3,32669,22,2,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,889,-100,-110,0,1,19,1,9,20,0,3,32669,22,2,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,890,-100,-100,0,1,20,1,9,21,0,3,32669,22,2,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,891,-100,-90,0,1,21,1,9,22,0,3,32669,22,3,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,892,-100,-80,0,1,22,1,9,23,0,3,32669,22,3,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,893,-100,-70,0,1,23,1,9,24,0,3,32669,22,3,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,894,-100,-60,0,1,24,1,9,25,0,3,32669,22,3,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,895,-100,-50,0,1,25,1,9,26,0,3,32669,22,4,0,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,896,-100,-40,0,1,26,1,9,27,0,3,32669,22,4,1,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,897,-100,-30,0,1,27,1,9,28,0,3,32669,22,4,2,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,898,-100,-20,0,1,28,1,9,29,0,3,32669,22,4,3,ON +14,0,0.637851,2.958,0,0,-1,lappd_v1,ON,899,-100,-10,0,1,29,1,10,0,0,3,32669,22,5,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,900,100,-300,0,0,0,1,10,1,0,3,32669,22,5,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,901,100,-290,0,0,1,1,10,2,0,3,32669,22,5,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,902,100,-280,0,0,2,1,10,3,0,3,32669,22,5,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,903,100,-270,0,0,3,1,10,4,0,3,32669,22,6,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,904,100,-260,0,0,4,1,10,5,0,3,32669,22,6,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,905,100,-250,0,0,5,1,10,6,0,3,32669,22,6,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,906,100,-240,0,0,6,1,10,7,0,3,32669,22,6,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,907,100,-230,0,0,7,1,10,8,0,3,32669,22,7,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,908,100,-220,0,0,8,1,10,9,0,3,32669,22,7,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,909,100,-210,0,0,9,1,10,10,0,3,32669,22,7,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,910,100,-200,0,0,10,1,10,11,0,3,32669,22,7,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,911,100,-190,0,0,11,1,10,12,0,3,32669,22,8,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,912,100,-180,0,0,12,1,10,13,0,3,32669,22,8,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,913,100,-170,0,0,13,1,10,14,0,3,32669,22,8,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,914,100,-160,0,0,14,1,10,15,0,3,32669,22,8,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,915,100,-150,0,0,15,1,10,16,0,3,32669,22,9,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,916,100,-140,0,0,16,1,10,17,0,3,32669,22,9,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,917,100,-130,0,0,17,1,10,18,0,3,32669,22,9,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,918,100,-120,0,0,18,1,10,19,0,3,32669,22,9,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,919,100,-110,0,0,19,1,10,20,0,3,32669,23,0,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,920,100,-100,0,0,20,1,10,21,0,3,32669,23,0,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,921,100,-90,0,0,21,1,10,22,0,3,32669,23,0,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,922,100,-80,0,0,22,1,10,23,0,3,32669,23,0,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,923,100,-70,0,0,23,1,10,24,0,3,32669,23,1,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,924,100,-60,0,0,24,1,10,25,0,3,32669,23,1,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,925,100,-50,0,0,25,1,10,26,0,3,32669,23,1,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,926,100,-40,0,0,26,1,10,27,0,3,32669,23,1,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,927,100,-30,0,0,27,1,10,28,0,3,32669,23,2,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,928,100,-20,0,0,28,1,10,29,0,3,32669,23,2,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,929,100,-10,0,0,29,1,11,0,0,3,32669,23,2,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,930,-100,-300,0,1,0,1,11,1,0,3,32669,23,2,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,931,-100,-290,0,1,1,1,11,2,0,3,32669,23,3,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,932,-100,-280,0,1,2,1,11,3,0,3,32669,23,3,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,933,-100,-270,0,1,3,1,11,4,0,3,32669,23,3,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,934,-100,-260,0,1,4,1,11,5,0,3,32669,23,3,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,935,-100,-250,0,1,5,1,11,6,0,3,32669,23,4,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,936,-100,-240,0,1,6,1,11,7,0,3,32669,23,4,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,937,-100,-230,0,1,7,1,11,8,0,3,32669,23,4,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,938,-100,-220,0,1,8,1,11,9,0,3,32669,23,4,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,939,-100,-210,0,1,9,1,11,10,0,3,32669,23,5,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,940,-100,-200,0,1,10,1,11,11,0,3,32669,23,5,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,941,-100,-190,0,1,11,1,11,12,0,3,32669,23,5,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,942,-100,-180,0,1,12,1,11,13,0,3,32669,23,5,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,943,-100,-170,0,1,13,1,11,14,0,3,32669,23,6,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,944,-100,-160,0,1,14,1,11,15,0,3,32669,23,6,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,945,-100,-150,0,1,15,1,11,16,0,3,32669,23,6,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,946,-100,-140,0,1,16,1,11,17,0,3,32669,23,6,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,947,-100,-130,0,1,17,1,11,18,0,3,32669,23,7,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,948,-100,-120,0,1,18,1,11,19,0,3,32669,23,7,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,949,-100,-110,0,1,19,1,11,20,0,3,32669,23,7,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,950,-100,-100,0,1,20,1,11,21,0,3,32669,23,7,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,951,-100,-90,0,1,21,1,11,22,0,3,32669,23,8,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,952,-100,-80,0,1,22,1,11,23,0,3,32669,23,8,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,953,-100,-70,0,1,23,1,11,24,0,3,32669,23,8,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,954,-100,-60,0,1,24,1,11,25,0,3,32669,23,8,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,955,-100,-50,0,1,25,1,11,26,0,3,32669,23,9,0,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,956,-100,-40,0,1,26,1,11,27,0,3,32669,23,9,1,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,957,-100,-30,0,1,27,1,11,28,0,3,32669,23,9,2,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,958,-100,-20,0,1,28,1,11,29,0,3,32669,23,9,3,ON +15,-0.902975,-0.927149,2.58398,0.707107,0,-0.707107,lappd_v1,ON,959,-100,-10,0,1,29,1,12,0,0,4,32669,24,0,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,960,100,-300,0,0,0,1,12,1,0,4,32669,24,0,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,961,100,-290,0,0,1,1,12,2,0,4,32669,24,0,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,962,100,-280,0,0,2,1,12,3,0,4,32669,24,0,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,963,100,-270,0,0,3,1,12,4,0,4,32669,24,1,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,964,100,-260,0,0,4,1,12,5,0,4,32669,24,1,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,965,100,-250,0,0,5,1,12,6,0,4,32669,24,1,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,966,100,-240,0,0,6,1,12,7,0,4,32669,24,1,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,967,100,-230,0,0,7,1,12,8,0,4,32669,24,2,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,968,100,-220,0,0,8,1,12,9,0,4,32669,24,2,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,969,100,-210,0,0,9,1,12,10,0,4,32669,24,2,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,970,100,-200,0,0,10,1,12,11,0,4,32669,24,2,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,971,100,-190,0,0,11,1,12,12,0,4,32669,24,3,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,972,100,-180,0,0,12,1,12,13,0,4,32669,24,3,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,973,100,-170,0,0,13,1,12,14,0,4,32669,24,3,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,974,100,-160,0,0,14,1,12,15,0,4,32669,24,3,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,975,100,-150,0,0,15,1,12,16,0,4,32669,24,4,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,976,100,-140,0,0,16,1,12,17,0,4,32669,24,4,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,977,100,-130,0,0,17,1,12,18,0,4,32669,24,4,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,978,100,-120,0,0,18,1,12,19,0,4,32669,24,4,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,979,100,-110,0,0,19,1,12,20,0,4,32669,24,5,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,980,100,-100,0,0,20,1,12,21,0,4,32669,24,5,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,981,100,-90,0,0,21,1,12,22,0,4,32669,24,5,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,982,100,-80,0,0,22,1,12,23,0,4,32669,24,5,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,983,100,-70,0,0,23,1,12,24,0,4,32669,24,6,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,984,100,-60,0,0,24,1,12,25,0,4,32669,24,6,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,985,100,-50,0,0,25,1,12,26,0,4,32669,24,6,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,986,100,-40,0,0,26,1,12,27,0,4,32669,24,6,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,987,100,-30,0,0,27,1,12,28,0,4,32669,24,7,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,988,100,-20,0,0,28,1,12,29,0,4,32669,24,7,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,989,100,-10,0,0,29,1,13,0,0,4,32669,24,7,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,990,-100,-300,0,1,0,1,13,1,0,4,32669,24,7,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,991,-100,-290,0,1,1,1,13,2,0,4,32669,24,8,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,992,-100,-280,0,1,2,1,13,3,0,4,32669,24,8,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,993,-100,-270,0,1,3,1,13,4,0,4,32669,24,8,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,994,-100,-260,0,1,4,1,13,5,0,4,32669,24,8,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,995,-100,-250,0,1,5,1,13,6,0,4,32669,24,9,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,996,-100,-240,0,1,6,1,13,7,0,4,32669,24,9,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,997,-100,-230,0,1,7,1,13,8,0,4,32669,24,9,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,998,-100,-220,0,1,8,1,13,9,0,4,32669,24,9,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,999,-100,-210,0,1,9,1,13,10,0,4,32669,25,0,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1000,-100,-200,0,1,10,1,13,11,0,4,32669,25,0,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1001,-100,-190,0,1,11,1,13,12,0,4,32669,25,0,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1002,-100,-180,0,1,12,1,13,13,0,4,32669,25,0,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1003,-100,-170,0,1,13,1,13,14,0,4,32669,25,1,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1004,-100,-160,0,1,14,1,13,15,0,4,32669,25,1,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1005,-100,-150,0,1,15,1,13,16,0,4,32669,25,1,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1006,-100,-140,0,1,16,1,13,17,0,4,32669,25,1,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1007,-100,-130,0,1,17,1,13,18,0,4,32669,25,2,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1008,-100,-120,0,1,18,1,13,19,0,4,32669,25,2,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1009,-100,-110,0,1,19,1,13,20,0,4,32669,25,2,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1010,-100,-100,0,1,20,1,13,21,0,4,32669,25,2,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1011,-100,-90,0,1,21,1,13,22,0,4,32669,25,3,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1012,-100,-80,0,1,22,1,13,23,0,4,32669,25,3,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1013,-100,-70,0,1,23,1,13,24,0,4,32669,25,3,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1014,-100,-60,0,1,24,1,13,25,0,4,32669,25,3,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1015,-100,-50,0,1,25,1,13,26,0,4,32669,25,4,0,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1016,-100,-40,0,1,26,1,13,27,0,4,32669,25,4,1,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1017,-100,-30,0,1,27,1,13,28,0,4,32669,25,4,2,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1018,-100,-20,0,1,28,1,13,29,0,4,32669,25,4,3,ON +16,-0.902975,-0.144649,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1019,-100,-10,0,1,29,1,14,0,0,4,32669,25,5,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1020,100,-300,0,0,0,1,14,1,0,4,32669,25,5,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1021,100,-290,0,0,1,1,14,2,0,4,32669,25,5,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1022,100,-280,0,0,2,1,14,3,0,4,32669,25,5,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1023,100,-270,0,0,3,1,14,4,0,4,32669,25,6,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1024,100,-260,0,0,4,1,14,5,0,4,32669,25,6,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1025,100,-250,0,0,5,1,14,6,0,4,32669,25,6,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1026,100,-240,0,0,6,1,14,7,0,4,32669,25,6,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1027,100,-230,0,0,7,1,14,8,0,4,32669,25,7,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1028,100,-220,0,0,8,1,14,9,0,4,32669,25,7,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1029,100,-210,0,0,9,1,14,10,0,4,32669,25,7,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1030,100,-200,0,0,10,1,14,11,0,4,32669,25,7,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1031,100,-190,0,0,11,1,14,12,0,4,32669,25,8,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1032,100,-180,0,0,12,1,14,13,0,4,32669,25,8,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1033,100,-170,0,0,13,1,14,14,0,4,32669,25,8,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1034,100,-160,0,0,14,1,14,15,0,4,32669,25,8,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1035,100,-150,0,0,15,1,14,16,0,4,32669,25,9,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1036,100,-140,0,0,16,1,14,17,0,4,32669,25,9,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1037,100,-130,0,0,17,1,14,18,0,4,32669,25,9,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1038,100,-120,0,0,18,1,14,19,0,4,32669,25,9,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1039,100,-110,0,0,19,1,14,20,0,4,32669,26,0,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1040,100,-100,0,0,20,1,14,21,0,4,32669,26,0,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1041,100,-90,0,0,21,1,14,22,0,4,32669,26,0,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1042,100,-80,0,0,22,1,14,23,0,4,32669,26,0,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1043,100,-70,0,0,23,1,14,24,0,4,32669,26,1,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1044,100,-60,0,0,24,1,14,25,0,4,32669,26,1,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1045,100,-50,0,0,25,1,14,26,0,4,32669,26,1,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1046,100,-40,0,0,26,1,14,27,0,4,32669,26,1,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1047,100,-30,0,0,27,1,14,28,0,4,32669,26,2,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1048,100,-20,0,0,28,1,14,29,0,4,32669,26,2,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1049,100,-10,0,0,29,1,15,0,0,4,32669,26,2,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1050,-100,-300,0,1,0,1,15,1,0,4,32669,26,2,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1051,-100,-290,0,1,1,1,15,2,0,4,32669,26,3,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1052,-100,-280,0,1,2,1,15,3,0,4,32669,26,3,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1053,-100,-270,0,1,3,1,15,4,0,4,32669,26,3,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1054,-100,-260,0,1,4,1,15,5,0,4,32669,26,3,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1055,-100,-250,0,1,5,1,15,6,0,4,32669,26,4,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1056,-100,-240,0,1,6,1,15,7,0,4,32669,26,4,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1057,-100,-230,0,1,7,1,15,8,0,4,32669,26,4,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1058,-100,-220,0,1,8,1,15,9,0,4,32669,26,4,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1059,-100,-210,0,1,9,1,15,10,0,4,32669,26,5,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1060,-100,-200,0,1,10,1,15,11,0,4,32669,26,5,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1061,-100,-190,0,1,11,1,15,12,0,4,32669,26,5,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1062,-100,-180,0,1,12,1,15,13,0,4,32669,26,5,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1063,-100,-170,0,1,13,1,15,14,0,4,32669,26,6,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1064,-100,-160,0,1,14,1,15,15,0,4,32669,26,6,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1065,-100,-150,0,1,15,1,15,16,0,4,32669,26,6,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1066,-100,-140,0,1,16,1,15,17,0,4,32669,26,6,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1067,-100,-130,0,1,17,1,15,18,0,4,32669,26,7,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1068,-100,-120,0,1,18,1,15,19,0,4,32669,26,7,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1069,-100,-110,0,1,19,1,15,20,0,4,32669,26,7,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1070,-100,-100,0,1,20,1,15,21,0,4,32669,26,7,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1071,-100,-90,0,1,21,1,15,22,0,4,32669,26,8,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1072,-100,-80,0,1,22,1,15,23,0,4,32669,26,8,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1073,-100,-70,0,1,23,1,15,24,0,4,32669,26,8,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1074,-100,-60,0,1,24,1,15,25,0,4,32669,26,8,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1075,-100,-50,0,1,25,1,15,26,0,4,32669,26,9,0,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1076,-100,-40,0,1,26,1,15,27,0,4,32669,26,9,1,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1077,-100,-30,0,1,27,1,15,28,0,4,32669,26,9,2,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1078,-100,-20,0,1,28,1,15,29,0,4,32669,26,9,3,ON +17,-0.902975,0.637851,2.58398,0.707107,0,-0.707107,lappd_v1,ON,1079,-100,-10,0,1,29,1,16,0,0,4,32669,27,0,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1080,100,-300,0,0,0,1,16,1,0,4,32669,27,0,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1081,100,-290,0,0,1,1,16,2,0,4,32669,27,0,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1082,100,-280,0,0,2,1,16,3,0,4,32669,27,0,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1083,100,-270,0,0,3,1,16,4,0,4,32669,27,1,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1084,100,-260,0,0,4,1,16,5,0,4,32669,27,1,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1085,100,-250,0,0,5,1,16,6,0,4,32669,27,1,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1086,100,-240,0,0,6,1,16,7,0,4,32669,27,1,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1087,100,-230,0,0,7,1,16,8,0,4,32669,27,2,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1088,100,-220,0,0,8,1,16,9,0,4,32669,27,2,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1089,100,-210,0,0,9,1,16,10,0,4,32669,27,2,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1090,100,-200,0,0,10,1,16,11,0,4,32669,27,2,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1091,100,-190,0,0,11,1,16,12,0,4,32669,27,3,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1092,100,-180,0,0,12,1,16,13,0,4,32669,27,3,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1093,100,-170,0,0,13,1,16,14,0,4,32669,27,3,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1094,100,-160,0,0,14,1,16,15,0,4,32669,27,3,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1095,100,-150,0,0,15,1,16,16,0,4,32669,27,4,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1096,100,-140,0,0,16,1,16,17,0,4,32669,27,4,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1097,100,-130,0,0,17,1,16,18,0,4,32669,27,4,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1098,100,-120,0,0,18,1,16,19,0,4,32669,27,4,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1099,100,-110,0,0,19,1,16,20,0,4,32669,27,5,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1100,100,-100,0,0,20,1,16,21,0,4,32669,27,5,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1101,100,-90,0,0,21,1,16,22,0,4,32669,27,5,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1102,100,-80,0,0,22,1,16,23,0,4,32669,27,5,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1103,100,-70,0,0,23,1,16,24,0,4,32669,27,6,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1104,100,-60,0,0,24,1,16,25,0,4,32669,27,6,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1105,100,-50,0,0,25,1,16,26,0,4,32669,27,6,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1106,100,-40,0,0,26,1,16,27,0,4,32669,27,6,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1107,100,-30,0,0,27,1,16,28,0,4,32669,27,7,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1108,100,-20,0,0,28,1,16,29,0,4,32669,27,7,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1109,100,-10,0,0,29,1,17,0,0,4,32669,27,7,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1110,-100,-300,0,1,0,1,17,1,0,4,32669,27,7,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1111,-100,-290,0,1,1,1,17,2,0,4,32669,27,8,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1112,-100,-280,0,1,2,1,17,3,0,4,32669,27,8,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1113,-100,-270,0,1,3,1,17,4,0,4,32669,27,8,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1114,-100,-260,0,1,4,1,17,5,0,4,32669,27,8,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1115,-100,-250,0,1,5,1,17,6,0,4,32669,27,9,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1116,-100,-240,0,1,6,1,17,7,0,4,32669,27,9,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1117,-100,-230,0,1,7,1,17,8,0,4,32669,27,9,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1118,-100,-220,0,1,8,1,17,9,0,4,32669,27,9,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1119,-100,-210,0,1,9,1,17,10,0,4,32669,28,0,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1120,-100,-200,0,1,10,1,17,11,0,4,32669,28,0,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1121,-100,-190,0,1,11,1,17,12,0,4,32669,28,0,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1122,-100,-180,0,1,12,1,17,13,0,4,32669,28,0,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1123,-100,-170,0,1,13,1,17,14,0,4,32669,28,1,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1124,-100,-160,0,1,14,1,17,15,0,4,32669,28,1,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1125,-100,-150,0,1,15,1,17,16,0,4,32669,28,1,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1126,-100,-140,0,1,16,1,17,17,0,4,32669,28,1,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1127,-100,-130,0,1,17,1,17,18,0,4,32669,28,2,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1128,-100,-120,0,1,18,1,17,19,0,4,32669,28,2,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1129,-100,-110,0,1,19,1,17,20,0,4,32669,28,2,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1130,-100,-100,0,1,20,1,17,21,0,4,32669,28,2,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1131,-100,-90,0,1,21,1,17,22,0,4,32669,28,3,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1132,-100,-80,0,1,22,1,17,23,0,4,32669,28,3,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1133,-100,-70,0,1,23,1,17,24,0,4,32669,28,3,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1134,-100,-60,0,1,24,1,17,25,0,4,32669,28,3,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1135,-100,-50,0,1,25,1,17,26,0,4,32669,28,4,0,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1136,-100,-40,0,1,26,1,17,27,0,4,32669,28,4,1,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1137,-100,-30,0,1,27,1,17,28,0,4,32669,28,4,2,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1138,-100,-20,0,1,28,1,17,29,0,4,32669,28,4,3,ON +18,-1.277,-0.927149,1.681,1,0,0,lappd_v1,ON,1139,-100,-10,0,1,29,1,18,0,0,4,32669,28,5,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1140,100,-300,0,0,0,1,18,1,0,4,32669,28,5,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1141,100,-290,0,0,1,1,18,2,0,4,32669,28,5,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1142,100,-280,0,0,2,1,18,3,0,4,32669,28,5,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1143,100,-270,0,0,3,1,18,4,0,4,32669,28,6,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1144,100,-260,0,0,4,1,18,5,0,4,32669,28,6,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1145,100,-250,0,0,5,1,18,6,0,4,32669,28,6,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1146,100,-240,0,0,6,1,18,7,0,4,32669,28,6,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1147,100,-230,0,0,7,1,18,8,0,4,32669,28,7,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1148,100,-220,0,0,8,1,18,9,0,4,32669,28,7,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1149,100,-210,0,0,9,1,18,10,0,4,32669,28,7,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1150,100,-200,0,0,10,1,18,11,0,4,32669,28,7,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1151,100,-190,0,0,11,1,18,12,0,4,32669,28,8,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1152,100,-180,0,0,12,1,18,13,0,4,32669,28,8,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1153,100,-170,0,0,13,1,18,14,0,4,32669,28,8,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1154,100,-160,0,0,14,1,18,15,0,4,32669,28,8,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1155,100,-150,0,0,15,1,18,16,0,4,32669,28,9,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1156,100,-140,0,0,16,1,18,17,0,4,32669,28,9,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1157,100,-130,0,0,17,1,18,18,0,4,32669,28,9,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1158,100,-120,0,0,18,1,18,19,0,4,32669,28,9,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1159,100,-110,0,0,19,1,18,20,0,4,32669,29,0,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1160,100,-100,0,0,20,1,18,21,0,4,32669,29,0,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1161,100,-90,0,0,21,1,18,22,0,4,32669,29,0,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1162,100,-80,0,0,22,1,18,23,0,4,32669,29,0,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1163,100,-70,0,0,23,1,18,24,0,4,32669,29,1,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1164,100,-60,0,0,24,1,18,25,0,4,32669,29,1,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1165,100,-50,0,0,25,1,18,26,0,4,32669,29,1,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1166,100,-40,0,0,26,1,18,27,0,4,32669,29,1,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1167,100,-30,0,0,27,1,18,28,0,4,32669,29,2,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1168,100,-20,0,0,28,1,18,29,0,4,32669,29,2,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1169,100,-10,0,0,29,1,19,0,0,4,32669,29,2,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1170,-100,-300,0,1,0,1,19,1,0,4,32669,29,2,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1171,-100,-290,0,1,1,1,19,2,0,4,32669,29,3,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1172,-100,-280,0,1,2,1,19,3,0,4,32669,29,3,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1173,-100,-270,0,1,3,1,19,4,0,4,32669,29,3,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1174,-100,-260,0,1,4,1,19,5,0,4,32669,29,3,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1175,-100,-250,0,1,5,1,19,6,0,4,32669,29,4,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1176,-100,-240,0,1,6,1,19,7,0,4,32669,29,4,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1177,-100,-230,0,1,7,1,19,8,0,4,32669,29,4,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1178,-100,-220,0,1,8,1,19,9,0,4,32669,29,4,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1179,-100,-210,0,1,9,1,19,10,0,4,32669,29,5,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1180,-100,-200,0,1,10,1,19,11,0,4,32669,29,5,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1181,-100,-190,0,1,11,1,19,12,0,4,32669,29,5,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1182,-100,-180,0,1,12,1,19,13,0,4,32669,29,5,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1183,-100,-170,0,1,13,1,19,14,0,4,32669,29,6,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1184,-100,-160,0,1,14,1,19,15,0,4,32669,29,6,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1185,-100,-150,0,1,15,1,19,16,0,4,32669,29,6,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1186,-100,-140,0,1,16,1,19,17,0,4,32669,29,6,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1187,-100,-130,0,1,17,1,19,18,0,4,32669,29,7,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1188,-100,-120,0,1,18,1,19,19,0,4,32669,29,7,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1189,-100,-110,0,1,19,1,19,20,0,4,32669,29,7,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1190,-100,-100,0,1,20,1,19,21,0,4,32669,29,7,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1191,-100,-90,0,1,21,1,19,22,0,4,32669,29,8,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1192,-100,-80,0,1,22,1,19,23,0,4,32669,29,8,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1193,-100,-70,0,1,23,1,19,24,0,4,32669,29,8,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1194,-100,-60,0,1,24,1,19,25,0,4,32669,29,8,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1195,-100,-50,0,1,25,1,19,26,0,4,32669,29,9,0,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1196,-100,-40,0,1,26,1,19,27,0,4,32669,29,9,1,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1197,-100,-30,0,1,27,1,19,28,0,4,32669,29,9,2,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1198,-100,-20,0,1,28,1,19,29,0,4,32669,29,9,3,ON +19,-1.277,-0.144649,1.681,1,0,0,lappd_v1,ON,1199,-100,-10,0,1,29,2,0,0,0,5,32669,30,0,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1200,100,-300,0,0,0,2,0,1,0,5,32669,30,0,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1201,100,-290,0,0,1,2,0,2,0,5,32669,30,0,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1202,100,-280,0,0,2,2,0,3,0,5,32669,30,0,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1203,100,-270,0,0,3,2,0,4,0,5,32669,30,1,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1204,100,-260,0,0,4,2,0,5,0,5,32669,30,1,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1205,100,-250,0,0,5,2,0,6,0,5,32669,30,1,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1206,100,-240,0,0,6,2,0,7,0,5,32669,30,1,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1207,100,-230,0,0,7,2,0,8,0,5,32669,30,2,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1208,100,-220,0,0,8,2,0,9,0,5,32669,30,2,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1209,100,-210,0,0,9,2,0,10,0,5,32669,30,2,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1210,100,-200,0,0,10,2,0,11,0,5,32669,30,2,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1211,100,-190,0,0,11,2,0,12,0,5,32669,30,3,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1212,100,-180,0,0,12,2,0,13,0,5,32669,30,3,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1213,100,-170,0,0,13,2,0,14,0,5,32669,30,3,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1214,100,-160,0,0,14,2,0,15,0,5,32669,30,3,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1215,100,-150,0,0,15,2,0,16,0,5,32669,30,4,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1216,100,-140,0,0,16,2,0,17,0,5,32669,30,4,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1217,100,-130,0,0,17,2,0,18,0,5,32669,30,4,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1218,100,-120,0,0,18,2,0,19,0,5,32669,30,4,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1219,100,-110,0,0,19,2,0,20,0,5,32669,30,5,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1220,100,-100,0,0,20,2,0,21,0,5,32669,30,5,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1221,100,-90,0,0,21,2,0,22,0,5,32669,30,5,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1222,100,-80,0,0,22,2,0,23,0,5,32669,30,5,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1223,100,-70,0,0,23,2,0,24,0,5,32669,30,6,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1224,100,-60,0,0,24,2,0,25,0,5,32669,30,6,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1225,100,-50,0,0,25,2,0,26,0,5,32669,30,6,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1226,100,-40,0,0,26,2,0,27,0,5,32669,30,6,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1227,100,-30,0,0,27,2,0,28,0,5,32669,30,7,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1228,100,-20,0,0,28,2,0,29,0,5,32669,30,7,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1229,100,-10,0,0,29,2,1,0,0,5,32669,30,7,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1230,-100,-300,0,1,0,2,1,1,0,5,32669,30,7,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1231,-100,-290,0,1,1,2,1,2,0,5,32669,30,8,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1232,-100,-280,0,1,2,2,1,3,0,5,32669,30,8,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1233,-100,-270,0,1,3,2,1,4,0,5,32669,30,8,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1234,-100,-260,0,1,4,2,1,5,0,5,32669,30,8,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1235,-100,-250,0,1,5,2,1,6,0,5,32669,30,9,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1236,-100,-240,0,1,6,2,1,7,0,5,32669,30,9,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1237,-100,-230,0,1,7,2,1,8,0,5,32669,30,9,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1238,-100,-220,0,1,8,2,1,9,0,5,32669,30,9,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1239,-100,-210,0,1,9,2,1,10,0,5,32669,31,0,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1240,-100,-200,0,1,10,2,1,11,0,5,32669,31,0,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1241,-100,-190,0,1,11,2,1,12,0,5,32669,31,0,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1242,-100,-180,0,1,12,2,1,13,0,5,32669,31,0,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1243,-100,-170,0,1,13,2,1,14,0,5,32669,31,1,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1244,-100,-160,0,1,14,2,1,15,0,5,32669,31,1,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1245,-100,-150,0,1,15,2,1,16,0,5,32669,31,1,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1246,-100,-140,0,1,16,2,1,17,0,5,32669,31,1,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1247,-100,-130,0,1,17,2,1,18,0,5,32669,31,2,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1248,-100,-120,0,1,18,2,1,19,0,5,32669,31,2,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1249,-100,-110,0,1,19,2,1,20,0,5,32669,31,2,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1250,-100,-100,0,1,20,2,1,21,0,5,32669,31,2,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1251,-100,-90,0,1,21,2,1,22,0,5,32669,31,3,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1252,-100,-80,0,1,22,2,1,23,0,5,32669,31,3,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1253,-100,-70,0,1,23,2,1,24,0,5,32669,31,3,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1254,-100,-60,0,1,24,2,1,25,0,5,32669,31,3,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1255,-100,-50,0,1,25,2,1,26,0,5,32669,31,4,0,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1256,-100,-40,0,1,26,2,1,27,0,5,32669,31,4,1,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1257,-100,-30,0,1,27,2,1,28,0,5,32669,31,4,2,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1258,-100,-20,0,1,28,2,1,29,0,5,32669,31,4,3,ON +20,-1.277,0.637851,1.681,1,0,0,lappd_v1,ON,1259,-100,-10,0,1,29,2,2,0,0,5,32669,31,5,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1260,100,-300,0,0,0,2,2,1,0,5,32669,31,5,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1261,100,-290,0,0,1,2,2,2,0,5,32669,31,5,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1262,100,-280,0,0,2,2,2,3,0,5,32669,31,5,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1263,100,-270,0,0,3,2,2,4,0,5,32669,31,6,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1264,100,-260,0,0,4,2,2,5,0,5,32669,31,6,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1265,100,-250,0,0,5,2,2,6,0,5,32669,31,6,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1266,100,-240,0,0,6,2,2,7,0,5,32669,31,6,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1267,100,-230,0,0,7,2,2,8,0,5,32669,31,7,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1268,100,-220,0,0,8,2,2,9,0,5,32669,31,7,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1269,100,-210,0,0,9,2,2,10,0,5,32669,31,7,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1270,100,-200,0,0,10,2,2,11,0,5,32669,31,7,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1271,100,-190,0,0,11,2,2,12,0,5,32669,31,8,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1272,100,-180,0,0,12,2,2,13,0,5,32669,31,8,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1273,100,-170,0,0,13,2,2,14,0,5,32669,31,8,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1274,100,-160,0,0,14,2,2,15,0,5,32669,31,8,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1275,100,-150,0,0,15,2,2,16,0,5,32669,31,9,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1276,100,-140,0,0,16,2,2,17,0,5,32669,31,9,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1277,100,-130,0,0,17,2,2,18,0,5,32669,31,9,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1278,100,-120,0,0,18,2,2,19,0,5,32669,31,9,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1279,100,-110,0,0,19,2,2,20,0,5,32669,32,0,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1280,100,-100,0,0,20,2,2,21,0,5,32669,32,0,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1281,100,-90,0,0,21,2,2,22,0,5,32669,32,0,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1282,100,-80,0,0,22,2,2,23,0,5,32669,32,0,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1283,100,-70,0,0,23,2,2,24,0,5,32669,32,1,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1284,100,-60,0,0,24,2,2,25,0,5,32669,32,1,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1285,100,-50,0,0,25,2,2,26,0,5,32669,32,1,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1286,100,-40,0,0,26,2,2,27,0,5,32669,32,1,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1287,100,-30,0,0,27,2,2,28,0,5,32669,32,2,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1288,100,-20,0,0,28,2,2,29,0,5,32669,32,2,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1289,100,-10,0,0,29,2,3,0,0,5,32669,32,2,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1290,-100,-300,0,1,0,2,3,1,0,5,32669,32,2,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1291,-100,-290,0,1,1,2,3,2,0,5,32669,32,3,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1292,-100,-280,0,1,2,2,3,3,0,5,32669,32,3,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1293,-100,-270,0,1,3,2,3,4,0,5,32669,32,3,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1294,-100,-260,0,1,4,2,3,5,0,5,32669,32,3,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1295,-100,-250,0,1,5,2,3,6,0,5,32669,32,4,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1296,-100,-240,0,1,6,2,3,7,0,5,32669,32,4,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1297,-100,-230,0,1,7,2,3,8,0,5,32669,32,4,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1298,-100,-220,0,1,8,2,3,9,0,5,32669,32,4,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1299,-100,-210,0,1,9,2,3,10,0,5,32669,32,5,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1300,-100,-200,0,1,10,2,3,11,0,5,32669,32,5,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1301,-100,-190,0,1,11,2,3,12,0,5,32669,32,5,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1302,-100,-180,0,1,12,2,3,13,0,5,32669,32,5,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1303,-100,-170,0,1,13,2,3,14,0,5,32669,32,6,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1304,-100,-160,0,1,14,2,3,15,0,5,32669,32,6,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1305,-100,-150,0,1,15,2,3,16,0,5,32669,32,6,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1306,-100,-140,0,1,16,2,3,17,0,5,32669,32,6,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1307,-100,-130,0,1,17,2,3,18,0,5,32669,32,7,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1308,-100,-120,0,1,18,2,3,19,0,5,32669,32,7,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1309,-100,-110,0,1,19,2,3,20,0,5,32669,32,7,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1310,-100,-100,0,1,20,2,3,21,0,5,32669,32,7,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1311,-100,-90,0,1,21,2,3,22,0,5,32669,32,8,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1312,-100,-80,0,1,22,2,3,23,0,5,32669,32,8,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1313,-100,-70,0,1,23,2,3,24,0,5,32669,32,8,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1314,-100,-60,0,1,24,2,3,25,0,5,32669,32,8,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1315,-100,-50,0,1,25,2,3,26,0,5,32669,32,9,0,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1316,-100,-40,0,1,26,2,3,27,0,5,32669,32,9,1,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1317,-100,-30,0,1,27,2,3,28,0,5,32669,32,9,2,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1318,-100,-20,0,1,28,2,3,29,0,5,32669,32,9,3,ON +21,-0.902975,-0.927149,0.778025,0.707107,0,0.707107,lappd_v1,ON,1319,-100,-10,0,1,29,2,4,0,0,5,32669,33,0,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1320,100,-300,0,0,0,2,4,1,0,5,32669,33,0,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1321,100,-290,0,0,1,2,4,2,0,5,32669,33,0,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1322,100,-280,0,0,2,2,4,3,0,5,32669,33,0,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1323,100,-270,0,0,3,2,4,4,0,5,32669,33,1,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1324,100,-260,0,0,4,2,4,5,0,5,32669,33,1,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1325,100,-250,0,0,5,2,4,6,0,5,32669,33,1,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1326,100,-240,0,0,6,2,4,7,0,5,32669,33,1,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1327,100,-230,0,0,7,2,4,8,0,5,32669,33,2,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1328,100,-220,0,0,8,2,4,9,0,5,32669,33,2,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1329,100,-210,0,0,9,2,4,10,0,5,32669,33,2,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1330,100,-200,0,0,10,2,4,11,0,5,32669,33,2,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1331,100,-190,0,0,11,2,4,12,0,5,32669,33,3,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1332,100,-180,0,0,12,2,4,13,0,5,32669,33,3,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1333,100,-170,0,0,13,2,4,14,0,5,32669,33,3,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1334,100,-160,0,0,14,2,4,15,0,5,32669,33,3,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1335,100,-150,0,0,15,2,4,16,0,5,32669,33,4,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1336,100,-140,0,0,16,2,4,17,0,5,32669,33,4,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1337,100,-130,0,0,17,2,4,18,0,5,32669,33,4,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1338,100,-120,0,0,18,2,4,19,0,5,32669,33,4,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1339,100,-110,0,0,19,2,4,20,0,5,32669,33,5,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1340,100,-100,0,0,20,2,4,21,0,5,32669,33,5,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1341,100,-90,0,0,21,2,4,22,0,5,32669,33,5,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1342,100,-80,0,0,22,2,4,23,0,5,32669,33,5,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1343,100,-70,0,0,23,2,4,24,0,5,32669,33,6,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1344,100,-60,0,0,24,2,4,25,0,5,32669,33,6,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1345,100,-50,0,0,25,2,4,26,0,5,32669,33,6,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1346,100,-40,0,0,26,2,4,27,0,5,32669,33,6,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1347,100,-30,0,0,27,2,4,28,0,5,32669,33,7,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1348,100,-20,0,0,28,2,4,29,0,5,32669,33,7,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1349,100,-10,0,0,29,2,5,0,0,5,32669,33,7,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1350,-100,-300,0,1,0,2,5,1,0,5,32669,33,7,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1351,-100,-290,0,1,1,2,5,2,0,5,32669,33,8,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1352,-100,-280,0,1,2,2,5,3,0,5,32669,33,8,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1353,-100,-270,0,1,3,2,5,4,0,5,32669,33,8,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1354,-100,-260,0,1,4,2,5,5,0,5,32669,33,8,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1355,-100,-250,0,1,5,2,5,6,0,5,32669,33,9,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1356,-100,-240,0,1,6,2,5,7,0,5,32669,33,9,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1357,-100,-230,0,1,7,2,5,8,0,5,32669,33,9,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1358,-100,-220,0,1,8,2,5,9,0,5,32669,33,9,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1359,-100,-210,0,1,9,2,5,10,0,5,32669,34,0,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1360,-100,-200,0,1,10,2,5,11,0,5,32669,34,0,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1361,-100,-190,0,1,11,2,5,12,0,5,32669,34,0,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1362,-100,-180,0,1,12,2,5,13,0,5,32669,34,0,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1363,-100,-170,0,1,13,2,5,14,0,5,32669,34,1,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1364,-100,-160,0,1,14,2,5,15,0,5,32669,34,1,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1365,-100,-150,0,1,15,2,5,16,0,5,32669,34,1,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1366,-100,-140,0,1,16,2,5,17,0,5,32669,34,1,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1367,-100,-130,0,1,17,2,5,18,0,5,32669,34,2,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1368,-100,-120,0,1,18,2,5,19,0,5,32669,34,2,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1369,-100,-110,0,1,19,2,5,20,0,5,32669,34,2,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1370,-100,-100,0,1,20,2,5,21,0,5,32669,34,2,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1371,-100,-90,0,1,21,2,5,22,0,5,32669,34,3,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1372,-100,-80,0,1,22,2,5,23,0,5,32669,34,3,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1373,-100,-70,0,1,23,2,5,24,0,5,32669,34,3,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1374,-100,-60,0,1,24,2,5,25,0,5,32669,34,3,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1375,-100,-50,0,1,25,2,5,26,0,5,32669,34,4,0,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1376,-100,-40,0,1,26,2,5,27,0,5,32669,34,4,1,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1377,-100,-30,0,1,27,2,5,28,0,5,32669,34,4,2,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1378,-100,-20,0,1,28,2,5,29,0,5,32669,34,4,3,ON +22,-0.902975,-0.144649,0.778025,0.707107,0,0.707107,lappd_v1,ON,1379,-100,-10,0,1,29,2,6,0,0,5,32669,34,5,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1380,100,-300,0,0,0,2,6,1,0,5,32669,34,5,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1381,100,-290,0,0,1,2,6,2,0,5,32669,34,5,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1382,100,-280,0,0,2,2,6,3,0,5,32669,34,5,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1383,100,-270,0,0,3,2,6,4,0,5,32669,34,6,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1384,100,-260,0,0,4,2,6,5,0,5,32669,34,6,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1385,100,-250,0,0,5,2,6,6,0,5,32669,34,6,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1386,100,-240,0,0,6,2,6,7,0,5,32669,34,6,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1387,100,-230,0,0,7,2,6,8,0,5,32669,34,7,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1388,100,-220,0,0,8,2,6,9,0,5,32669,34,7,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1389,100,-210,0,0,9,2,6,10,0,5,32669,34,7,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1390,100,-200,0,0,10,2,6,11,0,5,32669,34,7,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1391,100,-190,0,0,11,2,6,12,0,5,32669,34,8,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1392,100,-180,0,0,12,2,6,13,0,5,32669,34,8,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1393,100,-170,0,0,13,2,6,14,0,5,32669,34,8,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1394,100,-160,0,0,14,2,6,15,0,5,32669,34,8,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1395,100,-150,0,0,15,2,6,16,0,5,32669,34,9,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1396,100,-140,0,0,16,2,6,17,0,5,32669,34,9,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1397,100,-130,0,0,17,2,6,18,0,5,32669,34,9,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1398,100,-120,0,0,18,2,6,19,0,5,32669,34,9,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1399,100,-110,0,0,19,2,6,20,0,5,32669,35,0,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1400,100,-100,0,0,20,2,6,21,0,5,32669,35,0,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1401,100,-90,0,0,21,2,6,22,0,5,32669,35,0,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1402,100,-80,0,0,22,2,6,23,0,5,32669,35,0,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1403,100,-70,0,0,23,2,6,24,0,5,32669,35,1,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1404,100,-60,0,0,24,2,6,25,0,5,32669,35,1,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1405,100,-50,0,0,25,2,6,26,0,5,32669,35,1,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1406,100,-40,0,0,26,2,6,27,0,5,32669,35,1,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1407,100,-30,0,0,27,2,6,28,0,5,32669,35,2,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1408,100,-20,0,0,28,2,6,29,0,5,32669,35,2,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1409,100,-10,0,0,29,2,7,0,0,5,32669,35,2,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1410,-100,-300,0,1,0,2,7,1,0,5,32669,35,2,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1411,-100,-290,0,1,1,2,7,2,0,5,32669,35,3,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1412,-100,-280,0,1,2,2,7,3,0,5,32669,35,3,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1413,-100,-270,0,1,3,2,7,4,0,5,32669,35,3,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1414,-100,-260,0,1,4,2,7,5,0,5,32669,35,3,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1415,-100,-250,0,1,5,2,7,6,0,5,32669,35,4,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1416,-100,-240,0,1,6,2,7,7,0,5,32669,35,4,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1417,-100,-230,0,1,7,2,7,8,0,5,32669,35,4,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1418,-100,-220,0,1,8,2,7,9,0,5,32669,35,4,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1419,-100,-210,0,1,9,2,7,10,0,5,32669,35,5,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1420,-100,-200,0,1,10,2,7,11,0,5,32669,35,5,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1421,-100,-190,0,1,11,2,7,12,0,5,32669,35,5,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1422,-100,-180,0,1,12,2,7,13,0,5,32669,35,5,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1423,-100,-170,0,1,13,2,7,14,0,5,32669,35,6,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1424,-100,-160,0,1,14,2,7,15,0,5,32669,35,6,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1425,-100,-150,0,1,15,2,7,16,0,5,32669,35,6,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1426,-100,-140,0,1,16,2,7,17,0,5,32669,35,6,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1427,-100,-130,0,1,17,2,7,18,0,5,32669,35,7,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1428,-100,-120,0,1,18,2,7,19,0,5,32669,35,7,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1429,-100,-110,0,1,19,2,7,20,0,5,32669,35,7,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1430,-100,-100,0,1,20,2,7,21,0,5,32669,35,7,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1431,-100,-90,0,1,21,2,7,22,0,5,32669,35,8,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1432,-100,-80,0,1,22,2,7,23,0,5,32669,35,8,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1433,-100,-70,0,1,23,2,7,24,0,5,32669,35,8,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1434,-100,-60,0,1,24,2,7,25,0,5,32669,35,8,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1435,-100,-50,0,1,25,2,7,26,0,5,32669,35,9,0,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1436,-100,-40,0,1,26,2,7,27,0,5,32669,35,9,1,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1437,-100,-30,0,1,27,2,7,28,0,5,32669,35,9,2,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1438,-100,-20,0,1,28,2,7,29,0,5,32669,35,9,3,ON +23,-0.902975,0.637851,0.778025,0.707107,0,0.707107,lappd_v1,ON,1439,-100,-10,0,1,29,2,8,0,0,6,32669,36,0,0,ON +DATA_END,,,,,,,,,,,,,,,,,,,,,,,, \ No newline at end of file diff --git a/configfiles/LoadGeometry/LoadGeometryConfig b/configfiles/LoadGeometry/LoadGeometryConfig index 693f546d2..79efc3811 100644 --- a/configfiles/LoadGeometry/LoadGeometryConfig +++ b/configfiles/LoadGeometry/LoadGeometryConfig @@ -6,4 +6,5 @@ DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv LAPPDGeoFile ./configfiles/LoadGeometry/LAPPDGeometry.csv TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains2023.csv +TankPMTTimingOffsetFile ./configfiles/LoadGeometry/TankPMTTimingOffsets.csv AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv diff --git a/configfiles/LoadGeometry/TankPMTTimingOffsets.csv b/configfiles/LoadGeometry/TankPMTTimingOffsets.csv new file mode 100644 index 000000000..3aca644cb --- /dev/null +++ b/configfiles/LoadGeometry/TankPMTTimingOffsets.csv @@ -0,0 +1,121 @@ +##Channel,PMT_location,offset_value(ns),offset_std(ns),notes +332,Bottom,15.25,1.31,unreliable +334,Bottom,15.55,0.57,ok +335,Bottom,8.34,1.36,unreliable +336,Bottom,15.41,1.33,unreliable +338,Bottom,10.15,1.85,unreliable +339,Bottom,8.57,0.95,ok +340,Bottom,8.66,1.29,unreliable +341,Bottom,11.51,1.95,unreliable +343,Bottom,14.24,0.33,ok (low statistics) +344,Bottom,13.41,2.11,unreliable (low statistics) +347,Bottom,10.6,1.92,unreliable +348,Bottom,7.08,2.1,unreliable +350,Bottom,3.15,1.03,ok +351,Bottom,9.16,1.05,ok +353,Top,16.13,1.14,ok (low statistics) +354,Top,10.44,1.55,unreliable +355,Top,14.27,2.08,ok +356,Top,12.88,1.48,unreliable +357,Top,8.66,2.21,ok +358,Top,8.13,1.46,ok +360,Top,8.04,2.56,ok +361,Top,14.42,1.5,unreliable +362,Top,4.88,1.88,ok +363,Top,16.96,2.24,ok +364,Top,16.22,2.83,ok +365,Top,12.43,1.53,unreliable +366,Top,11.78,1.48,ok +367,Top,14.19,2.02,ok +368,Top,10.45,1.87,ok +369,Top,18.45,1.87,ok +370,Top,18.82,2.75,ok +371,Top,16.93,1.91,ok +372,Barrel,9.13,0.9,ok +373,Barrel,7.84,0.93,ok +374,Barrel,4.81,1.21,ok +375,Barrel,1.03,1.0,ok +376,Barrel,15.7,1.27,ok +377,Barrel,16.4,0.85,ok +378,Barrel,6.5,0.87,ok +379,Barrel,9.15,0.94,ok +380,Barrel,6.97,0.9,ok +381,Barrel,4.75,1.0,ok +382,Barrel,16.09,1.32,ok +383,Barrel,11.66,1.37,ok +384,Barrel,7.84,0.98,ok +385,Barrel,5.82,1.31,ok +386,Barrel,5.99,1.29,ok +387,Barrel,5.15,0.87,ok +388,Barrel,10.01,0.92,ok +389,Barrel,7.85,1.28,ok +390,Barrel,9.93,0.95,ok +391,Barrel,11.64,1.36,ok +392,Barrel,9.64,1.02,ok +393,Barrel,3.16,1.41,ok +394,Barrel,9.26,0.97,ok +395,Barrel,11.18,1.41,ok +396,Barrel,8.17,1.37,ok +397,Barrel,6.0,0.99,ok +398,Barrel,10.38,0.89,ok +399,Barrel,14.8,1.01,ok +400,Barrel,12.03,0.97,ok +401,Barrel,13.92,0.96,ok +402,Barrel,11.0,0.9,ok +403,Barrel,11.57,1.28,ok +404,Barrel,12.36,0.9,ok +405,Barrel,6.9,1.4,ok +406,Barrel,10.33,0.83,ok +407,Barrel,16.25,0.9,ok +409,Barrel,11.86,1.25,ok +410,Barrel,9.14,1.29,ok +411,Barrel,6.38,0.85,ok +412,Barrel,6.22,0.82,ok +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,unreliable +417,Barrel,7.98,1.45,ok +418,Barrel,7.96,2.28,unreliable +419,Barrel,17.9,1.92,ok +420,Barrel,6.82,1.96,ok +421,Barrel,11.13,1.96,ok +422,Barrel,11.53,2.0,ok +423,Barrel,9.71,2.84,ok +424,Barrel,8.68,1.92,ok +425,Barrel,12.89,2.32,ok +426,Barrel,10.84,2.51,ok +427,Barrel,7.92,1.37,ok +428,Barrel,10.07,2.24,ok +429,Barrel,12.23,1.01,ok +430,Barrel,7.6,2.0,ok +432,Barrel,11.94,1.57,ok +433,Barrel,12.1,1.47,ok +434,Barrel,9.58,1.85,ok +435,Barrel,12.41,1.5,ok +436,Barrel,8.17,1.43,ok +437,Barrel,4.91,1.57,ok +438,Barrel,14.03,2.01,ok +439,Barrel,10.26,1.57,ok +440,Barrel,5.55,2.54,ok +441,Barrel,9.52,2.28,ok +442,Barrel,12.17,1.58,ok +443,Barrel,16.01,2.88,ok +446,Barrel,10.01,2.45,ok +447,Barrel,12.17,1.49,ok +448,Barrel,11.31,1.55,ok +449,Barrel,13.17,1.32,ok +450,Barrel,5.7,1.88,ok +451,Barrel,6.34,1.46,ok +452,Barrel,12.1,1.42,ok +453,Barrel,0.0,1.55,ok +454,Barrel,8.29,1.04,ok +455,Barrel,17.55,1.42,ok +456,Barrel,9.53,1.53,unreliable +457,Barrel,10.18,1.6,ok +458,Barrel,10.18,1.54,ok +459,Barrel,9.69,1.99,ok +460,Barrel,5.08,1.04,ok +461,Barrel,9.32,1.59,ok +462,Barrel,17.05,2.13,ok +463,Barrel,16.18,1.44,ok diff --git a/configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt b/configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt index a5e258dad..cbc63ae99 100644 --- a/configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt +++ b/configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt @@ -1,9 +1,14 @@ 2 +6 11 +12 14 15 18 21 +27 +28 +77 85 100 113 diff --git a/configfiles/LoadWCSim/LoadWCSimConfig b/configfiles/LoadWCSim/LoadWCSimConfig index c142231f6..a25d47f59 100644 --- a/configfiles/LoadWCSim/LoadWCSimConfig +++ b/configfiles/LoadWCSim/LoadWCSimConfig @@ -2,17 +2,19 @@ # all variables retrieved with m_variables.Get() must be defined here! verbose 1 -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_24-09-17_BNB_Water_10k_22-05-17/wcsim_0.0.0.root -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_03-05-17_rhatcher/wcsim_0.1000.root ## first of the DOE proposal files -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_3-12-18_ANNIEp2v6_BNB_Water_10k_22-05-17/wcsim_0.0.0.root -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.0.0.root -InputFile ./25_04_19_wcsim_0.0.0.root +# 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 WCSimVersion 3 ## should reflect the WCSim version of the files being loaded HistoricTriggeroffset 0 ## time offset of digits relative to the trigger UseDigitSmearedTime 1 ## whether to use smeared digit time (T), or true time of first photon (F) -LappdNumStrips 56 ## num channels to construct from each LAPPD +LappdNumStrips 60 ## num channels to construct from each LAPPD LappdStripLength 100 ## relative x position of each LAPPD strip, for dual-sided readout [mm] LappdStripSeparation 10 ## stripline separation, for calculating relative y position of each LAPPD strip [mm] -PMTMask ./configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt ## Which PMTs should be masked out? / are dead? -ChankeyToPMTIDMap ./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt +PMTMask configfiles/BeamClusterAnalysisMC/DeadPMTIDs_p2v7.txt ## Which PMTs should be masked out? / are dead? +ChankeyToPMTIDMap ./configfiles/BeamClusterAnalysisMC/Chankey_WCSimID_v7.txt +SplitSubTriggers 0 # should subtriggers be loaded in separate Execute steps? diff --git a/configfiles/MuonFitter/ClusterClassifiersConfig b/configfiles/MuonFitter/ClusterClassifiersConfig new file mode 100644 index 000000000..948ed3354 --- /dev/null +++ b/configfiles/MuonFitter/ClusterClassifiersConfig @@ -0,0 +1,3 @@ +#ClusterClassifiers Config file +verbosity 0 +IsData 0 diff --git a/configfiles/MuonFitter/ClusterFinderConfig b/configfiles/MuonFitter/ClusterFinderConfig new file mode 100644 index 000000000..4e3606764 --- /dev/null +++ b/configfiles/MuonFitter/ClusterFinderConfig @@ -0,0 +1,11 @@ +# ClusterFinder Config File + +HitStore MCHits #Either MCHits or Hits (accessed in ANNIEEvent store) +OutputFile mc_clusters.root +ClusterFindingWindow 50 # in ns, size of the window used to "clusterize" +AcqTimeWindow 70000 # in ns, size of the acquisition window +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? +verbosity 0 diff --git a/configfiles/MuonFitter/DigitBuilderConfig b/configfiles/MuonFitter/DigitBuilderConfig new file mode 100644 index 000000000..989becdc6 --- /dev/null +++ b/configfiles/MuonFitter/DigitBuilderConfig @@ -0,0 +1,8 @@ +# DigitBuilder config file + +verbosity 0 +isMC 1 +ParametricModel 1 +PhotoDetectorConfiguration All +LAPPDIDFile ./configfiles/VertexReco/PhaseIIRecoTruth/LAPPDIDs.txt +DigitChargeThr 10 diff --git a/configfiles/MuonFitter/EventSelectorConfig b/configfiles/MuonFitter/EventSelectorConfig new file mode 100644 index 000000000..68c2686af --- /dev/null +++ b/configfiles/MuonFitter/EventSelectorConfig @@ -0,0 +1,25 @@ +# EventSelector config file + +verbosity 0 +MRDRecoCut 0 +MCFVCut 0 +MCPMTVolCut 0 +MCMRDCut 0 +MCPiKCut 0 +MCIsMuonCut 1 +MCIsElectronCut 0 +MCIsSingleRingCut 0 +MCIsMultiRingCut 0 +MCProjectedMRDHit 0 +MCEnergyCut 0 +Emin 0 +Emax 5000 +NHitCut 0 +NHitmin 4 +PromptTrigOnly 0 +RecoFVCut 0 +RecoPMTVolCut 0 +PMTMRDCoincCut 0 +PMTMRDOffset 10 +SaveStatusToStore 1 +IsMC 1 diff --git a/configfiles/MuonFitter/FindMrdTracksConfig b/configfiles/MuonFitter/FindMrdTracksConfig new file mode 100644 index 000000000..d78ed9b58 --- /dev/null +++ b/configfiles/MuonFitter/FindMrdTracksConfig @@ -0,0 +1,12 @@ +# FindMrdTracks Config File +# all variables retrieved with m_variables.Get() must be defined here! + +verbosity 0 +IsData 0 +OutputDirectory . +OutputFile mrdtrackfile # the output file built will be '/...root' +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/ReweightEventsGenie/LoadWCSimConfig b/configfiles/MuonFitter/LoadWCSimConfig similarity index 70% rename from configfiles/ReweightEventsGenie/LoadWCSimConfig rename to configfiles/MuonFitter/LoadWCSimConfig index 7945c02df..9907c8931 100644 --- a/configfiles/ReweightEventsGenie/LoadWCSimConfig +++ b/configfiles/MuonFitter/LoadWCSimConfig @@ -2,14 +2,16 @@ # all variables retrieved with m_variables.Get() must be defined here! verbose 1 -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_24-09-17_BNB_Water_10k_22-05-17/wcsim_0.0.0.root -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_03-05-17_rhatcher/wcsim_0.1000.root ## first of the DOE proposal files -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_3-12-18_ANNIEp2v6_BNB_Water_10k_22-05-17/wcsim_0.0.0.root -#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.0.0.root -#InputFile ./25_04_19_wcsim_0.0.0.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_24-09-17_BNB_Water_10k_22-05-17/wcsim_0.49......19.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_03-05-17_rhatcher/wcsim_0.49......00.root ## first of the DOE proposal files +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_3-12-18_ANNIEp2v6_BNB_Water_10k_22-05-17/wcsim_0.49......19.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.49......19.root +#InputFile ./25_04_19_wcsim_0.49......19.root -InputFile /annie/app/users/jminock/wcsim_test/wcsim_3.root -#InputFile /pnfs/annie/persistent/users/jminock/wcsim/wcsim_Gv3_0.root +#InputFile /annie/app/users/jminock/ToolAnalysis/wcsim_0.root +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beamlike/wcsim_beamlike_muon_0.100.root +InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/pmt/wcsim_0.0.0.root +#InputFile ./wcsim_0.*.root #InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/pmt-files/wcsim_beam_gst_1060_91_0.7091.root WCSimVersion 3 ## should reflect the WCSim version of the files being loaded diff --git a/configfiles/MuonFitter/LoadWCSimLAPPDConfig b/configfiles/MuonFitter/LoadWCSimLAPPDConfig new file mode 100644 index 000000000..0f1c9af59 --- /dev/null +++ b/configfiles/MuonFitter/LoadWCSimLAPPDConfig @@ -0,0 +1,14 @@ +#LoadWCSimLAPPD Config File +# all variables retrieved with m_variables.Get() must be defined here! +verbose 0 + +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_24-09-17_BNB_Water_10k_22-05-17/wcsim_lappd_0.49......19.root +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/lappd/tankonly/wcsim_lappd_tankonly_03-05-17_rhatcher/wcsim_lappd_0.49......00.root ## first of the DOE proposal files +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beamlike/wcsim_beamlike_muon_lappd_0.100.root +InputFile /pnfs/annie/persistent/simulations/wcsim/G1810a0211a/standard/tank/lappd/wcsim_lappd_0.0.0.root +#InputFile ./wcsim_lappd_0.*.root +#InputFile /annie/app/users/jminock/ToolAnalysis/wcsim_lappd_0.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/MuonFitter/MCParticlePropertiesConfig b/configfiles/MuonFitter/MCParticlePropertiesConfig new file mode 100644 index 000000000..019526011 --- /dev/null +++ b/configfiles/MuonFitter/MCParticlePropertiesConfig @@ -0,0 +1,3 @@ +# MCParticleProperties configuration file + +verbosity 0 diff --git a/configfiles/MuonFitter/MCRecoEventLoaderConfig b/configfiles/MuonFitter/MCRecoEventLoaderConfig new file mode 100644 index 000000000..81f5502a1 --- /dev/null +++ b/configfiles/MuonFitter/MCRecoEventLoaderConfig @@ -0,0 +1,10 @@ +# MCRecoEventLoader config file + +verbosity 1 +GetPionKaonInfo 1 +GetNRings 1 +ParticleID 13 +DoParticleSelection 1 +xshift 0.0 +yshift 14.46469 +zshift -168.1 diff --git a/configfiles/MuonFitter/MuonFitterConfig b/configfiles/MuonFitter/MuonFitterConfig new file mode 100644 index 000000000..69465ed64 --- /dev/null +++ b/configfiles/MuonFitter/MuonFitterConfig @@ -0,0 +1,33 @@ +verbosity 0 + +OutputFile MC_MuonFitter_Reco_2998.root +IsData 0 # 1:is data, not MC; 0:not data, is MC +LuxArea 506.7 # 10-inch R7081 Hamamatsu +EtelArea 613.1 # 11-inch D784UKFLB ETEL +HamamatsuArea 324.3 # 8-inch R5912-100 Hamamatsu +WatchboyArea 506.7 # 10-inch R7081 Hamamatsu +WatchmanArea 506.7 # 10-inch R7081-100 Hamamatsu +PMTMRDOffset 0 # delay btwn tank and MRD PMTs +StepSizeAi 15 # some distance muon travels [cm] +InsideAngle 1. # degrees added to Cherenkov angle for hits to be considered inside cone +OutsideAngle 9. # degrees added to Cherenkov angle for hits to be considered outside cone +PMTChargeThreshold 2 # minimum amount of charge seen by PMT +EtaThreshold 500 # threshold to find best vertex +DisplayTruth 0 # display truth information in graphs (only in MC) +RecoMode 0 # run tool after fitting tank track +AiEtaFile ev_ai_eta_R0.0.txt +#TankTrackFitFile /exp/annie/app/users/jhe/MyToolAnalysis_MFer/fitbyeye_wcsim_2000-2999_RNN_240525v1.txt +#TankTrackFitFile fitbyeye_wcsim_2000-2999_RNN_240525v1.txt +TankTrackFitFile tanktrackfitfile_r0.0_RNN.txt + +UseNumLayers 1 # Updates reco track length in MRD using number of layers +UsePCA 0 # Updates reco track length in MRD using number of layers and PCA-reconstructed track angle (set UseNumLayers 1) +UseConnDots 0 # Updates reco track length in MRD by connecting the MRD hits +UseELoss 0 # Use official ANNIE MRD energyLoss as starting MRD energy +UseSimpleEReco 0 # Just add ANNIE MRD energyLoss (set UseELoss 1); no updating dEdx +RecoEnergyShift 0 # Shift reco muon energy + +Plot3D 0 # 0:no plot; 1:yes plot +Draw3DFMV 0 +Draw3DMRD 0 +SaveHistograms 0 # 0:no; 1:yes diff --git a/configfiles/MuonFitter/README.md b/configfiles/MuonFitter/README.md new file mode 100644 index 000000000..a5ee2aa00 --- /dev/null +++ b/configfiles/MuonFitter/README.md @@ -0,0 +1,57 @@ +#MuonFitter Config + +*********************** +#Description +********************** + +Date created: 2024-10-02 +Date last updated: 2024-11-26 +The MuonFitter toolchain makes an attempt to fit muons using hit information. + +The Tool has 2 modes. The first mode is pre-reconstruction. It takes input information from the ANNIEEvent and generates a text file containing hit information for the RNN. It is advisable to include minimal tools in this ToolChain, as the same data must be re-analysed with ToolAnalysis later. + +This text file produced in this step is then processed by a standalone python script (Fit_data.py), which outputs fitted information into a new text file. + +The second mode is reconstruction. In this mode the Tool reads information from the ANNIEEvent, along with both text files from the previous two steps (the first mode and the python script) and reconstructs the vertex based on the fitted paths. The resulting muon fit information is passed into the DataModel. + +The Toolchain included in this directory is the minimal working Toolchain for MuonFitter to function. All Tools in the ToolChain MUST be included in order for MuonFitter to function. It is recommended to include PhaseIITreeMaker after MuonFitter in RecoMode 1 to generate an ntuple with reconstructed variables from MuonFitter. + +More detailed instructions are below. + +************************ +#Usage +************************ + +To generate (train) a model: +============================ + +1. Run a ToolChain containing the MuonFitter Tool configured in "RecoMode 0". This will generate 2 files: ev_ai_eta_R{RUN}.txt with a {RUN} number corresponding to the WCSim run number and true_track_len.txt. You should not include any Tools further along the ToolChain for this step. + +2. Run Data_prepare.py with the generated ev_ai_eta file and true_track_len file. This will generate data files to train the model for the next step. + +3. Run RNN_train.py with the data files generated from the previous step. This will generate model.pth to be used as the model for data analysis. + +Previously generated models and data are stored in /pnfs/annie/persistent/simulations/models/MuonFitter/ which may be used. + +Please update any paths in the Tool configuration and Fit_data.py accordingly, or copy the appropriate model files to the configfiles/MuonFitter/RNNFit directory. + +To analyse data: +================ + +1. First, run a ToolChain containing the MuonFitter Tool configured in "RecoMode 0". This will generate a file: ev_ai_eta_R{RUN}.txt with a {RUN} number corresponding to the WCSim run number. You should not include any Tools further along the ToolChain for this step. + +2. Second, run "python3 Fit_data.py ev_ai_eta_R{RUN}.txt". This will apply the fitting and generate another textfile to be ran in ToolAnalysis: tanktrackfitfile_r{RUN}_RNN.txt. Again: please update any paths such that all files and models are available. + +NOTE: the script RNNFit/rnn_fit.sh can act as a helper to process multiple ev_ai_eta_R{RUN}.txt files. Be sure to update the path in the script to point to your ev_ai_eta text files from step 1. + +3. Finally, run a ToolChain containing the MuonFitter Tool configured in "RecoMode 1". Please set the paths for the ev_ai_eta_R{RUN}.txt and tanktrackfitfile_r{RUN}_RNN.txt in the MuonFitter config file accordingly. You may include any downstream tools you desire for further analysis. See the UserTools/MuonFitter/README.md for short descriptions of information saved to the DataModel and how to access them. + +Storage for intermediate files: +=============================== + +Intermediate files can be stored in directories in /pnfs/annie/persistent/simulations/models/MuonFitter/ +truetanktracklength/ - would contain true_track_len.txt +tanktrackfit/ - would contain tanktrackfitfile_r{RUN}_RNN.txt +ev_ai_eta/ - would contain ev_ai_eta_R{RUN}.txt + +These directories are currently empty as of 11/26/2024 and will be filled upon Production level generation of ntuples using MuonFitter. diff --git a/configfiles/MuonFitter/RNNFit/Data_prepare.py b/configfiles/MuonFitter/RNNFit/Data_prepare.py new file mode 100644 index 000000000..b0f978eba --- /dev/null +++ b/configfiles/MuonFitter/RNNFit/Data_prepare.py @@ -0,0 +1,49 @@ +# coding: utf-8 + +# # Import modules +import pandas as pd +import json + + +# # Prepare data into pandas DataFrame +dataX = pd.read_csv("ev_ai_eta_R0.0.txt",sep=',',header=None,names=['id','ai','eta']) #ai is track segment +dataY = pd.read_csv("true_track_len.txt",sep=',',header=None,names=['id','truetracklen']) +# dataX['combine'] = dataX[['X','Y']].values.tolist() + + +# ### Preview dataframes +dataX.head(5) +dataY.head(5) + + +# # Aggregate data and filter out extremely long and negative tracks +grouped = dataX.groupby('id').agg(list).reset_index() +data = pd.merge(grouped, dataY, on='id') +print("after merge: " + str(len(data))) +criteria = data['truetracklen'] > 1000 +data = data[~criteria] +print("after first filter (>1000): " + str(len(data))) +critiera = data['truetracklen'] < 0 +data = data[~criteria] +print("after second filter (<0): " + str(len(data))) +print(data.columns) +data.head(10) + + +# # Prepare data into json format +json_data = data.to_json(orient='index') + + +# # Save json data into .json file +file_path = './data.json' +with open(file_path, 'w') as json_file: + json_file.write(json_data) + + +# # Save pandas DataFrame as csv file +data.to_csv('./data.csv', index=False) + + +# # Save data into h5 file << USE THIS ONE +data.to_hdf("./data.h5",key='df') + diff --git a/configfiles/MuonFitter/RNNFit/Fit_data.py b/configfiles/MuonFitter/RNNFit/Fit_data.py new file mode 100644 index 000000000..6bccecd82 --- /dev/null +++ b/configfiles/MuonFitter/RNNFit/Fit_data.py @@ -0,0 +1,77 @@ +# coding: utf-8 +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader +from torch.utils.data import Dataset +import torch.nn as nn +import torch.optim as optim +from sklearn.model_selection import train_test_split +import matplotlib.pyplot as plt +import time +import sys + +if (len(sys.argv) != 2): + print(" @@@@@ MISSING ev_ai_eta_R{RUN}.txt FILE !! @@@@@ ") + print(" syntax: python3 Fit_data.py ev_ai_eta_R{RUN}.txt") + print(" path: ~/annie/analysis/FILE") + exit(-1) + +DATAFILE = sys.argv[-1] + +# ## Extract run number from filename +# ## NOTE: Assumes filename has this structure: ev_ai_eta_R{RUN}.txt +RUN = DATAFILE[12:-4] + +# ## Define ManyToOneRNN class +class ManyToOneRNN(nn.Module): + def __init__(self, input_size, hidden_size, num_layers, output_size): + super(ManyToOneRNN, self).__init__() + self.hidden_size = hidden_size + self.num_layers = num_layers + self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True,nonlinearity='relu') + self.fc = nn.Linear(hidden_size, output_size) + + def forward(self, x): + # Initialize hidden state with zeros + h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) + # Forward propagate the RNN + out, _ = self.rnn(x,h0) + + # Decode the hidden state of the last time step + out = self.fc(out[:, -1, :]) + return out + + +# ## Load model +model = torch.load('model.pth') +model.eval() + + +# ## Load data (needs to be in Tensor format) +data = pd.read_csv(DATAFILE, header=None, names=['evid','cluster_time','ai','eta']) +print(data.head(5)) + +data = data.groupby(['evid', 'cluster_time']).agg(list).reset_index() +print(data.head(5)) + +print(data.iloc[0,2:]) + +# ## Do the fit +# open output file +OUTFILENAME = "tanktrackfitfile_r" + RUN + "_RNN.txt" +out_f = open(OUTFILENAME, "a") + +for idx in range(len(data)): + dataT = torch.tensor(data.iloc[idx,2:]).t() + dataT.unsqueeze_(0) + out = model(dataT) + print(data.iloc[idx,0], out) + out_f.write(str(data.iloc[idx,0]) + "," + str(data.iloc[idx,1]) + "," + str(out.data.numpy()[0][0]) + "\n") + +# close output file +out_f.close() + +############################################################ +############### EOF +############################################################ diff --git a/configfiles/MuonFitter/RNNFit/RNN_train.py b/configfiles/MuonFitter/RNNFit/RNN_train.py new file mode 100644 index 000000000..faa1ea3c8 --- /dev/null +++ b/configfiles/MuonFitter/RNNFit/RNN_train.py @@ -0,0 +1,214 @@ +# coding: utf-8 + +# ## Import modules +import numpy as np +import pandas as pd +import torch +from torch.utils.data import DataLoader +from torch.utils.data import Dataset +import torch.nn as nn +import torch.optim as optim +from sklearn.model_selection import train_test_split +import matplotlib.pyplot as plt +import time + + +# ## Load data, using half of the dataset to train +data = pd.read_hdf("data.h5", 'df') +train_df, test_df = train_test_split(data, test_size=0.5) +test_df, CV_df = train_test_split(test_df, test_size=0.5) +# validation used to keep track of training set; monitor accuracy + +# ### Preview data +print("len train_df: " + str(len(train_df))) +train_df.head(5) + +print("len test_df: " + str(len(test_df))) +test_df.head(5) + +print("len CV_df: " + str(len(CV_df))) +CV_df.head(5) + +print(data[data['truetracklen'] < 0.]) + + +# ## Define MyDataset class +class MyDataset(Dataset): + def __init__(self, dataframe): + self.data = dataframe + + def __len__(self): + return len(self.data) + + def __getitem__(self, idx): + evid = self.data.iloc[idx,0] #added to include evid in output file + features = torch.tensor(self.data.iloc[idx, 1:-1], dtype=torch.float32) + features = features.t() + target = torch.tensor(self.data.iloc[idx, -1], dtype=torch.float32) + return evid, features, target #added evid as return value + +# ### Prepare data for training +batch_size = 1 # Adjust batch size as needed +# sequence_length = 3 # Adjust sequence length as needed +shuffle = True # Shuffle the data during training (recommended) +dataS = MyDataset(data) +train = MyDataset(train_df) +test = MyDataset(test_df) +CVS = MyDataset(CV_df) +trainloader = DataLoader(train, batch_size=1, shuffle=shuffle) #how much data to train per epoch +testloader = DataLoader(test) +dataloader = DataLoader(dataS, batch_size=1, shuffle=shuffle) +CVloader = DataLoader(CVS) + +print(dataloader) + + +# ## Define ManyToOneRNN class +class ManyToOneRNN(nn.Module): + def __init__(self, input_size, hidden_size, num_layers, output_size): + super(ManyToOneRNN, self).__init__() + self.hidden_size = hidden_size + self.num_layers = num_layers + self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True,nonlinearity='relu') + self.fc = nn.Linear(hidden_size, output_size) + + def forward(self, x): + # Initialize hidden state with zeros + h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) + # Forward propagate the RNN + out, _ = self.rnn(x,h0) + + # Decode the hidden state of the last time step + out = self.fc(out[:, -1, :]) + return out + +# ### Set parameters for training model +cost_list = [] +CVcost_list = [] +input_size = 2 +hidden_size = 4 +num_layers = 1 +output_size = 1 +learning_rate = 0.001 #can tune this for better model +num_epochs = 10000 #default:10000 + +model = ManyToOneRNN(input_size, hidden_size, num_layers, output_size) +criterion = nn.MSELoss() +optimizer = optim.Adam(model.parameters(), lr=learning_rate) + +N = 100 #for printing progress + + +# ## Define training +def train(): + model.train() + + for epoch in range(num_epochs): + COST=0 + CVCost = 0 + i = 0 + for ev,dat,target in trainloader: # Iterate in batches over the training dataset.; EDIT: added ev + out = model(dat) # Perform a single forward pass. + loss = criterion(out, target) # Compute the loss. + loss.backward() # Derive gradients. + optimizer.step() # Update parameters based on gradients. + optimizer.zero_grad() # Clear gradients. + COST += loss.data + i += 1 + # if epoch % 100 == 0 and i ==1 : + # print("loss is {}".format(loss.data)) + # print("target value is {}".format(target)) + # print("out is {}".format(out)) + + cost_list.append(COST) + + #perform a prediction on the validation data + for CVID,CVD,CVT in CVloader: + + with torch.no_grad(): + CVout = model(CVD) + loss = criterion(CVout, CVT) + + CVCost += loss + + CVcost_list.append(CVCost) + + if epoch%N == 0: + print("epoch number:{}".format(epoch)) + print("validation MSE is {}".format(COST)) + print("train MSE is {}".format(CVCost)) + + +# ## Train model +tstart=time.time() +print("start time={}".format(tstart)) +train() +torch.save(model, 'model.pth') # save model + +print((time.time()-tstart)) + + +# ### Plot the loss and accuracy +fig, ax1 = plt.subplots() +color = 'tab:red' +ax1.plot(cost_list[200::100], color=color,label="Train") +ax1.plot(CVcost_list[200::100], color='tab:blue',label="Validation") +ax1.set_xlabel('epoch', color=color) +ax1.set_ylabel('Cost', color=color) +ax1.tick_params(axis='y', color=color) +ax1.legend() +plt.savefig("loss.png", dpi=300) + +# want red and blue to be close and cost to be low + + +# ## Test model +def test(loader): + model.eval() + + #open output file for fitted track length + out_f = open("fitbyeye_wcsim_RNN.txt", "a") + + diff_list = [] + for evid,data,target in loader: # Iterate in batches over the training/test dataset. + with torch.no_grad(): + out = model(data) # just need this for data + diff = out - target # Use the class with highest probability. + #print(evid[0], out.data.numpy()[0][0], target.data.numpy()[0]) #evid, fit, truelen + #print(diff) + out_f.write(str(evid[0]) + "," + str(out.data.numpy()[0][0]) + "\n") + diff_list.append(diff.data.numpy()[0][0]) # Check against ground-truth labels. + # diff_list.append(diff.data.numpy()) # Check against ground-truth labels. + out_f.close() + return diff_list # Derive ratio of correct predictions. + +diff_list = test(dataloader) + + +# ### Plot difference btwn model fit and truth info +plt.hist(diff_list) + +mean = np.mean(diff_list) +std = np.std(diff_list) + +# custom_labels = ['Mean is {}'.format(mean), 'Std is {}'.format(std)] + +# Add a legend with custom labels +plt.text(20, 40, f'Mean: {mean:.2f}', fontsize=12, color='red') +plt.text(20, 35, f'Std: {std:.2f}', fontsize=12, color='green') + + +plt.xlabel("y - yhat") +plt.ylabel("Number of Event") +plt.title("RNN Muon Vetex Reconstruction Performance") +# plt.legend(custom_labels) +plt.savefig("RNN.png") + +print("mean: ",mean) +print("std: " + str(std)) + + +# ## Save the model +#torch.save or model.save +#load model in another script and just use + diff --git a/configfiles/MuonFitter/RNNFit/rnn_fit.sh b/configfiles/MuonFitter/RNNFit/rnn_fit.sh new file mode 100755 index 000000000..958b417b6 --- /dev/null +++ b/configfiles/MuonFitter/RNNFit/rnn_fit.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +filelist="/home/jhe/annie/analysis/flist.txt" + +while read -r file +do + echo "python3 Fit_data.py ${file}" + python3 Fit_data.py ${file} +done < $filelist diff --git a/configfiles/MuonFitter/TimeClusteringConfig b/configfiles/MuonFitter/TimeClusteringConfig new file mode 100644 index 000000000..4a968f850 --- /dev/null +++ b/configfiles/MuonFitter/TimeClusteringConfig @@ -0,0 +1,12 @@ +#TimeClustering Config File + +verbosity 0 +IsData 0 +MinDigitsForTrack 4 +MaxMrdSubEventDuration 30 # [ns] if all hits are within this period, just make one subevent +MinSubeventTimeSep 30 # [ns] gaps of at leas this long delimit subevents +MakeMrdDigitTimePlot 0 # draw a 1D histogram of times to check subevent splitting is suitble +MakeSingleEventPlots 0 +LaunchTApplication 0 +MapChankey_WCSimID ./configfiles/CC_MC_RECO_ntuple/MRD_Chankey_WCSimID.dat +OutputROOTFile test.root diff --git a/configfiles/MuonFitter/ToolChainConfig b/configfiles/MuonFitter/ToolChainConfig new file mode 100644 index 000000000..332810a4f --- /dev/null +++ b/configfiles/MuonFitter/ToolChainConfig @@ -0,0 +1,26 @@ +#ToolChain dynamic setup file + +##### Runtime Parameters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandled errors only, 2= exit on unhandled errors and handled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails +remote_port 24002 +IO_Threads 1 ## Number of threads for network traffic (~ 1/Gbps) + +###### 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/MuonFitter/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/MuonFitter/ToolsConfig b/configfiles/MuonFitter/ToolsConfig new file mode 100644 index 000000000..59cd923b6 --- /dev/null +++ b/configfiles/MuonFitter/ToolsConfig @@ -0,0 +1,12 @@ +myLoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig +myLoadWCSim LoadWCSim configfiles/MuonFitter/LoadWCSimConfig +myLoadWCSimLAPPD LoadWCSimLAPPD configfiles/MuonFitter/LoadWCSimLAPPDConfig +myMCParticleProperties MCParticleProperties configfiles/MuonFitter/MCParticlePropertiesConfig +myMCRecoEventLoader MCRecoEventLoader configfiles/MuonFitter/MCRecoEventLoaderConfig +myTimeClustering TimeClustering configfiles/MuonFitter/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/MuonFitter/FindMrdTracksConfig +myClusterFinder ClusterFinder configfiles/MuonFitter/ClusterFinderConfig +myClusterClassifiers ClusterClassifiers configfiles/MuonFitter/ClusterClassifiersConfig +myDigitBuilder DigitBuilder configfiles/MuonFitter/DigitBuilderConfig +myEventSelector EventSelector configfiles/MuonFitter/EventSelectorConfig +myMuonFitter MuonFitter configfiles/MuonFitter/MuonFitterConfig diff --git a/configfiles/PMTWaveformSim/ClusterClassifiersConfig b/configfiles/PMTWaveformSim/ClusterClassifiersConfig new file mode 100644 index 000000000..f079d9b8a --- /dev/null +++ b/configfiles/PMTWaveformSim/ClusterClassifiersConfig @@ -0,0 +1,3 @@ +#ClusterClassifiers Config file +verbosity 0 +IsData 1 diff --git a/configfiles/PMTWaveformSim/ClusterFinderConfig b/configfiles/PMTWaveformSim/ClusterFinderConfig new file mode 100644 index 000000000..ded568144 --- /dev/null +++ b/configfiles/PMTWaveformSim/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 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/PMTWaveformSim/LoadGeometryConfig b/configfiles/PMTWaveformSim/LoadGeometryConfig new file mode 100644 index 000000000..b52737aa4 --- /dev/null +++ b/configfiles/PMTWaveformSim/LoadGeometryConfig @@ -0,0 +1,9 @@ +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LoadGeometry/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +TankPMTTimingOffsetFile ./configfiles/LoadGeometry/TankPMTTimingOffsets.csv \ No newline at end of file diff --git a/configfiles/PMTWaveformSim/LoadWCSimConfig b/configfiles/PMTWaveformSim/LoadWCSimConfig new file mode 100644 index 000000000..810e60949 --- /dev/null +++ b/configfiles/PMTWaveformSim/LoadWCSimConfig @@ -0,0 +1,13 @@ +verbose 1 +InputFile wcsim_0.root + +WCSimVersion 3 +HistoricTriggeroffset 0 +UseDigitSmearedTime 0 +LappdNumStrips 56 +LappdStripLength 100 +LappdStripSeparation 10 +PMTMask ./configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt +ChankeyToPMTIDMap ./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt +ChankeyToMRDIDMap ./configfiles/LoadWCSim/MRD_Chankey_WCSimID.dat +ChankeyToFMVIDMap ./configfiles/LoadWCSim/FMV_Chankey_WCSimID.dat diff --git a/configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv b/configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv new file mode 100644 index 000000000..4106d8905 --- /dev/null +++ b/configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv @@ -0,0 +1,119 @@ +PMT, p0, p1, p2, T1, T2, r1, r2, uncertainty_p0, uncertainty_p1, uncertainty_p2, uncertainty_T1, uncertainty_T2, uncertainty_r1, uncertainty_r2 +332, 20.357853978341936, 65.90384439721554, 0.0340967744115092, 7.557160702639488, 6.585655917219643, 0.1503852922643872, 0.0283262902553479, 1.5006784011077394, 0.1821045576494313, 0.0020383848858524, 0.8183581423499159, 1.3294537012359884, 0.0319670913492465, 0.0212107330727452 +334, 6.292263691717479, 66.17529055087431, 0.0479550421907901, 7.028760743259689, 6.708418856643082, 1.2999999999999998, 0.8831324340336038, 0.754961760469793, 0.5060144651618599, 0.0047079405839556, 0.5494404969709311, 0.3931356265396093, 0.2227145854675353, 0.262187622488554 +335, 15.790696448010278, 66.7984345406303, 0.0421359716208697, 8.681214051550992, 8.406762885569735, 0.1665020833218284, 0.0798274099045134, 1.4366601798060934, 0.2926699462545326, 0.0025504882574863, 0.9806570759481033, 0.5682558594952786, 0.0388617629341706, 0.020493300267404 +336, 14.383511954753358, 66.3345096634602, 0.0402961636208563, 9.030202858813963, 8.12502775564912, 0.2018161494205744, 0.1099581127595617, 0.7312133475898853, 0.1505907674866848, 0.0015810733327726, 0.6038714965494124, 0.3897435593647128, 0.0284952802199744, 0.0213485284430556 +338, 9.751203657255116, 66.09204333811005, 0.0417688718421429, 7.870905656037526, 7.48408716940295, 0.8793499987261487, 0.3813396934209984, 0.6291471368220871, 0.1842806521392485, 0.0017302975245936, 0.2386304454804918, 0.2398935612948264, 0.0695339006141688, 0.0506630520223418 +339, 12.297137860654884, 66.25433439234966, 0.0410039389624383, 8.712815893450685, 9.078555383381486, 0.287588600092208, 0.1860505124675845, 0.9699956938398736, 0.2237270945022526, 0.0024822126317048, 0.7725603832311662, 0.5379861371461777, 0.0611103629288461, 0.0494593533475276 +340, 13.236372335808973, 66.6125305674671, 0.0426244102502171, 9.341517097309929, 9.341753844982414, 0.2787903874544818, 0.1298472064798972, 0.9722414439332344, 0.197676827031285, 0.0020950128178821, 0.5415375345441487, 0.5358072131451369, 0.0395040903759332, 0.0343961868646554 +341, 19.671767926618845, 66.57659829699266, 0.0392724761439105, 8.66492442594544, 7.823086748074368, 0.1733782616419335, 0.0251066508853136, 0.8609250064152121, 0.117863382297257, 0.0012647868135769, 0.4943269882416702, 1.105360575091787, 0.0199459893319272, 0.013031301380743 +344, 12.2135404235275, 66.21814185876319, 0.0402443983589074, 9.999999999999998, 9.999999999999998, 0.4583938774896324, 0.327458807747422, 3.271092049037668, 0.6677256037508603, 0.0052553814226796, 0.9418292192490556, 0.6611275022340305, 0.1554458296742829, 0.1270203810499398 +347, 17.237522282606196, 66.88819719304713, 0.041863701801471, 7.054668116607341, 7.904142341113217, 0.2386773215632731, 0.0525338860923424, 1.0016354950146786, 0.2279784361981261, 0.0021616698215719, 0.7097112099875018, 0.8459998117959165, 0.0545083704982428, 0.0215464687425428 +348, 19.330360090339248, 66.71209409634614, 0.0398160824347048, 8.850519058543316, 9.357958326080697, 0.1643832828586765, 0.0631286738890893, 1.0058583214126628, 0.1409381082663351, 0.0014471801848537, 0.4954874299763987, 0.3541299315363446, 0.0210955720887048, 0.0119934424997495 +350, 19.050897037557963, 66.06911930633586, 0.0349696973891647, 7.771461656171925, 7.385219746743812, 0.1361972160753289, 0.0283486293661057, 0.959697403682776, 0.1300662540797689, 0.0013681710052555, 0.5474234625525469, 0.7528051678346602, 0.0219350406831112, 0.0118744913643624 +351, 20.46018688687866, 66.28463751212165, 0.0356813804674755, 7.949883842739932, 7.924394777152569, 0.1433122937248124, 0.0151484017212938, 0.8684720810861236, 0.1107167474626796, 0.0011120124103089, 0.3853890130351099, 0.898701255137052, 0.016464840588247, 0.0070669185445902 +353, 7.538493076099391, 64.90405391519464, 0.033709862211958, 7.147215216338458, 7.387082838850287, 0.2740162858771454, 0.0279572647798352, 0.385700571206148, 0.144271104398858, 0.0019475881695673, 0.46593025700815, 2.0866025789857123, 0.0452298134623492, 0.0363609431824052 +354, 17.811456970786526, 67.46145611134042, 0.0448806473551208, 8.364787449091981, 9.365560244850483, 0.2884148127179849, 0.0841552346104563, 1.0550132433996708, 0.1871692339128528, 0.0017231848649593, 0.3858520847309457, 0.3692117386846541, 0.0334737210055136, 0.015474857709283 +355, 11.008456595647305, 67.4326306929489, 0.050884817029899, 9.098796385195598, 9.954330813147434, 0.271961217862843, 0.0785939358749361, 0.497947186364587, 0.1775190810225733, 0.0018378629024142, 0.4393889369072745, 0.5048889587521092, 0.0300373539886787, 0.015456706806295 +356, 8.266511790339552, 64.90421719919337, 0.0362584188783418, 7.296051860387467, 7.936996736221687, 0.3119339831842557, 0.1065571987204909, 0.7747643827392147, 0.2278143488689185, 0.0025563167861311, 0.4831649049641118, 0.607733953959011, 0.047786977324938, 0.0411330394082787 +357, 16.83827719845519, 67.98649737338961, 0.0488589063764169, 8.715776607463875, 9.686373080102197, 0.317360105169386, 0.1091658092760097, 1.47255133189011, 0.3058130787158061, 0.0027411885052504, 0.5468664172609529, 0.437332187025368, 0.0571768798045901, 0.0218602903508639 +358, 10.588611200775787, 65.55145501058198, 0.0375302199806138, 7.032609490880665, 7.382789294556115, 0.395240092652954, 0.0821026238510351, 0.7166051123354304, 0.1959985392242673, 0.0020450892586263, 0.3602105518180945, 0.5735352663913568, 0.0480789232970733, 0.0241669289931063 +360, 12.989523387362754, 67.43889722954187, 0.0490778437418347, 9.178232884799996, 9.999999999999998, 0.2838452583454555, 0.0790984645918084, 0.611297868773257, 0.1789603734389225, 0.0017966225547267, 0.440223444369138, 0.5150740343162961, 0.0318429640634362, 0.016963149224655 +361, 9.152541649643704, 65.19848920697314, 0.0355782101555033, 5.754350987206749, 6.240737091825019, 0.4882725615755737, 0.1921702513822433, 0.9039223425346138, 0.3169800739912223, 0.0033503817235365, 0.5195944812474874, 0.4262150700328748, 0.1067108748039876, 0.055461481172022 +362, 14.257330335978208, 67.25062803286859, 0.0455298878788364, 8.785319479913118, 9.544639360492388, 0.2372920619753069, 0.0662136604169978, 0.6248513845555664, 0.1407506162089925, 0.001330056292391, 0.2913950619337741, 0.3149709085760995, 0.0218185539178776, 0.009425473245432 +363, 14.37440551348584, 66.99281218787614, 0.0441690641032088, 8.162230183905065, 9.328589221880376, 0.2791999479399347, 0.071630276694176, 0.7955827329506822, 0.1743714143274772, 0.0017276221333635, 0.4042614793689724, 0.4629478891129285, 0.0350566328301072, 0.0151883879792555 +364, 11.209341886338796, 67.5298345924113, 0.0505583268434526, 8.589305269459647, 9.361193322478924, 0.3083212753213922, 0.0652203603825681, 0.5024802349597685, 0.2071002609469198, 0.0020526916892498, 0.4983360964235795, 0.7692829232687812, 0.0419311772303984, 0.0197042258068616 +365, 10.466342200724522, 67.01549260673573, 0.0490357604131224, 8.703495741380584, 9.5413216467255, 0.2901998987673181, 0.0695586495138962, 0.4811489426909944, 0.1889924442762473, 0.0019915926052866, 0.4574497254291375, 0.6446410926555026, 0.03496492394386, 0.0179338200887867 +366, 8.238963208355255, 65.31371086437863, 0.037826453042094, 6.9440160033602645, 7.083326382024604, 0.3404063954596296, 0.0848594805349115, 0.4225362793625691, 0.165471263411407, 0.0018784814058399, 0.3947423550768326, 0.5990073974407618, 0.0396755579772224, 0.0270374337457129 +367, 17.221447145341997, 67.38180136856019, 0.0463019190587128, 9.261792583194069, 8.910818909916847, 0.2647917364447043, 0.0688395476615478, 1.1122327907666834, 0.2083636694046652, 0.0021228996696989, 0.4957113399827973, 0.5918826537798941, 0.0326279028697975, 0.0177669028319231 +368, 16.055617970932637, 67.6045562971837, 0.048645952971135, 8.668428731726522, 9.397754566149544, 0.3177199305298535, 0.0875385610776006, 0.8087785725388428, 0.1903535750972179, 0.001858743137012, 0.4110759187780123, 0.4443929993361959, 0.0377975861469125, 0.016091114671514 +369, 8.235514483612029, 65.39845991622674, 0.0379919780567145, 5.195837313213686, 5.841392431189012, 0.4633905603219343, 0.218082652995764, 0.6753439039520601, 0.3058374607984611, 0.0027808731333128, 0.5093918536723553, 0.3062621394095709, 0.1260503074233654, 0.0513733019244091 +370, 9.827913801926622, 66.0029553149226, 0.0408463267695314, 4.670733303673959, 5.530465872066271, 0.5330036879159584, 0.2881785488445582, 1.4064672968668608, 0.5336943438568987, 0.0038190146827619, 0.7204958564658008, 0.3638948806595114, 0.2616106607633683, 0.0898330223648199 +371, 15.536924107906126, 67.31011301676995, 0.0460609945752772, 8.170689499542611, 8.776286477487787, 0.3358923530971972, 0.090995966096718, 0.8326839920806605, 0.1914391963734649, 0.0018055048426144, 0.3863461541721553, 0.4212820655693525, 0.0385778283500794, 0.0173991403126674 +372, 20.265801207087076, 66.26643798500443, 0.037625758884311, 7.691365477704399, 7.934860337473662, 0.2062905507564349, 0.1099545604410246, 1.7323620620757134, 0.2165536486686666, 0.00208843117146, 0.6060900699060611, 0.3691399059204142, 0.040189979210692, 0.0216112090271472 +373, 18.47144696591243, 66.10843510828055, 0.0368250562553195, 7.37889451927354, 7.926558542135284, 0.1780689923412876, 0.0992824526972676, 1.0386260204178026, 0.1465209405415157, 0.001423639726641, 0.4960782919123777, 0.2651544908150366, 0.0266197166251409, 0.0151614616280693 +374, 18.733450625202543, 66.03714395896549, 0.0357466721532745, 6.821980748374166, 7.42455753358584, 0.2004897248381177, 0.0967446905983924, 1.3117159659263418, 0.181747766583614, 0.0018190688074595, 0.593356767971712, 0.349141087276101, 0.0431702972880477, 0.0196726485958993 +375, 18.29964101164197, 65.99041546078678, 0.0360924681726434, 6.788350534514889, 6.9933261635974935, 0.1890352464355826, 0.0883206877550451, 1.2398531836790057, 0.1838388338187482, 0.0018043317084514, 0.5978804693061366, 0.3329718257885954, 0.0387644050824806, 0.0169542976112072 +376, 18.27003660075122, 65.93388119788045, 0.0349124830899537, 6.324933649949538, 7.154945500990409, 0.2517633898831827, 0.1143958038629183, 1.2831597386108702, 0.1882514192308142, 0.0017213712270112, 0.4547619440641796, 0.2994235057762209, 0.0459274076706117, 0.0204626135754265 +377, 18.025089963105607, 66.2495254397634, 0.0371680236705387, 7.892418019437722, 7.9585813233008444, 0.18547839075243, 0.0807544808460221, 1.3576058819403294, 0.1899875859611221, 0.0017963602647972, 0.5574188200868234, 0.3787728361010564, 0.0337894783102483, 0.0171747233015483 +378, 17.988837317346352, 66.08187729182039, 0.0364098975116126, 6.894381296547095, 7.301397539820902, 0.1992731803776769, 0.0956253533013246, 1.2081798572278206, 0.1780396826276052, 0.0017803965463349, 0.5626408446382771, 0.3369999517809889, 0.0386051086745962, 0.0165434939462849 +379, 21.50877185750913, 65.96737726011403, 0.0343135506346025, 7.7513648710468575, 7.45351379507988, 0.1989535915872935, 0.151952869094528, 2.5981886395246474, 0.2677781707724807, 0.0023178437891173, 0.5574264198249208, 0.2757627249010551, 0.0390261909252865, 0.0274969121020276 +380, 19.20067503080077, 65.96608849830523, 0.0348164848817087, 6.751549684509847, 7.549526260525422, 0.1536762714722039, 0.0472637374182467, 0.8116528840617694, 0.1141492539432269, 0.00116861811166, 0.4411194763191918, 0.3812347749849946, 0.025121907803883, 0.0103321410468936 +381, 17.373081367523614, 66.24625742254646, 0.0378614207286974, 7.058499878398702, 7.805230215675485, 0.2074217019099125, 0.1071282800626527, 1.2767576312163291, 0.212589811996142, 0.0020290076265826, 0.6642612060123632, 0.3525885463695034, 0.0463197718986886, 0.0208680968948524 +382, 12.035449884160748, 66.9814753401914, 0.0495179853093072, 9.898642200418037, 9.78068460991484, 0.2455030398469793, 0.1076958517097385, 0.842790170414863, 0.2292453179005805, 0.0024749354189114, 0.6673103138889279, 0.589306878409522, 0.0360797354574715, 0.0254876370478119 +383, 18.02803411091742, 65.99957975522472, 0.0359672818202815, 7.347588346388168, 7.888858554124166, 0.2282692590779507, 0.1407724686399679, 2.246573357275466, 0.2930788517603523, 0.0027350351938541, 0.7700762746189261, 0.3939793257977521, 0.0614681340090239, 0.03697267174153 +384, 19.990891339914636, 66.19086992380423, 0.0366187702093468, 6.60064475992842, 7.56601411210285, 0.2066197181833559, 0.1057978101114609, 1.369998565897189, 0.1858096285376867, 0.0017348413420067, 0.5352162951737549, 0.2617819434580249, 0.0443216182342138, 0.0163303533071465 +385, 18.523793279834774, 65.84651142599436, 0.0347846700196521, 7.292703282789168, 7.606764018496365, 0.1965404832383936, 0.1220467410511367, 2.744299821033251, 0.3331344789498712, 0.0033851060567715, 0.9950885779911394, 0.584952402765698, 0.063760657983406, 0.0446504329813765 +386, 19.07726440643801, 66.91110115728442, 0.0404877968005175, 9.3457389261798, 8.801588388186175, 0.1413111184631165, 0.0668636614954617, 1.5547918021830218, 0.2076457843813306, 0.0020459811188574, 0.6471765125686321, 0.4491016927395748, 0.0255891247621286, 0.0146109756918254 +387, 19.698840619318755, 66.51687876007263, 0.037732742430993, 6.877548622374473, 8.090376674361364, 0.2390210913944661, 0.1244593890144124, 1.805196123494598, 0.2411285469294603, 0.0020875042942138, 0.5231229274062029, 0.2489240884588758, 0.0467137601036716, 0.0186004012257697 +388, 16.976419363727093, 66.0691858132698, 0.0374432826384177, 7.1985994097835295, 7.501018713933011, 0.1802775935228593, 0.1045309384955463, 1.1414698962373522, 0.189256076969585, 0.0018847684596867, 0.6651225124034182, 0.3378953313385421, 0.0367934612419309, 0.0182629608387061 +389, 20.69153184363912, 66.28230965465572, 0.0366506428225253, 7.009714867797686, 7.749748176725212, 0.196747081733372, 0.0917180855550247, 1.4397651841289492, 0.1776323801606303, 0.0016986888604135, 0.4911473343227802, 0.2976906425874857, 0.0343977488673439, 0.0160849546142348 +390, 18.29513190531393, 65.75895717472372, 0.0339468262737206, 7.454371556179617, 7.554554244355689, 0.1732254815092535, 0.1174627447756332, 1.896160982875436, 0.2368148607245767, 0.0022655554252346, 0.5632723891929925, 0.299523491895407, 0.0354989337738146, 0.0229176746212104 +391, 16.446869331081242, 66.12979926977948, 0.0379419994523057, 7.181182541211345, 7.737013516212239, 0.188169166484076, 0.0892611930713792, 1.0828882227404226, 0.1801285397128989, 0.0018446786702973, 0.5544571989296538, 0.3474597031348681, 0.0365686292085394, 0.0162268388532557 +392, 18.10037597973357, 66.13110631031017, 0.0369513369809789, 7.181066931323182, 7.597669687683862, 0.1855849996470122, 0.0888038209476141, 1.3108869397795335, 0.1960559898989754, 0.0019157971481176, 0.6198250315927314, 0.3853619860733604, 0.0394935834185836, 0.0193155083754942 +393, 16.907142155837317, 66.31821105893007, 0.0393941877499777, 7.22108876162418, 7.616071759503668, 0.2477481744276517, 0.1294502016635013, 2.087445457543301, 0.3689872815921458, 0.0035304151531983, 0.9065999618407272, 0.4876294236433435, 0.0721352880383473, 0.0338746014782778 +394, 19.918159041001275, 66.40899554102111, 0.0370423668487652, 7.028823815234155, 7.665309813485248, 0.2007470307506836, 0.0573860631176127, 2.448833765127851, 0.329798413164323, 0.0032356005433289, 0.7850040130046321, 0.7141855934938324, 0.0597276635543796, 0.022486123157187 +395, 22.343993034188436, 66.11378217453917, 0.0350021638642662, 7.376000768588432, 7.550235367490872, 0.2151184784793641, 0.0899018126299405, 1.696670091023725, 0.1781860799542669, 0.0016955259313657, 0.4958129017597347, 0.3012811840362435, 0.0362693058451072, 0.0158272495985619 +396, 20.074373764845888, 66.35473559924681, 0.0371498495984742, 7.901628568055258, 7.942950347545157, 0.213036869473744, 0.0938528219108705, 1.369997194613913, 0.1686054439967259, 0.0016140387613863, 0.5057755114094593, 0.3471847000569977, 0.0332788667573514, 0.0197874051426945 +397, 19.56498509234194, 66.26312491775246, 0.0373598600055074, 7.454663270906445, 7.526250758930758, 0.1927075193053785, 0.1063612683328234, 2.1170098543862808, 0.284643908560572, 0.0025944113675331, 0.7144890504946412, 0.3770123507902998, 0.0469995263907288, 0.0245167190502662 +398, 17.874340661390136, 66.14173415188586, 0.0366365596025424, 7.5141582372027695, 7.571126562390608, 0.1985528544549165, 0.0794684999890907, 1.1155494983032366, 0.1615435276086761, 0.0015543412293081, 0.4939204021857534, 0.327086003197535, 0.0300156034087383, 0.0149868305270727 +399, 19.81292933880471, 65.70681528941532, 0.0330754115381455, 6.323241851889453, 7.867137817361507, 0.1986768171798851, 0.1320660242018618, 1.7298469588978902, 0.2094210384991726, 0.0019879310642329, 0.5623427739862503, 0.2125323903904961, 0.0447672279504401, 0.0185065880069016 +400, 20.887858398591177, 65.59317125645961, 0.0318375922629219, 6.672196043752917, 6.838505228232379, 0.1934165499816758, 0.071791704460624, 1.729900593608972, 0.1929097789831603, 0.0018975641536606, 0.4774939654930509, 0.3591248213297429, 0.0350835093783025, 0.0167991232698852 +401, 17.95262429630529, 66.0343636467792, 0.0352484340615266, 5.658319455056447, 6.271911382371345, 0.2047087958044494, 0.1135588305890174, 1.3369287934995924, 0.2360756261147048, 0.0021439371524606, 0.7430200616472216, 0.286489960913077, 0.0678092197290203, 0.020580582081731 +402, 20.214258672155527, 65.44467074338986, 0.0305942978562151, 6.68275307724832, 7.378976500481007, 0.1886627849334542, 0.0756526265145536, 1.423133773549715, 0.1480722317004907, 0.0015422718175544, 0.3744930234299622, 0.2530772864300156, 0.0282201012205183, 0.0130827003446219 +403, 16.876453295867062, 65.44778665291958, 0.0318506579313678, 6.59334206721106, 6.974529059279896, 0.1744721725129299, 0.0491263152042068, 1.1831808923244895, 0.162596385119135, 0.0017088080969836, 0.4877049034391983, 0.4658885581070544, 0.0313896668521573, 0.0144426616503463 +404, 12.989420341666008, 67.55584133302663, 0.0516572581158946, 9.999999999999998, 9.999999999999936, 0.2659266958541229, 0.1208655630877946, 1.3064324358560242, 0.348932648847728, 0.0036007108908314, 0.89994197288172, 0.6448582917030454, 0.0506801803205766, 0.0309956473185391 +405, 8.841391133850305, 66.22175520396388, 0.0435373695959395, 7.349773567034183, 7.756711847442749, 0.3211131726274235, 0.1803268511455277, 0.6501942966146254, 0.2866537737821133, 0.0028640509950068, 0.6740589707544311, 0.3970773490903765, 0.0679234041859579, 0.0364547511944473 +406, 17.984188875454638, 66.43931296078893, 0.0388031951030341, 7.679776801181958, 8.155260395469567, 0.2068254080408273, 0.1180313658362269, 1.765932045716578, 0.2602285783654933, 0.0025602021559334, 0.757136851188016, 0.4759856942968204, 0.0455822966261769, 0.0300367510429369 +407, 20.8296242850307, 65.64040208689386, 0.0322871298909452, 6.316102512553846, 6.938889498533984, 0.1622260423769429, 0.0660045713901145, 2.067644337653926, 0.2372656455541333, 0.0023471024640966, 0.6746761716343133, 0.4228472602578131, 0.0435734519040125, 0.0182603664581294 +409, 18.895808965616013, 66.22305369407037, 0.0366970452803449, 8.099697776569181, 8.074330081289373, 0.1725348967635966, 0.0779833605254992, 1.8204582625445416, 0.2223096740041255, 0.0021561933765174, 0.5739942013597409, 0.4161988922452162, 0.03381159648897, 0.018662097561366 +410, 18.13919532189455, 66.60061478521499, 0.0382288171995885, 7.415356811400521, 7.829234957111108, 0.2744352418286567, 0.1143439314648725, 1.9603491202503245, 0.2891398733392141, 0.0026025021404837, 0.551903889459659, 0.388289587219339, 0.0500010687185159, 0.0239531754068601 +411, 16.03974453728752, 65.86826762267665, 0.035710675303522, 6.556466247020019, 7.756976915833579, 0.2438999223848733, 0.1130114318371147, 0.9939515061505104, 0.1634237044308242, 0.0015917200655788, 0.4213552808280931, 0.2575274238070944, 0.0413234508732263, 0.017592846028183 +412, 18.73468089354676, 65.8525864266488, 0.0355683511526484, 7.070978202725093, 7.66267825815321, 0.2034514127772492, 0.084354220004157, 1.1546446325467312, 0.1513512007595489, 0.0015077755681148, 0.4271728423001572, 0.2981863503737384, 0.0307904191437006, 0.0144229395726077 +413, 19.091261597873693, 66.24084541673696, 0.0370946250482944, 7.517795429792926, 7.925008939428284, 0.1722666465599524, 0.092381588500136, 1.4014225539381793, 0.1962555069510597, 0.0019292771137502, 0.6996854378297949, 0.3717898547401424, 0.0378710683765004, 0.01899087352699 +414, 20.18183630297641, 66.02304138191256, 0.034930391498557, 7.488876310797508, 7.734832100414675, 0.1947943088818413, 0.0865410032708088, 1.415621792217299, 0.1619893616855036, 0.0015848590877043, 0.495056587763702, 0.319698335967824, 0.0313571812826614, 0.0161071160080269 +415, 20.386408427244948, 65.34484423951572, 0.0295689310069173, 6.861031189018985, 7.881622563464948, 0.1692531394734677, 0.0935458253415347, 1.894535123529596, 0.1956957008164354, 0.0021012019522695, 0.5456810028481168, 0.328004390569142, 0.0338156986279808, 0.0225849153359102 +417, 21.65346959270596, 65.6451643731617, 0.031202239742052, 7.840525760175249, 8.214419556728744, 0.274076244420219, 0.0844083937534889, 1.1853794137382527, 0.1246519648013942, 0.0011933666997029, 0.2838262121653028, 0.1982446711254029, 0.0284934232635238, 0.0122368631342197 +418, 20.789177585513368, 65.9638696231725, 0.033803258903743, 8.153834151130688, 8.5496869065135, 0.2600622822340173, 0.0783336317470313, 0.801090418618431, 0.089926797962843, 0.0008553869566324, 0.2293466133491089, 0.2196531561393827, 0.0198480831420829, 0.0110987302680096 +419, 16.736511851590315, 65.7704723944457, 0.0342444717447583, 7.745275162859688, 8.450251577276843, 0.2598808230607848, 0.0786207636349865, 0.5581733374254342, 0.0832504232240767, 0.0007884204160615, 0.208716291388075, 0.2152281549386959, 0.0177637896515609, 0.0116606677945402 +420, 17.822321737523325, 65.445969110379, 0.0321217930476515, 8.083072120116062, 7.485415477090315, 0.6843770683240785, 0.3195479042031249, 1.3769214244885952, 0.1600133321908912, 0.0014284050114644, 0.2700999423263581, 0.1914797763097361, 0.0730765582989, 0.0391252362965674 +421, 19.2409954338793, 65.87331944092587, 0.0337603917929127, 8.043721913248069, 8.521911504840208, 0.2535238366396616, 0.0743047083221945, 1.231163429800794, 0.1446691015870124, 0.0014018015306112, 0.3541129435998789, 0.3028417938999865, 0.0312785743826359, 0.0142954664919282 +422, 20.3457623623276, 65.62510135233299, 0.0319024763686103, 7.806965810900566, 8.086127620908186, 0.2940513123569279, 0.1008223530338031, 1.7010953235011872, 0.1873262759664873, 0.0017773376064251, 0.4150922842885959, 0.3043101492319108, 0.0437065540788175, 0.0216862163593942 +423, 20.727229324095724, 65.60427763366253, 0.0312668130855889, 7.835699547944687, 8.033141040562358, 0.2607588541252869, 0.0600276015918915, 1.0654014686370352, 0.1109814117988401, 0.0010930238936029, 0.2745264569675429, 0.2951530569236021, 0.0253013749326926, 0.012659067541964 +424, 21.064234246040453, 66.19993084081977, 0.034428183687201, 8.438406330494141, 8.81163611146005, 0.2452094698771383, 0.0794181065099458, 1.1130351172886823, 0.1294766320814448, 0.0011574343752242, 0.2849636017415481, 0.2646098532366801, 0.023697776622307, 0.0141279849500886 +425, 17.32379650305197, 66.23711709845979, 0.0369409934039274, 7.883360992653102, 8.421182771179392, 0.3234191829726071, 0.1218464346473362, 0.988813893361572, 0.1423235065873731, 0.001255544812004, 0.2879400064110314, 0.1746076199063987, 0.0313401358206672, 0.0126721228492435 +426, 19.676408549677543, 65.6019741040735, 0.0320935264621533, 8.045569275791959, 8.261193852516683, 0.2092446426936531, 0.0843378189830445, 1.0561706590349569, 0.1261778977291271, 0.0012004207885413, 0.3688369671783133, 0.2913125798018823, 0.027092161290261, 0.0173444726615215 +427, 18.931327713830598, 65.72046441709304, 0.0328857951294851, 8.38358366471532, 8.284176711815778, 0.2038443331332205, 0.0975119724184071, 0.7899064344799026, 0.0966000642632132, 0.0009430010991718, 0.2793010899289433, 0.2269185598610383, 0.0191086562594229, 0.0176587899464906 +428, 18.8428709142582, 66.3178751310621, 0.0355361226821072, 8.385430986970228, 8.77198680380445, 0.2575823232687283, 0.0701379979233186, 1.0058079860800564, 0.1377671649095061, 0.0012913257826597, 0.3023324876885616, 0.3024495554309677, 0.0263265422468645, 0.0122580873654274 +429, 18.60395056738597, 65.80293591432954, 0.0329687675543597, 8.361217179715945, 8.47008030662252, 0.229383190897102, 0.0916630463832661, 0.8387471513608692, 0.1025484486237376, 0.0009937035713919, 0.2772545546841503, 0.2705469464995127, 0.0216314485263755, 0.0158846903022361 +430, 18.01501353412002, 66.23060957849347, 0.0364507654272159, 8.220695094159039, 8.775390744540426, 0.289226629323711, 0.1175522347079003, 1.6304590802052283, 0.220955013694321, 0.0020352321585428, 0.5013362200712546, 0.3723838259451199, 0.0490104018349032, 0.0275011263161908 +432, 17.50310932710253, 65.81046577097354, 0.0345844742576821, 7.94062644945325, 8.483832297126815, 0.2873095312785791, 0.090199696490066, 0.8227433165779013, 0.1098181086994381, 0.0010902968507599, 0.2706055286267805, 0.2786378313003572, 0.0249250240647009, 0.015116726841983 +433, 20.34139152083189, 65.61537246706635, 0.0318335911460926, 8.209073898280089, 8.154158929947496, 0.184936468778572, 0.0502758596090779, 0.8507955538360962, 0.0995229223780767, 0.0009872420477397, 0.316362223711494, 0.4384408033859829, 0.0198550564240856, 0.0154409959500234 +434, 16.93680068907594, 65.96340732429614, 0.0349959384534805, 7.842666696584803, 8.359046609088988, 0.2902541470418494, 0.0951409046237551, 0.842341521857461, 0.1239265757102382, 0.0011682064754019, 0.2927515112513859, 0.2504492568775668, 0.028562187488646, 0.0147933040772646 +435, 20.460542714162383, 66.20300863582169, 0.0340557894928244, 8.439241154046266, 9.377191121474372, 0.2100677884866865, 0.0590973313544583, 2.367162370170629, 0.2753744441590828, 0.0025960475796094, 0.63875795435106, 0.6637682513147795, 0.0494351301520202, 0.0248660689436474 +436, 21.261446244641316, 65.84254903624077, 0.0325829888822235, 8.723049208886982, 8.704078327282467, 0.2021549254471222, 0.0758684531215836, 0.8914967026871833, 0.0977470506009845, 0.0009372929729155, 0.2783268605616823, 0.3080094008806317, 0.0187587506392808, 0.0155422015543724 +437, 24.835155807915577, 65.69078354061978, 0.0304931587241177, 8.337810885750056, 8.530229978726432, 0.1856802519431378, 0.0696724392427746, 1.2403135990928689, 0.1112315864183901, 0.0010426280003629, 0.284552329375029, 0.229741605003026, 0.0186299687664994, 0.0127606662712546 +438, 20.568601463733376, 65.72886058621853, 0.0326922206153394, 8.102501120684007, 8.716521493243379, 0.224000176717178, 0.0598075975406976, 1.08301456412506, 0.1269462454308264, 0.0012546684626599, 0.3222177399849242, 0.3235798524595886, 0.0246562548372528, 0.0136318947119127 +439, 20.93785685157656, 65.93113652729623, 0.0322441076269637, 8.218843502143404, 8.497221012995727, 0.2532835312860731, 0.089376909808957, 1.3757170566318744, 0.1520032937933028, 0.0013886851253614, 0.3278451782433996, 0.2475402794058355, 0.0294701900140717, 0.0151638725870107 +440, 19.52782256493223, 66.0510773177615, 0.0355230303065688, 8.122334923508763, 8.832968695264174, 0.2669774744745575, 0.0832092351568731, 0.8610970424254204, 0.1100153381809537, 0.0010879861812948, 0.270431304349643, 0.2764968006167488, 0.0228727693816378, 0.012986674056354 +441, 18.73975532269145, 65.90148380887688, 0.0345523870453647, 7.842589090219954, 8.516367453929854, 0.2645666581189351, 0.0819017193034798, 1.120119892359901, 0.1458830338980886, 0.0013460399838721, 0.3469815618414059, 0.2870738230158016, 0.0302535685063239, 0.0150391072475234 +442, 19.82417702271372, 65.64195425033728, 0.0321834587810454, 8.34991236918498, 8.415152429545298, 0.2104877536190419, 0.1022213322845603, 1.1253904215859043, 0.1225542997472593, 0.0012157248385016, 0.3791955434962882, 0.3743172752864463, 0.0264228825989434, 0.0245977659502914 +443, 17.63017098277628, 65.83674204196093, 0.0342535656684394, 7.773766164335162, 8.573401421344306, 0.2769845488159174, 0.0952904466700415, 0.9348620335365484, 0.1237269087959292, 0.0011870092132544, 0.3094996083536473, 0.2811382048898285, 0.0298152876541073, 0.016404881110685 +446, 21.21005864070331, 65.85765505064813, 0.0332423860311022, 7.950067619386306, 8.411151169707017, 0.2610163519856194, 0.0705570143204864, 1.4327822256743246, 0.1574899211822774, 0.0014649094544818, 0.3638104782525744, 0.3134131947080908, 0.0318846490366453, 0.0144681991556606 +447, 18.024962359993005, 66.1203525344101, 0.034833596648156, 7.926579541604622, 8.448753872052244, 0.2916463678722938, 0.0797666433143335, 0.8681703337409233, 0.1120879817856488, 0.0010693388858398, 0.2594507816288838, 0.253643348872702, 0.0249488717716234, 0.0121191920886137 +448, 21.229410789693503, 65.86958829929925, 0.0329611810699021, 8.486385133628673, 8.56142562240672, 0.2035053775593352, 0.0789764517803622, 1.0261216363608503, 0.1076851362782755, 0.0010547785624211, 0.3142421063177205, 0.2980255718589237, 0.0207276847276626, 0.0161827131168983 +449, 19.36204538837964, 65.83115929187589, 0.0330160826253947, 8.285036241700993, 8.393143605453032, 0.2309219389151962, 0.086827790885734, 0.9085196940086974, 0.1018088683497137, 0.000964274046825, 0.2825709615773661, 0.2466787149573407, 0.0227731867985071, 0.0136402836241971 +450, 15.605930224141211, 65.7262746628475, 0.0365130339275594, 9.27911272142386, 8.97112782240633, 0.3181293853785584, 0.3084125773926113, 1.4420689002609757, 0.2041582818049802, 0.0021147924526227, 0.5063844638679416, 0.2815362646048324, 0.0513824519396528, 0.0571438253845317 +451, 17.892296774529324, 65.92977876948336, 0.0334040666481763, 8.18306123417763, 9.049839199837038, 0.2649877475923062, 0.1001244132073916, 0.7906046523803519, 0.0979924240890918, 0.0009227768376427, 0.2368062163066847, 0.227378339025932, 0.0215607607129154, 0.0167124027636894 +452, 21.45289724271045, 65.71360431346936, 0.0320911908769673, 7.797039056244331, 7.890168075828954, 0.3097835679665351, 0.1086531038883223, 2.136407676593817, 0.2153108864492142, 0.0019390946733159, 0.4324791057442891, 0.2975928500602989, 0.048979712575082, 0.0233862952875551 +453, 23.70092560857747, 65.5720639607955, 0.0299784733843956, 8.991747798421404, 8.637276663340929, 0.1891142318609101, 0.0703114974034916, 1.7967228300196925, 0.1723302614156794, 0.0016387429236658, 0.3840045749262791, 0.3821228417360033, 0.0263945086269092, 0.0216646555640289 +454, 18.66578105930316, 65.69283409314251, 0.0324265394534018, 8.340798954111703, 8.274189917993427, 0.1989739792863297, 0.067515862823484, 1.011444593547323, 0.1284391537398137, 0.0012249784137876, 0.3878277212452012, 0.4046428190587978, 0.0254083551720694, 0.0169926450163182 +455, 20.864152263473716, 65.88070481069025, 0.0334423108504933, 8.307775718023986, 8.806212941796938, 0.2219791413073081, 0.0845146441681902, 1.2629369207527668, 0.1384193990412489, 0.0013411893988092, 0.3700314905022108, 0.3321642343456721, 0.0277409967329666, 0.0183921949054767 +456, 24.04758277915513, 65.88902367573554, 0.03265420682809, 8.113147110547649, 8.285686062206084, 0.2057632940986345, 0.0816611742248908, 1.429430422822425, 0.1336346776109253, 0.0012649548465252, 0.3692014206487338, 0.3336590976834644, 0.0268653835485691, 0.0192432687414581 +457, 22.524337089712034, 66.40272251545233, 0.0350583423054751, 8.152381713001738, 8.809750603715884, 0.2370252900644747, 0.0722123891113932, 1.8262320742723184, 0.1935442843590715, 0.001783977123646, 0.4395306806182772, 0.3430382852587487, 0.0369322559756491, 0.0150512306695985 +458, 19.04410189843947, 66.1513604684099, 0.0358942855799551, 8.380945399861085, 8.940382669492662, 0.2698886308905548, 0.09269746519517, 0.8466125248970239, 0.1115465863327161, 0.0010272317084075, 0.2662552989499304, 0.2337500138267207, 0.0235177585996511, 0.0141074921940522 +459, 18.78974591666449, 65.96462651578425, 0.0350990416778611, 7.961221812121976, 8.60373213249672, 0.266761349861109, 0.0851341625206457, 0.8767675996046631, 0.1114317573269102, 0.0010565716094747, 0.2570958316324297, 0.24117720547176, 0.022943195421895, 0.0119338821678387 +460, 19.408156932454204, 65.93524288343467, 0.0348306099805193, 7.769343162341361, 8.612247046731538, 0.2813242136473392, 0.0839646550775433, 0.9504377039750032, 0.1184544330738325, 0.0011460882301083, 0.2922765249395898, 0.3371088567439712, 0.0272394973249799, 0.0181051599699306 +461, 20.020743112335285, 65.89707625032543, 0.0335736791603121, 7.7842799261141185, 8.47354946421575, 0.2479320527499865, 0.0585432137944318, 1.007261124249476, 0.1255715800898394, 0.0011355648564087, 0.2979597576017224, 0.3018134455319902, 0.0243841238803686, 0.0117222329761243 +462, 20.375573178806075, 65.73169167301837, 0.032519640610326, 7.831248736233272, 8.065557711517458, 0.2906815786616215, 0.0974104825449875, 1.0728886191070537, 0.1196039761422414, 0.0010995272015496, 0.2509817827705711, 0.1834693401171643, 0.0254244700399541, 0.0120713588091314 +463, 19.16083120620851, 65.89760300409763, 0.0338505749224141, 8.019163343422518, 8.637498150193235, 0.2420626085004077, 0.0617444885717428, 0.7583045097495793, 0.0934682873505771, 0.0009009392559887, 0.2468982277841892, 0.3152915630889853, 0.0198917517496276, 0.0122472565898517 diff --git a/configfiles/PMTWaveformSim/PMTWaveformSimConfig b/configfiles/PMTWaveformSim/PMTWaveformSimConfig new file mode 100644 index 000000000..4233a2a9c --- /dev/null +++ b/configfiles/PMTWaveformSim/PMTWaveformSimConfig @@ -0,0 +1,8 @@ +verbosity 0 +PMTParameterFile configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv +useTimeSmearing 0 +Prewindow 80 +ReadoutWindow 200 +T0Offset 25 +TimeShift 0 +MakeDebugFile 0 diff --git a/configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig b/configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..d7df3353e --- /dev/null +++ b/configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig @@ -0,0 +1,11 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 0 +MCWaveforms 1 diff --git a/configfiles/PMTWaveformSim/README.md b/configfiles/PMTWaveformSim/README.md new file mode 100644 index 000000000..c54af24b0 --- /dev/null +++ b/configfiles/PMTWaveformSim/README.md @@ -0,0 +1,22 @@ +# Configure files + +*********************** +#Description +********************** + +`PMTWaveformSim` toolchain. + + +************************ +#Usage +************************ + +The toolchain requires the following tools to be run beforehand: + +``` +LoadGeometry +LoadWCSim +``` + +It also requires the presence of a `PMTWaveformLognormFit.csv` with fits from the SPE data. + diff --git a/configfiles/PMTWaveformSim/ToolChainConfig b/configfiles/PMTWaveformSim/ToolChainConfig new file mode 100644 index 000000000..499818543 --- /dev/null +++ b/configfiles/PMTWaveformSim/ToolChainConfig @@ -0,0 +1,26 @@ +#ToolChain dynamic setup file + +##### Runtime Parameters ##### +verbose 0 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandled errors only, 2= exit on unhandled errors and handled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails +remote_port 24002 +IO_Threads 1 ## Number of threads for network traffic (~ 1/Gbps) + +###### 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/PMTWaveformSim/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/PMTWaveformSim/ToolsConfig b/configfiles/PMTWaveformSim/ToolsConfig new file mode 100644 index 000000000..782b19507 --- /dev/null +++ b/configfiles/PMTWaveformSim/ToolsConfig @@ -0,0 +1,5 @@ +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig +LoadWCSim LoadWCSim configfiles/PMTWaveformSim/LoadWCSimConfig +PMTWaveformSim PMTWaveformSim configfiles/PMTWaveformSim/PMTWaveformSimConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig +ClusterFinder ClusterFinder configfiles/PMTWaveformSim/ClusterFinderConfig \ No newline at end of file diff --git a/configfiles/PreProcessTrigOverlap/CreateMyList.sh b/configfiles/PreProcessTrigOverlap/CreateMyList.sh index e72ac51a6..4ccfef7cc 100755 --- a/configfiles/PreProcessTrigOverlap/CreateMyList.sh +++ b/configfiles/PreProcessTrigOverlap/CreateMyList.sh @@ -1,17 +1,19 @@ -if [ "$#" -ne 2 ]; then - echo "Usage: ./CreateMyList.sh DIR RUN" - echo "Specified input variable must contain the directory where the files are stored, second variable run number" +if [ "$#" -ne 1 ]; then + echo "Usage: ./CreateMyList.sh RUN" + echo "Specified input variable must contain the run number" exit 1 fi -FILEDIR=$1 -RUN=$2 +RUN=$1 +DIR=/pnfs/annie/persistent/raw/raw/ -NUMFILES=$(ls -1q ${FILEDIR}/RAWDataR${RUN}* | wc -l) +NUMFILES=$(ls -1q ${DIR}${RUN}/RAWDataR${RUN}* | wc -l) -echo "NUMBER OF FILES IN ${FILEDIR}: ${NUMFILES}" +echo "NUMBER OF FILES IN ${DIR}${RUN}: ${NUMFILES}" + +rm my_files.txt for p in $(seq 0 $(($NUMFILES -1 ))) do - echo "${FILEDIR}/RAWDataR${RUN}S0p${p}" >> my_files.txt + echo "${DIR}${RUN}/RAWDataR${RUN}S0p${p}" >> my_files.txt done 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/PrintADCData/LoadANNIEEventConfig b/configfiles/PrintADCData/LoadANNIEEventConfig new file mode 100644 index 000000000..de401a767 --- /dev/null +++ b/configfiles/PrintADCData/LoadANNIEEventConfig @@ -0,0 +1,4 @@ +verbose 4 +EventOffset 0 +FileForListOfInputs ./configfiles/PrintADCData/my_inputs.txt +GlobalEvNr 1 # If multiple files are present, introduce a global event number across files? diff --git a/configfiles/PrintADCData/PhaseIIADCCalibratorConfig b/configfiles/PrintADCData/PhaseIIADCCalibratorConfig new file mode 100644 index 000000000..e67bc4513 --- /dev/null +++ b/configfiles/PrintADCData/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 0 +ExecutesPerBuild 10 diff --git a/configfiles/PrintADCData/PhaseIIADCHitFinderConfig b/configfiles/PrintADCData/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..473dd1dc7 --- /dev/null +++ b/configfiles/PrintADCData/PhaseIIADCHitFinderConfig @@ -0,0 +1,10 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType dynamic +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 0 diff --git a/configfiles/PrintADCData/PrintADCDataConfig b/configfiles/PrintADCData/PrintADCDataConfig new file mode 100644 index 000000000..817d22b20 --- /dev/null +++ b/configfiles/PrintADCData/PrintADCDataConfig @@ -0,0 +1,11 @@ +verbosity 5 + +UseLEDWaveforms 0 # specifies whether to show or save full waveforms from the DAQ or the LED waveform windows + +OutputFile test # Base filename given to both the ROOT and txt file that are output from the tool + +SaveWaveforms 1 # Determines whether or not to save raw waveforms in the output ROOT file + +WavesWithPulsesOnly 0 # Controls whether or not to save only waveforms that have a pulse in them (determined by the hit finding tools) + +MaxWaveforms 1000 # Controls the number of raw waveforms to be saved to the output ROOT file. Used to keep the ROOT file from exploding under the sheer number of raw waveforms saved diff --git a/configfiles/PrintADCData/README.md b/configfiles/PrintADCData/README.md new file mode 100644 index 000000000..e9a5e6b21 --- /dev/null +++ b/configfiles/PrintADCData/README.md @@ -0,0 +1,64 @@ +# PrintADCData toolchain + +*********************** +# Description +********************** + +The `PrintADCData` toolchain is used to analyze properties in an ANNIEEvent booststore's RecoADCHits vector (and the Aux information). The tool specifically looks at the raw and calibrated waveforms for Tank PMTs and Aux channels and outputs information including: +* Example raw waveforms for all PMTs channels, and aux channels (BoosterRWM, BoosterRF) +* The number of waveforms collected for each channel +* The number of pulses collected for each channel +* The number of waveforms with at least one pulse for each channel +* 2D histograms of the hit occupancy in y vs, phi space + +************************ +# Data +************************ + +Two files are producing after running this toolchain: +* ROOT file with raw waveforms and the 2D hit occupancy histograms +* .txt file with the waveform/pulse info described above + +************************ +# Configuration of PrintADCData tool +************************ +``` + +UseLEDWaveforms [int] +Specifies whether to show and save full waveforms from the DAQ, or +the LED waveform windows produced from running +PhaseIIADCCalibrator with MakeLEDWaveforms set at 1. +1=Show/save LED waveforms, +0= Show/save raw waveforms. + +verbosity [int] +controls the amount of print output (0- lowest, 5-highest) + +OutputFile [string] +Base filename given to both the ROOT and text file that are output from the tool. + + +SaveWaveforms [bool] +Determines whether or not to save raw waveforms in the output ROOT file. +1 = yes, 0 = no + +WavesWithPulsesOnly [bool] +Controls whether or not to save only waveforms that have a pulse in them. Whether +or not the wave has a pulse is determined by logic output by the PhaseIIADCHitFinder +tool. + +MaxWaveforms [int] +Controls the number of raw waveform examples saved to the output ROOT file. +Used to keep the ROOT file from exploding under the sheer number of raw +waveforms saved. + +LEDsUsed [string] +Log string saved in the output text file to record what LEDs were used for the +run being processed. Will eventually be automated when the DAQ can control +the LEDs. + +LEDSetpoints [string] +Log string saved in the output text file to record what LED setpoints were used + for the run being processed. Will eventually be automated when the DAQ +can control the LEDs. +``` diff --git a/configfiles/PrintADCData/ToolChainConfig b/configfiles/PrintADCData/ToolChainConfig new file mode 100644 index 000000000..552a4ccf3 --- /dev/null +++ b/configfiles/PrintADCData/ToolChainConfig @@ -0,0 +1,26 @@ +#ToolChain dynamic setup file + +##### Runtime Parameters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandled errors only, 2= exit on unhandled errors and handled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails +remote_port 24002 +IO_Threads 1 ## Number of threads for network traffic (~ 1/Gbps) + +###### 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/PrintADCData/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/PrintADCData/ToolsConfig b/configfiles/PrintADCData/ToolsConfig new file mode 100644 index 000000000..57c6ac4db --- /dev/null +++ b/configfiles/PrintADCData/ToolsConfig @@ -0,0 +1,5 @@ +myLoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig +myLoadANNIEEvent LoadANNIEEvent configfiles/PrintADCData/LoadANNIEEventConfig +myPhaseIIADCCalibrator PhaseIIADCCalibrator ./configfiles/PrintADCData/PhaseIIADCCalibratorConfig +myPhaseIIADCHitFinder PhaseIIADCHitFinder ./configfiles/PrintADCData/PhaseIIADCHitFinderConfig +myPrintADCData PrintADCData configfiles/PrintADCData/PrintADCDataConfig diff --git a/configfiles/PrintADCData/my_inputs.txt b/configfiles/PrintADCData/my_inputs.txt new file mode 100644 index 000000000..c7a51732f --- /dev/null +++ b/configfiles/PrintADCData/my_inputs.txt @@ -0,0 +1 @@ +./ProcessedRawData_TankAndCTC_R4314S0p1 diff --git a/configfiles/PrintADCTraces/ClusterFinderConfig b/configfiles/PrintADCTraces/ClusterFinderConfig new file mode 100644 index 000000000..53330c25d --- /dev/null +++ b/configfiles/PrintADCTraces/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 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? +ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat diff --git a/configfiles/PrintADCTraces/LoadANNIEEventConfig b/configfiles/PrintADCTraces/LoadANNIEEventConfig new file mode 100644 index 000000000..284622ea2 --- /dev/null +++ b/configfiles/PrintADCTraces/LoadANNIEEventConfig @@ -0,0 +1,4 @@ +verbose 1 +FileForListOfInputs ./configfiles/PrintADCTraces/my_inputs.txt +EventOffset 0 +GlobalEvNr 1 diff --git a/configfiles/PrintADCTraces/PrintADCTracesConfig b/configfiles/PrintADCTraces/PrintADCTracesConfig new file mode 100644 index 000000000..42e58746c --- /dev/null +++ b/configfiles/PrintADCTraces/PrintADCTracesConfig @@ -0,0 +1,19 @@ +verbosity 0 + +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 + # omitting both of these will not impose a time selection + +MaxTraces 10000 # maximum number of traces to include in the root file (default is 10,000 if not set by user) + # if set to '0', no limit will be imposed + +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 diff --git a/configfiles/PrintADCTraces/README.md b/configfiles/PrintADCTraces/README.md new file mode 100644 index 000000000..769faa69e --- /dev/null +++ b/configfiles/PrintADCTraces/README.md @@ -0,0 +1,59 @@ +# 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. + +## Output rootfile + +`PrintADCTraces` produces a root file containing directories for each PMT channel - within each channel will be TGraphs for each ADC trace: + +``` +// ROOT file: +// ├── chankey/ # directory for each PMT channel +// ├── 332/ +// │ ├── wf1 TGraph # for each pulse, a TGraph +// │ └── wf2 TGraph +// ├── 463/ +// │ ├── wf1 TGraph +// │ └── ... +// └── 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] +``` + +where the TGraph name is given by: ```____``` + + +## Configuration +``` +# PrintADCTraces Config File + +verbosity 0 + +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 + # omitting both of these will not impose a time selection + +MaxTraces 10000 # maximum number of traces to include in the root file (default is 10,000 if not set by user) + # if set to '0', no limit will be imposed + +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 +``` + +## Additional information +- ADC traces will be in ADC (y) vs time [ns] (x). All pulse times will be relative (and zeroed) to the start time of the pulse. All pulse amplitudes (y) are baseline-subtracted. This way its easier to compare. You can cross reference the pulse features with the title (which contains the charge and time of the pulse) to determine more information. +- This tool is similar to the `PrintADCData` toolchain, but instead of printing out all raw PMT waveforms, it only prints out the found pulse traces (and provides more identifying / filtering information based on charge / time). +- `create_my_inputs.sh` will populate the my_inputs.txt file with all ProcessedData from a given run. Adjust the internal paths accordingly. Usage: `sh create_my_inputs.sh ` diff --git a/configfiles/PrintADCTraces/ToolChainConfig b/configfiles/PrintADCTraces/ToolChainConfig new file mode 100644 index 000000000..bfe534b1c --- /dev/null +++ b/configfiles/PrintADCTraces/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/PrintADCTraces/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/PrintADCTraces/ToolsConfig b/configfiles/PrintADCTraces/ToolsConfig new file mode 100644 index 000000000..38ac2af03 --- /dev/null +++ b/configfiles/PrintADCTraces/ToolsConfig @@ -0,0 +1,3 @@ +LoadANNIEEvent LoadANNIEEvent ./configfiles/PrintADCTraces/LoadANNIEEventConfig +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 new file mode 100644 index 000000000..c63be866a --- /dev/null +++ b/configfiles/PrintADCTraces/my_inputs.txt @@ -0,0 +1 @@ +/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/PrintDQ/ClusterClassifiersConfig b/configfiles/PrintDQ/ClusterClassifiersConfig new file mode 100644 index 000000000..752200268 --- /dev/null +++ b/configfiles/PrintDQ/ClusterClassifiersConfig @@ -0,0 +1 @@ +verbosity 0 diff --git a/configfiles/PrintDQ/ClusterFinderConfig b/configfiles/PrintDQ/ClusterFinderConfig new file mode 100644 index 000000000..53330c25d --- /dev/null +++ b/configfiles/PrintDQ/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 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? +ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat diff --git a/configfiles/PrintDQ/EventSelectorConfig b/configfiles/PrintDQ/EventSelectorConfig new file mode 100644 index 000000000..a711f08bf --- /dev/null +++ b/configfiles/PrintDQ/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/PrintDQ/FindMrdTracksConfig b/configfiles/PrintDQ/FindMrdTracksConfig new file mode 100644 index 000000000..5ba5e8f77 --- /dev/null +++ b/configfiles/PrintDQ/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/PrintDQ/FitRWMWaveformConfig b/configfiles/PrintDQ/FitRWMWaveformConfig new file mode 100644 index 000000000..4d3e235aa --- /dev/null +++ b/configfiles/PrintDQ/FitRWMWaveformConfig @@ -0,0 +1,4 @@ +verbosityFitRWMWaveform 0 +printToRootFile 0 + + diff --git a/configfiles/PrintDQ/LoadANNIEEventConfig b/configfiles/PrintDQ/LoadANNIEEventConfig new file mode 100644 index 000000000..d1e73c16e --- /dev/null +++ b/configfiles/PrintDQ/LoadANNIEEventConfig @@ -0,0 +1,4 @@ +verbose 1 +FileForListOfInputs ./configfiles/PrintDQ/my_inputs.txt +EventOffset 0 +GlobalEvNr 1 diff --git a/configfiles/PrintDQ/PrintDQConfig b/configfiles/PrintDQ/PrintDQConfig new file mode 100644 index 000000000..752200268 --- /dev/null +++ b/configfiles/PrintDQ/PrintDQConfig @@ -0,0 +1 @@ +verbosity 0 diff --git a/configfiles/PrintDQ/README.md b/configfiles/PrintDQ/README.md new file mode 100644 index 000000000..527269809 --- /dev/null +++ b/configfiles/PrintDQ/README.md @@ -0,0 +1,23 @@ +# PrintDQ + +*********************** +# Description +*********************** + +The `PrintDQ` toolchain runs the clustering tools (MRD + PMT) over the ProcessedData files created by the event building toolchain to output run quality statistics. For more information, check out the README for the tool: https://github.com/ANNIEsoft/ToolAnalysis/tree/Application/UserTools/PrintDQ. This tool can be used for assessing the quality of Processed runs to help identify issues with the detector. + +************************ +# Usage +************************ + +- Populate the `my_inputs.txt` file with all part files from a Processed runs. Running the script `sh create_my_inputs.sh ` will automatically populate the input file with all Processed Data part files for that run. +- Run the toolchain via: `./Analyse ./configfiles/PrintDQ/ToolChain` +- Run statistics will be outputted via `std::out` once the toolchain completes, in addition to a .csv file containing the metrics. + + +************************ +# Additional information +************************ + +- The current version of the `PrintDQ` tool is intended to be run over 1 run at a time. As the clustering tools may take some time to compile, the processing time of this toolchain may take several minutes (for a ~100 part file run) to ~1 hour (~thousands of part files) depending on how many part files exist. +- Find [here](https://github.com/S81D/PrintDQ/tree/main) a set of scripts to run this toolchain on the grid and produce data quality plots from the outputted .csv files. diff --git a/configfiles/PrintDQ/TimeClusteringConfig b/configfiles/PrintDQ/TimeClusteringConfig new file mode 100644 index 000000000..e778247fc --- /dev/null +++ b/configfiles/PrintDQ/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/PrintDQ/ToolChainConfig b/configfiles/PrintDQ/ToolChainConfig new file mode 100644 index 000000000..2e56577ac --- /dev/null +++ b/configfiles/PrintDQ/ToolChainConfig @@ -0,0 +1,24 @@ +#ToolChain dynamic setup file + +##### Runtime Parameters ##### +verbose 1 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandled errors only, 2= exit on unhandled errors and handled 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/PrintDQ/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/PrintDQ/ToolsConfig b/configfiles/PrintDQ/ToolsConfig new file mode 100644 index 000000000..87046c72d --- /dev/null +++ b/configfiles/PrintDQ/ToolsConfig @@ -0,0 +1,10 @@ +myLoadANNIEEvent LoadANNIEEvent ./configfiles/PrintDQ/LoadANNIEEventConfig +myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +myTimeClustering TimeClustering configfiles/PrintDQ/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/PrintDQ/FindMrdTracksConfig +myClusterFinder ClusterFinder ./configfiles/PrintDQ/ClusterFinderConfig +myClusterClassifiers ClusterClassifiers ./configfiles/PrintDQ/ClusterClassifiersConfig +myEventSelector EventSelector ./configfiles/PrintDQ/EventSelectorConfig +myFitRWMWaveform FitRWMWaveform ./configfiles/PrintDQ/FitRWMWaveformConfig + +myPrintDQ PrintDQ ./configfiles/PrintDQ/PrintDQConfig diff --git a/configfiles/PrintDQ/create_my_inputs.sh b/configfiles/PrintDQ/create_my_inputs.sh new file mode 100644 index 000000000..214f789fe --- /dev/null +++ b/configfiles/PrintDQ/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/processed_EBV2/R${run}/" + +find "$processed_dir" -type f -name "Processed*" | sort -t'/' -k2V > "$output_file" + +echo "done" diff --git a/configfiles/PrintDQ/my_inputs.txt b/configfiles/PrintDQ/my_inputs.txt new file mode 100644 index 000000000..d1fe477d4 --- /dev/null +++ b/configfiles/PrintDQ/my_inputs.txt @@ -0,0 +1,205 @@ +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p0 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p1 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p2 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p3 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p4 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p5 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p6 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p7 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p8 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p9 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p10 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p11 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p12 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p13 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p14 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p15 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p16 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p17 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p18 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p19 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p20 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p21 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p22 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p23 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p24 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p25 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p26 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p27 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p28 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p29 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p30 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p31 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p32 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p33 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p34 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p35 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p36 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p37 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p38 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p39 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p40 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p41 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p42 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p43 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p44 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p45 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p46 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p47 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p48 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p49 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p50 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p51 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p52 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p53 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p54 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p55 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p56 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p57 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p58 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p59 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p60 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p61 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p62 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p63 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p64 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p65 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p66 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p67 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p68 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p69 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p70 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p71 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p72 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p73 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p74 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p75 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p76 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p77 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p78 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p79 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p80 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p81 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p82 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p83 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p84 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p85 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p86 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p87 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p88 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p89 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p90 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p91 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p92 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p93 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p94 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p95 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p96 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p97 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p98 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p99 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p100 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p101 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p102 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p103 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p104 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p105 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p106 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p107 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p108 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p109 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p110 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p111 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p112 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p113 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p114 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p115 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p116 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p117 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p118 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p119 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p120 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p121 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p122 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p123 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p124 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p125 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p126 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p127 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p128 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p129 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p130 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p131 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p132 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p133 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p134 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p135 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p136 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p137 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p138 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p139 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p140 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p141 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p142 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p143 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p144 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p145 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p146 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p147 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p148 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p149 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p150 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p151 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p152 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p153 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p154 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p155 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p156 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p157 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p158 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p159 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p160 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p161 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p162 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p163 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p164 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p165 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p166 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p167 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p168 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p169 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p170 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p171 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p172 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p173 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p174 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p175 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p176 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p177 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p178 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p179 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p180 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p181 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p182 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p183 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p184 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p185 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p186 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p187 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p188 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p189 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p190 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p191 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p192 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p193 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p194 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p195 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p196 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p197 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p198 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p199 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p200 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p201 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p202 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p203 +/pnfs/annie/persistent/processed/processed_EBV2/R4939/ProcessedData_PMTMRDLAPPD_R4939S0p204 diff --git a/configfiles/ReweightEventsGenie/README.md b/configfiles/ReweightEventsGenie/README.md deleted file mode 100644 index 693c52bd3..000000000 --- a/configfiles/ReweightEventsGenie/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Configure files - -*********************** -#Description -********************** - -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 - -Values that contain multiple variables are separated by "|" into separate tokens -These tokens are broken up into "key:value" pairs -Syntax matters. Follow example in ReweightEventsGenieConfig - -Note: Only one value is permitted per name and they are stored in a string stream and template cast back to the type given. - diff --git a/configfiles/ReweightEventsGenie/ReweightEventsGenieConfig b/configfiles/ReweightEventsGenie/ReweightEventsGenieConfig deleted file mode 100644 index 46191e03d..000000000 --- a/configfiles/ReweightEventsGenie/ReweightEventsGenieConfig +++ /dev/null @@ -1,89 +0,0 @@ -verbosity 100 -FluxVersion 1 # use 0 to load genie files based on bnb_annie_0000.root etc files - # use 1 to load files based on beammc_annie_0000.root etc files -#FileDir NA # specify "NA" for newer files: full path is saved in WCSim -FileDir /pnfs/annie/persistent/users/jminock/annie_genie -FilePattern gntp.0.ghep.root ## for specifying specific files to load -FromWCSim 1 -OnGrid 0 -## ^-if using in conjunction with LoadWCSim Tool - -# Reweightable GENIE cross section and beam flux model uncertainties -# Revised 9 February 2023 -# -# Maintainer:James Minock - -genie_module_label generator - -genie_central_values MaCCQE:4.9778|RPA_CCQE:0.151|NormCCMEC:1.31189|XSecShape_CCMEC:1.0 - -weight_functions_genie All,AxFFCCQEshape,DecayAngMEC,NormCCCOH,Norm_NCCOH,RPA_CCQE,RootinoFix,ThetaDelta2NRad,Theta_Delta2Npi,TunedCentralValue,VecFFCCQEshape,XSecShape_CCMEC - - #Full set of well-formed Beam Uncertainties for use with post-MCC8 Flux -weight_functions_flux piplus,piminus,kplus,kzero,kminus,horncurrent,pioninexsec,nucleontotxsec,nucleonqexsec,nucleoninexsec,pionqexsec,piontotxsec,expskin - - - # INDIVIDUAL WEIGHT CALCULATORS - # Thse use "minmax" mode and represent a variation between two extremes. The - # recommended uncertainty is the full spread between them. - -genie_qema type:Genie|random_seed:15|parameter_list:["QEMA"]|parameter_sigma:[1]|mode:multisim|number_of_multisims:10 - -RPA_CCQE type:UBGenie|random_seed:2|parameter_list:["RPA_CCQE"]|parameter_sigma:[0.4]|parameter_min:[-0.249]|parameter_max:[0.551]|mode:minmax|number_of_multisims:2 - -XSecShape_CCMEC type:UBGenie|random_seed:4|parameter_list:["XSecShape_CCMEC"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - -AxFFCCQEshape type:UBGenie|random_seed:5|parameter_list:["AxFFCCQEshape"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - -VecFFCCQEshape type:UBGenie|random_seed:6|parameter_list:["VecFFCCQEshape"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - -DecayAngMEC type:UBGenie|random_seed:7|parameter_list:["DecayAngMEC"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - -Theta_Delta2Npi type:UBGenie|random_seed:53|parameter_list:["Theta_Delta2Npi"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - - # New angular distribution variation for radiative Delta decays -ThetaDelta2NRad type:UBGenie|random_seed:54|parameter_list:["ThetaDelta2Rad"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - - # Unisim variation of CC COH normalization (still finalizing approach) -NormCCCOH type:UBGenie|random_seed:56|parameter_list:["NormCCCOH"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - - # Unisim variation of NC COH normalization (still finalizing approach) -NormNCCOH type:UBGenie|random_seed:57|parameter_list:["NormNCCOH"]|parameter_sigma:[1]|parameter_min:[0.0]|parameter_max:[1.0]|mode:minmax|number_of_multisims:2 - -TunedCentralValue type:UBGenie|random_seed:99|parameter_list:["MaCCQE","RPA_CCQE","NormCCMEC","XSecShape_CCMEC"]|parameter_sigma:[1,1,1,1]|mode:central_value|number_of_multisims:1 - -RootinoFix type:UBGenie|random_seed:101|parameter_list:["RESRootino"]|parameter_sigma:[1]|mode:multisim|number_of_multisims:1 - - # ALL OTHER RECOMMENDED SYSTEMATIC VARIATIONS THROWN TOGETHER -All type:UBGenie|random_seed:100|parameter_list:["MaCCQE","CoulombCCQE","MaNCEL","EtaNCEL","NormCCMEC","NormNCMEC","FracPN_CCMEC","FracDelta_CCMEC","MaCCRES","MvCCRES","MaNCRES","MvNCRES","NonRESBGvpCC1pi","NonRESBGvpCC2pi","NonRESBGvpNC1pi","NonRESBGvpNC2pi","NonRESBGvnCC1pi","NonRESBGvnCC2pi","NonRESBGvnNC1pi","NonRESBGvnNC2pi","NonRESBGvbarpCC1pi","NonRESBGvbarpCC2pi","NonRESBGvbarpNC1pi","NonRESBGvbarpNC2pi","NonRESBGvbarnCC1pi","NonRESBGvbarnCC2pi","NonRESBGvbarnNC1pi","NonRESBGvbarnNC2pi","AhtBY","BhtBY","CV1uBY","CV2uBY","AGKYxF1pi","AGKYpT1pi","MFP_pi","MFP_N","FrCEx_pi","FrInel_pi","FrAbs_pi","FrCEx_N","FrInel_N","FrAbs_N","RDecBR1gamma","RDecBR1eta"]|parameter_sigma:[3.467735,1.5,1,1,1.0,2.0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]|mode:multisim|number_of_multisims:100 - - - -# FLUX CONFIGS -horncurrent type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_horn175ka_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_horn173ka_rgen610.6_flux.root"|parameter_list:["horncurrent"]|random_seed:7|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -pioninexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_pioninexsec_up_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_pioninexsec_down_rgen610.6_flux.root"|parameter_list:["pioninexsec"]|random_seed:8|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -nucleontotxsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_nucleontotxsec_up_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_nucleontotxsec_down_rgen610.6_flux.root"|parameter_list:["nucleontotxsec"]|random_seed:9|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -nucleonqexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_nucleonqexsec_up_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_nucleonqexsec_down_rgen610.6_flux.root"|parameter_list:["nucleonqexse"]|random_seed:10|scale_factor_pos:0.333|scale_factor_neg:0.573|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -nucleoninexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_nucleoninexsec_up_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_nucleoninexsec_down_rgen610.6_flux.root"|parameter_list:["nucleoninexsec"]|random_seed:11|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -pionqexsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_pionqexsec_up_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_pionqexsec_down_rgen610.6_flux.root"|parameter_list:["pionqexsec"]|random_seed:12|scale_factor_pos:0.292|scale_factor_neg:0.585|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -piontotxsec type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/may06_piontotxsec_up_rgen610.6_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/may06_piontotxsec_down_rgen610.6_flux.root"|parameter_list:["piontotxsec"]|random_seed:13|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -expskin type:FluxUnisim|CentralValue_hist_file:"beamData/UnisimHists/may06_10kpot_ntrd1000_flux.root"|PositiveSystematicVariation_hist_file:"beamData/UnisimHists/expskin_nrtd1000_flux.root"|NegativeSystematicVariation_hist_file:"beamData/UnisimHists/expskin_nrtd1000_flux.root"|parameter_list:["expskin"]|random_seed:14|scale_factor_pos:1|scale_factor_neg:1|weight_calculator:"MicroBooNE"|mode:multisim|number_of_multisims:1000|use_MiniBooNE_random_numbers:false - -bnbcorrection type:FluxHist|cv_hist_file:"beamData/bnbcorrection/bnb_oldflux_volAVTPC.root"|rw_hist_file:"beamData/bnbcorrection/bnb_newflux_volAVTPC.root"|random_seed:985|mode:reweight|number_of_multisims:1000 - -piplus type:PrimaryHadronSWCentralSplineVariation|random_seed:2|parameter_list:["piplus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:211|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root"|ExternalFit:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false - -piminus type:PrimaryHadronSWCentralSplineVariation|random_seed:3|parameter_list:["piminus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:-211|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE_SplinesHARP.root"|ExternalFit:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false - -kplus type:PrimaryHadronFeynmanScaling|random_seed:4|parameter_sigma:1|mode:multisim|number_of_multisims:1000|PrimaryHadronGeantCode:321|weight_calculator:"MicroBooNE"|parameter_list:["kplus"]|scale_factor:1|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false - -kzero type:PrimaryHadronSanfordWang|random_seed:5|parameter_list:["kzero"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:[130,310,311]|weight_calculator:"MicroBooNE"|ExternalData:"beamData/ExternalData/BNBExternalData_uBooNE.root"|use_MiniBooNE_random_numbers:false - -kminus type:PrimaryHadronNormalization|random_seed:6|parameter_list:["kminus"]|parameter_sigma:1|mode:multisim|scale_factor:1|number_of_multisims:1000|PrimaryHadronGeantCode:-321|weight_calculator:"MiniBooNE"|use_MiniBooNE_random_numbers:false diff --git a/configfiles/ReweightEventsGenie/ToolsConfig b/configfiles/ReweightEventsGenie/ToolsConfig deleted file mode 100644 index c8416646d..000000000 --- a/configfiles/ReweightEventsGenie/ToolsConfig +++ /dev/null @@ -1,14 +0,0 @@ -myLoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig -myLoadWCSim LoadWCSim configfiles/ReweightEventsGenie/LoadWCSimConfig -myLoadWCSimLAPPD LoadWCSimLAPPD configfiles/ReweightEventsGenie/LoadWCSimLAPPDConfig -myLoadGenieEvent LoadGenieEvent configfiles/ReweightEventsGenie/LoadGenieEventConfig -#myReweightEventsGenie ReweightEventsGenie configfiles/ReweightEventsGenie/ReweightEventsGenieConfig -myMCParticleProperties MCParticleProperties configfiles/ReweightEventsGenie/MCParticlePropertiesConfig -myMCRecoEventLoader MCRecoEventLoader configfiles/ReweightEventsGenie/MCRecoEventLoaderConfig -myTimeClustering TimeClustering configfiles/ReweightEventsGenie/TimeClusteringConfig -myFindMrdTracks FindMrdTracks configfiles/ReweightEventsGenie/FindMrdTracksConfig -myClusterFinder ClusterFinder configfiles/ReweightEventsGenie/ClusterFinderConfig -myClusterClassifiers ClusterClassifiers configfiles/ReweightEventsGenie/ClusterClassifiersConfig -myDigitBuilder DigitBuilder configfiles/ReweightEventsGenie/DigitBuilderConfig -myEventSelector EventSelector configfiles/ReweightEventsGenie/EventSelectorConfig -myPhaseIITreeMaker PhaseIITreeMaker configfiles/ReweightEventsGenie/PhaseIITreeMakerConfig diff --git a/configfiles/RingCounting/RC_files_to_load.txt b/configfiles/RingCounting/RC_files_to_load.txt index ba0ee1c19..888a106a6 100644 --- a/configfiles/RingCounting/RC_files_to_load.txt +++ b/configfiles/RingCounting/RC_files_to_load.txt @@ -2,6 +2,6 @@ singleEntry.csv singleEntry.csv singleEntry.csv singleEntry.csv -/annie/app/users/dschmid/ToolAnalysisDev/R1613p1_CNNImage_charge.csv +R1613p1_CNNImage_charge.csv singleEntry.csv R1613p1_CNNImage_charge.csv diff --git a/configfiles/RingCounting/RingCountingConfig b/configfiles/RingCounting/RingCountingConfig index 8570e7474..c88bf7927 100644 --- a/configfiles/RingCounting/RingCountingConfig +++ b/configfiles/RingCounting/RingCountingConfig @@ -9,12 +9,13 @@ verbose 1 # analysis specific settings # # Define file containing (multiple) filepath(s) to be loaded -load_from_file 0 +load_from_csv 0 +save_to_csv 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 /pnfs/annie/persistent/reconstruction/RingCounting/RingCountingStore/models/ # Masked PMTs (to 0) config -> check documentation pmt_mask november_22 # Output file diff --git a/getobjects.sh b/getobjects.sh new file mode 100755 index 000000000..d89039af0 --- /dev/null +++ b/getobjects.sh @@ -0,0 +1,21 @@ +#!/bin/bash +if [ $# -ne 0 ]; then + #echo "getting objects needed for tools $*" >&2 + declare -a OBJS; + #echo "looping over $# tools" >&2 + for TOOL in "$@"; do + #echo "searching for objects for tool ${TOOL}" >&2 + OBJ=$(ls -1 UserTools/${TOOL}/*.cpp 2>/dev/null | sed 's/.cpp$/.o/') + if [ ! -z "${OBJ}" ]; then + OBJS+=( "${OBJ}" ) + fi + #echo "adding obj ${OBJ}" >&2 + + # hack for examples as they don't follow normal folder structure + if ! ls UserTools/${TOOL}/${TOOL}.cpp &> /dev/null && ls UserTools/Examples/${TOOL}.cpp &> /dev/null; then + OBJS+=( "UserTools/Examples/${TOOL}.o" ) + fi + done + #OBJS+=( "UserTools/MyFactory/MyFactory.o" ) + echo "${OBJS[@]}" +fi diff --git a/gettools.sh b/gettools.sh new file mode 100755 index 000000000..5c75fef74 --- /dev/null +++ b/gettools.sh @@ -0,0 +1,41 @@ +#!/bin/bash +TOOLCHAIN="${1##./configfiles/}" +#echo "get tools for toolchain '${TOOLCHAIN}'" +if [ $# -eq 0 ] || [ ! -f "configfiles/$TOOLCHAIN/ToolsConfig" ]; then + DIRS=( $(find -L UserTools -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | grep -v -e Factory -e template -e InactiveTools) ) + declare -a TOOLS; + # filter out python tools as they do not need to go into Unity/Factory + for DIR in "${DIRS[@]}"; do + #echo "checking ${DIR}" + if [ -f "UserTools/${DIR}/${DIR}.cpp" ]; then + TOOLS+=( "${DIR}" ) + fi + done + + # hack to handle examples which do not follow standard folder structure... should we just move them? + for FILE in `ls UserTools/Examples/Example*.h`; do + cp ${FILE} include/ + TOOLNAME=$(basename ${FILE%%.h}) + TOOLS+=( "${TOOLNAME}" ) + done + + #echo "${TOOLS[@]}" + UNIQUE_TOOLS=( $(for ATOOL in "${TOOLS[@]}"; do echo "${ATOOL}"; done | sort -u) ) + echo "${UNIQUE_TOOLS[@]}" + #ls UserTools/*/*.cpp | sed 's/.cpp$//' | xargs -n1 basename | grep -v -e Factory -e template -e InactiveTools +else + #echo "getting tools needed for toolchain $TOOLCHAIN" >&2 + # parse into bash array + declare -a TOOLS; + while read -r line; do + if [ -z "${line}" ]; then continue; fi + NC=$(echo ${line:0:1}) + if [ "${NC}" == "#" ]; then continue; fi + TOOL=$(echo "${line}" | cut -d' ' -f 2) + TOOLS+=( "${TOOL}" ) + #echo "adding tool ${TOOL}" >&2 + done < <(cat "./configfiles/$TOOLCHAIN/ToolsConfig") + #echo "${TOOLS[@]}" + UNIQUE_TOOLS=( $(for ATOOL in "${TOOLS[@]}"; do echo "${ATOOL}"; done | sort -u) ) + echo "${UNIQUE_TOOLS[@]}" +fi diff --git a/src/main.cpp b/src/main.cpp index db57d15ec..4952dbd70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ #include #include "ToolChain.h" -#include "DummyTool.h" +//#include "DummyTool.h" int main(int argc, char* argv[]){