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..b7ff70d9f 100644 --- a/.github/workflows/tempbuild.yml +++ b/.github/workflows/tempbuild.yml @@ -100,6 +100,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..0c448d557 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ DataModel/DataModel_Linkdef.hh # These are imported as part of ToolPack UserTools/ImportedTools UserTools/InactiveTools +UserTools/MyFactory 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/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..8aff68195 100755 --- a/DataModel/LAPPDPulse.h +++ b/DataModel/LAPPDPulse.h @@ -22,12 +22,20 @@ class LAPPDPulse : public Hit{ inline void SetChannelID(int channelid){ChannelID=channelid;} inline void SetPeak(double peak){Peak=peak;} inline void SetRange(double low, double hi){LowRange=low; HiRange=hi;} + inline void SetHalfHeightTime(double half){halfHeightTime=half;} + inline double GetHalfHeightTime(){return halfHeightTime;} + inline void SetHalfEndTime(double half){halfEndTime=half;} + inline double GetHalfEndTime(){return halfEndTime;} + inline void SetBaseline(double base){baseline=base;} + inline double GetBaseline(){return baseline;} bool Print() { cout<<"TubeId : "< void serialize(Archive & ar, const unsigned int version){ @@ -47,6 +59,9 @@ class LAPPDPulse : public Hit{ ar & Peak; ar & LowRange; ar & HiRange; + ar & halfHeightTime; + ar & halfEndTime; + ar & baseline; } } }; diff --git a/UserTools/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/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/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/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..79c8c26e0 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,6 +70,16 @@ 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) { @@ -87,6 +98,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 +113,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(); + 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 (goodFetch) { - // Emplace fBeamDataToSave to CStore for other tools to use - m_data->CStore.Set("BeamData",fBeamDataToSave); - goodFetch = true; - } - - 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 +162,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; + // 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 - grab the undelayed beam trigger 14 + if (std::find(iterator->second.begin(), iterator->second.end(), 14) == iterator->second.end()) { + continue; + } - uint64_t trigTimestamp = iterator.first; + // 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 +203,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; - 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 +238,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 +253,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 +293,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 +324,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..deedadd37 100644 --- a/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp +++ b/UserTools/BeamFetcherV2/IFBeamDBInterfaceV2.cpp @@ -16,6 +16,19 @@ IFBeamDBInterfaceV2::IFBeamDBInterfaceV2() fCurl = curl_easy_init(); if (!fCurl) throw std::runtime_error("IFBeamDBInterfaceV2 failed to" " initialize libcurl"); + + 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"}}; } IFBeamDBInterfaceV2::~IFBeamDBInterfaceV2() @@ -237,6 +250,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 +301,29 @@ 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(); + } + + // 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..4b8b33e99 --- /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 14 (undelayed beam trigger) + // If it's not there then it isn't a beam trigger and there's nothing more to do + if (std::find(iterator->second.begin(), iterator->second.end(), 14) == iterator->second.end()) { + 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..3d90cf910 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)< mc_pulse_width) { 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/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/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/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["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/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/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/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/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/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..d30bbc97e 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); @@ -906,3 +920,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..85768367a --- /dev/null +++ b/UserTools/LoadReweightGenieEvent/LoadReweightGenieEvent.cpp @@ -0,0 +1,1487 @@ +/* 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 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 ) { + weights[i][k] = reweightVector[i].at(k).CalcWeight( *gevtRec ); + } + + 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..5d9600108 100644 --- a/UserTools/LoadWCSim/LoadWCSim.cpp +++ b/UserTools/LoadWCSim/LoadWCSim.cpp @@ -418,7 +418,7 @@ bool LoadWCSim::Execute(){ 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)); + m_data->CStore.Set("GenieEntry",genieentry); for(int trigi=0; trigiwcsimrootevent->GetNumberOfEvents(); trigi++){ @@ -658,10 +658,13 @@ bool LoadWCSim::Execute(){ if(verbosity>2) cout<<"digit Q is "< parents = GetHitParentIds(digihit, firsttrigt); - //std::cout <<"digittime before adding event time: "<2){ std::cout <<"digittime before adding event time: "< therefore we shouldn't add the event / trigger time if using unsmeared + if(use_smeared_digit_time){ + if (!splitSubtriggers) digittime += EventTimeNs; + } + if(verbosity>2){ std::cout <<"digittime after adding event time: "<count(key)==0) MCHits->emplace(key, std::vector{nexthit}); 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/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..00c6db28b 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,46 @@ 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(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/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp index a7a4563ca..f1a48b62d 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,231 @@ 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 << "PhaseIIADCHitFinder: 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 << "PhaseIIADCHitFinder: 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 << "PhaseIIADCHitFinder: 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 << "PhaseIIADCHitFinder: Pulse found is VERY LATE in the minibuffer (we're at the final sample)... forcing pulse to end" << std::endl; + pulse_end_sample = s; + } else { + pulse_end_sample = (s + 5 < (num_samples - 1)) ? (s + 5) : (num_samples - 1); // ensure we don't exceed the buffer + } + + // double check that pulse start and stop were found successfully + if (verbosity > v_debug) { + std::cout << "PhaseIIADCHitFinder: Pulse start and end determined! (" << pulse_start_sample + << ", " << 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 && !mc_waveforms){ + std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel " << channel_key << "... setting this channel's offset to 0ns" << 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 << "PhaseIIADCHitFinder: Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; + + if (hit_time < 0.0) { + if(verbosity>v_debug) std::cout << "PhaseIIADCHitFinder: Hit time is negative! Defaulting to peak time" << std::endl; + hit_time = peak_sample; + } + + if(verbosity>v_debug) { + std::cout << "PhaseIIADCHitFinder: Pulse properties: " << std::endl; + std::cout << " chanID: " << channel_key << std::endl; + std::cout << " charge: " << ( charge ) << std::endl; + std::cout << " start time: " << ( pulse_start_sample ) << std::endl; + std::cout << " hit time: " << ( hit_time ) << std::endl; + std::cout << " stop time: " << ( pulse_end_sample ) << std::endl; + } + + // 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 +1165,94 @@ 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 + } + } + + // 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..d952cd04f 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.cpp @@ -13,23 +13,36 @@ 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("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 +114,19 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIITankClusterTree->Branch("SiPM1NPulses",&fSiPM1NPulses,"SiPM1NPulses/I"); fPhaseIITankClusterTree->Branch("SiPM2NPulses",&fSiPM2NPulses,"SiPM2NPulses/I"); } + //MuonFitter reco track length, vtx, energy; juju + if (MuonFitter_fill) + { + 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 +182,7 @@ bool PhaseIITreeMaker::Initialise(std::string configfile, DataModel &data){ fPhaseIIMRDClusterTree->Branch("MRDStop",&fMRDStop); fPhaseIIMRDClusterTree->Branch("MRDThrough",&fMRDThrough); } + } if(TriggerProcessing){ @@ -164,6 +191,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 +300,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 +375,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 +412,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 @@ -421,8 +544,6 @@ bool PhaseIITreeMaker::Execute(){ } } - - if(TankClusterProcessing){ Log("PhaseIITreeMaker Tool: Beginning Tank cluster processing",v_debug,verbosity); //bool get_clusters = m_data->Stores.at("ANNIEEvent")->Get("ClusterMap",m_all_clusters); @@ -434,12 +555,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,14 +578,29 @@ 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) { @@ -549,6 +693,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 +717,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); @@ -765,12 +949,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 +995,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 +1013,18 @@ bool PhaseIITreeMaker::Execute(){ // FIll tree with all reconstruction information if (RecoDebug_fill) this->FillRecoDebugInfo(); + if (MuonFitter_fill) + { + Position tmp_vtx(-999,-999,-999); + m_data->CStore.Get("FittedMuonVertex", tmp_vtx); + fRecoMuonVtxX = tmp_vtx.X(); + fRecoMuonVtxY = tmp_vtx.Y(); + fRecoMuonVtxZ = tmp_vtx.Z(); + m_data->CStore.Get("FittedTrackLengthInWater", fRecoTankTrack); + m_data->CStore.Get("RecoMuonKE", fRecoMuonKE); + m_data->CStore.Get("NLyers", fNumMrdLayers); + } + fPhaseIITrigTree->Fill(); } return true; @@ -817,6 +1048,8 @@ void PhaseIITreeMaker::ResetVariables() { fEventNumber = -9999; fEventTimeTank_Tree = 9999; fNHits = -9999; + fNDigitsPMTs = 0; + fNDigitsLAPPDs = 0; fVetoHit = -9999; fEventTimeMRD_Tree = 9999; fTriggerword = -1; @@ -837,6 +1070,10 @@ void PhaseIITreeMaker::ResetVariables() { fSiPMNum.clear(); } + if(hasBNBtimingMC){ + fbunchTimes = -9999; + } + if(TankClusterProcessing){ fClusterMaxPE = -9999; fClusterChargePointX = -9999; @@ -881,6 +1118,7 @@ void PhaseIITreeMaker::ResetVariables() { fTrueNeutCapE->clear(); fTrueNeutCapGammaE->clear(); fTrueNeutrinoEnergy = -9999; + fTrueNuPDG = -9999; fTrueNeutrinoMomentum_X = -9999; fTrueNeutrinoMomentum_Y = -9999; fTrueNeutrinoMomentum_Z = -9999; @@ -917,6 +1155,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 +1273,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 +1325,25 @@ void PhaseIITreeMaker::ResetVariables() { fDeltaZenith = -9999; fDeltaAngle = -9999; } + + //DIGITS + if (Digit_fill){ + fdigitX.clear(); + fdigitY.clear(); + fdigitZ.clear(); + fdigitT.clear(); + } + //DIGITS + + if (MuonFitter_fill) + { + fRecoMuonVtxX = -9999; + fRecoMuonVtxY = -9999; + fRecoMuonVtxZ = -9999; + fRecoTankTrack = -9999; + fRecoMuonKE = -9999; + fNumMrdLayers = -9999; + } } bool PhaseIITreeMaker::LoadTankClusterClassifiers(double cluster_time){ @@ -1047,6 +1368,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 +1391,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 +1440,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 +1587,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 +1684,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 +1830,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 +2124,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 +2161,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); diff --git a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h index 1bb0f9789..91d1d33f2 100644 --- a/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h +++ b/UserTools/PhaseIITreeMaker/PhaseIITreeMaker.h @@ -22,6 +22,30 @@ #include "TimeClass.h" #include "BeamStatus.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 +65,30 @@ 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(); - + + private: //General variables bool isData; + bool MCWaveform; + bool ApplyDeadMask; bool hasGenie; + bool hasBNBtimingMC; std::map* AuxChannelNumToTypeMap; std::map ChannelKeyToSPEMap; @@ -112,7 +145,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 +158,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 +210,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 +272,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 +327,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 +393,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 +445,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 +472,14 @@ 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; + 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..92ed92d59 100755 --- a/UserTools/PlotWaveforms/Makefile +++ b/UserTools/PlotWaveforms/Makefile @@ -72,23 +72,27 @@ endif dictionary: viewer_linkdef.hh @echo "making $@" $(RM) dict.* dict*.pcm - $(ROOTCLING) -f dict.cc -c -I ../recoANNIE -I ../../DataModel $(BoostInclude) RawViewer.h viewer_linkdef.hh + $(ROOTCLING) -f dict.cc -c -I ../../DataModel $(BoostInclude) RawViewer.h viewer_linkdef.hh dict.o: dictionary 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 $^ -libRawViewer.so: dict.o RawViewer.o +../../DataModel/%.o: ../../DataModel/%.cpp + $(CXX) $(ROOT_CXXFLAGS) $(CXXFLAGS) -fPIC -I../../include -I../../DataModel $(BoostInclude) $(BoostLib) -o $@ -c $^ + +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..d0a102d66 --- /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 # minimum hit charge [pe] to include in the root file +hitPE_max 2.5 # maximum hit charge [pe] to include in the root file + # omitting both of these will not impose a charge selection + +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/PrintDQ/PrintDQ.cpp b/UserTools/PrintDQ/PrintDQ.cpp new file mode 100644 index 000000000..b75bcd004 --- /dev/null +++ b/UserTools/PrintDQ/PrintDQ.cpp @@ -0,0 +1,483 @@ +#include "PrintDQ.h" + +PrintDQ::PrintDQ():Tool(){} + +//------------------------------------------------------------------------------ + +bool PrintDQ::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); + + if (!got_verbosity) { + verbosity = 0; + logmessage = "Warning (PrintDQ): \"verbosity\" not set in the config, defaulting to 0"; + Log(logmessage, v_warning, verbosity); + } + + // initialize counts + totalclusters = 0; + totalevents = 0; + totalclusters_in_prompt = 0; + totalclusters_in_ext = 0; + totalext_rate_1 = 0; + totalext_rate_2 = 0; + totalokay_beam = 0; + totaltmrd_coinc = 0; + totalveto_hit = 0; + totalveto_tmrd_coinc = 0; + totalhas_track = 0; + totalhas_lappd = 0; + totalhas_BRF = 0; + totaltimezero = 0; + totalclusters_in_spill = 0; + + return true; +} + +//------------------------------------------------------------------------------ + + +bool PrintDQ::Execute() +{ + + if (verbosity >= 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/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..4cfd706b9 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,7 +251,7 @@ 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]. """ 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..98ac956f6 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)); diff --git a/UserTools/Unity.h b/UserTools/Unity.h index 9e00352b5..ece5408f4 100644 --- a/UserTools/Unity.h +++ b/UserTools/Unity.h @@ -164,7 +164,8 @@ #include "LAPPDDataDecoder.h" #include "PythonScript.h" #include "MeanTimeCheck.h" -#include "ReweightEventsGenie.h" +#include "LoadReweightGenieEvent.h" +#include "ReweightFlux.h" #include "FilterLAPPDEvents.h" #include "VtxSeedFineGrid.h" #include "FilterEvents.h" @@ -175,3 +176,15 @@ #include "PlotsTrackLengthAndEnergy.h" #include "SaveConfigInfo.h" #include "ReadConfigInfo.h" +#include "MuonFitter.h" +#include "BeamQuality.h" +#include "BackTracker.h" +#include "PrintDQ.h" +#include "AssignBunchTimingMC.h" +#include "FitRWMWaveform.h" +#include "EBPMT.h" +#include "EBPMT.h" +#include "LAPPDLoadStore.h" +#include "PMTWaveformSim.h" +#include "LAPPDWaveformDisplay.h" +#include "PrintADCTraces.h" diff --git a/UserTools/parseLAPPDData/parseLAPPDData.cpp b/UserTools/parseLAPPDData/parseLAPPDData.cpp index e00fd48a2..1f5efa517 100644 --- a/UserTools/parseLAPPDData/parseLAPPDData.cpp +++ b/UserTools/parseLAPPDData/parseLAPPDData.cpp @@ -1,5 +1,13 @@ #include "parseLAPPDData.h" +namespace { +const unsigned int NUM_CH = 30; +const unsigned int NUM_SAMP = 256; +const unsigned int NUM_PSEC = 5; +const unsigned int NUM_VECTOR_DATA = 7795; +const unsigned int NUM_VECTOR_PPS = 16; +} + parseLAPPDData::parseLAPPDData():Tool(){} diff --git a/UserTools/parseLAPPDData/parseLAPPDData.h b/UserTools/parseLAPPDData/parseLAPPDData.h index 8ed1e9ba6..53e38dc57 100644 --- a/UserTools/parseLAPPDData/parseLAPPDData.h +++ b/UserTools/parseLAPPDData/parseLAPPDData.h @@ -9,14 +9,6 @@ #include "PsecData.h" -#define NUM_CH 30 -#define NUM_SAMP 256 -#define NUM_PSEC 5 -#define NUM_VECTOR_DATA 7795 -#define NUM_VECTOR_PPS 16 - - - /** * \class parseLAPPDData * diff --git a/UserTools/recoANNIE/Unity_recoANNIE.cpp b/UserTools/recoANNIE/Unity_recoANNIE.cpp deleted file mode 100644 index 3b069d70a..000000000 --- a/UserTools/recoANNIE/Unity_recoANNIE.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "annie_math.cc" -#include "RawAnalyzer.cc" -#include "RawCard.cc" -#include "RawChannel.cc" -#include "RawReader.cc" -#include "RawReadout.cc" -#include "RawTrigData.cc" -#include "RecoReadout.cc" -#include "RecoPulse.cc" diff --git a/VGCheck-pdfcharge.root b/VGCheck-pdfcharge.root deleted file mode 100644 index 315a9464e..000000000 Binary files a/VGCheck-pdfcharge.root and /dev/null differ diff --git a/configfiles/AmBeWaveform/FitRWMWaveformConfig b/configfiles/AmBeWaveform/FitRWMWaveformConfig new file mode 100644 index 000000000..50fce5571 --- /dev/null +++ b/configfiles/AmBeWaveform/FitRWMWaveformConfig @@ -0,0 +1,3 @@ +verbosityFitRWMWaveform 0 +maxPrintNumber 100000 +printToRootFile 1 diff --git a/configfiles/AmBeWaveform/LoadANNIEEventConfig b/configfiles/AmBeWaveform/LoadANNIEEventConfig new file mode 100644 index 000000000..92e2ce95c --- /dev/null +++ b/configfiles/AmBeWaveform/LoadANNIEEventConfig @@ -0,0 +1,4 @@ +verbose 1 +FileForListOfInputs ./configfiles/AmBeWaveform/my_inputs.txt +EventOffset 0 +GlobalEvNr 1 diff --git a/configfiles/AmBeWaveform/README.md b/configfiles/AmBeWaveform/README.md new file mode 100644 index 000000000..550e09535 --- /dev/null +++ b/configfiles/AmBeWaveform/README.md @@ -0,0 +1,45 @@ +# AmBeWaveform + +*********************** +## Description +********************** + +The `AmBeWaveform` toolchain produces a ROOT file containing all raw AmBe PMT waveforms. + +For AmBe source runs, there is a small PMT within the AmBe housing that records the initial scintillation light within the BGO crystal and acts as the primary trigger for the rest of the PMTs. The small AmBe waveforms are stored in the [RWM auxillary channel](https://github.com/S81D/ToolAnalysis/blob/005d0930b57a266b9d8f4c1ef3ad07f31850e871/configfiles/LoadGeometry/AuxChannels.csv#L6). This waveform can be used to reduce backgrounds in the AmBe neutron analysis. + +Currently, the `FitRWMWaveform` tool which does the heavy lifting for this toolchain is designed for beam runs and the fitting / storing of both the Booster RWM and RF waveforms. This toolchain will therefore populate the output root file with **both** Booster RWM and Booster RF raw waveforms (Booster RF waveforms will be useless for the AmBe source runs). TO DO: Adjust `FitRWMWaveform` tool to handle and fit small AmBe PMT waveforms and send the information to the store for use by other tools. + + +************************ +## Tools +************************ + +The toolchain consists of the following tools: + +``` +LoadANNIEEvent +LoadGeometry +FitRWMWaveform +``` + + +************************ +## Additional information +************************ + +### FitRWMWaveform Config +``` +verbosityFitRWMWaveform 0 +maxPrintNumber 20000 # controls how many waveforms are written to the root file +printToRootFile 1 # whether to print the raw waveforms to the root file +``` +For a 20 part file sample of an AmBe run, there will be ~7000 waveforms recorded in the Booster RWM channel. As stated above, the current iteration of the tool includes the Booster RF channel as well, so for 20 part files we can expect ~14,000 total waveforms. As a result, it is recommended `printToRootFile` is set to 20000 per 20 part files. + + +### Usage +Populate `my_inputs.txt` with ProcessedData part files to run the toolchain over. To quickly populate the list file with part files from a processed run, you can do: `sh create_my_inputs.sh `. + +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..0bb9ca86d --- /dev/null +++ b/configfiles/AmBeWaveform/ToolsConfig @@ -0,0 +1,3 @@ +myLoadANNIEEvent LoadANNIEEvent ./configfiles/AmBeWaveform/LoadANNIEEventConfig +myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +myFitRWMWaveform FitRWMWaveform ./configfiles/AmBeWaveform/FitRWMWaveform \ No newline at end of file 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/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/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/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/ClusterFinderConfig b/configfiles/BeamClusterAnalysisMC/ClusterFinderConfig index 59ef4564a..e0d3c4120 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 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 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/LoadGenieEventConfig b/configfiles/BeamClusterAnalysisMC/LoadGenieEventConfig index 6e22a33ba..4bd3619c4 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 + +# 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/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 + +# 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..a25d47f59 100644 --- a/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig +++ b/configfiles/BeamClusterAnalysisMC/LoadWCSimConfig @@ -2,12 +2,12 @@ # all variables retrieved with m_variables.Get() must be defined here! verbose 1 -#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/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 diff --git a/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig b/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig index 29999cdee..316b98195 100644 --- a/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig +++ b/configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig @@ -1,6 +1,6 @@ verbose 5 -OutputFile MCBeam_Gst_new_Run9000_NoSplitSubTriggers.ntuple.root +OutputFile MCBeam.ntuple.root TankClusterProcessing 1 MRDClusterProcessing 1 TriggerProcessing 1 @@ -11,7 +11,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/ToolsConfig b/configfiles/BeamClusterAnalysisMC/ToolsConfig index 55400ce09..4913dd192 100644 --- a/configfiles/BeamClusterAnalysisMC/ToolsConfig +++ b/configfiles/BeamClusterAnalysisMC/ToolsConfig @@ -9,4 +9,5 @@ myFindMrdTracks FindMrdTracks configfiles/BeamClusterAnalysisMC/FindMrdTracksCon myClusterFinder ClusterFinder ./configfiles/BeamClusterAnalysisMC/ClusterFinderConfig myClusterClassifiers ClusterClassifiers ./configfiles/BeamClusterAnalysisMC/ClusterClassifiersConfig myEventSelector EventSelector ./configfiles/BeamClusterAnalysisMC/EventSelectorConfig +myAssignBunchTimingMC AssignBunchTimingMC ./configfiles/BeamClusterAnalysisMC/AssignBunchTimingMCConfig myPhaseIITreeMaker PhaseIITreeMaker ./configfiles/BeamClusterAnalysisMC/PhaseIITreeMakerConfig 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..3c4bbe337 --- /dev/null +++ b/configfiles/BeamFetcherV2/README.md @@ -0,0 +1,9 @@ +# Configure files + +*********************** +#Description +********************** + +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/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/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/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..6d0350575 --- /dev/null +++ b/configfiles/EventBuilder/README.md @@ -0,0 +1,29 @@ +# EventBuilder + +*********************** +## Description +********************** + +The `EventBuilder` toolchain is used to create ANNIEEvents. The toolchain reads in RAWData files, time match, and creates processed ANNIEEvents with Tank, CTC, MRD, and Beam information (no LAPPD information is included in this toolchain). This toolchain replaces the `DataDecoder` toolchain which is now considered depreciated. + +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/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..050c4681e --- /dev/null +++ b/configfiles/EventBuilderRaw/LoadRawDataConfig @@ -0,0 +1,8 @@ +verbosity 0 +BuildType TankAndCTC +Mode FileList +InputFile ./configfiles/EventBuilderRaw/my_files.txt +DummyRunInfo 1 +StoreTrigOverlap 0 +ReadTrigOverlap 0 +StoreRawData 1 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/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..5156f6b55 --- /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 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 5 +#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 -20 + +CanvasWidth 1000 +CanvasHeight 500 + +maxDrawEventNumber 200 + +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/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..d047a0162 --- /dev/null +++ b/configfiles/LAPPD_EB/my_files.txt @@ -0,0 +1,50 @@ +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p0 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p1 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p2 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p3 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p4 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p5 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p6 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p7 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p8 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p9 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p10 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p11 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p12 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p13 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p14 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p15 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p16 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p17 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p18 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p19 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p20 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p21 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p22 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p23 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p24 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p25 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p26 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p27 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p28 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p29 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p30 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p31 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p32 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p33 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p34 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p35 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p36 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p37 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p38 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p39 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p40 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p41 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p42 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p43 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p44 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p45 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p46 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p47 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p48 +/pnfs/annie/persistent/raw/raw/4795/RAWDataR4795S0p49 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/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..b1f16ff3f --- /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,inactive +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/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..223d13be8 --- /dev/null +++ b/configfiles/PrintADCTraces/PrintADCTracesConfig @@ -0,0 +1,19 @@ +verbosity 0 + +hitPE_min 0 # minimum hit charge [pe] to include in the root file +hitPE_max 2.5 # maximum hit charge [pe] to include in the root file + # omitting both of these will not impose a charge selection + +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 \ No newline at end of file diff --git a/configfiles/PrintADCTraces/README.md b/configfiles/PrintADCTraces/README.md new file mode 100644 index 000000000..33abd3962 --- /dev/null +++ b/configfiles/PrintADCTraces/README.md @@ -0,0 +1,68 @@ +# 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 2.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 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). +- 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/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..1e9497f16 --- /dev/null +++ b/configfiles/PrintADCTraces/ToolsConfig @@ -0,0 +1,4 @@ +LoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +LoadANNIEEvent LoadANNIEEvent ./configfiles/PrintADCTraces/LoadANNIEEventConfig +#ClusterFinder ClusterFinder ./configfiles/PrintADCTraces/ClusterFinderConfig +PrintADCTraces PrintADCTraces ./configfiles/PrintADCTraces/PrintADCTracesConfig diff --git a/configfiles/PrintADCTraces/my_inputs.txt b/configfiles/PrintADCTraces/my_inputs.txt new file mode 100644 index 000000000..463a08792 --- /dev/null +++ b/configfiles/PrintADCTraces/my_inputs.txt @@ -0,0 +1,10 @@ +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p0 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p1 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p2 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p3 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p4 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p5 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p6 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p7 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p8 +/pnfs/annie/persistent/processed/processingData_EBV2/processed_EBV2/R4695/ProcessedData_PMTLAPPD_R4695S0p9 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/RingCountingConfig b/configfiles/RingCounting/RingCountingConfig index 8570e7474..36c0c9cf8 100644 --- a/configfiles/RingCounting/RingCountingConfig +++ b/configfiles/RingCounting/RingCountingConfig @@ -9,7 +9,8 @@ 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 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[]){