From a70d570f9e9de8c1d9dc33c26a4be0d0587ab87d Mon Sep 17 00:00:00 2001 From: Michael Nieslony <41126346+mnieslony@users.noreply.github.com> Date: Sat, 17 Feb 2024 01:01:43 +0100 Subject: [PATCH] Neutron Multiplicity toolchain (#245) * added framework for simple reco * added Factory & Unity * added muon and neutron identification cuts in ClusterClassifiers * add FindNeutrons tool * added FindNeutrons * new tool * updated Makefile & Setup.sh * fixed compilation errors in FindNeutrons & ClusterClassifiers * more compilation fixes * moved neutron finding algorithms to FindNeutrons tool * SimpleReconstruction & FindNeutrons progress * wip SimpleReconstruction * first version SimpleReco + FindNeutrons * first working version of simple reco * added extended window and beamok flag to EventSelector * fix for variables SimpleReco/NeutronMult tools * add tree framework to NeutronMultiplicity tool * fill more variables in output tree * added BoostStore read-in and store mode for NeutronMultiplicity * Update README of FindNeutrons Added README of FindNeutrons tool with relevant information * Update README of SimpleReconstruction Added README with basic properties of SimpleReconstruction tool * Update README of NeutronMultiplicity tool Added README with description of properties of NeutronMultiplicity tool. * moved some variables to RecoEvent instead of ANNIEEvent * Update visible_energy_vertex.C Removed unnecessary parts of the code (which were commented out) * Update neutrino_selection.C Added verbose configuration variable * Update reconstruction_migration.C Added verbose configuration variable * Update and rename plot_neutrons_mc_new.C to plot_neutrons_mc.C rename + add configuration variable verbose * Update and rename plot_neutrons_dirt.C to plot_neutrons_data_dirt.C Rename + add verbose configuration variable * Update and rename plot_neutrons_data_new.C to plot_neutrons_data_beam.C Rename + add verbose configuration variable * Create README.md Added README for the root-scripts * Update README.md Extended description * Update README.md Added text to README file * Update README.md Added additional sentence about ReadFromBoostStore version of the toolchain * wip NeutronMultiplicity * re-add LoadGenieEvent & PrintGenieEvent * Add FindParticlePdgs to MCRecoEventLoader * more MRD variables in SimpleReco tool * add MC version of NeutronMultiplicity toolchain * Add Particles object in LoadWCSim * verbosity changes * add primary/secondary information for neutron captures * more verbosity cleanup * add efficiency map in FindNeutrons * add effiency map in NeutronMultiplicity * Add transverse momentum in SimpleReconstruction * Add neutron efficiency scripts (MC) * bugfix in neutronmultiplicity efficiency correction * add scripts for running on many files * Reduced verbosity of NeutronMultiplicity tool * Added NeutronMultiplicity script for filtered ANNIEEvent BoostStore input files * config file madness * removed duplicate filelist file * Update README.md update readme of NeutronMultiplicity tool * Update README.md update README of FindNeutrons tool * Add NHits method for neutron candidates * add event offset to LoadGenieEvent tool * toolchain modifications for different neutron cuts --- .../ClusterClassifiers/ClusterClassifiers.cpp | 115 ++ .../ClusterClassifiers/ClusterClassifiers.h | 19 +- UserTools/ClusterFinder/ClusterFinder.cpp | 2 +- UserTools/EventSelector/EventSelector.cpp | 64 +- UserTools/EventSelector/EventSelector.h | 18 +- UserTools/Factory/Factory.cpp | 5 +- UserTools/FindNeutrons/FindNeutrons.cpp | 320 ++++ UserTools/FindNeutrons/FindNeutrons.h | 69 + UserTools/FindNeutrons/README.md | 47 + UserTools/LoadGenieEvent/LoadGenieEvent.cpp | 9 +- UserTools/LoadWCSim/LoadWCSim.cpp | 41 +- .../MCRecoEventLoader/MCRecoEventLoader.cpp | 20 +- .../MCRecoEventLoader/MCRecoEventLoader.h | 8 +- .../NeutronMultiplicity.cpp | 1414 +++++++++++++++++ .../NeutronMultiplicity/NeutronMultiplicity.h | 327 ++++ UserTools/NeutronMultiplicity/README.md | 63 + UserTools/SimpleReconstruction/README.md | 41 + .../SimpleReconstruction.cpp | 390 +++++ .../SimpleReconstruction.h | 94 ++ UserTools/TimeClustering/TimeClustering.cpp | 2 +- UserTools/Unity.h | 5 +- .../ClusterClassifiersConfig | 1 + .../NeutronMultiplicity/ClusterFinderConfig | 12 + .../CreateMyList_Processed.sh | 20 + .../NeutronMultiplicity/EventSelectorConfig | 31 + .../NeutronMultiplicity/FindMrdTracksConfig | 12 + .../NeutronMultiplicity/FindNeutronsConfig | 5 + .../NeutronMultiplicity/LoadANNIEEventConfig | 4 + .../MC/Chankey_WCSimID_v7.txt | 132 ++ .../MC/ClusterClassifiersConfig | 3 + .../MC/ClusterFinderConfig | 12 + .../MC/DeadPMTIDs_p2v7.txt | 10 + .../MC/EventSelectorConfig | 31 + .../MC/FindMrdTracksConfig | 12 + .../NeutronMultiplicity/MC/FindNeutronsConfig | 5 + .../MC/LoadGenieEventConfig | 11 + .../NeutronMultiplicity/MC/LoadWCSimConfig | 20 + .../MC/LoadWCSimLAPPDConfig | 14 + .../MC/MCParticlePropertiesConfig | 3 + .../MC/MCRecoEventLoaderConfig | 11 + .../MC/NeutronMultiplicityConfig | 7 + configfiles/NeutronMultiplicity/MC/README.md | 30 + .../MC/RunNeutronMultiplicityMC.sh | 37 + .../MC/TimeClusteringConfig | 13 + .../NeutronMultiplicity/MC/ToolChainConfig | 23 + .../NeutronMultiplicity/MC/ToolsConfig | 14 + .../MC/genie-files-gst.txt | 1 + .../NeutronMultiplicity/MC/offset-gst.txt | 1 + .../NeutronMultiplicity/MC/pmt-files-gst.txt | 1 + .../NeutronEffMap_Data.txt | 24 + .../NeutronEffMap_MC_CB.txt | 25 + .../NeutronEffMap_MC_CBStrict.txt | 25 + .../NeutronEffMap_MC_NHits10.txt | 25 + .../NeutronMultiplicityConfig | 7 + configfiles/NeutronMultiplicity/README.md | 30 + .../NeutronMultiplicityConfig | 10 + .../ReadFromBoostStore/ToolChainConfig | 26 + .../ReadFromBoostStore/ToolsConfig | 1 + .../ReadFromBoostStore/datafiles.txt | 58 + .../ReadFromBoostStore/mcfiles.txt | 101 ++ .../RunNeutronMultiplicity.sh | 28 + .../RunNeutronMultiplicityFiltered.sh | 37 + .../SimpleReconstructionConfig | 3 + .../NeutronMultiplicity/TimeClusteringConfig | 13 + .../NeutronMultiplicity/ToolChainConfig | 26 + configfiles/NeutronMultiplicity/ToolsConfig | 10 + configfiles/NeutronMultiplicity/my_inputs.txt | 1 + .../NeutronMultiplicity/my_inputs_old.txt | 173 ++ .../root-scripts/README.md | 16 + .../root-scripts/RunCreateEfficiencyMC.sh | 15 + .../root-scripts/create_efficiency_mc.C | 133 ++ .../root-scripts/heightlist.txt | 5 + .../root-scripts/neutrino_selection.C | 202 +++ .../root-scripts/plot_neutrons_data_beam.C | 479 ++++++ .../root-scripts/plot_neutrons_data_dirt.C | 483 ++++++ .../root-scripts/plot_neutrons_mc.C | 582 +++++++ .../root-scripts/portlist.txt | 5 + .../root-scripts/reconstruction_migration.C | 655 ++++++++ .../root-scripts/visible_energy_vertex.C | 367 +++++ .../runlist_r2506-r2630.txt | 58 + 80 files changed, 7138 insertions(+), 34 deletions(-) create mode 100644 UserTools/FindNeutrons/FindNeutrons.cpp create mode 100644 UserTools/FindNeutrons/FindNeutrons.h create mode 100644 UserTools/FindNeutrons/README.md create mode 100644 UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp create mode 100644 UserTools/NeutronMultiplicity/NeutronMultiplicity.h create mode 100644 UserTools/NeutronMultiplicity/README.md create mode 100644 UserTools/SimpleReconstruction/README.md create mode 100644 UserTools/SimpleReconstruction/SimpleReconstruction.cpp create mode 100644 UserTools/SimpleReconstruction/SimpleReconstruction.h create mode 100644 configfiles/NeutronMultiplicity/ClusterClassifiersConfig create mode 100644 configfiles/NeutronMultiplicity/ClusterFinderConfig create mode 100755 configfiles/NeutronMultiplicity/CreateMyList_Processed.sh create mode 100644 configfiles/NeutronMultiplicity/EventSelectorConfig create mode 100644 configfiles/NeutronMultiplicity/FindMrdTracksConfig create mode 100644 configfiles/NeutronMultiplicity/FindNeutronsConfig create mode 100644 configfiles/NeutronMultiplicity/LoadANNIEEventConfig create mode 100644 configfiles/NeutronMultiplicity/MC/Chankey_WCSimID_v7.txt create mode 100644 configfiles/NeutronMultiplicity/MC/ClusterClassifiersConfig create mode 100644 configfiles/NeutronMultiplicity/MC/ClusterFinderConfig create mode 100644 configfiles/NeutronMultiplicity/MC/DeadPMTIDs_p2v7.txt create mode 100644 configfiles/NeutronMultiplicity/MC/EventSelectorConfig create mode 100644 configfiles/NeutronMultiplicity/MC/FindMrdTracksConfig create mode 100644 configfiles/NeutronMultiplicity/MC/FindNeutronsConfig create mode 100644 configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig create mode 100644 configfiles/NeutronMultiplicity/MC/LoadWCSimConfig create mode 100644 configfiles/NeutronMultiplicity/MC/LoadWCSimLAPPDConfig create mode 100644 configfiles/NeutronMultiplicity/MC/MCParticlePropertiesConfig create mode 100644 configfiles/NeutronMultiplicity/MC/MCRecoEventLoaderConfig create mode 100644 configfiles/NeutronMultiplicity/MC/NeutronMultiplicityConfig create mode 100644 configfiles/NeutronMultiplicity/MC/README.md create mode 100755 configfiles/NeutronMultiplicity/MC/RunNeutronMultiplicityMC.sh create mode 100644 configfiles/NeutronMultiplicity/MC/TimeClusteringConfig create mode 100644 configfiles/NeutronMultiplicity/MC/ToolChainConfig create mode 100644 configfiles/NeutronMultiplicity/MC/ToolsConfig create mode 120000 configfiles/NeutronMultiplicity/MC/genie-files-gst.txt create mode 120000 configfiles/NeutronMultiplicity/MC/offset-gst.txt create mode 120000 configfiles/NeutronMultiplicity/MC/pmt-files-gst.txt create mode 100644 configfiles/NeutronMultiplicity/NeutronEffMap_Data.txt create mode 100644 configfiles/NeutronMultiplicity/NeutronEffMap_MC_CB.txt create mode 100644 configfiles/NeutronMultiplicity/NeutronEffMap_MC_CBStrict.txt create mode 100644 configfiles/NeutronMultiplicity/NeutronEffMap_MC_NHits10.txt create mode 100644 configfiles/NeutronMultiplicity/NeutronMultiplicityConfig create mode 100644 configfiles/NeutronMultiplicity/README.md create mode 100644 configfiles/NeutronMultiplicity/ReadFromBoostStore/NeutronMultiplicityConfig create mode 100644 configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolChainConfig create mode 100644 configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolsConfig create mode 100644 configfiles/NeutronMultiplicity/ReadFromBoostStore/datafiles.txt create mode 100644 configfiles/NeutronMultiplicity/ReadFromBoostStore/mcfiles.txt create mode 100755 configfiles/NeutronMultiplicity/RunNeutronMultiplicity.sh create mode 100755 configfiles/NeutronMultiplicity/RunNeutronMultiplicityFiltered.sh create mode 100644 configfiles/NeutronMultiplicity/SimpleReconstructionConfig create mode 100644 configfiles/NeutronMultiplicity/TimeClusteringConfig create mode 100644 configfiles/NeutronMultiplicity/ToolChainConfig create mode 100644 configfiles/NeutronMultiplicity/ToolsConfig create mode 100644 configfiles/NeutronMultiplicity/my_inputs.txt create mode 100644 configfiles/NeutronMultiplicity/my_inputs_old.txt create mode 100644 configfiles/NeutronMultiplicity/root-scripts/README.md create mode 100755 configfiles/NeutronMultiplicity/root-scripts/RunCreateEfficiencyMC.sh create mode 100644 configfiles/NeutronMultiplicity/root-scripts/create_efficiency_mc.C create mode 100644 configfiles/NeutronMultiplicity/root-scripts/heightlist.txt create mode 100644 configfiles/NeutronMultiplicity/root-scripts/neutrino_selection.C create mode 100644 configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_data_beam.C create mode 100644 configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_data_dirt.C create mode 100644 configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_mc.C create mode 100644 configfiles/NeutronMultiplicity/root-scripts/portlist.txt create mode 100644 configfiles/NeutronMultiplicity/root-scripts/reconstruction_migration.C create mode 100644 configfiles/NeutronMultiplicity/root-scripts/visible_energy_vertex.C create mode 100644 configfiles/NeutronMultiplicity/runlist_r2506-r2630.txt diff --git a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp index 860a13748..6b8fb705f 100644 --- a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp +++ b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp @@ -62,6 +62,9 @@ bool ClusterClassifiers::Execute(){ std::map ClusterMaxPEs; std::map ClusterChargePoints; std::map ClusterChargeBalances; + std::map ClusterTotalPEs; + std::vector ClusterTimes; + std::map ClusterNHits; if (isData){ for (std::pair>&& cluster_pair : *m_all_clusters) { @@ -74,6 +77,10 @@ bool ClusterClassifiers::Execute(){ ClusterChargeBalances.emplace(cluster_time,ChargeBalance); double max_PE = this->CalculateMaxPE(cluster_hits); ClusterMaxPEs.emplace(cluster_time,max_PE); + double total_PE = this->CalculateTotalPE(cluster_hits); + ClusterTotalPEs.emplace(cluster_time,total_PE); + ClusterTimes.push_back(cluster_time); + ClusterNHits.emplace(cluster_time,int(cluster_hits.size())); } } else { for (std::pair>&& cluster_pair : *m_all_clusters_MC) { @@ -87,6 +94,10 @@ bool ClusterClassifiers::Execute(){ ClusterChargeBalances.emplace(cluster_time,ChargeBalance); double max_PE = this->CalculateMaxPEMC(cluster_hits,cluster_detkey); ClusterMaxPEs.emplace(cluster_time,max_PE); + double total_PE = this->CalculateTotalPEMC(cluster_hits,cluster_detkey); + ClusterTotalPEs.emplace(cluster_time,total_PE); + ClusterTimes.push_back(cluster_time); + ClusterNHits.emplace(cluster_time,int(cluster_hits.size())); } } @@ -95,6 +106,19 @@ bool ClusterClassifiers::Execute(){ m_data->Stores.at("ANNIEEvent")->Set("ClusterChargePoints", ClusterChargePoints); m_data->Stores.at("ANNIEEvent")->Set("ClusterChargeBalances", ClusterChargeBalances); m_data->Stores.at("ANNIEEvent")->Set("ClusterMaxPEs", ClusterMaxPEs); + m_data->Stores.at("ANNIEEvent")->Set("ClusterTotalPEs", ClusterTotalPEs); + m_data->Stores.at("ANNIEEvent")->Set("ClusterNHits", ClusterNHits); + + //identify prompt muon candidate + bool found_prompt_muon = this->IdentifyPromptMuonCluster(ClusterTotalPEs); + + //store indices of muon and neutron clusters to ANNIEEvent Store + m_data->Stores.at("RecoEvent")->Set("ClusterIndexPromptMuon", prompt_muon_index); + if (found_prompt_muon){ + m_data->Stores.at("RecoEvent")->Set("PromptMuonTotalPE", ClusterTotalPEs.at(ClusterTimes.at(prompt_muon_index))); + m_data->Stores.at("RecoEvent")->Set("PromptMuonTime", ClusterTimes.at(prompt_muon_index)); + } + return true; } @@ -272,3 +296,94 @@ double ClusterClassifiers::CalculateMaxPEMC(std::vector cluster_hits, std if(verbosity>4) std::cout << "ClusterClassifiers Tool: Calculated max PE hit of " << max_PE << std::endl; return max_PE; } + +bool ClusterClassifiers::IdentifyPromptMuonCluster(std::map cluster_totalq){ + + bool return_prompt = false; + int tmp_cluster_id = 0; + int cluster_muon = -1; + double max_pe = 0; + for (std::map::iterator it = cluster_totalq.begin(); it!= cluster_totalq.end(); it++){ + //Check if the cluster charge is higher than the current maximum + //Only consider clusters in the prompt window (time < 2000 ns) + if (it->second > max_pe && it->first < 2000){ + max_pe = it->second; + cluster_muon = tmp_cluster_id; //For now, associate the cluster with the highest charge with the muon + return_prompt = true; + } + tmp_cluster_id ++; + } + + prompt_muon_index = cluster_muon; + + return return_prompt; +} + +bool ClusterClassifiers::IdentifyDelayedNeutronClusters(std::map cluster_cb, std::map cluster_totalq){ + + bool return_delayed = false; + int tmp_cluster_id = 0; + std::vector cluster_neutron; + for (std::map::iterator it = cluster_totalq.begin(); it!= cluster_totalq.end(); it++){ + //Check if the cluster is in the delayed window and has a time > 10 us (exclude afterpulses) + //The window should should be extended in the future after relevant exlusion cuts for afterpulsing have been implemented + //check if the charge balance cut for neutrons is passed -> consider a neutron candidate + //Improve the neutron selection cuts in the future, probably cutting more signal than necessary at the moment + if (it->first > 10000){ + double current_cb = cluster_cb.at(it->first); + double current_q = cluster_totalq.at(it->first); + if (current_cb < 0.4 && current_q < 150 && (current_cb <= (1. - current_q/150.)*0.5)){ + cluster_neutron.push_back(tmp_cluster_id); + return_delayed = true; + } + } + tmp_cluster_id ++; + } + + delayed_neutron_index = cluster_neutron; + + return return_delayed; + +} + +double ClusterClassifiers::CalculateTotalPE(std::vector cluster_hits) +{ + double total_PE = 0; + for (int i = 0; i < (int) cluster_hits.size(); i++){ + Hit ahit = cluster_hits.at(i); + double hit_charge = ahit.GetCharge(); + int channel_key = ahit.GetTubeId(); + double hit_PE = 0; + std::map::iterator it = ChannelKeyToSPEMap.find(channel_key); + if(it != ChannelKeyToSPEMap.end()){ //Charge to SPE conversion is available + hit_PE = hit_charge / ChannelKeyToSPEMap.at(channel_key); + total_PE += hit_PE; + } + } + if(verbosity>4) std::cout << "ClusterClassifiers Tool: Calculated total PE of " << total_PE << std::endl; + return total_PE; +} + +double ClusterClassifiers::CalculateTotalPEMC(std::vector cluster_hits, std::vector cluster_detkeys) + { + double total_PE = 0; + for (int i = 0; i < (int) cluster_hits.size(); i++){ + MCHit ahit = cluster_hits.at(i); + double hit_charge = ahit.GetCharge(); + //int channel_key = ahit.GetTubeId(); + unsigned long detkey = cluster_detkeys.at(i); + int channel_key = (int) detkey; + int tubeid = ahit.GetTubeId(); + unsigned long utubeid = (unsigned long) tubeid; + int wcsimid = channelkey_to_pmtid.at(utubeid); + unsigned long detkey_data = pmtid_to_channelkey[wcsimid]; + int channel_key_data = (int) detkey_data; + std::map::iterator it = ChannelKeyToSPEMap.find(channel_key_data); + if(it != ChannelKeyToSPEMap.end()){ //Charge to SPE conversion is available + total_PE += hit_charge; + } + } + if(verbosity>4) std::cout << "ClusterClassifiers Tool: Calculated total PE of " << total_PE << std::endl; + return total_PE; + } + diff --git a/UserTools/ClusterClassifiers/ClusterClassifiers.h b/UserTools/ClusterClassifiers/ClusterClassifiers.h index fef2ecfa9..8f7aef9e6 100644 --- a/UserTools/ClusterClassifiers/ClusterClassifiers.h +++ b/UserTools/ClusterClassifiers/ClusterClassifiers.h @@ -27,12 +27,16 @@ class ClusterClassifiers: public Tool { 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. - Position CalculateChargePoint(std::vector cluster_hits); - double CalculateChargeBalance(std::vector cluster_hits); - double CalculateMaxPE(std::vector cluster_hits); - Position CalculateChargePointMC(std::vector cluster_hits, std::vector cluster_detkeys); - double CalculateChargeBalanceMC(std::vector cluster_hits, std::vector cluster_detkeys); - double CalculateMaxPEMC(std::vector cluster_hits, std::vector cluster_detkeys); + Position CalculateChargePoint(std::vector cluster_hits); ///< function to calculate the charge points for clusters (data) + double CalculateChargeBalance(std::vector cluster_hits); ///< function to calculate the charge balance values for clusters (data) + double CalculateMaxPE(std::vector cluster_hits); ///< function to identify the MaxPE value recorded by a single PMT in a cluster (data) + Position CalculateChargePointMC(std::vector cluster_hits, std::vector cluster_detkeys); ///< function to calculate the charge points for clusters (MC) + double CalculateChargeBalanceMC(std::vector cluster_hits, std::vector cluster_detkeys); ///< function to calculate the charge balance values for clusters (MC) + double CalculateMaxPEMC(std::vector cluster_hits, std::vector cluster_detkeys); ///< function to calculate the MaxPE value recorded by a single PMT in a cluster (MC) + double CalculateTotalPE(std::vector cluster_hits); ///< function to calculate the total PE recorded in a cluster (data) + double CalculateTotalPEMC(std::vector cluster_hits, std::vector cluster_detkeys); ///< function to calculate the total PE recorded in a cluster (MC) + bool IdentifyPromptMuonCluster(std::map cluster_totalq); ///< function to identify the prompt muon cluster + bool IdentifyDelayedNeutronClusters(std::map cluster_cb, std::map cluster_totalq); ///< function to identify delayed neutron clusters private: @@ -48,6 +52,9 @@ class ClusterClassifiers: public Tool { std::map pmtid_to_channelkey; std::map channelkey_to_pmtid; + int prompt_muon_index; //cluster index for prompt muon candidate + std::vector delayed_neutron_index; //cluster indices for delayed neutron candidates + /// \brief verbosity levels: if 'verbosity' < this level, the message type will be logged. int verbosity; int v_error=0; diff --git a/UserTools/ClusterFinder/ClusterFinder.cpp b/UserTools/ClusterFinder/ClusterFinder.cpp index 032799767..f88ca62c6 100644 --- a/UserTools/ClusterFinder/ClusterFinder.cpp +++ b/UserTools/ClusterFinder/ClusterFinder.cpp @@ -542,7 +542,7 @@ bool ClusterFinder::Execute(){ } else { - std::cout <<"ClusterFinder: RecoADCHits Store does not exist and is not read out"< 0) std::cout <<"ClusterFinder: RecoADCHits Store does not exist and is not read out"<Stores.at("RecoEvent")->Set("RecoPDGVector",cluster_reco_pdg); m_data->Stores.at("RecoEvent")->Set("PDG",fRecoPDG); + bool passExtendedCut = this->EventSelectionByTriggerExtended(); + m_data->Stores.at("RecoEvent")->Set("TriggerExtended",passExtendedCut); + + bool passBeamOKCut = this->EventSelectionByBeamOK(); + m_data->Stores.at("RecoEvent")->Set("BeamOK",passBeamOKCut); + // Fill the EventSelection mask for the cuts that are supposed to be applied if (fMCPiKCut){ fEventApplied |= EventSelector::kFlagMCPiK; @@ -329,6 +337,16 @@ bool EventSelector::Execute(){ if (!passTriggerCut) fEventFlagged |= EventSelector::kFlagTrigger; } + if (fTriggerExtended){ + fEventApplied |= EventSelector::kFlagExtended; + if (!passExtendedCut) fEventFlagged |= EventSelector::kFlagExtended; + } + + if (fBeamOK){ + fEventApplied |= EventSelector::kFlagBeamOK; + if (!passBeamOKCut) fEventFlagged |= EventSelector::kFlagBeamOK; + } + if (fRecoPDG != -1){ fEventApplied |= EventSelector::kFlagRecoPDG; if (!passRecoPDGCut) fEventFlagged |= EventSelector::kFlagRecoPDG; @@ -338,7 +356,10 @@ bool EventSelector::Execute(){ if(fEventCutStatus){ Log("EventSelector Tool: Event is clean according to current event selection.",v_message,verbosity); } - if(fSaveStatusToStore) m_data->Stores.at("RecoEvent")->Set("EventCutStatus", fEventCutStatus); + if(fSaveStatusToStore) { + m_data->Stores.at("RecoEvent")->Set("EventCutStatus", fEventCutStatus); + m_data->Stores.at("ANNIEEvent")->Set("EventCutStatus", fEventCutStatus); + } m_data->Stores.at("RecoEvent")->Set("EventFlagApplied", fEventApplied); m_data->Stores.at("RecoEvent")->Set("EventFlagged", fEventFlagged); @@ -349,6 +370,9 @@ bool EventSelector::Execute(){ if (verbosity > 1) std::cout <<"EventCutStatus: "<(fEventApplied) << ", fEventFlagged: " << std::bitset<32>(fEventFlagged) << std::endl; + //std::cout <<"EventCutStatus: "<GetMrdEnd()*100-168.1; double mrdHeightY = fGeometry->GetMrdHeight()*100; double mrdWidthX = fGeometry->GetMrdWidth()*100; - std::cout <<"mrdStartZ: "<mrdEndZ || muonStopX<-1.0*mrdWidthX || muonStopX>mrdWidthX || muonStopY<-1.0*mrdHeightY || muonStopY>mrdHeightY) { @@ -626,10 +649,10 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { m_data->Stores["RecoEvent"]->Set("NumPMTClusters",pmt_cluster_size); vec_pmtclusters_charge->clear(); vec_pmtclusters_time->clear(); - m_data->Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,false); - m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,false); + m_data->Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,true); + m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,true); vec_mrdclusters_time->clear(); - m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time); + m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time,true); if (verbosity > 1) std::cout <<"pmt_cluster_size: "<Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,false); - m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,false); + m_data->Stores["RecoEvent"]->Set("PMTClustersCharge",vec_pmtclusters_charge,true); + m_data->Stores["RecoEvent"]->Set("PMTClustersTime",vec_pmtclusters_time,true); std::vector mrd_meantimes; if (verbosity > 1) std::cout <<"MrdTimeClusters.size(): "<push_back(mrd_meantimes.at(i)); } - m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time); + m_data->Stores["RecoEvent"]->Set("MRDClustersTime",vec_mrdclusters_time, true); if (fIsMC){ if (MrdTimeClusters.size() == 0 || m_all_clusters_MC->size() == 0) return false; @@ -736,16 +759,23 @@ bool EventSelector::EventSelectionByPMTMRDCoinc() { pmtmrd_coinc_min = fPMTMRDOffset - 50; pmtmrd_coinc_max = fPMTMRDOffset + 50; + std::vector vector_mrd_coincidence; + bool coincidence = false; for (int i_mrd = 0; i_mrd < int(mrd_meantimes.size()); i_mrd++){ double time_diff = mrd_meantimes.at(i_mrd) - pmt_time; if (verbosity > 0) std::cout <<"MRD time: "< 1) std::cout <<"max_charge: "< pmtmrd_coinc_min && time_diff < pmtmrd_coinc_max && max_charge > 200 && n_hits >= 20){ coincidence = true; + vector_mrd_coincidence.push_back(i_mrd); } } + + m_data->Stores["RecoEvent"]->Set("MRDCoincidenceCluster",vector_mrd_coincidence); return coincidence; @@ -1054,4 +1084,20 @@ bool EventSelector::EventSelectionByRecoPDG(int recoPDG, std::vector & c return found_pdg; } +bool EventSelector::EventSelectionByTriggerExtended(){ + + int fExtended = 0; + m_data->Stores["ANNIEEvent"]->Get("TriggerExtended",fExtended); + if (fExtended == 1) return true; + else return false; + +} + +bool EventSelector::EventSelectionByBeamOK(){ + BeamStatus beamstat; + m_data->Stores["ANNIEEvent"]->Get("BeamStatus",beamstat); + if (beamstat.ok()) return true; + else return false; + +} diff --git a/UserTools/EventSelector/EventSelector.h b/UserTools/EventSelector/EventSelector.h index 3e65cd47f..82a18d3cf 100644 --- a/UserTools/EventSelector/EventSelector.h +++ b/UserTools/EventSelector/EventSelector.h @@ -19,6 +19,8 @@ #include "ANNIEGeometry.h" #include "TMath.h" +#include "BeamStatus.h" + class EventSelector: public Tool { @@ -51,7 +53,9 @@ class EventSelector: public Tool { kFlagVeto = 0x20000, //131072 kFlagTrigger = 0x40000, kFlagThroughGoing = 0x80000, - kFlagRecoPDG = 0x1000000, + kFlagRecoPDG = 0x100000, + kFlagExtended = 0x200000, + kFlagBeamOK = 0x400000, } EventFlags_t; private: @@ -176,6 +180,16 @@ class EventSelector: public Tool { // bool EventSelectionByRecoPDG(int recoPDG, std::vector & vector_reco_pdg); + /// \brief Event selection for extended acquisition windows + // + /// This event selection criterion flags events with an extended trigger window (70us) + bool EventSelectionByTriggerExtended(); + + /// \brief Event selection for beam status + /// + /// This event selection criterion flags events for which beam status was ok + bool EventSelectionByBeamOK(); + /// \brief MC entry number uint64_t fMCEventNum; @@ -237,6 +251,8 @@ class EventSelector: public Tool { bool fIsMC; int fTriggerWord; int fRecoPDG; + bool fTriggerExtended = false; + bool fBeamOK = false; std::string fCutConfigurationName; bool get_mrd = false; diff --git a/UserTools/Factory/Factory.cpp b/UserTools/Factory/Factory.cpp index a5b96e603..c932574cd 100644 --- a/UserTools/Factory/Factory.cpp +++ b/UserTools/Factory/Factory.cpp @@ -96,7 +96,7 @@ if (tool=="MCPropertiesToTree") ret=new MCPropertiesToTree; if (tool=="CalcClassificationVars") ret=new CalcClassificationVars; if (tool=="StoreClassificationVars") ret=new StoreClassificationVars; if (tool=="LoadGenieEvent") ret=new LoadGenieEvent; -//if (tool=="PrintGenieEvent") ret=new PrintGenieEvent; +if (tool=="PrintGenieEvent") ret=new PrintGenieEvent; if (tool=="PlotWaveforms") ret=new PlotWaveforms; if (tool=="PMTDataDecoder") ret=new PMTDataDecoder; if (tool=="ANNIEEventBuilder") ret=new ANNIEEventBuilder; @@ -144,6 +144,7 @@ if (tool=="LAPPDASCIIReadIn") ret=new LAPPDASCIIReadIn; if (tool=="BeamDecoder") ret=new BeamDecoder; if (tool=="LoadRunInfo") ret=new LoadRunInfo; if (tool=="ApplyMRDEff") ret=new ApplyMRDEff; +if (tool=="SimpleReconstruction") ret=new SimpleReconstruction; if (tool=="LAPPDnnlsPeak") ret=new LAPPDnnlsPeak; if (tool=="LAPPDLocateHit") ret=new LAPPDLocateHit; if (tool=="LAPPDOtherSimp") ret=new LAPPDOtherSimp; @@ -161,6 +162,8 @@ if (tool=="VtxSeedFineGrid") ret=new VtxSeedFineGrid; if (tool=="FilterEvents") ret=new FilterEvents; if (tool=="Stage1DataBuilder") ret=new Stage1DataBuilder; if (tool=="BeamFetcherV2") ret=new BeamFetcherV2; +if (tool=="FindNeutrons") ret=new FindNeutrons; +if (tool=="NeutronMultiplicity") ret=new NeutronMultiplicity; if (tool=="PlotsTrackLengthAndEnergy") ret=new PlotsTrackLengthAndEnergy; if (tool=="SaveConfigInfo") ret=new SaveConfigInfo; if (tool=="ReadConfigInfo") ret=new ReadConfigInfo; diff --git a/UserTools/FindNeutrons/FindNeutrons.cpp b/UserTools/FindNeutrons/FindNeutrons.cpp new file mode 100644 index 000000000..1a3c3026d --- /dev/null +++ b/UserTools/FindNeutrons/FindNeutrons.cpp @@ -0,0 +1,320 @@ +#include "FindNeutrons.h" + +FindNeutrons::FindNeutrons():Tool(){} + + +bool FindNeutrons::Initialise(std::string configfile, DataModel &data){ + + if(configfile!="") m_variables.Initialise(configfile); // loading config file + m_data= &data; //assigning transient data pointer + + //Set defaults + Method = "CBStrict"; //Options: CB, CBStrict, NHits10 + verbosity = 2; + EfficiencyMapPath = "./configfiles/NeutronMultiplicity/NeutronEffMap_Data.txt"; + + //Get configuration variables + bool get_ok = m_variables.Get("verbosity",verbosity); + get_ok = m_variables.Get("Method",Method); + if (!get_ok){ + Log("FindNeutrons tool: Get variable >>> Method <<< failed. Check configuration file.",v_error,verbosity); + Log("FindNeutrons tool: Stopping toolchain",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + if (Method == "CB" || Method == "CBStrict" || Method == "NHits10"){ + Log("FindNeutrons tool: Loaded neutron finding method >>> "+ Method + "<<< successfully",v_message,verbosity); + } else { + Log("FindNeutrons tool: Unknown neutron finding method >>> "+ Method + "<<< specified. Please check available options and restart toolchain.",v_error,verbosity); + Log("FindNeutrons tool: Available options: CB",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } + } + + //Load neutron efficiency map + bool load_eff = this->LoadNeutronEfficiencyMap(); + if (!load_eff){ + Log("FindNeutrons tool: Did not find efficiency map for selected cut. Abort toolchain.",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + //Store neutron efficiency map in RecoEvent store + m_data->Stores["RecoEvent"]->Set("NeutronEffMap",eff_map); + } + + return true; +} + + +bool FindNeutrons::Execute(){ + + //Find neutron candidates for current event + this->FindNeutronCandidates(Method); + + //Construct Particle objects for neutrons + this->FillRecoParticles(); + + //Append the reco particles to the main Particle object + std::vector Particles_Temp; + bool get_ok = m_data->Stores["ANNIEEvent"]->Get("Particles",Particles_Temp); + if (get_ok){ + Log("FindNeutrons tool: Particles object already exists in ANNIEEvent store. Append neutrons...",v_message,verbosity); + for (int i_neutron=0; i_neutron < vec_neutrons.size(); i_neutron++){ + Particles_Temp.push_back(vec_neutrons.at(i_neutron)); + } + } else { + Log("FindNeutrons tool: Particles object did not exist in ANNIEEvent store yet. Set Particles object equal to vector of neutrons",vv_debug,verbosity); + Particles_Temp = vec_neutrons; + } + m_data->Stores["ANNIEEvent"]->Set("Particles",Particles_Temp); + + //Store neutron candidate information + m_data->Stores["RecoEvent"]->Set("ClusterIndicesNeutron",cluster_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterTimesNeutron",cluster_times_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterChargesNeutron",cluster_charges_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterCBNeutron",cluster_cb_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterNHitsNeutron",cluster_nhits_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterTimes",cluster_times); + m_data->Stores["RecoEvent"]->Set("ClusterCharges",cluster_charges); + m_data->Stores["RecoEvent"]->Set("ClusterCB",cluster_cb); + m_data->Stores["RecoEvent"]->Set("ClusterNHits",cluster_nhits); + + + return true; +} + + +bool FindNeutrons::Finalise(){ + + return true; +} + + +bool FindNeutrons::FindNeutronCandidates(std::string method){ + + //Currently only Charge Balance cut & Nhits cut available + //TODO: add Machine Learning classifiers in the future + + //Clear vectors first + if (cluster_neutron.size()>0) cluster_neutron.clear(); + if (cluster_times_neutron.size()>0) cluster_times_neutron.clear(); + if (cluster_charges_neutron.size()>0) cluster_charges_neutron.clear(); + if (cluster_cb_neutron.size()>0) cluster_cb_neutron.clear(); + if (cluster_nhits_neutron.size()>0) cluster_nhits_neutron.clear(); + if (cluster_times.size()>0) cluster_times.clear(); + if (cluster_charges.size()>0) cluster_charges.clear(); + if (cluster_cb.size()>0) cluster_cb.clear(); + if (cluster_nhits.size()>0) cluster_nhits.clear(); + + if (method == "CB"){ + this->FindNeutronsByCB(false); + } + else if (method == "CBStrict"){ + this->FindNeutronsByCB(true); + } + else if (method == "NHits10"){ + this->FindNeutronsByNHits(10); + } + else if (method == "ML"){ + Log("FindNeutrons: ML method not implemented yet in ToolAnalysis",v_message,verbosity); + return false; + } + else { + Log("FindNeutrons: Method "+method+" is unknown! Please choose one of the known options (CB / CBStrict / ...)",v_warning,verbosity); + return false; + } + + return true; + +} + +bool FindNeutrons::FindNeutronsByCB(bool strict){ + + bool return_val=false; + + //Get cluster objects (filled in ClusterClassifiers tool) + std::map ClusterChargeBalances; + std::map ClusterTotalPEs; + std::map ClusterNHits; + bool get_ok; + get_ok = m_data->Stores.at("ANNIEEvent")->Get("ClusterChargeBalances", ClusterChargeBalances); + if (!get_ok){ + Log("FindNeutrons tool: Did not find ClusterChargeBalances object! Please add ClusterClassifiers tool to your toolchain!",v_error,verbosity); + m_variables.Set("StopLoop",1); + } + get_ok = m_data->Stores.at("ANNIEEvent")->Get("ClusterTotalPEs", ClusterTotalPEs); + if (!get_ok){ + Log("FindNeutrons tool: Did not find ClusterTotalPEs object! Please add ClusterClassifiers tool to your toolchain!",v_error,verbosity); + m_variables.Set("StopLoop",1); + } + get_ok = m_data->Stores.at("ANNIEEvent")->Get("ClusterNHits", ClusterNHits); + if (!get_ok){ + Log("FindNeutrons tool: Did not find ClusterNHits object! Please add ClusterClassifiers tool to your toolchain!",v_error,verbosity); + m_variables.Set("StopLoop",1); + } + + //Loop through clusters and find neutrons + int tmp_cluster_id = 0; + + for (std::map::iterator it = ClusterTotalPEs.begin(); it!= ClusterTotalPEs.end(); it++){ + //First fill general cluster information into vectors + cluster_times.push_back(it->first); + cluster_charges.push_back(ClusterTotalPEs.at(it->first)); + cluster_cb.push_back(ClusterChargeBalances.at(it->first)); + cluster_nhits.push_back(ClusterNHits.at(it->first)); + + //Check if the cluster is in the delayed window and has a time > 10 us (exclude afterpulses) + //The window should should be extended in the future after relevant exlusion cuts for afterpulsing have been implemented + //check if the charge balance cut for neutrons is passed -> consider a neutron candidate + //Improve the neutron selection cuts in the future, probably cutting more signal than necessary at the moment + if (it->first > 10000){ + double current_cb = ClusterChargeBalances.at(it->first); + double current_q = ClusterTotalPEs.at(it->first); + int current_nhits = ClusterNHits.at(it->first); + bool pass_cut = false; + if (current_cb < 0.4 && current_q < 150){ + if (!strict) pass_cut = true; + else if (current_cb <= (1. - current_q/150.)*0.5) pass_cut = true; + } + if (pass_cut){ + Log("FindNeutrons tool: Found neutron candidate at cluster # "+std::to_string(tmp_cluster_id)+", time: "+std::to_string(it->first)+" ns!!!",v_message,verbosity); + cluster_neutron.push_back(tmp_cluster_id); + cluster_times_neutron.push_back(it->first); + cluster_charges_neutron.push_back(current_q); + cluster_cb_neutron.push_back(current_cb); + cluster_nhits_neutron.push_back(current_nhits); + return_val = true; + } + } + tmp_cluster_id ++; + } + + return return_val; + +} + +bool FindNeutrons::FindNeutronsByNHits(int nhits_thr){ + + bool return_val=false; + + //Get cluster objects (filled in ClusterClassifiers tool) + std::map ClusterTotalPEs; + std::map ClusterNHits; + std::map ClusterChargeBalances; + + bool get_ok; + get_ok = m_data->Stores.at("ANNIEEvent")->Get("ClusterTotalPEs", ClusterTotalPEs); + if (!get_ok){ + Log("FindNeutrons tool: Did not find ClusterTotalPEs object! Please add ClusterClassifiers tool to your toolchain!",v_error,verbosity); + m_variables.Set("StopLoop",1); + } + get_ok = m_data->Stores.at("ANNIEEvent")->Get("ClusterChargeBalances", ClusterChargeBalances); + if (!get_ok){ + Log("FindNeutrons tool: Did not find ClusterChargeBalances object! Please add ClusterClassifiers tool to your toolchain!",v_error,verbosity); + m_variables.Set("StopLoop",1); + } + get_ok = m_data->Stores.at("ANNIEEvent")->Get("ClusterNHits", ClusterNHits); + if (!get_ok){ + Log("FindNeutrons tool: Did not find ClusterNHits object! Please add ClusterClassifiers tool to your toolchain!",v_error,verbosity); + m_variables.Set("StopLoop",1); + } + + //Loop through clusters and find neutrons + int tmp_cluster_id = 0; + + for (std::map::iterator it = ClusterTotalPEs.begin(); it!= ClusterTotalPEs.end(); it++){ + //First fill general cluster information into vectors + cluster_times.push_back(it->first); + cluster_charges.push_back(ClusterTotalPEs.at(it->first)); + cluster_cb.push_back(ClusterChargeBalances.at(it->first)); + cluster_nhits.push_back(ClusterNHits.at(it->first)); + + //Check if the cluster is in the delayed window and has a time > 10 us (exclude afterpulses) + //The window should should be extended in the future after relevant exlusion cuts for afterpulsing have been implemented + //check if the nhits cut for neutrons is passed -> consider a neutron candidate + //Improve the neutron selection cuts in the future, probably cutting more signal than necessary at the moment + if (it->first > 10000){ + double current_cb = ClusterChargeBalances.at(it->first); + double current_q = ClusterTotalPEs.at(it->first); + int current_nhits = ClusterNHits.at(it->first); + if (current_nhits >= nhits_thr && current_q < 150){ + Log("FindNeutrons tool: Found neutron candidate at cluster # "+std::to_string(tmp_cluster_id)+", time: "+std::to_string(it->first)+" ns!!!",v_message,verbosity); + cluster_neutron.push_back(tmp_cluster_id); + cluster_times_neutron.push_back(it->first); + cluster_charges_neutron.push_back(current_q); + cluster_cb_neutron.push_back(current_cb); + cluster_nhits_neutron.push_back(current_nhits); + return_val = true; + } + } + tmp_cluster_id ++; + } + + + return return_val; + +} + +bool FindNeutrons::FillRecoParticles(){ + + bool return_val=false; + + vec_neutrons.clear(); + + int neutron_pdg = 2112; + tracktype neutron_tracktype = tracktype::UNDEFINED; + double neutron_E_start = -9999; + double neutron_E_stop = -9999; + Position neutron_vtx_start(-999,-999,-999); + Position neutron_vtx_stop(-999,-999,-999); + Direction neutron_start_dir(0,0,1); + double neutron_start_time; + double neutron_stop_time; + double neutron_tracklength = -9999; + + for (int i_neutron=0; i_neutron < cluster_times_neutron.size(); i_neutron++){ + double stop_time = cluster_times_neutron.at(i_neutron); + neutron_stop_time = stop_time; + neutron_start_time = 0; + + Particle neutron(neutron_pdg,neutron_E_start,neutron_E_stop,neutron_vtx_start,neutron_vtx_stop,neutron_start_time,neutron_stop_time,neutron_start_dir,neutron_tracklength,neutron_tracktype); + vec_neutrons.push_back(neutron); + + if (verbosity > 2){ + Log("FindNeutrons: Added neutron with the following properties as a particle:",v_message,verbosity); + neutron.Print(); + } + + return_val = true; + } + + return return_val; + +} + +bool FindNeutrons::LoadNeutronEfficiencyMap(){ + + ifstream eff_file(EfficiencyMapPath.c_str()); + if (!eff_file.good()) return false; + + //Order of file should be + // PORT | Heigth | X | Y | Z | EFF + + int temp_port, y; + double temp_eff_cut; //cut efficiency + double temp_eff_time; //timing cut efficiency + double temp_x, temp_y, temp_z; + while (!eff_file.eof()){ + eff_file >> temp_port >> y >> temp_x >> temp_y >> temp_z >> temp_eff_cut >> temp_eff_time; + //Conversion Port/Height to X/Y/Z (if needed) + /*temp_y = y - 14.4; + if (temp_port == 1) {temp_x = 0., temp_z = 93.1;} + else if (temp_port == 2) {temp_x = 0., temp_z = 243.1;} + else if (temp_port == 3) {temp_x = 0., temp_z = 270.1;} + else if (temp_port == 4) {temp_x = 75., temp_z = 168.1;} + else if (temp_port == 5) {temp_x = 0., temp_z = 168.1;}*/ + std::vector position{temp_x/100.,temp_y/100.,temp_z/100.}; + eff_map.emplace(position,temp_eff_cut*temp_eff_time); + } + + return true; + +} diff --git a/UserTools/FindNeutrons/FindNeutrons.h b/UserTools/FindNeutrons/FindNeutrons.h new file mode 100644 index 000000000..28885e18c --- /dev/null +++ b/UserTools/FindNeutrons/FindNeutrons.h @@ -0,0 +1,69 @@ +#ifndef FindNeutrons_H +#define FindNeutrons_H + +#include +#include + +#include "Tool.h" +#include "Particle.h" + +/** + * \class FindNeutrons + * + * 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: M. Nieslony $ +* $Date: 2023/01/23 10:44:00 $ +* Contact: mnieslon@uni-mainz.de +*/ +class FindNeutrons: public Tool { + + + public: + + FindNeutrons(); ///< 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 FindNeutronCandidates(std::string method); ///< Neutron identification + bool FindNeutronsByCB(bool strict); ///< Neutron identification by Charge Balance cut + bool FindNeutronsByNHits(int nhits_thr); /// < Neutron identification by NHits + bool FillRecoParticles(); ///< Fill reco particle object with neutron information + bool LoadNeutronEfficiencyMap(); ///< Load neutron efficiency map (from calibration/simulation) + + private: + + //configuration variables + int verbosity; + std::string Method; + std::string EfficiencyMapPath; + + //vectors storing neutron candidate properties + std::vector cluster_neutron; + std::vector cluster_times_neutron; + std::vector cluster_charges_neutron; + std::vector cluster_cb_neutron; + std::vector cluster_nhits_neutron; + std::vector cluster_times; + std::vector cluster_charges; + std::vector cluster_cb; + std::vector cluster_nhits; + + //vector storing neutron particles + std::vector vec_neutrons; + + //map storing the efficiency map for a given cut (from calibration / simulation) + std::map,double> eff_map; + + //verbosity variables + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + int vv_debug=4; + +}; + + +#endif diff --git a/UserTools/FindNeutrons/README.md b/UserTools/FindNeutrons/README.md new file mode 100644 index 000000000..3ae793424 --- /dev/null +++ b/UserTools/FindNeutrons/README.md @@ -0,0 +1,47 @@ +# FindNeutrons + +The `FindNeutrons` tools looks for neutrons in the ANNIE data and saves them as `Particle` object in the "Particles" vector in the ANNIEEvent BoostStore. + +## Input data + +The tool expects the `ClusterChargeBalances` and `ClusterTotalPEs` objects to be present in the ANNIEEvent BoostStore. In order for them to be present, it is essential to add the `ClusterClassifiers` tool to the toolchain. + +## Output data + +The `FindNeutrons` tool defines `Particle` objects for the clusters that passed the specified neutron selection cuts. Since at this point many of the neutron properties (e.g. the vertex) are undefined and not defined by a fit, they are set to default values. Only the PDG value and the stop time are set correctly based on the observed properties: +* PDG value: 2112 +* Stop Time: time at which the candidate cluster occured. + +For each identified neutron candidate, a `Particle` object is defined and appended to the ANNIEEvent variable "Particles", which is a vector of all identified `Particle` objects. + +In addition to the Particles vector, additional information about the clusters are also saved to the ANNIEEvent: +* Particles (`std::vector`) +* ClusterIndicesNeutron (`std::vector`): Indices of clusters which were identified as neutron candidates +* ClusterTimesNeutron (`std::vector`): Times of neutron candidate clusters +* ClusterChargesNeutron (`std::vector`): Charges (in p.e.) of neutron candidate clusters +* ClusterCBNeutron (`std::vector`): Charge Balancce values of neutron candidate clusters +* ClusterTimes (`std::vector`): Times of all clusters +* ClusterCharges (`std::vector`): Charges of all clusters +* ClusterCB (`std::vector`): Charge Balance values of all clusters + +## Configuration options + +Currently, the user can choose between three cut-based selection techniques for neutrons, "CB", "CBStrict", or "NHits10". The former uses a charge balance cut of CB < 0.4 and a maximum total charge of 150 p.e., whereas the strict cut also applies a combined cut in the CB - total charge plane. The "NHits10" method classifies all clusters with at least 10 hits as neutrons. + +In addition to the selection cut, the user also has to provide the neutron efficiency map for the selected cut, in the form of a txt file. The txt file should be tab separated and should consist of 7 columns, indicating the port, height within the port, x-positiion, y-position, z-position, efficiency of the cut, and efficiency of the selected time window. The path to the efficiency map file needs to be provided with the `EfficiencyMapPath` keyword. + +An exemplary efficiency map file with two data points (and very good efficiency) would look like this: + +``` +1 100 0 85.6 93.1 0.99 0.99 +1 50 0 35.6 93.1 0.99 0.99 +``` + +The options can be chosen in the configuration file via + +``` +Method CB/CBStrict/NHits10 +EfficiencyMapPath /path/to/file +``` + +Additional selection techniques can simply be added by adding a new keyword to the available Methods and implementing them in the code. diff --git a/UserTools/LoadGenieEvent/LoadGenieEvent.cpp b/UserTools/LoadGenieEvent/LoadGenieEvent.cpp index 0bc5fe1fc..7995901fc 100644 --- a/UserTools/LoadGenieEvent/LoadGenieEvent.cpp +++ b/UserTools/LoadGenieEvent/LoadGenieEvent.cpp @@ -72,11 +72,14 @@ bool LoadGenieEvent::Initialise(std::string configfile, DataModel &data){ ///////////////////////////////////////////////////////////////// + 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); // create a store for holding Genie information to pass to downstream Tools @@ -98,6 +101,8 @@ bool LoadGenieEvent::Initialise(std::string configfile, DataModel &data){ Log("Tool LoadGenieEvent: Read "+to_string(numbytes)+" bytes loading TChain "+inputfiles,v_debug,verbosity); Log("Tool LoadGenieEvent: Genie TChain has "+to_string(flux->GetEntries())+" entries",v_message,verbosity); SetBranchAddresses(); + tchainentrynum = evoffset; + Log("LoadGenieEvent tool: # of flux entries: "+std::to_string(flux->GetEntries()),v_message,verbosity); } if(manualmatch){ @@ -163,7 +168,7 @@ bool LoadGenieEvent::Execute(){ } } - Log("Tool LoadGenieEvent: Loading tchain entry "+to_string(tchainentrynum),v_debug,verbosity); + Log("Tool LoadGenieEvent: Loading tchain entry "+to_string(tchainentrynum),v_message,verbosity); local_entry = flux->LoadTree(tchainentrynum); Log("Tool LoadGenieEvent: localentry is "+to_string(local_entry),v_debug,verbosity); if(local_entry<0||local_entry!=tchainentrynum){ @@ -785,7 +790,7 @@ std::string LoadGenieEvent::MediumToString(int code){ if(mediummap.count(code)!=0){ return mediummap.at(code); } else { - cerr<<"unknown medium "<CStore.Get("CurrentTriggernum",currentTriggernum); MCEventNum = user_evnum; currentTriggernum++; - std::cout <<"check_further_triggers = "< 3){ + std::cout <<"check_further_triggers = "< neutcap_is_primary; //map to store whether a neutron capture was from primary neutron or secondary, key = ncapture time, value = was the capture primary? + triggers_event = WCSimEntry->wcsimrootevent->GetNumberOfEvents(); int MaxEventNr = MCTriggernum+1; @@ -412,7 +416,7 @@ bool LoadWCSim::Execute(){ std::string geniefilename = firsttrigt->GetHeader()->GetGenieFileName().Data(); int genieentry = firsttrigt->GetHeader()->GetGenieEntryNum(); - /*if(verbosity>3)*/ cout<<"Genie file is "<1) cout<<"Genie file is "<CStore.Set("GenieFile",geniefilename); m_data->CStore.Set("GenieEntry",std::to_string(genieentry)); @@ -492,6 +496,11 @@ bool LoadWCSim::Execute(){ starttime = (static_cast(nextrack->GetTime())); stoptime = (static_cast(nextrack->GetStopTime())); } + if (verbosity > 2) std::cout <<"LoadWCSim tool, loaded particle with PDG: "<GetIpnu()<<", Time: "<GetParenttype() << ", EndProcess: "<GetEndProcess()<GetIpnu() == 2112 && nextrack->GetEndProcess() == "nCapture"){ + if (verbosity > 2) std::cout <<"LoadWCSim tool: Neutron capture! Parent: "<GetParenttype()<<", Time: "<GetParenttype()==0)); //store whether neutron was primary + } MCParticle thisparticle( nextrack->GetIpnu(), nextrack->GetE(), nextrack->GetEndE(), Position(nextrack->GetStart(0) / 100., @@ -778,21 +787,31 @@ bool LoadWCSim::Execute(){ capt_t -= EventTimeNs; } int capt_nucleus = capt->GetCaptureNucleus(); + double double_primary = -9999; + if (neutcap_is_primary.count(capt_t) > 0){ + bool is_primary = neutcap_is_primary.at(capt_t); + if (verbosity > 2) std::cout <<"LoadWCSim tool: NeutCap object at "< check WCSim options + Log("LoadWCSim tool: Capture parent: "+std::to_string(capt_parent)+", capt_nucleus: "+std::to_string(capt_nucleus)+ ", time " + std::to_string(capt_t) + " was not found in neutcap_is_primary map. Was the EndProcess saved in the WCSim output file?",v_warning,verbosity); + } std::vector gamma_energies; for (int i_gamma=0; i_gamma < capt_ngamma; i_gamma++){ WCSimRootCaptureGamma* captgamma = (WCSimRootCaptureGamma*) capt->GetGammas()->At(i_gamma); gamma_energies.push_back(captgamma->GetE()); } if (MCNeutCap.size()==0){ - MCNeutCap.emplace("CaptParent",std::vector{capt_parent}); + MCNeutCap.emplace("CaptParent",std::vector{double(capt_parent)}); MCNeutCap.emplace("CaptVtxX",std::vector{capt_vtxx}); MCNeutCap.emplace("CaptVtxY",std::vector{capt_vtxy}); MCNeutCap.emplace("CaptVtxZ",std::vector{capt_vtxz}); - MCNeutCap.emplace("CaptNGamma",std::vector{capt_ngamma}); + MCNeutCap.emplace("CaptNGamma",std::vector{double(capt_ngamma)}); MCNeutCap.emplace("CaptTotalE",std::vector{capt_totalE}); MCNeutCap.emplace("CaptTime",std::vector{capt_t}); - MCNeutCap.emplace("CaptNucleus",std::vector{capt_nucleus}); + MCNeutCap.emplace("CaptNucleus",std::vector{double(capt_nucleus)}); MCNeutCapGammas.emplace("CaptGammas",std::vector>{gamma_energies}); + MCNeutCap.emplace("CaptPrimary",std::vector{double_primary}); } else { MCNeutCap.at("CaptParent").push_back(capt_parent); MCNeutCap.at("CaptVtxX").push_back(capt_vtxx); @@ -803,6 +822,7 @@ bool LoadWCSim::Execute(){ MCNeutCap.at("CaptTime").push_back(capt_t); MCNeutCap.at("CaptNucleus").push_back(capt_nucleus); MCNeutCapGammas.at("CaptGammas").push_back(gamma_energies); + MCNeutCap.at("CaptPrimary").push_back(double_primary); } } @@ -844,6 +864,9 @@ bool LoadWCSim::Execute(){ m_data->Stores.at("ANNIEEvent")->Set("EventNumber",EventNumber); if(verbosity>2) cout<<"particles"<Stores.at("ANNIEEvent")->Set("MCParticles",MCParticles,true); + //Set up Particles object for reconstructed particles + std::vector Particles_Reco; + m_data->Stores["ANNIEEvent"]->Set("Particles",Particles_Reco); if(verbosity>2) cout<<"hits"<Stores.at("ANNIEEvent")->Set("MCHits",MCHits,true); if(verbosity>2) cout<<"tdcdata"<vars.Set("StopLoop",1); } else { int nbytesread = WCSimEntry->GetEntry(MCEventNum); // <0 if out of file - std::cout <<"Trying to get next event, MCEventNum: "< 2) std::cout <<"LoadWCSim tool: Trying to get next event, MCEventNum: "<vars.Set("StopLoop",1); diff --git a/UserTools/MCRecoEventLoader/MCRecoEventLoader.cpp b/UserTools/MCRecoEventLoader/MCRecoEventLoader.cpp index 48009f06f..76bc799c6 100644 --- a/UserTools/MCRecoEventLoader/MCRecoEventLoader.cpp +++ b/UserTools/MCRecoEventLoader/MCRecoEventLoader.cpp @@ -80,6 +80,7 @@ bool MCRecoEventLoader::Execute(){ ///Get MC Particle information this->FindTrueVertexFromMC(); + this->FindParticlePdgs(); if (fGetPiKInfo) this->FindPionKaonCountFromMC(); this->PushIBDInfo(); @@ -133,7 +134,7 @@ void MCRecoEventLoader::FindTrueVertexFromMC() { break; // won't have more than one primary muon } else { //Accept both electrons and muons as primary particles, if no selection is specified - if( aparticle.GetPdgCode()!=11 && aparticle.GetPdgCode()!=13) continue; + if( fabs(aparticle.GetPdgCode())!=11 && fabs(aparticle.GetPdgCode())!=13) continue; primarymuon = aparticle; mufound=true; m_data->Stores.at("RecoEvent")->Set("PdgPrimary",aparticle.GetPdgCode()); @@ -191,6 +192,21 @@ void MCRecoEventLoader::FindTrueVertexFromMC() { } +void MCRecoEventLoader::FindParticlePdgs(){ + + std::vector primary_pdgs; + if(fMCParticles){ + for(unsigned int particlei=0; particleisize(); particlei++){ + MCParticle aparticle = fMCParticles->at(particlei); + if(aparticle.GetParentPdg()!=0) continue; // not a primary particle + int pdg_code = aparticle.GetPdgCode(); + primary_pdgs.push_back(pdg_code); + } + } + + m_data->Stores.at("RecoEvent")->Set("PrimaryPdgs",primary_pdgs); + +} void MCRecoEventLoader::FindPionKaonCountFromMC() { @@ -271,7 +287,7 @@ void MCRecoEventLoader::FindPionKaonCountFromMC() { Log("MCRecoEventLoader:: Tool: No kaons in this event",v_warning,verbosity); } if (fGetNRings){ - Log("MCRecoEventLoader: Found "+std::to_string(nrings)+" rings in this event, from "+std::to_string(nprimary)+" primary particles and "+std::to_string(nsecondary)+" secondary particles."); + Log("MCRecoEventLoader: Found "+std::to_string(nrings)+" rings in this event, from "+std::to_string(nprimary)+" primary particles and "+std::to_string(nsecondary)+" secondary particles.",2,verbosity); } //Fill in pion counts for this event m_data->Stores.at("RecoEvent")->Set("MCPi0Count", pi0count); diff --git a/UserTools/MCRecoEventLoader/MCRecoEventLoader.h b/UserTools/MCRecoEventLoader/MCRecoEventLoader.h index 729ad86d0..546d82eda 100644 --- a/UserTools/MCRecoEventLoader/MCRecoEventLoader.h +++ b/UserTools/MCRecoEventLoader/MCRecoEventLoader.h @@ -49,7 +49,13 @@ class MCRecoEventLoader: public Tool { /// This particle is the primary muon. The muon start position, time and /// the muon direction are used to initise the true neutrino vertex void FindTrueVertexFromMC(); - + + /// \brief Find all primary particle pdgs + /// + /// Loop over all MC particles with parent ID = 0 (primaries) and + /// store their pdg numbers in a vector + void FindParticlePdgs(); + /// \brief Find PionKaon Count /// /// Loop over all MC particles and find any particles with PDG codes diff --git a/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp b/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp new file mode 100644 index 000000000..1b51d95b7 --- /dev/null +++ b/UserTools/NeutronMultiplicity/NeutronMultiplicity.cpp @@ -0,0 +1,1414 @@ +#include "NeutronMultiplicity.h" + +NeutronMultiplicity::NeutronMultiplicity():Tool(){} + + +bool NeutronMultiplicity::Initialise(std::string configfile, DataModel &data){ + + if(configfile!="") m_variables.Initialise(configfile); // loading config file + m_data= &data; //assigning transient data pointer + + bool get_ok = false; + + save_bs = true; + save_root = true; + filename = "NeutronMultiplicity"; + read_bs = "None"; + + get_ok = m_variables.Get("verbosity",verbosity); + get_ok = m_variables.Get("SaveROOT",save_root); + get_ok = m_variables.Get("SaveBoostStore",save_bs); + get_ok = m_variables.Get("Filename",filename); + get_ok = m_variables.Get("ReadFromBoostStore",read_bs); + get_ok = m_variables.Get("MRDTrackRestriction",mrdtrack_restriction); + + //Check if we are dealing with a MC file or not + //isMC = m_data->Stores.at("ANNIEEvent")->Get("MCFile",MCFile); + + if (verbosity > 1){ + std::cout <<"Initialise NeutronMultiplicity tool"<InitialiseHistograms(); + } + if (save_bs){ + //Initialise Boost Store + store_neutronmult = new BoostStore(false,2); + } + if (read_bs != "None"){ + //Read ANNIEEvent from BoostStore file + ifstream input_bs(read_bs.c_str()); + if (!input_bs.good()){ + Log("NeutronMultiplicity tool: Tried to read in filelist for BoostStores "+read_bs+", but file does not exist! Stop execution",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + std::string temp_str; + while (input_bs >> temp_str ) input_filenames_.push_back( temp_str ); + if (input_filenames_.size() ==0){ + Log("NeutronMultiplicity tool: Error! No input file names!", v_error, verbosity); + m_data->vars.Set("StopLoop",1); + } + } + //Check if ANNIEEvent is already loaded -> would interfere with loaded BoostStore file + if (m_data->Stores.count("ANNIEEvent")>0) { + Log("NeutronMultiplicity tool: m_data->Stores[\"ANNIEEvent\"] seems to be already loaded! Please remove LoadANNIEEvent/LoadWCSim/... tools from toolchain when using the option ReadFromBoostStore! Stop execution",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + m_data->Stores["ANNIEEvent"] = new BoostStore(false,2); + } + + //Check if RecoEvent is already loaded -> would interfere with loaded BoostStore file + if (m_data->Stores.count("RecoEvent")>0) { + Log("NeutronMultiplicity tool: m_data->Stores[\"RecoEvent\"] seems to be already loaded! Please remove LoadANNIEEvent/LoadWCSim/... tools from toolchain when using the option ReadFromBoostStore! Stop execution",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + m_data->Stores["RecoEvent"] = new BoostStore(false,2); + } + + //Check if MRDTracks store is already loaded -> would interfere with loaded BoostStore file + if (m_data->Stores.count("MRDTracks")>0) { + Log("NeutronMultiplicity tool: m_data->Stores[\"MRDTracks\"] seems to be already loaded! Please remove LoadANNIEEvent/LoadWCSim/... tools from toolchain when using the option ReadFromBoostStore! Stop execution",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + m_data->Stores["MRDTracks"] = new BoostStore(false,2); + } + + //Check if GenieInfo store is already loaded -> would interfere with loaded BoostStore file + if (m_data->Stores.count("GenieInfo")>0) { + Log("NeutronMultiplicity tool: m_data->Stores[\"GenieInfo\"] seems to be already loaded! Please remove LoadANNIEEvent/LoadWCSim/LoadGenieEvent... tools from toolchain when using the option ReadFromBoostStore! Stop execution",v_error,verbosity); + m_data->vars.Set("StopLoop",1); + } else { + m_data->Stores["GenieInfo"] = new BoostStore(false,2); + } + + } + + need_new_file_ = true; + current_entry_ = 0u; + current_file_ = 0u; + + return true; +} + + +bool NeutronMultiplicity::Execute(){ + + isMC = m_data->Stores.at("ANNIEEvent")->Get("MCFile",MCFile); + + //Reset tree variables + this->ResetVariables(); + + //Set ANNIEEvent if reading from BoostStore file + if (read_bs!= "None"){ + if (need_new_file_){ + need_new_file_ = false; + //if (read_neutronmult) delete read_neutronmult; + if (current_file_ != 0) { + read_neutronmult->Close(); + read_neutronmult->Delete(); + delete read_neutronmult; + } + read_neutronmult = new BoostStore(false,2); + read_neutronmult->Initialise(input_filenames_.at(current_file_)); + read_neutronmult->Print(false); + read_neutronmult->Header->Get("TotalEntries",total_entries_in_file_); + isMC = read_neutronmult->Get("MCFile",MCFile); + } + if (current_entry_ != 0) { + //Delete calls for stores is necessary for pointers to work correctly + read_neutronmult->Delete(); + } + + Log("NeutronMultiplicity tool: ReadFromBoostStore mode: Get entry "+std::to_string(current_entry_) + " / " + std::to_string(total_entries_in_file_),v_message,verbosity); + read_neutronmult->GetEntry(current_entry_); + ++current_entry_; + + if (current_entry_ >= total_entries_in_file_){ + ++current_file_; + if (current_file_ >= input_filenames_.size() ){ + m_data->vars.Set("StopLoop",1); + } else { + current_entry_ = 0u; + need_new_file_ = true; + } + } + + //Read current BoostStore entry + this->ReadBoostStore(); + } + + //Get Particles variable + bool get_ok = m_data->Stores["ANNIEEvent"]->Get("Particles",Particles); + + m_data->Stores["ANNIEEvent"]->Get("EventNumber",EventNumber); + m_data->Stores["ANNIEEvent"]->Get("RunNumber",RunNumber); + + NumberNeutrons = 0; + if (get_ok){ + for (int i_particle=0; i_particle < (int) Particles.size(); i_particle++){ + Log("NeutronMultiplicity tool: Retrieved particle # "+std::to_string(i_particle)+"...",2,verbosity); + if (verbosity > 2) Particles.at(i_particle).Print(); + if (Particles.at(i_particle).GetPdgCode() == 2112) NumberNeutrons++; + } + } + + //Get selection cut variables + bool pass_selection = false; + m_data->Stores["RecoEvent"]->Get("EventCutStatus",pass_selection); + + //Fill h_neutrons independent of reconstruction status if selection cuts are passed + if (pass_selection) h_neutrons->Fill(NumberNeutrons); + + bool pass_reconstruction = false; + m_data->Stores["RecoEvent"]->Get("SimpleRecoFlag",SimpleRecoFlag); + if (SimpleRecoFlag != -9999) pass_reconstruction = true; + + //Get information about clusters + this->GetClusterInformation(); + + m_data->Stores["MRDTracks"]->Get("NumMrdTracks",numtracksinev); + //If MRDTrackRestriction is enabled, check if there was only one MRD track + if (mrdtrack_restriction){ + if (numtracksinev != 1) pass_reconstruction = false; + if (pass_selection && numtracksinev == 1) { + for (int i_n=0; i_n < (int) reco_NCandTime->size(); i_n++){ + h_time_neutrons->Fill(reco_NCandTime->at(i_n)); + } + } + } else if (pass_selection) { + for (int i_n=0; i_n < (int) reco_NCandTime->size(); i_n++){ + h_time_neutrons->Fill(reco_NCandTime->at(i_n)); + } + } + + //std::cout <<"EventNumber: "<GetParticleInformation(); + + //Get truth information (if MC) + if (isMC) this->GetMCTruthInformation(); + + //Fill ROOT histograms + if (save_root) this->FillHistograms(); + + //Save variables to BoostStore + if (save_bs) this->SaveBoostStore(); + + } + + return true; +} + + +bool NeutronMultiplicity::Finalise(){ + + //Fill TGraphErrors + this->FillTGraphs(); + + if (save_root) { + file_neutronmult->Write(); + + dir_graph->cd(); + gr_neutrons_muonE->Write("gr_neutrons_muonE"); + gr_neutrons_muonE_fv->Write("gr_neutrons_muonE_fv"); + gr_neutrons_muonE_zoom->Write("gr_neutrons_muonE_zoom"); + gr_neutrons_muonE_fv_zoom->Write("gr_neutrons_muonE_fv_zoom"); + gr_neutrons_muonCosTheta->Write("gr_neutrons_muonCosTheta"); + gr_neutrons_muonCosTheta_fv->Write("gr_neutrons_muonCosTheta_fv"); + gr_neutrons_pT->Write("gr_neutrons_pT"); + gr_neutrons_pT_fv->Write("gr_neutrons_pT_fv"); + + dir_graph_mc->cd(); + gr_primneutrons_muonE->Write("gr_primneutrons_muonE"); + gr_totalneutrons_muonE->Write("gr_totalneutrons_muonE"); + gr_pmtvolneutrons_muonE->Write("gr_pmtvolneutrons_muonE"); + gr_primneutrons_muonE_fv->Write("gr_primneutrons_muonE_fv"); + gr_totalneutrons_muonE_fv->Write("gr_totalneutrons_muonE_fv"); + gr_pmtvolneutrons_muonE_fv->Write("gr_pmtvolneutrons_muonE_fv"); + gr_primneutrons_muonE_zoom->Write("gr_primneutrons_muonE_zoom"); + gr_totalneutrons_muonE_zoom->Write("gr_totalneutrons_muonE_zoom"); + gr_pmtvolneutrons_muonE_zoom->Write("gr_pmtvolneutrons_muonE_zoom"); + gr_primneutrons_muonE_fv_zoom->Write("gr_primneutrons_muonE_fv_zoom"); + gr_totalneutrons_muonE_fv_zoom->Write("gr_totalneutrons_muonE_fv_zoom"); + gr_pmtvolneutrons_muonE_fv_zoom->Write("gr_pmtvolneutrons_muonE_fv_zoom"); + gr_primneutrons_muonCosTheta->Write("gr_primneutrons_muonCosTheta"); + gr_totalneutrons_muonCosTheta->Write("gr_totalneutrons_muonCosTheta"); + gr_pmtvolneutrons_muonCosTheta->Write("gr_pmtvolneutrons_muonCosTheta"); + gr_primneutrons_muonCosTheta_fv->Write("gr_primneutrons_muonCosTheta_fv"); + gr_totalneutrons_muonCosTheta_fv->Write("gr_totalneutrons_muonCosTheta_fv"); + gr_pmtvolneutrons_muonCosTheta_fv->Write("gr_pmtvolneutrons_muonCosTheta_fv"); + gr_primneutrons_pT->Write("gr_primneutrons_pT"); + gr_totalneutrons_pT->Write("gr_totalneutrons_pT"); + gr_pmtvolneutrons_pT->Write("gr_pmtvolneutrons_pT"); + gr_primneutrons_pT_fv->Write("gr_primneutrons_pT_fv"); + gr_totalneutrons_pT_fv->Write("gr_totalneutrons_pT_fv"); + gr_pmtvolneutrons_pT_fv->Write("gr_pmtvolneutrons_pT_fv"); + + dir_graph_eff->cd(); + gr_eff_muonE->Write("gr_eff_muonE"); + gr_eff_muonE_fv->Write("gr_eff_muonE_fv"); + gr_eff_muonE_zoom->Write("gr_eff_muonE_zoom"); + gr_eff_muonE_fv_zoom->Write("gr_eff_muonE_fv_zoom"); + gr_eff_costheta->Write("gr_eff_costheta"); + gr_eff_costheta_fv->Write("gr_eff_costheta_fv"); + gr_eff_pT->Write("gr_eff_pT"); + gr_eff_pT_fv->Write("gr_eff_pT_fv"); + + dir_graph_corr->cd(); + gr_neutrons_muonE_corr->Write("gr_neutrons_muonE_corr"); + gr_neutrons_muonE_corr_fv->Write("gr_neutrons_muonE_corr_fv"); + gr_neutrons_muonE_corr_zoom->Write("gr_neutrons_muonE_corr_zoom"); + gr_neutrons_muonE_corr_fv_zoom->Write("gr_neutrons_muonE_corr_fv_zoom"); + gr_neutrons_muonCosTheta_corr->Write("gr_neutrons_muonCosTheta_corr"); + gr_neutrons_muonCosTheta_corr_fv->Write("gr_neutrons_muonCosTheta_corr_fv"); + gr_neutrons_pT_corr->Write("gr_neutrons_pT_corr"); + gr_neutrons_pT_corr_fv->Write("gr_neutrons_pT_corr_fv"); + delete file_neutronmult; + } + + store_neutronmult->Close(); + store_neutronmult->Delete(); + delete store_neutronmult; + + return true; +} + +bool NeutronMultiplicity::InitialiseHistograms(){ + + Log("NeutronMultiplicity tool: InitialiseHistograms",2,verbosity); + + //Initialise truevtx + truevtx = new RecoVertex(); + + //output TFile + std::stringstream ss_filename; + ss_filename << filename << ".root"; + file_neutronmult = new TFile(ss_filename.str().c_str(),"RECREATE"); + + dir_overall = (TDirectory*) gDirectory->CurrentDirectory(); + + Log("NeutronMultiplicity tool: Define histograms",2,verbosity); + + dir_muon = (TDirectory*) file_neutronmult->mkdir("hist_muon"); + dir_neutron = (TDirectory*) file_neutronmult->mkdir("hist_neutron"); + dir_mc = (TDirectory*) file_neutronmult->mkdir("hist_mc"); + dir_eff = (TDirectory*) file_neutronmult->mkdir("hist_eff"); + dir_graph = (TDirectory*) file_neutronmult->mkdir("graph_neutron"); + dir_graph_mc = (TDirectory*) file_neutronmult->mkdir("graph_neutron_mc"); + dir_graph_eff = (TDirectory*) file_neutronmult->mkdir("graph_neutron_eff"); + dir_graph_corr = (TDirectory*) file_neutronmult->mkdir("graph_neutron_corr"); + + //output histograms + dir_muon->cd(); + h_muon_energy = new TH1F("h_muon_energy","Muon energy distribution",100,0,2000); + h_muon_energy_fv = new TH1F("h_muon_energy_fv","Muon energy distribution (FV)",100,0,2000); + h_muon_vtx_yz = new TH2F("h_muon_vtx_yz","Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + h_muon_vtx_xz = new TH2F("h_muon_vtx_xz","Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + h_muon_costheta = new TH1F("h_muon_costheta","Muon cos(#theta) distribution",100,-1,1); + h_muon_costheta_fv = new TH1F("h_muon_costheta_fv","Muon cos(#theta) distribution (FV)",100,-1,1); + h_muon_vtx_x = new TH1F("h_muon_vtx_x","Muon vertex (x)",200,-3,3); + h_muon_vtx_y = new TH1F("h_muon_vtx_y","Muon vertex (y)",200,-3,3); + h_muon_vtx_z = new TH1F("h_muon_vtx_z","Muon vertex (z)",200,-3,3); + + dir_neutron->cd(); + h_neutrons = new TH1F("h_neutrons","Number of neutrons in beam events",10,0,10); + h_neutrons_mrdstop = new TH1F("h_neutrons_mrdstop","Number of of neutrons in beam events (MRD stop)",10,0,10); + h_neutrons_mrdstop_fv = new TH1F("h_neutrons_mrdstop_fv","Number of of neutrons in beam events (MRD stop, FV)",10,0,10); + h_time_neutrons = new TH1F("h_time_neutrons","Cluster time beam neutrons",200,10000,70000); + h_time_neutrons_mrdstop = new TH1F("h_time_neutrons_mrdstop","Cluster time beam neutrons",200,10000,70000); + h_neutrons_energy = new TH2F("h_neutrons_energy","Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + 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_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); + h_neutrons_pT_fv = new TH2F("h_neutrons_pT_fv","Neutron multiplicity vs transverse muon momentum (FV)",6,0,600,20,0,20); + + dir_mc->cd(); + h_primneutrons_energy = new TH2F("h_primneutrons_energy","Primary Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + h_primneutrons_energy_fv = new TH2F("h_primneutrons_energy_fv","Primary Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + h_primneutrons_energy_zoom = new TH2F("h_primneutrons_energy_zoom","Primary Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + h_primneutrons_energy_fv_zoom = new TH2F("h_primneutrons_energy_fv_zoom","Primary Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + h_totalneutrons_energy = new TH2F("h_totalneutrons_energy","Total Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + h_totalneutrons_energy_fv = new TH2F("h_totalneutrons_energy_fv","Total Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + h_totalneutrons_energy_zoom = new TH2F("h_totalneutrons_energy_zoom","Total Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + h_totalneutrons_energy_fv_zoom = new TH2F("h_totalneutrons_energy_fv_zoom","Total Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + h_pmtvolneutrons_energy = new TH2F("h_pmtvolneutrons_energy","PMTVol Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + h_pmtvolneutrons_energy_fv = new TH2F("h_pmtvolneutrons_energy_fv","PMTVol Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + h_pmtvolneutrons_energy_zoom = new TH2F("h_pmtvolneutrons_energy_zoom","PMTVol Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + h_pmtvolneutrons_energy_fv_zoom = new TH2F("h_pmtvolneutrons_energy_fv_zoom","PMTVol Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + h_primneutrons_costheta = new TH2F("h_primneutrons_costheta","Primary Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + h_primneutrons_costheta_fv = new TH2F("h_primvolneutrons_costheta_fv","Primary Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + h_totalneutrons_costheta = new TH2F("h_totalneutrons_costheta","Total Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + h_totalneutrons_costheta_fv = new TH2F("h_totalneutrons_costheta_fv","Total Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + h_pmtvolneutrons_costheta = new TH2F("h_pmtvolneutrons_costheta","PMTVol Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + h_pmtvolneutrons_costheta_fv = new TH2F("h_pmtvolneutrons_costheta_fv","PMTVol Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + h_primneutrons_pT = new TH2F("h_primneutrons_pT","Primary Neutron multiplicity vs transverse muon momentum",10,0,1000,20,0,20); + h_primneutrons_pT_fv = new TH2F("h_primneutrons_pT_fv","Primary Neutron multiplicity vs transverse muon momentum (FV)",6,0,600,20,0,20); + h_totalneutrons_pT = new TH2F("h_totalneutrons_pT","Total Neutron multiplicity vs transverse muon momentum",10,0,1000,20,0,20); + h_totalneutrons_pT_fv = new TH2F("h_totalneutrons_pT_fv","Total Neutron multiplicity vs transverse muon momentum (FV)",6,0,600,20,0,20); + h_pmtvolneutrons_pT = new TH2F("h_pmtvolneutrons_pT","PMTVol Neutron multiplicity vs transverse muon momentum",10,0,1000,20,0,20); + h_pmtvolneutrons_pT_fv = new TH2F("h_pmtvolneutrons_pT_fv","PMTVol Neutron multiplicity vs transverse muon momentum (FV)",6,0,600,20,0,20); + + dir_eff->cd(); + hist_neutron_eff = new TH3F("hist_neutron_eff","Neutron efficiency",100,-3,3,100,-3,3,100,-1,5); + h_eff_energy = new TH2F("h_eff_energy","Neutron detection efficiency vs muon energy",10,0,2000,100,0,1.0); + h_eff_energy_fv = new TH2F("h_eff_energy_fv","Neutron detection efficiency vs muon energy (FV)",10,0,2000,100,0,1.0); + h_eff_energy_zoom = new TH2F("h_eff_energy_zoom","Neutron detection efficiency vs muon energy",8,400,1200,100,0,1.0); + h_eff_energy_fv_zoom = new TH2F("h_eff_energy_fv_zoom","Neutron detection efficiency vs muon energy (FV)",6,600,1200,100,0,1.0); + h_eff_costheta = new TH2F("h_eff_costheta","Neutron detection efficiency vs muon angle",6,0.7,1.0,100,0,1.0); + h_eff_costheta_fv = new TH2F("h_eff_costheta_fv","Neutron detection efficiency vs muon angle (FV)",6,0.7,1.0,100,0,1.0); + h_eff_pT = new TH2F("h_eff_pT","Neutron detection efficiency vs transverse muon momentum",10,0,1000,100,0,1.0); + h_eff_pT_fv = new TH2F("h_eff_pT_fv","Neutron detection efficiency vs transverse muon momentum (FV)",6,0,600,100,0,1.0); + + + //Set properties of histograms (axes titles, etc) + h_neutrons->SetLineWidth(2); + h_neutrons->SetStats(0); + h_neutrons->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop->SetLineWidth(2); + h_neutrons_mrdstop->SetLineColor(kBlack); + h_neutrons_mrdstop->SetStats(0); + h_neutrons_mrdstop->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop_fv->SetLineWidth(2); + h_neutrons_mrdstop_fv->SetStats(0); + h_neutrons_mrdstop_fv->SetLineColor(kRed); + h_neutrons_mrdstop_fv->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop_fv->GetYaxis()->SetTitle("#"); + + h_neutrons_energy->SetStats(0); + h_neutrons_energy->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_zoom->SetStats(0); + h_neutrons_energy_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_zoom->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv->SetStats(0); + h_neutrons_energy_fv->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv_zoom->SetStats(0); + h_neutrons_energy_fv_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv_zoom->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"); + + h_neutrons_costheta_fv->SetStats(0); + h_neutrons_costheta_fv->GetXaxis()->SetTitle("cos(#theta)"); + h_neutrons_costheta_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_pT->SetStats(0); + h_neutrons_pT->GetXaxis()->SetTitle("p_{T} [MeV]"); + h_neutrons_pT->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_pT_fv->SetStats(0); + h_neutrons_pT_fv->GetXaxis()->SetTitle("p_{T} [MeV]"); + h_neutrons_pT_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_muon_energy->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_muon_energy->GetYaxis()->SetTitle("#"); + h_muon_energy->SetStats(0); + h_muon_energy->SetLineWidth(2); + h_muon_energy_fv->SetStats(0); + h_muon_energy_fv->SetLineColor(kRed); + h_muon_energy_fv->SetLineWidth(2); + + h_muon_costheta->GetXaxis()->SetTitle("cos(#theta)"); + h_muon_costheta->GetYaxis()->SetTitle("#"); + h_muon_costheta->SetStats(0); + h_muon_costheta->SetLineWidth(2); + + h_muon_costheta_fv->GetXaxis()->SetTitle("cos(#theta)"); + h_muon_costheta_fv->GetYaxis()->SetTitle("#"); + h_muon_costheta_fv->SetStats(0); + h_muon_costheta_fv->SetLineWidth(2); + h_muon_costheta_fv->SetLineColor(kRed); + + + h_muon_vtx_yz->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_yz->GetYaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_yz->SetStats(0); + h_muon_vtx_xz->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_xz->GetYaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_xz->SetStats(0); + + h_muon_vtx_x->GetXaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_x->GetYaxis()->SetTitle("#"); + h_muon_vtx_y->GetXaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_y->GetYaxis()->SetTitle("#"); + h_muon_vtx_z->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_z->GetYaxis()->SetTitle("#"); + + //Define TGraphs + gr_neutrons_muonE = new TGraphErrors(); + gr_neutrons_muonE_fv = new TGraphErrors(); + gr_neutrons_muonE_zoom = new TGraphErrors(); + gr_neutrons_muonE_fv_zoom = new TGraphErrors(); + gr_neutrons_muonCosTheta = new TGraphErrors(); + gr_neutrons_muonCosTheta_fv = new TGraphErrors(); + gr_neutrons_pT = new TGraphErrors(); + gr_neutrons_pT_fv = new TGraphErrors(); + + gr_primneutrons_muonE = new TGraphErrors(); + gr_totalneutrons_muonE = new TGraphErrors(); + gr_pmtvolneutrons_muonE = new TGraphErrors(); + gr_primneutrons_muonE_fv = new TGraphErrors(); + gr_totalneutrons_muonE_fv = new TGraphErrors(); + gr_pmtvolneutrons_muonE_fv = new TGraphErrors(); + gr_primneutrons_muonE_zoom = new TGraphErrors(); + gr_totalneutrons_muonE_zoom = new TGraphErrors(); + gr_pmtvolneutrons_muonE_zoom = new TGraphErrors(); + gr_primneutrons_muonE_fv_zoom = new TGraphErrors(); + gr_totalneutrons_muonE_fv_zoom = new TGraphErrors(); + gr_pmtvolneutrons_muonE_fv_zoom = new TGraphErrors(); + gr_primneutrons_muonCosTheta = new TGraphErrors(); + gr_totalneutrons_muonCosTheta = new TGraphErrors(); + gr_pmtvolneutrons_muonCosTheta = new TGraphErrors(); + gr_primneutrons_muonCosTheta_fv = new TGraphErrors(); + gr_totalneutrons_muonCosTheta_fv = new TGraphErrors(); + gr_pmtvolneutrons_muonCosTheta_fv = new TGraphErrors(); + gr_primneutrons_pT = new TGraphErrors(); + gr_totalneutrons_pT = new TGraphErrors(); + gr_pmtvolneutrons_pT = new TGraphErrors(); + gr_primneutrons_pT_fv = new TGraphErrors(); + gr_totalneutrons_pT_fv = new TGraphErrors(); + gr_pmtvolneutrons_pT_fv = new TGraphErrors(); + + gr_eff_muonE = new TGraphErrors(); + gr_eff_muonE_fv = new TGraphErrors(); + gr_eff_muonE_zoom = new TGraphErrors(); + gr_eff_muonE_fv_zoom = new TGraphErrors(); + gr_eff_costheta = new TGraphErrors(); + gr_eff_costheta_fv = new TGraphErrors(); + gr_eff_pT = new TGraphErrors(); + gr_eff_pT_fv = new TGraphErrors(); + + gr_neutrons_muonE_corr = new TGraphErrors(); + gr_neutrons_muonE_corr_fv = new TGraphErrors(); + gr_neutrons_muonE_corr_zoom = new TGraphErrors(); + gr_neutrons_muonE_corr_fv_zoom = new TGraphErrors(); + gr_neutrons_muonCosTheta_corr = new TGraphErrors(); + gr_neutrons_muonCosTheta_corr_fv = new TGraphErrors(); + gr_neutrons_pT_corr = new TGraphErrors(); + gr_neutrons_pT_corr_fv = new TGraphErrors(); + + //Define tree properties and variables + // + + dir_overall->cd(); + + true_NeutVtxX = new std::vector; + true_NeutVtxY = new std::vector; + true_NeutVtxZ = new std::vector; + true_NeutCapNucl = new std::vector; + true_NeutCapTime = new std::vector; + true_NeutCapETotal = new std::vector; + true_NeutCapNGamma = new std::vector; + true_NeutCapPrimary = new std::vector; + reco_ClusterCB = new std::vector; + reco_ClusterTime = new std::vector; + reco_ClusterPE = new std::vector; + reco_NCandCB = new std::vector; + reco_NCandTime = new std::vector; + reco_NCandPE = new std::vector; + true_PrimaryPdgs = new std::vector; + + neutron_tree = new TTree("neutron_tree","Neutron tree"); + neutron_tree->Branch("RunNumber",&run_nr); + neutron_tree->Branch("EventNumber",&ev_nr); + neutron_tree->Branch("RecoTankMRDCoinc",&reco_TankMRDCoinc); + neutron_tree->Branch("RecoNCandidates",&reco_NCandidates); + neutron_tree->Branch("RecoEmu",&reco_Emu); + neutron_tree->Branch("RecoEnu",&reco_Enu); + neutron_tree->Branch("RecoQ2",&reco_Q2); + neutron_tree->Branch("RecoPt",&reco_pT); + neutron_tree->Branch("RecoVtxX",&reco_VtxX); + neutron_tree->Branch("RecoVtxY",&reco_VtxY); + neutron_tree->Branch("RecoVtxZ",&reco_VtxZ); + neutron_tree->Branch("RecoFV",&reco_FV); + neutron_tree->Branch("RecoCosTheta",&reco_CosTheta); + neutron_tree->Branch("RecoClusters",&reco_Clusters); + neutron_tree->Branch("RecoClusterCB",&reco_ClusterCB); + neutron_tree->Branch("RecoClusterTime",&reco_ClusterTime); + neutron_tree->Branch("RecoClusterPE",&reco_ClusterPE); + neutron_tree->Branch("RecoNCandCB",&reco_NCandCB); + neutron_tree->Branch("RecoNCandTime",&reco_NCandTime); + neutron_tree->Branch("RecoNCandPE",&reco_NCandPE); + neutron_tree->Branch("RecoMrdEnergyLoss",&reco_MrdEnergyLoss); + neutron_tree->Branch("RecoTrackLengthInMRD",&reco_TrackLengthInMRD); + neutron_tree->Branch("RecoMrdStartX",&reco_MrdStartX); + neutron_tree->Branch("RecoMrdStartY",&reco_MrdStartY); + neutron_tree->Branch("RecoMrdStartZ",&reco_MrdStartZ); + neutron_tree->Branch("RecoMrdStopX",&reco_MrdStopX); + neutron_tree->Branch("RecoMrdStopY",&reco_MrdStopY); + neutron_tree->Branch("RecoMrdStopZ",&reco_MrdStopZ); + neutron_tree->Branch("TrueEmu",&true_Emu); + neutron_tree->Branch("TrueEnu",&true_Enu); + neutron_tree->Branch("TrueQ2",&true_Q2); + neutron_tree->Branch("TruePt",&true_pT); + neutron_tree->Branch("TrueVtxX",&true_VtxX); + neutron_tree->Branch("TrueVtxY",&true_VtxY); + neutron_tree->Branch("TrueVtxZ",&true_VtxZ); + neutron_tree->Branch("TrueVtxTime",&true_VtxTime); + neutron_tree->Branch("TrueDirX",&true_DirX); + neutron_tree->Branch("TrueDirY",&true_DirY); + neutron_tree->Branch("TrueDirZ",&true_DirZ); + neutron_tree->Branch("TrueCosTheta",&true_CosTheta); + neutron_tree->Branch("TrueFV",&true_FV); + neutron_tree->Branch("TrueTrackLengthInWater",&true_TrackLengthInWater); + neutron_tree->Branch("TrueTrackLengthInMRD",&true_TrackLengthInMRD); + neutron_tree->Branch("TruePrimNeut",&true_PrimNeut); + neutron_tree->Branch("TruePrimProt",&true_PrimProt); + neutron_tree->Branch("TrueNCaptures",&true_NCaptures); + neutron_tree->Branch("TrueNCapturesPMTVol",&true_NCapturesPMTVol); + neutron_tree->Branch("TrueNeutVtxX",&true_NeutVtxX); + neutron_tree->Branch("TrueNeutVtxY",&true_NeutVtxY); + neutron_tree->Branch("TrueNeutVtxZ",&true_NeutVtxZ); + neutron_tree->Branch("TrueNeutCapNucl",&true_NeutCapNucl); + neutron_tree->Branch("TrueNeutCapTime",&true_NeutCapTime); + neutron_tree->Branch("TrueNeutCapETotal",&true_NeutCapETotal); + neutron_tree->Branch("TrueNeutCapNGamma",&true_NeutCapNGamma); + neutron_tree->Branch("TrueNeutCapPrimary",&true_NeutCapPrimary); + neutron_tree->Branch("TrueCC",&true_CC); + neutron_tree->Branch("TrueQEL",&true_QEL); + neutron_tree->Branch("TrueDIS",&true_DIS); + neutron_tree->Branch("TrueRES",&true_RES); + neutron_tree->Branch("TrueMEC",&true_MEC); + neutron_tree->Branch("TrueCOH",&true_COH); + neutron_tree->Branch("TrueMultiRing",&true_MultiRing); + neutron_tree->Branch("TruePrimaryPdgs",&true_PrimaryPdgs); + neutron_tree->Branch("TruePdgPrimary",&true_PdgPrimary); + + return true; + +} + +bool NeutronMultiplicity::FillHistograms(){ + + h_neutrons_mrdstop->Fill(NumberNeutrons); + h_neutrons_energy->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_energy_zoom->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_costheta->Fill(SimpleRecoCosTheta,NumberNeutrons); + h_neutrons_pT->Fill(SimpleRecoPt,NumberNeutrons); + h_muon_energy->Fill(SimpleRecoEnergy); + h_muon_costheta->Fill(SimpleRecoCosTheta); + if (isMC){ + h_primneutrons_energy->Fill(SimpleRecoEnergy,true_PrimNeut); + h_primneutrons_energy_zoom->Fill(SimpleRecoEnergy,true_PrimNeut); + h_totalneutrons_energy->Fill(SimpleRecoEnergy,true_NCaptures); + h_totalneutrons_energy_zoom->Fill(SimpleRecoEnergy,true_NCaptures); + h_pmtvolneutrons_energy->Fill(SimpleRecoEnergy,true_NCapturesPMTVol); + h_pmtvolneutrons_energy_zoom->Fill(SimpleRecoEnergy,true_NCapturesPMTVol); + h_primneutrons_costheta->Fill(SimpleRecoCosTheta,true_PrimNeut); + h_totalneutrons_costheta->Fill(SimpleRecoCosTheta,true_NCaptures); + h_pmtvolneutrons_costheta->Fill(SimpleRecoCosTheta,true_NCapturesPMTVol); + h_primneutrons_pT->Fill(SimpleRecoPt,true_PrimNeut); + h_totalneutrons_pT->Fill(SimpleRecoPt,true_NCaptures); + h_pmtvolneutrons_pT->Fill(SimpleRecoPt,true_NCapturesPMTVol); + } + + if (SimpleRecoFV) { + h_muon_energy_fv->Fill(SimpleRecoEnergy); + h_muon_costheta_fv->Fill(SimpleRecoCosTheta); + h_neutrons_energy_fv->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_energy_fv_zoom->Fill(SimpleRecoEnergy,NumberNeutrons); + h_neutrons_costheta_fv->Fill(SimpleRecoCosTheta,NumberNeutrons); + h_neutrons_pT_fv->Fill(SimpleRecoPt,NumberNeutrons); + h_neutrons_mrdstop_fv->Fill(NumberNeutrons); + if (isMC){ + h_primneutrons_energy_fv->Fill(SimpleRecoEnergy,true_PrimNeut); + h_primneutrons_energy_fv_zoom->Fill(SimpleRecoEnergy,true_PrimNeut); + h_totalneutrons_energy_fv->Fill(SimpleRecoEnergy,true_NCaptures); + h_totalneutrons_energy_fv_zoom->Fill(SimpleRecoEnergy,true_NCaptures); + h_pmtvolneutrons_energy_fv->Fill(SimpleRecoEnergy,true_NCapturesPMTVol); + h_pmtvolneutrons_energy_fv_zoom->Fill(SimpleRecoEnergy,true_NCapturesPMTVol); + h_primneutrons_costheta_fv->Fill(SimpleRecoCosTheta,true_PrimNeut); + h_totalneutrons_costheta_fv->Fill(SimpleRecoCosTheta,true_NCaptures); + h_pmtvolneutrons_costheta_fv->Fill(SimpleRecoCosTheta,true_NCapturesPMTVol); + h_primneutrons_pT_fv->Fill(SimpleRecoPt,true_PrimNeut); + h_totalneutrons_pT_fv->Fill(SimpleRecoPt,true_NCaptures); + h_pmtvolneutrons_pT_fv->Fill(SimpleRecoPt,true_NCapturesPMTVol); + } + } + + 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()); + + reco_VtxX = SimpleRecoVtx.X(); + reco_VtxY = SimpleRecoVtx.Y(); + reco_VtxZ = SimpleRecoVtx.Z(); + reco_Emu = SimpleRecoEnergy; + reco_CosTheta = SimpleRecoCosTheta; + reco_pT = SimpleRecoPt; + reco_NCandidates = NumberNeutrons; + reco_FV = SimpleRecoFV; + reco_MrdEnergyLoss = SimpleRecoMrdEnergyLoss; + reco_TrackLengthInMRD = SimpleRecoTrackLengthInMRD; + reco_MrdStartX = SimpleRecoMRDStart.X(); + reco_MrdStartY = SimpleRecoMRDStart.Y(); + reco_MrdStartZ = SimpleRecoMRDStart.Z(); + reco_MrdStopX = SimpleRecoMRDStop.X(); + reco_MrdStopY = SimpleRecoMRDStop.Y(); + reco_MrdStopZ = SimpleRecoMRDStop.Z(); + + for (int i_n=0; i_n < (int) reco_NCandTime->size(); i_n++){ + h_time_neutrons_mrdstop->Fill(reco_NCandTime->at(i_n)); + } + + //Fill efficiency histogram + //Get efficiency for current vertex position + + //Unfortunately interpolation only works for a full rectangular grid of efficiency points, not unstructed data -> fix in future + //double current_eff = hist_neutron_eff->Interpolate(reco_VtxX,reco_VtxY,reco_VtxZ); + + //For now check which AmBe calibration point is closest + double min_dist = 99999999; + double min_eff = 0.; + for (std::map,double>::iterator it = neutron_eff_map.begin(); it!= neutron_eff_map.end(); it++) + { + std::vector pos = it->first; + double distX = reco_VtxX - pos.at(0); + double distY = reco_VtxY - pos.at(1); + double distZ = reco_VtxZ - pos.at(2); + double dist = sqrt(distX*distX+distY*distY+distZ*distZ); + if (dist < min_dist) { + min_dist = dist; + min_eff = it->second; + } + } + double current_eff = min_eff; + if (verbosity > 1){ + std::cout <<"NeutronMultiplicity tool: vertex: ("<Fill(SimpleRecoEnergy,current_eff); + h_eff_energy_zoom->Fill(SimpleRecoEnergy,current_eff); + h_eff_costheta->Fill(SimpleRecoCosTheta,current_eff); + h_eff_pT->Fill(SimpleRecoPt,current_eff); + if (SimpleRecoFV) { + h_eff_energy_fv->Fill(SimpleRecoEnergy,current_eff); + h_eff_energy_fv_zoom->Fill(SimpleRecoEnergy,current_eff); + h_eff_costheta_fv->Fill(SimpleRecoCosTheta,current_eff); + h_eff_pT_fv->Fill(SimpleRecoPt,current_eff); + } + + neutron_tree->Fill(); + + return true; + +} + +bool NeutronMultiplicity::SaveBoostStore(){ + + //Set BoostStore variables + store_neutronmult->Set("RunNumber",RunNumber); + store_neutronmult->Set("EventNumber",EventNumber); + store_neutronmult->Set("EventCutStatus",true); + store_neutronmult->Set("Particles",Particles); + store_neutronmult->Set("SimpleRecoFlag",SimpleRecoFlag); + store_neutronmult->Set("SimpleRecoEnergy",SimpleRecoEnergy); + store_neutronmult->Set("SimpleRecoVtx",SimpleRecoVtx); + store_neutronmult->Set("SimpleRecoStopVtx",SimpleRecoStopVtx); + store_neutronmult->Set("SimpleRecoCosTheta",SimpleRecoCosTheta); + store_neutronmult->Set("SimpleRecoPt",SimpleRecoPt); + store_neutronmult->Set("SimpleRecoFV",SimpleRecoFV); + store_neutronmult->Set("SimpleRecoMrdEnergyLoss",SimpleRecoMrdEnergyLoss); + store_neutronmult->Set("SimpleRecoTrackLengthInMRD",SimpleRecoTrackLengthInMRD); + store_neutronmult->Set("SimpleRecoMRDStart",SimpleRecoMRDStart); + store_neutronmult->Set("SimpleRecoMRDStop",SimpleRecoMRDStop); + store_neutronmult->Set("ClusterIndicesNeutron",cluster_neutron); + store_neutronmult->Set("ClusterTimesNeutron",cluster_times_neutron); + store_neutronmult->Set("ClusterChargesNeutron",cluster_charges_neutron); + store_neutronmult->Set("ClusterCBNeutron",cluster_cb_neutron); + store_neutronmult->Set("ClusterTimes",cluster_times); + store_neutronmult->Set("ClusterCharges",cluster_charges); + store_neutronmult->Set("ClusterCB",cluster_cb); + store_neutronmult->Set("NeutronEffMap",neutron_eff_map); + store_neutronmult->Set("PMTMRDCoinc",passPMTMRDCoincCut); + store_neutronmult->Set("NumMRDTracks",numtracksinev); + + if (isMC){ + store_neutronmult->Set("NeutrinoEnergy",true_Enu); + store_neutronmult->Set("EventQ2",true_Q2); + store_neutronmult->Set("IsWeakCC",true_CC); + store_neutronmult->Set("IsQuasiElastic",true_QEL); + store_neutronmult->Set("IsResonant",true_RES); + store_neutronmult->Set("IsDeepInelastic",true_DIS); + store_neutronmult->Set("IsCoherent",true_COH); + store_neutronmult->Set("IsMEC",true_MEC); + store_neutronmult->Set("NumFSNeutrons",true_PrimNeut); + store_neutronmult->Set("NumFSProtons",true_PrimProt); + + double temp_vtx_x = true_VtxX; + double temp_vtx_y = true_VtxY; + double temp_vtx_z = true_VtxZ; + double temp_vtx_t = true_VtxTime; + Log("NeutronMultiplicity tool: Set vertex with "+std::to_string(true_VtxX*100.)+", "+std::to_string((true_VtxY+0.144)*100.)+", "+std::to_string((true_VtxZ-1.681)*100.)+", "+std::to_string(true_VtxTime),v_message,verbosity); + store_neutronmult->Set("TrueVertex_X",temp_vtx_x*100.); + store_neutronmult->Set("TrueVertex_Y",(temp_vtx_y+0.144)*100.); + store_neutronmult->Set("TrueVertex_Z",(temp_vtx_z-1.681)*100.); + store_neutronmult->Set("TrueVertex_T",temp_vtx_t); + store_neutronmult->Set("TrueVertex_DirX",true_DirX); + store_neutronmult->Set("TrueVertex_DirY",true_DirY); + store_neutronmult->Set("TrueVertex_DirZ",true_DirZ); + + store_neutronmult->Set("TrueMuonEnergy",true_Emu+105.66); + store_neutronmult->Set("PrimaryPdgs",vec_true_PrimaryPdgs); + store_neutronmult->Set("PdgPrimary",true_PdgPrimary); + store_neutronmult->Set("TrueTrackLengthInWater",true_TrackLengthInWater); + store_neutronmult->Set("TrueTrackLengthInMRD",true_TrackLengthInMRD); + store_neutronmult->Set("MCMultiRingEvent",IsMultiRing); + store_neutronmult->Set("MCNeutCap",MCNeutCap); + store_neutronmult->Set("MCNeutCapGammas",MCNeutCapGammas); + store_neutronmult->Set("MCFile",MCFile); + } + + //Construct BoostStore filename + std::stringstream ss_filename; + ss_filename << filename << ".bs"; + Log("NeutronMultiplicity tool: Saving BoostStore file "+ss_filename.str(),2,verbosity); + + //Save BoostStore + store_neutronmult->Save(ss_filename.str().c_str()); + + return true; +} + +bool NeutronMultiplicity::ReadBoostStore(){ + + bool EventCutStatus = false; + + //Get BoostStore variables + read_neutronmult->Get("RunNumber",RunNumber); + read_neutronmult->Get("EventNumber",EventNumber); + read_neutronmult->Get("EventCutStatus",EventCutStatus); + read_neutronmult->Get("Particles",Particles); + read_neutronmult->Get("SimpleRecoFlag",SimpleRecoFlag); + read_neutronmult->Get("SimpleRecoEnergy",SimpleRecoEnergy); + read_neutronmult->Get("SimpleRecoVtx",SimpleRecoVtx); + read_neutronmult->Get("SimpleRecoStopVtx",SimpleRecoStopVtx); + read_neutronmult->Get("SimpleRecoCosTheta",SimpleRecoCosTheta); + read_neutronmult->Get("SimpleRecoPt",SimpleRecoPt); + read_neutronmult->Get("SimpleRecoFV",SimpleRecoFV); + read_neutronmult->Get("SimpleRecoMrdEnergyLoss",SimpleRecoMrdEnergyLoss); + read_neutronmult->Get("SimpleRecoTrackLengthInMRD",SimpleRecoTrackLengthInMRD); + read_neutronmult->Get("SimpleRecoMRDStart",SimpleRecoMRDStart); + read_neutronmult->Get("SimpleRecoMRDStop",SimpleRecoMRDStop); + read_neutronmult->Get("ClusterIndicesNeutron",cluster_neutron); + read_neutronmult->Get("ClusterTimesNeutron",cluster_times_neutron); + read_neutronmult->Get("ClusterChargesNeutron",cluster_charges_neutron); + read_neutronmult->Get("ClusterCBNeutron",cluster_cb_neutron); + read_neutronmult->Get("ClusterTimes",cluster_times); + read_neutronmult->Get("ClusterCharges",cluster_charges); + read_neutronmult->Get("ClusterCB",cluster_cb); + read_neutronmult->Get("NeutronEffMap",neutron_eff_map); + read_neutronmult->Get("PMTMRDCoinc",passPMTMRDCoincCut); + read_neutronmult->Get("NumMRDTracks",numtracksinev); + + m_data->Stores["ANNIEEvent"]->Set("RunNumber",RunNumber); + m_data->Stores["ANNIEEvent"]->Set("EventNumber",EventNumber); + m_data->Stores["RecoEvent"]->Set("EventCutStatus",EventCutStatus); + m_data->Stores["ANNIEEvent"]->Set("Particles",Particles); + 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("ClusterIndicesNeutron",cluster_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterTimesNeutron",cluster_times_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterChargesNeutron",cluster_charges_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterCBNeutron",cluster_cb_neutron); + m_data->Stores["RecoEvent"]->Set("ClusterTimes",cluster_times); + m_data->Stores["RecoEvent"]->Set("ClusterCharges",cluster_charges); + m_data->Stores["RecoEvent"]->Set("ClusterCB",cluster_cb); + m_data->Stores["RecoEvent"]->Set("NeutronEffMap",neutron_eff_map); + m_data->Stores.at("RecoEvent")->Set("PMTMRDCoinc",passPMTMRDCoincCut); + m_data->Stores["MRDTracks"]->Set("NumMrdTracks",numtracksinev); + + if (isMC){ + read_neutronmult->Get("NeutrinoEnergy",true_Enu); + read_neutronmult->Get("EventQ2",true_Q2); + read_neutronmult->Get("IsWeakCC",true_CC); + read_neutronmult->Get("IsQuasiElastic",true_QEL); + read_neutronmult->Get("IsResonant",true_RES); + read_neutronmult->Get("IsDeepInelastic",true_DIS); + read_neutronmult->Get("IsCoherent",true_COH); + read_neutronmult->Get("IsMEC",true_MEC); + read_neutronmult->Get("NumFSNeutrons",true_PrimNeut); + read_neutronmult->Get("NumFSProtons",true_PrimProt); + double temp_vtx_x, temp_vtx_y, temp_vtx_z, temp_vtx_t; + read_neutronmult->Get("TrueVertex_X",temp_vtx_x); + read_neutronmult->Get("TrueVertex_Y",temp_vtx_y); + read_neutronmult->Get("TrueVertex_Z",temp_vtx_z); + read_neutronmult->Get("TrueVertex_T",temp_vtx_t); + read_neutronmult->Get("TrueVertex_DirX",true_DirX); + read_neutronmult->Get("TrueVertex_DirY",true_DirY); + read_neutronmult->Get("TrueVertex_DirZ",true_DirZ); + read_neutronmult->Get("TrueVertex",true_vertex); + read_neutronmult->Get("TrueMuonEnergy",true_Emu); + read_neutronmult->Get("PrimaryPdgs",vec_true_PrimaryPdgs); + read_neutronmult->Get("PdgPrimary",true_PdgPrimary); + read_neutronmult->Get("TrueTrackLengthInWater",true_TrackLengthInWater); + read_neutronmult->Get("TrueTrackLengthInMRD",true_TrackLengthInMRD); + read_neutronmult->Get("MCMultiRingEvent",IsMultiRing); + read_neutronmult->Get("MCNeutCap",MCNeutCap); + read_neutronmult->Get("MCNeutCapGammas",MCNeutCapGammas); + read_neutronmult->Get("MCFile",MCFile); + + Log("NeutronMultiplicity tool: Got TrueVertex from file with properties: "+std::to_string(temp_vtx_x)+", "+std::to_string(temp_vtx_y)+", "+std::to_string(temp_vtx_z)+", "+std::to_string(temp_vtx_t),v_message,verbosity); + + truevtx->SetVertex(temp_vtx_x,temp_vtx_y,temp_vtx_z,temp_vtx_t); + truevtx->SetDirection(true_DirX,true_DirY,true_DirZ); + + m_data->Stores["GenieInfo"]->Set("NeutrinoEnergy",true_Enu/1000.); + m_data->Stores["GenieInfo"]->Set("EventQ2",true_Q2/1000.); + m_data->Stores["GenieInfo"]->Set("IsWeakCC",bool(true_CC)); + m_data->Stores["GenieInfo"]->Set("IsQuasiElastic",true_QEL); + m_data->Stores["GenieInfo"]->Set("IsResonant",true_RES); + m_data->Stores["GenieInfo"]->Set("IsDeepInelastic",true_DIS); + m_data->Stores["GenieInfo"]->Set("IsCoherent",true_COH); + m_data->Stores["GenieInfo"]->Set("IsMEC",true_MEC); + m_data->Stores["GenieInfo"]->Set("NumFSNeutrons",true_PrimNeut); + m_data->Stores["GenieInfo"]->Set("NumFSProtons",true_PrimProt); + m_data->Stores.at("RecoEvent")->Set("TrueVertex",truevtx,true); + m_data->Stores.at("RecoEvent")->Set("TrueMuonEnergy",true_Emu); + m_data->Stores.at("RecoEvent")->Set("PrimaryPdgs",vec_true_PrimaryPdgs); + m_data->Stores.at("RecoEvent")->Set("PdgPrimary",true_PdgPrimary); + m_data->Stores.at("RecoEvent")->Set("TrueTrackLengthInWater",true_TrackLengthInWater); + m_data->Stores.at("RecoEvent")->Set("TrueTrackLengthInMRD",true_TrackLengthInMRD*100.); + m_data->Stores["RecoEvent"]->Set("MCMultiRingEvent",IsMultiRing); + m_data->Stores.at("ANNIEEvent")->Set("MCNeutCap",MCNeutCap); + m_data->Stores.at("ANNIEEvent")->Set("MCNeutCapGammas",MCNeutCapGammas); + m_data->Stores.at("ANNIEEvent")->Set("MCFile",MCFile); + } + + return true; +} + +bool NeutronMultiplicity::GetClusterInformation(){ + + bool return_value = true; + + bool get_cluster_idxN = m_data->Stores["RecoEvent"]->Get("ClusterIndicesNeutron",cluster_neutron); + if (!get_cluster_idxN) Log("NeutronMultiplicity tool: No ClusterIndicesNeutron In RecoEvent!",v_error,verbosity); + bool get_cluster_tN = m_data->Stores["RecoEvent"]->Get("ClusterTimesNeutron",cluster_times_neutron); + if (!get_cluster_tN) Log("NeutronMultiplicity tool: No ClusterTimesNeutron In RecoEvent!",v_error,verbosity); + bool get_cluster_qN = m_data->Stores["RecoEvent"]->Get("ClusterChargesNeutron",cluster_charges_neutron); + if (!get_cluster_qN) Log("NeutronMultiplicity tool: No ClusterChargesNeutron In RecoEvent!",v_error,verbosity); + bool get_cluster_cbN = m_data->Stores["RecoEvent"]->Get("ClusterCBNeutron",cluster_cb_neutron); + if (!get_cluster_cbN) Log("NeutronMultiplicity tool: No ClusterCBNeutron In RecoEvent!",v_error,verbosity); + bool get_cluster_t = m_data->Stores["RecoEvent"]->Get("ClusterTimes",cluster_times); + if (!get_cluster_t) Log("NeutronMultiplicity tool: No ClusterTimes In RecoEvent!",v_error,verbosity); + bool get_cluster_q = m_data->Stores["RecoEvent"]->Get("ClusterCharges",cluster_charges); + if (!get_cluster_q) Log("NeutronMultiplicity tool: No ClusterCharges In RecoEvent!",v_error,verbosity); + bool get_cluster_cb = m_data->Stores["RecoEvent"]->Get("ClusterCB",cluster_cb); + if (!get_cluster_cb) Log("NeutronMultiplicity tool: No ClusterCB In RecoEvent!",v_error,verbosity); + + return_value = (get_cluster_idxN && get_cluster_tN && get_cluster_qN && get_cluster_cbN && get_cluster_t && get_cluster_q && get_cluster_cb); + + (*reco_NCandCB) = cluster_cb_neutron; + (*reco_NCandTime) = cluster_times_neutron; + (*reco_NCandPE) = cluster_charges_neutron; + (*reco_ClusterCB) = cluster_cb; + (*reco_ClusterTime) = cluster_times; + (*reco_ClusterPE) = cluster_charges; + reco_Clusters = reco_ClusterCB->size(); + + return return_value; + +} + +bool NeutronMultiplicity::GetParticleInformation(){ + + bool return_value = true; + + bool get_simple_e = m_data->Stores["RecoEvent"]->Get("SimpleRecoEnergy",SimpleRecoEnergy); + if (!get_simple_e) Log("NeutronMultiplicity tool: No SimpleRecoEnergy In RecoEvent!",v_error,verbosity); + bool get_simple_vtx = m_data->Stores["RecoEvent"]->Get("SimpleRecoVtx",SimpleRecoVtx); + if (!get_simple_vtx) Log("NeutronMultiplicity tool: No SimpleRecoVtx In RecoEvent!",v_error,verbosity); + bool get_simple_stop = m_data->Stores["RecoEvent"]->Get("SimpleRecoStopVtx",SimpleRecoStopVtx); + if (!get_simple_stop) Log("NeutronMultiplicity tool: No SimpleRecoStopVtx In RecoEvent!",v_error,verbosity); + bool get_simple_cos = m_data->Stores["RecoEvent"]->Get("SimpleRecoCosTheta",SimpleRecoCosTheta); + if (!get_simple_cos) Log("NeutronMultiplicity tool: No SimpleRecoCosTheta In RecoEvent!",v_error,verbosity); + bool get_simple_pT = m_data->Stores["RecoEvent"]->Get("SimpleRecoPt",SimpleRecoPt); + if (!get_simple_pT) Log("NeutronMultiplicity tool: No SimpleRecoPt In RecoEvent!",v_error,verbosity); + bool get_simple_fv = m_data->Stores["RecoEvent"]->Get("SimpleRecoFV",SimpleRecoFV); + if (!get_simple_fv) Log("NeutronMultiplicity tool: No SimpleRecoFV in RecoEvent!",v_error,verbosity); + bool get_simple_mrdloss = m_data->Stores["RecoEvent"]->Get("SimpleRecoMrdEnergyLoss",SimpleRecoMrdEnergyLoss); + if (!get_simple_mrdloss) Log("NeutronMultiplicity tool: No SimpleRecoMrdEnergyLoss in RecoEvent!",v_error,verbosity); + bool get_simple_mrdlength = m_data->Stores["RecoEvent"]->Get("SimpleRecoTrackLengthInMRD",SimpleRecoTrackLengthInMRD); + if (!get_simple_mrdlength) Log("NeutronMultiplicity tool: No SimpleRecoTrackLength in RecoEvent!",v_error,verbosity); + bool get_simple_mrdstart = m_data->Stores["RecoEvent"]->Get("SimpleRecoMRDStart",SimpleRecoMRDStart); + if (!get_simple_mrdstart) Log("NeutronMultiplicity tool: No SimpleRecoMRDStart in RecoEvent!",v_error,verbosity); + 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_pmtmrdcoinc = m_data->Stores.at("RecoEvent")->Get("PMTMRDCoinc",passPMTMRDCoincCut); + if (!get_pmtmrdcoinc) Log("NeutronMultiplicity tool: No PMTMRDCoinc in RecoEvent!",v_error,verbosity); + reco_TankMRDCoinc = (passPMTMRDCoincCut)? 1 : 0; + + bool get_neutroneff = m_data->Stores.at("RecoEvent")->Get("NeutronEffMap",neutron_eff_map); + if (!get_neutroneff) Log("NeutronMultiplicity tool: No NeutronEffMap in RecoEvent!",v_error,verbosity); + else { + if (!neutron_hist_filled){ //Just fill it once + for (std::map,double>::iterator it = neutron_eff_map.begin(); it!= neutron_eff_map.end(); it++){ + std::vector position = it->first; + double eff = it->second; + int bin_nr = hist_neutron_eff->FindBin(position.at(0),position.at(1),position.at(2)); + hist_neutron_eff->SetBinContent(bin_nr,eff); + } + neutron_hist_filled = true; + } + } + + return_value = (get_simple_e && get_simple_vtx && get_simple_stop && get_simple_cos && get_simple_pT && get_simple_fv && get_simple_mrdloss && get_pmtmrdcoinc && get_simple_mrdlength && get_simple_mrdstart && get_simple_mrdstop && get_neutroneff); + + run_nr = RunNumber; + ev_nr = (int) EventNumber; + + return return_value; + +} + +bool NeutronMultiplicity::GetMCTruthInformation(){ + + bool return_value = true; + + //Get information from GENIE store + 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); + if (!get_q2) Log("NeutronMultiplicity tool: No EventQ2 In GenieInfo!",v_error,verbosity); + true_Q2 *= 1000; //convert to MeV for consistency + bool bool_true_CC=false; + bool get_cc = m_data->Stores["GenieInfo"]->Get("IsWeakCC",bool_true_CC); + true_CC = (bool_true_CC)? 1 : 0; + if (!get_cc) Log("NeutronMultiplicity tool: No IsWeakCC In GenieInfo!",v_error,verbosity); + bool bool_true_QEL=false; + bool get_qel = m_data->Stores["GenieInfo"]->Get("IsQuasiElastic",bool_true_QEL); + true_QEL = (bool_true_QEL)? 1 : 0; + if (!get_qel) Log("NeutronMultiplicity tool: No IsQuasiElastic In GenieInfo!",v_error,verbosity); + bool bool_true_RES=false; + bool get_res = m_data->Stores["GenieInfo"]->Get("IsResonant",bool_true_RES); + true_RES = (bool_true_RES)? 1 : 0; + if (!get_res) Log("NeutronMultiplicity tool: No IsReonant In GenieInfo!",v_error,verbosity); + bool bool_true_DIS=false; + bool get_dis = m_data->Stores["GenieInfo"]->Get("IsDeepInelastic",bool_true_DIS); + true_DIS = (bool_true_DIS)? 1 : 0; + if (!get_dis) Log("NeutronMultiplicity tool: No IsDeepInelastic In GenieInfo!",v_error,verbosity); + bool bool_true_COH=false; + bool get_coh = m_data->Stores["GenieInfo"]->Get("IsCoherent",bool_true_COH); + true_COH = (bool_true_COH)? 1 : 0; + if (!get_coh) Log("NeutronMultiplicity tool: No IsCoherent In GenieInfo!",v_error,verbosity); + bool bool_true_MEC=false; + bool get_mec = m_data->Stores["GenieInfo"]->Get("IsMEC",bool_true_MEC); + true_MEC = (bool_true_MEC)? 1 : 0; + if (!get_mec) Log("NeutronMultiplicity tool: No IsMEC In GenieInfo!",v_error,verbosity); + bool get_n = m_data->Stores["GenieInfo"]->Get("NumFSNeutrons",true_PrimNeut); + if (!get_n) Log("NeutronMultiplicity tool: No NumFSNeutrons In GenieInfo!",v_error,verbosity); + 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); + //Get information from RecoEvent store + RecoVertex* TrueVtx = nullptr; + auto get_muonMC = m_data->Stores.at("RecoEvent")->Get("TrueVertex",TrueVtx); + if (!get_muonMC) Log("NeutronMultiplicity tool: No TrueVertex In RecoEvent!",v_error,verbosity); + else { + truevtx->SetVertex(TrueVtx->GetPosition().X(),TrueVtx->GetPosition().Y(),TrueVtx->GetPosition().Z(),TrueVtx->GetTime()); + truevtx->SetDirection(TrueVtx->GetDirection().X(),TrueVtx->GetDirection().Y(),TrueVtx->GetDirection().Z()); + } + auto get_muonMCEnergy = m_data->Stores.at("RecoEvent")->Get("TrueMuonEnergy",true_Emu); + if (!get_muonMCEnergy) Log("NeutronMultiplicity tool: No TrueMuonEnergy In RecoEvent!",v_error,verbosity); + auto get_pdg = m_data->Stores.at("RecoEvent")->Get("PdgPrimary",true_PdgPrimary); + if (!get_pdg) Log("NeutronMultiplicity tool: No PdgPrimary In RecoEvent!",v_error,verbosity); + bool has_primaries = m_data->Stores.at("RecoEvent")->Get("PrimaryPdgs",vec_true_PrimaryPdgs); + if (has_primaries){ + for (int i_part=0; i_part < (int) vec_true_PrimaryPdgs.size(); i_part++){ + true_PrimaryPdgs->push_back(vec_true_PrimaryPdgs.at(i_part)); + } + } + true_Emu -= 105.66; //Correct true muon energy by rest mass to get true kinetic energy + std::cout <<"get_muonMC && get_muonMCEnergy: "<<(get_muonMC && get_muonMCEnergy)<GetPosition().X()/100.; //convert to meters + true_VtxY = truevtx->GetPosition().Y()/100.-0.144; //convert to meters, offset + true_VtxZ = truevtx->GetPosition().Z()/100.+1.681; //convert to meters, offset + true_VtxTime = truevtx->GetTime(); + true_DirX = truevtx->GetDirection().X(); + true_DirY = truevtx->GetDirection().Y(); + true_DirZ = truevtx->GetDirection().Z(); + true_CosTheta = true_DirZ; + double true_Emu_total = true_Emu + 105.66; + true_pT = sqrt((1-true_CosTheta*true_CosTheta)*(true_Emu_total*true_Emu_total-105.6*105.6)); + if (sqrt(true_VtxX*true_VtxX+(true_VtxZ-1.681)*(true_VtxZ-1.681))<1.0 && fabs(true_VtxY)<0.5 && (true_VtxZ < 1.681)) true_FV = 1; + else true_FV = 0; + } + return_value = (return_value && get_muonMC && get_muonMCEnergy && get_pdg); + + auto get_tankTrackLength = m_data->Stores.at("RecoEvent")->Get("TrueTrackLengthInWater",true_TrackLengthInWater); + if (!get_tankTrackLength) Log("NeutronMultiplicity tool: No TrueTrackLengthInWater in RecoEvent!",v_error,verbosity); + auto get_MRDTrackLength = m_data->Stores.at("RecoEvent")->Get("TrueTrackLengthInMRD",true_TrackLengthInMRD); + if (!get_MRDTrackLength) Log("NeutronMultiplicity tool: No TrueTrackLengthInMRD In RecoEvent!",v_error,verbosity); + true_TrackLengthInMRD /= 100; //convert to meters + return_value = (return_value && get_tankTrackLength && get_MRDTrackLength); + + bool get_multi = m_data->Stores["RecoEvent"]->Get("MCMultiRingEvent",IsMultiRing); + if (get_multi) { true_MultiRing = (IsMultiRing)? 1 : 0;} + else Log("NeutronMultiplicity tool: No MCMultiRingEvent information in RecoEvent!",v_error,verbosity); + + return_value = (return_value && get_multi); + + bool get_neutcap = m_data->Stores.at("ANNIEEvent")->Get("MCNeutCap",MCNeutCap); + if (!get_neutcap){ + Log("NeutronMultiplicity tool: Did not find MCNeutCap in ANNIEEvent Store!",v_warning,verbosity); + } + + bool get_neutcap_gammas = m_data->Stores.at("ANNIEEvent")->Get("MCNeutCapGammas",MCNeutCapGammas); + if (!get_neutcap_gammas){ + Log("NeutronMultiplicity tool: Did not find MCNeutCapGammas in ANNIEEvent Store!",v_warning,verbosity); + } + + return_value = (return_value && get_neutcap && get_neutcap_gammas); + + if (MCNeutCap.count("CaptVtxX")>0){ + std::vector n_vtxx = MCNeutCap["CaptVtxX"]; + std::vector n_vtxy = MCNeutCap["CaptVtxY"]; + std::vector n_vtxz = MCNeutCap["CaptVtxZ"]; + std::vector n_parent = MCNeutCap["CaptParent"]; + std::vector n_ngamma = MCNeutCap["CaptNGamma"]; + std::vector n_totale = MCNeutCap["CaptTotalE"]; + std::vector n_time = MCNeutCap["CaptTime"]; + std::vector n_nuc = MCNeutCap["CaptNucleus"]; + std::vector n_primary = MCNeutCap["CaptPrimary"]; + + true_NCapturesPMTVol = 0; + + for (int i_cap=0; i_cap < (int) n_vtxx.size(); i_cap++){ + true_NeutVtxX->push_back(n_vtxx.at(i_cap)/100.); //convert to meters for consistency + true_NeutVtxY->push_back(n_vtxy.at(i_cap)/100.); //convert to meters for consistency + true_NeutVtxZ->push_back(n_vtxz.at(i_cap)/100.); //convert to meters for consistency + true_NeutCapNucl->push_back(n_nuc.at(i_cap)); + true_NeutCapTime->push_back(n_time.at(i_cap)); + true_NeutCapNGamma->push_back(n_ngamma.at(i_cap)); + true_NeutCapETotal->push_back(n_totale.at(i_cap)); + true_NeutCapPrimary->push_back(n_primary.at(i_cap)); + double n_VtxX = n_vtxx.at(i_cap)/100.; + double n_VtxY = n_vtxy.at(i_cap)/100.; + double n_VtxZ = n_vtxz.at(i_cap)/100.; + if (sqrt(n_VtxX*n_VtxX+(n_VtxZ-1.681)*(n_VtxZ-1.681))<1.5 && fabs(n_VtxY)<2.0) { + true_NCapturesPMTVol++; + } + } + true_NCaptures = int(n_vtxx.size()); + } + + return return_value; + +} + +bool NeutronMultiplicity::ResetVariables(){ + + SimpleRecoFlag = -9999; + SimpleRecoVtx = Position(-9999,-9999,-9999); + SimpleRecoStopVtx = Position(-9999,-9999,-9999); + SimpleRecoEnergy = -9999; + SimpleRecoCosTheta = -9999; + SimpleRecoPt = -9999; + SimpleRecoFV = false; + NumberNeutrons = -9999; + SimpleRecoMrdEnergyLoss = -9999; + Particles.clear(); + passPMTMRDCoincCut = false; + cluster_neutron.clear(); + cluster_times_neutron.clear(); + cluster_charges_neutron.clear(); + cluster_cb_neutron.clear(); + cluster_times.clear(); + cluster_charges.clear(); + cluster_cb.clear(); + numtracksinev = -9999; + MCNeutCapGammas.clear(); + MCNeutCap.clear(); + IsMultiRing = false; + truevtx->SetVertex(-9999,-9999,-9999,-9999); + true_vertex.SetVertex(-9999,-9999,-9999,-9999); + true_vertex.SetDirection(-9999,-9999,-9999); + + //ROOT tree variables + true_PrimNeut = -9999; + true_PrimProt = -9999; + true_NCaptures = 0; + true_NCapturesPMTVol = 0; + true_VtxX = -9999; + true_VtxY = -9999; + true_VtxZ = -9999; + true_VtxTime = -9999; + true_DirX = -9999; + true_DirY = -9999; + true_DirZ = -9999; + true_Emu = -9999; + true_Enu = -9999; + true_Q2 = -9999; + true_pT = -9999; + true_FV = -9999; + true_CosTheta = -9999; + true_TrackLengthInWater = -9999; + true_TrackLengthInMRD = -9999; + true_NeutVtxX->clear(); + true_NeutVtxY->clear(); + true_NeutVtxZ->clear(); + true_NeutCapNucl->clear(); + true_NeutCapTime->clear(); + true_NeutCapETotal->clear(); + true_NeutCapNGamma->clear(); + true_NeutCapPrimary->clear(); + true_CC = -9999; + true_QEL = -9999; + true_DIS = -9999; + true_RES = -9999; + true_COH = -9999; + true_MEC = -9999; + true_MultiRing = -9999; + true_PrimaryPdgs->clear(); + true_PdgPrimary = -9999; + vec_true_PrimaryPdgs.clear(); + + reco_Emu = -9999; + reco_Enu = -9999; + reco_Q2 = -9999; + reco_pT = -9999; + reco_ClusterCB->clear(); + reco_ClusterTime->clear(); + reco_ClusterPE->clear(); + reco_NCandCB->clear(); + reco_NCandTime->clear(); + reco_NCandPE->clear(); + reco_MrdEnergyLoss = -9999; + reco_TrackLengthInMRD = -9999; + reco_MrdStartX = -9999; + reco_MrdStartY = -9999; + reco_MrdStartZ = -9999; + reco_MrdStopX = -9999; + reco_MrdStopY = -9999; + reco_MrdStopZ = -9999; + reco_TankMRDCoinc = -9999; + reco_Clusters = -9999; + reco_NCandidates = -9999; + reco_VtxX = -9999; + reco_VtxY = -9999; + reco_VtxZ = -9999; + reco_FV = -9999; + reco_CosTheta = -9999; + + run_nr = -9999; + ev_nr = -9999; + + return true; +} + +bool NeutronMultiplicity::FillTGraphs(){ + + std::vector labels_muon_E = {"E_{#mu} [MeV]","Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_E_fv= {"E_{#mu} [MeV]","Neutron multiplicity","ANNIE Neutron multiplicity (FV)"}; + std::vector labels_muon_CosTheta = {"cos(#theta)","Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_CosTheta_fv = {"cos(#theta)","Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + std::vector labels_muon_pT = {"p_{T} [MeV]","Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_pT_fv = {"p_{T} [MeV]","Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + + this->FillSingleTGraph(gr_neutrons_muonE,h_neutrons_energy,labels_muon_E); + this->FillSingleTGraph(gr_neutrons_muonE_zoom,h_neutrons_energy_zoom,labels_muon_E); + this->FillSingleTGraph(gr_neutrons_muonE_fv,h_neutrons_energy_fv,labels_muon_E_fv); + this->FillSingleTGraph(gr_neutrons_muonE_fv_zoom,h_neutrons_energy_fv_zoom,labels_muon_E_fv); + this->FillSingleTGraph(gr_neutrons_muonCosTheta,h_neutrons_costheta,labels_muon_CosTheta); + this->FillSingleTGraph(gr_neutrons_muonCosTheta_fv,h_neutrons_costheta_fv,labels_muon_CosTheta_fv); + this->FillSingleTGraph(gr_neutrons_pT,h_neutrons_pT,labels_muon_pT); + this->FillSingleTGraph(gr_neutrons_pT_fv,h_neutrons_pT_fv,labels_muon_pT_fv); + + std::vector labels_eff_E = {"E_{#mu} [MeV]","Efficiency #varepsilon","ANNIE Neutron efficiency"}; + std::vector labels_eff_E_fv= {"E_{#mu} [MeV]","Efficiency #varepsilon","ANNIE Neutron efficiency (FV)"}; + std::vector labels_eff_CosTheta = {"cos(#theta)","Efficiency #varepsilon","ANNIE Neutron efficiency"}; + std::vector labels_eff_CosTheta_fv = {"cos(#theta)","Efficiency #varepsilon","ANNIE Neutron efficiency (FV) "}; + std::vector labels_eff_pT = {"p_{T} [MeV]","Efficiency #varepsilon","ANNIE Neutron efficiency"}; + std::vector labels_eff_pT_fv = {"p_{T} [MeV]","Efficiency #varepsilon","ANNIE Neutron efficiency (FV) "}; + + this->FillSingleTGraph(gr_eff_muonE,h_eff_energy,labels_eff_E); + this->FillSingleTGraph(gr_eff_muonE_zoom,h_eff_energy_zoom,labels_eff_E); + this->FillSingleTGraph(gr_eff_muonE_fv,h_eff_energy_fv,labels_eff_E_fv); + this->FillSingleTGraph(gr_eff_muonE_fv_zoom,h_eff_energy_fv_zoom,labels_eff_E_fv); + this->FillSingleTGraph(gr_eff_costheta,h_eff_costheta,labels_eff_CosTheta); + this->FillSingleTGraph(gr_eff_costheta_fv,h_eff_costheta_fv,labels_eff_CosTheta_fv); + this->FillSingleTGraph(gr_eff_pT,h_eff_pT,labels_eff_pT); + this->FillSingleTGraph(gr_eff_pT_fv,h_eff_pT_fv,labels_eff_pT_fv); + + std::vector labels_muon_E_prim = {"E_{#mu} [MeV]","Primary Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_E_fv_prim= {"E_{#mu} [MeV]","Primary Neutron multiplicity","ANNIE Neutron multiplicity (FV)"}; + std::vector labels_muon_CosTheta_prim = {"cos(#theta)","Primary Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_CosTheta_fv_prim = {"cos(#theta)","Primary Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + std::vector labels_muon_pT_prim = {"p_{T} [MeV]","Primary Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_pT_fv_prim = {"p_{T} [MeV]","Primary Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + this->FillSingleTGraph(gr_primneutrons_muonE,h_primneutrons_energy,labels_muon_E_prim); + this->FillSingleTGraph(gr_primneutrons_muonE_zoom,h_primneutrons_energy_zoom,labels_muon_E_prim); + this->FillSingleTGraph(gr_primneutrons_muonE_fv,h_primneutrons_energy_fv,labels_muon_E_fv_prim); + this->FillSingleTGraph(gr_primneutrons_muonE_fv_zoom,h_primneutrons_energy_fv_zoom,labels_muon_E_fv_prim); + this->FillSingleTGraph(gr_primneutrons_muonCosTheta,h_primneutrons_costheta,labels_muon_CosTheta_prim); + this->FillSingleTGraph(gr_primneutrons_muonCosTheta_fv,h_primneutrons_costheta_fv,labels_muon_CosTheta_fv_prim); + this->FillSingleTGraph(gr_primneutrons_pT,h_primneutrons_pT,labels_muon_pT_prim); + this->FillSingleTGraph(gr_primneutrons_pT_fv,h_primneutrons_pT_fv,labels_muon_pT_fv_prim); + + std::vector labels_muon_E_total = {"E_{#mu} [MeV]","Total Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_E_fv_total= {"E_{#mu} [MeV]","Total Neutron multiplicity","ANNIE Neutron multiplicity (FV)"}; + std::vector labels_muon_CosTheta_total = {"cos(#theta)","Total Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_CosTheta_fv_total = {"cos(#theta)","Total Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + std::vector labels_muon_pT_total = {"p_{T} [MeV]","Total Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_pT_fv_total = {"p_{T} [MeV]","Total Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + this->FillSingleTGraph(gr_totalneutrons_muonE,h_totalneutrons_energy,labels_muon_E_total); + this->FillSingleTGraph(gr_totalneutrons_muonE_zoom,h_totalneutrons_energy_zoom,labels_muon_E_total); + this->FillSingleTGraph(gr_totalneutrons_muonE_fv,h_totalneutrons_energy_fv,labels_muon_E_fv_total); + this->FillSingleTGraph(gr_totalneutrons_muonE_fv_zoom,h_totalneutrons_energy_fv_zoom,labels_muon_E_fv_total); + this->FillSingleTGraph(gr_totalneutrons_muonCosTheta,h_totalneutrons_costheta,labels_muon_CosTheta_total); + this->FillSingleTGraph(gr_totalneutrons_muonCosTheta_fv,h_totalneutrons_costheta_fv,labels_muon_CosTheta_fv_total); + this->FillSingleTGraph(gr_totalneutrons_pT,h_totalneutrons_pT,labels_muon_pT_total); + this->FillSingleTGraph(gr_totalneutrons_pT_fv,h_totalneutrons_pT_fv,labels_muon_pT_fv_total); + + std::vector labels_muon_E_pmtvol = {"E_{#mu} [MeV]","PMTVolume Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_E_fv_pmtvol= {"E_{#mu} [MeV]","PMTVolume Neutron multiplicity","ANNIE Neutron multiplicity (FV)"}; + std::vector labels_muon_CosTheta_pmtvol = {"cos(#theta)","PMTVolume Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_CosTheta_fv_pmtvol = {"cos(#theta)","PMTVolume Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + std::vector labels_muon_pT_pmtvol = {"p_{T} [MeV]","PMTVolume Neutron multiplicity","ANNIE Neutron multiplicity"}; + std::vector labels_muon_pT_fv_pmtvol = {"p_{T} [MeV]","PMTVolume Neutron multiplicity","ANNIE Neutron multiplicity (FV) "}; + this->FillSingleTGraph(gr_pmtvolneutrons_muonE,h_pmtvolneutrons_energy,labels_muon_E_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_muonE_zoom,h_pmtvolneutrons_energy_zoom,labels_muon_E_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_muonE_fv,h_pmtvolneutrons_energy_fv,labels_muon_E_fv_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_muonE_fv_zoom,h_pmtvolneutrons_energy_fv_zoom,labels_muon_E_fv_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_muonCosTheta,h_pmtvolneutrons_costheta,labels_muon_CosTheta_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_muonCosTheta_fv,h_pmtvolneutrons_costheta_fv,labels_muon_CosTheta_fv_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_pT,h_pmtvolneutrons_pT,labels_muon_pT_pmtvol); + this->FillSingleTGraph(gr_pmtvolneutrons_pT_fv,h_pmtvolneutrons_pT_fv,labels_muon_pT_fv_pmtvol); + + + //Correct graphs with efficiencies: + this->CorrectEfficiency(gr_neutrons_muonE,gr_eff_muonE,gr_neutrons_muonE_corr,labels_muon_E); + this->CorrectEfficiency(gr_neutrons_muonE_fv,gr_eff_muonE_fv,gr_neutrons_muonE_corr_fv,labels_muon_E_fv); + this->CorrectEfficiency(gr_neutrons_muonE_zoom,gr_eff_muonE_zoom,gr_neutrons_muonE_corr_zoom,labels_muon_E); + this->CorrectEfficiency(gr_neutrons_muonE_fv_zoom,gr_eff_muonE_fv_zoom,gr_neutrons_muonE_corr_fv_zoom,labels_muon_E_fv); + this->CorrectEfficiency(gr_neutrons_muonCosTheta,gr_eff_costheta,gr_neutrons_muonCosTheta_corr,labels_muon_CosTheta); + this->CorrectEfficiency(gr_neutrons_muonCosTheta_fv,gr_eff_costheta_fv,gr_neutrons_muonCosTheta_corr_fv,labels_muon_CosTheta_fv); + this->CorrectEfficiency(gr_neutrons_pT,gr_eff_pT,gr_neutrons_pT_corr,labels_muon_pT); + this->CorrectEfficiency(gr_neutrons_pT_fv,gr_eff_pT_fv,gr_neutrons_pT_corr_fv,labels_muon_pT_fv); + + return true; +} + +bool NeutronMultiplicity::FillSingleTGraph(TGraphErrors *gr, TH2F *h2d, std::vector labels){ + + if (labels.size() != 3) { + Log("NeutronMultiplicity::FillSingleTGraph: Encountered wrong size for labels vector! Check that the object is defined correctly!",v_error,verbosity); + return false; + } + + int i_graph=0; + int n_bins_x = h2d->GetNbinsX(); + int n_bins_y = h2d->GetNbinsY(); + + TAxis *xaxis = h2d->GetXaxis(); + TAxis *yaxis = h2d->GetYaxis(); + //Get lower end of xaxis -> use first bin + double lower_range = xaxis->GetBinLowEdge(1); + //Get bin width -> any bin possible, but first is always possible + double bin_width = xaxis->GetBinWidth(1); + double bin_width_y = yaxis->GetBinWidth(1); + + for (int i=0; iGetBinContent(i+1,j+1); + mean_n+= (j*bin_width_y*nentries); + n_n += nentries; + } + if (n_n>0){ + mean_n /= n_n; + gr->SetPoint(i_graph,lower_range+(i+0.5)*bin_width,mean_n); + double std_dev = 0; + for (int j=0; jGetBinContent(i+1,j+1); + std_dev+=(nentries*(j*bin_width_y-mean_n)*(j*bin_width_y-mean_n)); + } + if (n_n>1) std_dev/=(n_n-1); + std_dev = sqrt(std_dev); + if (n_n>0) std_dev/=sqrt(n_n); + gr->SetPointError(i_graph,bin_width/2.,std_dev); + i_graph++; + } + } + + std::string title_string = labels.at(2)+";"+labels.at(0)+";"+labels.at(1); + gr->SetTitle(title_string.c_str()); + gr->SetDrawOption("ALP"); + gr->SetLineWidth(2); + + return true; +} + +bool NeutronMultiplicity::CorrectEfficiency(TGraphErrors *gr_original, TGraphErrors *gr_eff, TGraphErrors *gr_new,std::vector labels){ + + //Loop over points in original graph, grab x-values + int n_points = gr_eff->GetN(); + for (int i_point=0; i_point < n_points; i_point++){ + double point_x; + double original_value; + double eff_value; + double original_errorx, original_errory; + double errory; + + gr_eff->GetPoint(i_point,point_x,eff_value); + gr_original->GetPoint(i_point,point_x,original_value); + original_errorx = gr_original->GetErrorX(i_point); + original_errory = gr_original->GetErrorY(i_point); + double new_value = (eff_value > 0)? original_value/eff_value : original_value; + errory = (eff_value > 0)? original_errory/eff_value : original_errory; + gr_new->SetPoint(i_point,point_x,new_value); + gr_new->SetPointError(i_point,original_errorx,errory); + } + + std::string title_string = labels.at(2)+";"+labels.at(0)+";"+labels.at(1); + gr_new->SetTitle(title_string.c_str()); + gr_new->SetDrawOption("ALP"); + gr_new->SetLineWidth(2); + + return true; + +} diff --git a/UserTools/NeutronMultiplicity/NeutronMultiplicity.h b/UserTools/NeutronMultiplicity/NeutronMultiplicity.h new file mode 100644 index 000000000..93392784b --- /dev/null +++ b/UserTools/NeutronMultiplicity/NeutronMultiplicity.h @@ -0,0 +1,327 @@ +#ifndef NeutronMultiplicity_H +#define NeutronMultiplicity_H + +#include +#include +#include + +#include "Tool.h" + +#include "Particle.h" +#include "Position.h" +#include "RecoVertex.h" + +#include "TTree.h" +#include "TFile.h" +#include "TH1.h" +#include "TH2.h" +#include "TH3.h" +#include "TGraph.h" +#include "TGraphErrors.h" +#include "TMath.h" + +/** + * \class NeutronMultiplicity + * + * 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: M.Nieslony $ +* $Date: 2023/02/18 10:44:00 $ +* Contact: mnieslon@uni-mainz.de +*/ + +class NeutronMultiplicity: public Tool { + + + public: + + NeutronMultiplicity(); ///< 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 InitialiseHistograms(); ///< Initialise root histograms & file + bool SaveBoostStore(); ///< Save variables to BoostStore + bool ReadBoostStore(); ///< Read variables from BoostStore + bool FillHistograms(); ///< Fill histograms & save to root file + bool GetParticleInformation(); ///< Get reconstructed information about muon vertex + bool GetClusterInformation(); ///< Get reconstructed information about clusters + bool GetMCTruthInformation(); ///< Get MCTruth variables (only called for MC files) + bool ResetVariables(); ///< Reset variables every Execute step + bool FillTGraphs(); ///< Fill TGraph objects + bool FillSingleTGraph(TGraphErrors *gr, TH2F *h2d, std::vector labels); ////< Fill TGraph based on averaging a 2D histogra + bool CorrectEfficiency(TGraphErrors *gr_original, TGraphErrors *gr_eff, TGraphErrors *gr_new,std::vector labels); ///< Correct neutron multiplicity with efficiency + + private: + + //configuration variables + int verbosity; + bool save_root; + bool save_bs; + std::string filename; + bool mrdtrack_restriction = false; + std::string read_bs; + + //MC configuration variable -> automatic detection + bool isMC; + + //root file variables + TFile *file_neutronmult = nullptr; + + //BoostStore file variable + BoostStore *store_neutronmult = nullptr; + BoostStore *read_neutronmult = nullptr; + bool need_new_file_; + size_t current_file_; + size_t total_entries_in_file_; + size_t current_entry_; + std::vector input_filenames_; + + //Reconstruction variables + int SimpleRecoFlag; + Position SimpleRecoVtx; + Position SimpleRecoStopVtx; + double SimpleRecoEnergy; + double SimpleRecoCosTheta; + double SimpleRecoPt; + bool SimpleRecoFV; + double SimpleRecoMrdEnergyLoss; + double SimpleRecoTrackLengthInMRD; + Position SimpleRecoMRDStart; + Position SimpleRecoMRDStop; + int NumberNeutrons; + std::vector Particles; + uint32_t EventNumber; + int RunNumber; + int numtracksinev; + + std::vector cluster_neutron; + std::vector cluster_times_neutron; + std::vector cluster_charges_neutron; + std::vector cluster_cb_neutron; + std::vector cluster_times; + std::vector cluster_charges; + std::vector cluster_cb; + bool passPMTMRDCoincCut; + + std::map,double> neutron_eff_map; + TH3F *hist_neutron_eff = nullptr; + bool neutron_hist_filled = false; + + //MCTruth variables + std::map>> MCNeutCapGammas; + std::map> MCNeutCap; + bool IsMultiRing = false; + RecoVertex* truevtx = nullptr; + std::string MCFile; + RecoVertex true_vertex; + + //histogram variables + TH1F *h_time_neutrons = nullptr; + TH1F *h_time_neutrons_mrdstop = nullptr; + TH1F *h_neutrons = nullptr; + TH1F *h_neutrons_mrdstop = nullptr; + TH1F *h_neutrons_mrdstop_fv = nullptr; + TH2F *h_neutrons_energy = nullptr; + TH2F *h_neutrons_energy_fv = nullptr; + TH2F *h_neutrons_energy_zoom = nullptr; + TH2F *h_neutrons_energy_fv_zoom = nullptr; + TH2F *h_primneutrons_energy = nullptr; + TH2F *h_primneutrons_energy_fv = nullptr; + TH2F *h_primneutrons_energy_zoom = nullptr; + TH2F *h_primneutrons_energy_fv_zoom = nullptr; + TH2F *h_totalneutrons_energy = nullptr; + TH2F *h_totalneutrons_energy_fv = nullptr; + TH2F *h_totalneutrons_energy_zoom = nullptr; + TH2F *h_totalneutrons_energy_fv_zoom = nullptr; + TH2F *h_pmtvolneutrons_energy = nullptr; + TH2F *h_pmtvolneutrons_energy_fv = nullptr; + TH2F *h_pmtvolneutrons_energy_zoom = nullptr; + TH2F *h_pmtvolneutrons_energy_fv_zoom = nullptr; + TH2F *h_neutrons_costheta = nullptr; + TH2F *h_neutrons_costheta_fv = nullptr; + TH2F *h_primneutrons_costheta = nullptr; + TH2F *h_primneutrons_costheta_fv = nullptr; + TH2F *h_totalneutrons_costheta = nullptr; + TH2F *h_totalneutrons_costheta_fv = nullptr; + TH2F *h_pmtvolneutrons_costheta = nullptr; + TH2F *h_pmtvolneutrons_costheta_fv = nullptr; + TH2F *h_neutrons_pT = nullptr; + TH2F *h_neutrons_pT_fv = nullptr; + TH2F *h_primneutrons_pT = nullptr; + TH2F *h_primneutrons_pT_fv = nullptr; + TH2F *h_totalneutrons_pT = nullptr; + TH2F *h_totalneutrons_pT_fv = nullptr; + TH2F *h_pmtvolneutrons_pT = nullptr; + TH2F *h_pmtvolneutrons_pT_fv = nullptr; + TH2F *h_eff_energy = nullptr; + TH2F *h_eff_energy_fv = nullptr; + TH2F *h_eff_energy_zoom = nullptr; + TH2F *h_eff_energy_fv_zoom = nullptr; + TH2F *h_eff_costheta = nullptr; + TH2F *h_eff_costheta_fv = nullptr; + TH2F *h_eff_pT = nullptr; + TH2F *h_eff_pT_fv = nullptr; + + TH1F *h_muon_energy = nullptr; + TH1F *h_muon_energy_fv = nullptr; + TH2F *h_muon_vtx_yz = nullptr; + TH2F *h_muon_vtx_xz = nullptr; + TH1F *h_muon_costheta = nullptr; + TH1F *h_muon_costheta_fv = nullptr; + TH1F *h_muon_vtx_x = nullptr; + TH1F *h_muon_vtx_y = nullptr; + TH1F *h_muon_vtx_z = nullptr; + + //graph variables + TGraphErrors *gr_neutrons_muonE = nullptr; + TGraphErrors *gr_neutrons_muonE_fv = nullptr; + TGraphErrors *gr_neutrons_muonE_zoom = nullptr; + TGraphErrors *gr_neutrons_muonE_fv_zoom = nullptr; + TGraphErrors *gr_neutrons_muonCosTheta = nullptr; + TGraphErrors *gr_neutrons_muonCosTheta_fv = nullptr; + TGraphErrors *gr_neutrons_pT = nullptr; + TGraphErrors *gr_neutrons_pT_fv = nullptr; + + //graph variables - MC + TGraphErrors *gr_primneutrons_muonE = nullptr; + TGraphErrors *gr_totalneutrons_muonE = nullptr; + TGraphErrors *gr_pmtvolneutrons_muonE = nullptr; + TGraphErrors *gr_primneutrons_muonE_fv = nullptr; + TGraphErrors *gr_totalneutrons_muonE_fv = nullptr; + TGraphErrors *gr_pmtvolneutrons_muonE_fv = nullptr; + TGraphErrors *gr_primneutrons_muonE_zoom = nullptr; + TGraphErrors *gr_totalneutrons_muonE_zoom = nullptr; + TGraphErrors *gr_pmtvolneutrons_muonE_zoom = nullptr; + TGraphErrors *gr_primneutrons_muonE_fv_zoom = nullptr; + TGraphErrors *gr_totalneutrons_muonE_fv_zoom = nullptr; + TGraphErrors *gr_pmtvolneutrons_muonE_fv_zoom = nullptr; + TGraphErrors *gr_primneutrons_muonCosTheta = nullptr; + TGraphErrors *gr_totalneutrons_muonCosTheta = nullptr; + TGraphErrors *gr_pmtvolneutrons_muonCosTheta = nullptr; + TGraphErrors *gr_primneutrons_muonCosTheta_fv = nullptr; + TGraphErrors *gr_totalneutrons_muonCosTheta_fv = nullptr; + TGraphErrors *gr_pmtvolneutrons_muonCosTheta_fv = nullptr; + TGraphErrors *gr_primneutrons_pT = nullptr; + TGraphErrors *gr_totalneutrons_pT = nullptr; + TGraphErrors *gr_pmtvolneutrons_pT = nullptr; + TGraphErrors *gr_primneutrons_pT_fv = nullptr; + TGraphErrors *gr_totalneutrons_pT_fv = nullptr; + TGraphErrors *gr_pmtvolneutrons_pT_fv = nullptr; + + //graph variables - efficiency + TGraphErrors *gr_eff_muonE = nullptr; + TGraphErrors *gr_eff_muonE_fv = nullptr; + TGraphErrors *gr_eff_muonE_zoom = nullptr; + TGraphErrors *gr_eff_muonE_fv_zoom = nullptr; + TGraphErrors *gr_eff_costheta = nullptr; + TGraphErrors *gr_eff_costheta_fv = nullptr; + TGraphErrors *gr_eff_pT = nullptr; + TGraphErrors *gr_eff_pT_fv = nullptr; + + //graph variables - corrected + TGraphErrors *gr_neutrons_muonE_corr = nullptr; + TGraphErrors *gr_neutrons_muonE_corr_fv = nullptr; + TGraphErrors *gr_neutrons_muonE_corr_zoom = nullptr; + TGraphErrors *gr_neutrons_muonE_corr_fv_zoom = nullptr; + TGraphErrors *gr_neutrons_muonCosTheta_corr = nullptr; + TGraphErrors *gr_neutrons_muonCosTheta_corr_fv = nullptr; + TGraphErrors *gr_neutrons_pT_corr = nullptr; + TGraphErrors *gr_neutrons_pT_corr_fv = nullptr; + + //directory variables + TDirectory *dir_overall = nullptr; + TDirectory *dir_muon = nullptr; + TDirectory *dir_neutron = nullptr; + TDirectory *dir_mc = nullptr; + TDirectory *dir_eff = nullptr; + TDirectory *dir_graph = nullptr; + TDirectory *dir_graph_mc = nullptr; + TDirectory *dir_graph_eff = nullptr; + TDirectory *dir_graph_corr = nullptr; + + //tree variables + // + TTree *neutron_tree = nullptr; + //true tree variables + int true_PrimNeut; + int true_PrimProt; + int true_NCaptures; + int true_NCapturesPMTVol; + double true_VtxX; + double true_VtxY; + double true_VtxZ; + double true_VtxTime; + double true_DirX; + double true_DirY; + double true_DirZ; + double true_Emu; + double true_Enu; + double true_Q2; + double true_pT; + int true_FV; + double true_CosTheta; + double true_TrackLengthInWater; + double true_TrackLengthInMRD; + std::vector *true_NeutVtxX = nullptr; + std::vector *true_NeutVtxY = nullptr; + std::vector *true_NeutVtxZ = nullptr; + std::vector *true_NeutCapNucl = nullptr; + std::vector *true_NeutCapTime = nullptr; + std::vector *true_NeutCapETotal = nullptr; + std::vector *true_NeutCapNGamma = nullptr; + std::vector *true_NeutCapPrimary = nullptr; + int true_CC; + int true_QEL; + int true_DIS; + int true_RES; + int true_COH; + int true_MEC; + int true_MultiRing; + std::vector *true_PrimaryPdgs = nullptr; + std::vector vec_true_PrimaryPdgs; + int true_PdgPrimary; + + //reco tree variables + double reco_Emu; + double reco_Enu; + double reco_Q2; + double reco_pT; + std::vector *reco_ClusterCB = nullptr; + std::vector *reco_ClusterTime = nullptr; + std::vector *reco_ClusterPE = nullptr; + std::vector *reco_NCandCB = nullptr; + std::vector *reco_NCandTime = nullptr; + std::vector *reco_NCandPE = nullptr; + double reco_MrdEnergyLoss; + double reco_TrackLengthInMRD; + double reco_MrdStartX; + double reco_MrdStartY; + double reco_MrdStartZ; + double reco_MrdStopX; + double reco_MrdStopY; + double reco_MrdStopZ; + int reco_TankMRDCoinc; + int reco_Clusters; + int reco_NCandidates; + double reco_VtxX; + double reco_VtxY; + double reco_VtxZ; + int reco_FV; + double reco_CosTheta; + + //general event variables + int run_nr; + int ev_nr; + + //verbosity variables + int v_error = 0; + int v_warning = 1; + int v_message = 2; + int v_debug = 3; + int vv_debug = 4; + +}; + + +#endif diff --git a/UserTools/NeutronMultiplicity/README.md b/UserTools/NeutronMultiplicity/README.md new file mode 100644 index 000000000..10fc39260 --- /dev/null +++ b/UserTools/NeutronMultiplicity/README.md @@ -0,0 +1,63 @@ +# NeutronMultiplicity + +The `NeutronMultiplicity` creates the plots of the neutron multiplicity analysis and has the possibility of storing them to an output ROOT file or an output BoostStore file (or both). + +## Input data + +The `NeutronMultiplicity` tool can be operated in two modes: Either in a toolchain where the necessary reconstruction tools are included, or as a single-handed tool when the neutron reconstruction information was already saved beforehand in BoostStores. + +The complete toolchain (`configfiles/NeutronMultiplicity/ToolsConfig`) includes the following tools: +* LoadANNIEEvent +* LoadGeometry +* TimeClustering +* FindMrdTracks +* ClusterFinder +* ClusterClassifiers +* EventSelector +* SimpleReconstruction +* FindNeutrons +* NeutronMultiplicity + +The single-handed toolchain relies on BoostStores created beforehand by the full toolchain mentioned above. If those are present, the `ReadFromBoostStore` toolchain (`configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolChainConfig`) can be used. + +## Output data + +The neutron multiplicity tool will fill the information about the neutron multiplicity and the muon properties in histograms and graphs and save them to the output ROOT file. The output ROOT file is structed into the following directories: +* hist_muon: Histograms about the reconstructed muon properties +* hist_neutron: Histograms about the reconstructed neutron properties +* hist_mc: Histograms about MC specific properties +* hist_eff: Histograms about the neutron detection efficiency as a function of muon properties +* graph_neutron: Resulting graphs showing the neutron multiplicity as a function of the muon properties +* graph_neutron_mc: Resulting graphs showing the TRUE neutron multiplicity as a function of the RECONSTRUCTED muon properties. True neutron multiplicity is divided into three categories: primary (number of primary neutrons), total (number of neutron captures from all primary + secondary neutrons in the whole experiment volume), pmtvol (primary + secondary neutron captures, but restricted to the water volume) +* graph_neutron_eff: Efficiency graphs +* graph_neutron_corr: Neutron multiplicity graphs, corrected by efficiency graphs +* neutron_tree: the neutron_tree saves the information additionally in the form of a TTree for more interactive investigations + +## Configuration variables + +The configuration options for the `NeutronMultiplicity` tool are listed below: + +``` +verbosity 1 #verbosity setting + +SaveROOT 0/1 +#should an output ROOT file be produced? +#This ROOT file will contain all the histograms, graphs, and a tree + +SaveBoostStore 0/1 +#Should an output BoostStore be produced? +#The BoostStore will store all the necessary variables needed to create the plots in an output BoostStore file +#The BoostStores can then be read in later via the ReadFromBoostStore option (see below) +#Saving to a BoostStore is very convenient since it will allow to first run the ToolChain for each run separately, and then read in all the BoostStores again afterwards to combine all the information + +Filename filename +#This is the output filename string +#For output rootfiles, .root will be appended, for output BoostStore files, .bs will be appended + +ReadFromBoostStore None/filelist.txt +#This option can be used to read the neutron multiplicity information from a list of BoostStore files +#If this option is selected, make sure to only have the NeutronMultiplicity tool in your toolchain, no LoadANNIEEvent or reconstruction tools (since the reconstruction information is already saved to the input BoostStores) + +MRDTRackRestriction 0/1 +#Selection variable which describes whether only events with 1 MRD track should be considered for the analysis. +``` diff --git a/UserTools/SimpleReconstruction/README.md b/UserTools/SimpleReconstruction/README.md new file mode 100644 index 000000000..a01f6ee05 --- /dev/null +++ b/UserTools/SimpleReconstruction/README.md @@ -0,0 +1,41 @@ +# SimpleReconstruction + +The `SimpleReconstruction` tool performs a simple reconstruction of the muon vertex and energy properties based on the observed MRD track properties. The main principle is the back-propagation of the muon-track into the water tank volume based on the amount of observed light in the main detector. Please note that this method requires a stopping track in the MRD and does not work for any other event topologies. + +## Input data + +The tool first checks whether there was coincident tank and MRD activity by getting the "MRDCoincidenceCluster" variable from the ANNIEEvent store. It then checks whether there was a corresponding reconstructed MRD track which also stopped in the MRD. For this purpose, the MRD reconstruction variables are obtained from the "MRDTracks" BoostStore. + +In case there is a stopping MRD track found, the reconstruction proceeds and uses the energy loss in the MRD, the observed light level in the tank and fit parameters obtained in MC simulations in order to predict the muon energy: + +``` +E_mu [MeV] = 87.3MeV + 200 MeV/cm x dist_pmtvol_tank + Eloss(MRD) + Qmax*0.08534 MeV/p.e. +``` + +The vertex is subsequently reconstructed via + +``` +vtx = vtx(exit) - Qmax/9/200. x dir(track) +``` + +## Output data + +The reconstruction properties are then added to the ANNIEEvent store directly via the following variables: +* SimpleRecoFlag (`int`): flags whether reconstruction was successful. 1 if successful, -9999 if not. +* SimpleRecoEnergy (`double`): reconstructed muon energy (in MeV) +* SimpleRecoVtx (`Position`): reconstructed muon vertex +* SimpleRecoStopVtx (`Position`): reconstructed muon stop position (per selection definition in the MRD) +* SimpleRecoCosTheta (`double`): reconstructed cos(theta) of muon direction with respect to beam direction (0,0,1) +* SimpleRecoFV (`bool`): was the reconstructed muon vertex in the Fiducial Volume? +* SimpleRecoMrdEnergyLoss (`double`): reconstructed energy loss in the MRD (in MeV) + +Furthermore, the tool also adds the reconstructed muon as a `Particle` object to the Particles vector in the ANNIEEvent store. +* Particles (`std::vector`): add muon as a `Particle` to the vector. + +## Configuration variables + +Currently, the `SimpleReconstruction` tool only has a verbosity setting, but no other configuration variables. + +``` +verbosity 1 +``` diff --git a/UserTools/SimpleReconstruction/SimpleReconstruction.cpp b/UserTools/SimpleReconstruction/SimpleReconstruction.cpp new file mode 100644 index 000000000..a512f4afe --- /dev/null +++ b/UserTools/SimpleReconstruction/SimpleReconstruction.cpp @@ -0,0 +1,390 @@ +#include "SimpleReconstruction.h" + +SimpleReconstruction::SimpleReconstruction():Tool(){} + + +bool SimpleReconstruction::Initialise(std::string configfile, DataModel &data){ + + if(configfile!="") m_variables.Initialise(configfile); // loading config file + m_data= &data; //assigning transient data pointer + + m_variables.Get("verbosity",verbosity); + + return true; +} + + +bool SimpleReconstruction::Execute(){ + + //Set default values for reconstruction variables + this->SetDefaultValues(); + + //Get ANNIEEvent variables which are necessary for reconstruction + bool get_annie = this->GetANNIEEventVariables(); + + //Check which track id should be considered + m_data->Stores.at("RecoEvent")->Get("PromptMuonTotalPE",max_pe); + + std::vector vector_clusterid; + m_data->Stores["RecoEvent"]->Get("MRDCoincidenceCluster",vector_clusterid); + + bool reco_possible = this->RecoTankExitPoint(vector_clusterid); + + //Only proceed with reconstructed if extrapolated MRD track passes the tank + if (reco_possible){ + + //Do simple energy reconstruction + this->SimpleEnergyReconstruction(); + + //Do simple vertex reconstruction + this->SimpleVertexReconstruction(); + } + + //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); + + //Fill Particles object with muon + if (reco_possible){ + + //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("SimpleReconstruction: Added muon with the following properties as a particle:",v_message,verbosity); + muon.Print(); + } + + //Add muon particle to Particles collection + std::vector Particles; + bool 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); + } + + return true; +} + + +bool SimpleReconstruction::Finalise(){ + + return true; +} + +void SimpleReconstruction::SetDefaultValues(){ + + //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); + + //Helper variables + mrd_eloss = -9999; + mrd_tracklength = -9999; + dist_pmtvol_tank = -9999; + max_pe = -9999; + exitx = -9999; + exity = -9999; + exitz = -9999; + dirx = -9999; + diry = -9999; + dirz = -9999; + + // Clear vectors + fMRDTrackAngle.clear(); + fMRDTrackAngleError.clear(); + fMRDTrackLength.clear(); + fMRDPenetrationDepth.clear(); + fMRDEntryPointRadius.clear(); + fMRDEnergyLoss.clear(); + fMRDEnergyLossError.clear(); + fMRDTrackStartX.clear(); + fMRDTrackStartY.clear(); + fMRDTrackStartZ.clear(); + fMRDTrackStopX.clear(); + fMRDTrackStopY.clear(); + fMRDTrackStopZ.clear(); + fMRDStop.clear(); + fMRDSide.clear(); + fMRDThrough.clear(); + fMRDTrackEventID.clear(); + +} + +bool SimpleReconstruction::GetANNIEEventVariables(){ + + //Get MRD track reco variables + PMT information from BoostStores + + //MRD reco variables + Position StartVertex; + Position StopVertex; + double TrackLength = -9999; + double TrackAngle = -9999; + double TrackAngleError = -9999; + double PenetrationDepth = -9999; + Position MrdEntryPoint; + double EnergyLoss = -9999; //in MeV + double EnergyLossError = -9999; + double EntryPointRadius = -9999; + bool IsMrdPenetrating; + bool IsMrdStopped; + bool IsMrdSideExit; + int numtracksinev; + int TrackEventID = -1; + std::vector* theMrdTracks; + + bool get_annie = true; + + std::vector> MrdTimeClusters; + get_annie = m_data->CStore.Get("MrdTimeClusters",MrdTimeClusters); + if (!get_annie) { + Log("SimpleReconstruction tool: No MrdTimeClusters object in CStore! Did you run TimeClustering beforehand?",v_warning,verbosity); + return false; + } else if (MrdTimeClusters.size()==0){ + Log("SimpleReconstruction tool: MrdTimeClusters object is empty! Don't proceed with reconstruction...",vv_debug,verbosity); + return false; + } + + m_data->Stores["MRDTracks"]->Get("MRDTracks",theMrdTracks); + m_data->Stores["MRDTracks"]->Get("NumMrdTracks",numtracksinev); + + int NumClusterTracks = 0; + + for(int tracki=0; trackiat(tracki)); + + thisTrackAsBoostStore->Get("StartVertex",StartVertex); + thisTrackAsBoostStore->Get("StopVertex",StopVertex); + thisTrackAsBoostStore->Get("TrackAngle",TrackAngle); + thisTrackAsBoostStore->Get("TrackAngleError",TrackAngleError); + thisTrackAsBoostStore->Get("PenetrationDepth",PenetrationDepth); + thisTrackAsBoostStore->Get("MrdEntryPoint",MrdEntryPoint); + thisTrackAsBoostStore->Get("EnergyLoss",EnergyLoss); + thisTrackAsBoostStore->Get("EnergyLossError",EnergyLossError); + thisTrackAsBoostStore->Get("IsMrdPenetrating",IsMrdPenetrating); // bool + thisTrackAsBoostStore->Get("IsMrdStopped",IsMrdStopped); // bool + thisTrackAsBoostStore->Get("IsMrdSideExit",IsMrdSideExit); + thisTrackAsBoostStore->Get("MrdSubEventID",TrackEventID); + TrackLength = sqrt(pow((StopVertex.X()-StartVertex.X()),2)+pow(StopVertex.Y()-StartVertex.Y(),2)+pow(StopVertex.Z()-StartVertex.Z(),2)) * 100.0; + EntryPointRadius = sqrt(pow(MrdEntryPoint.X(),2) + pow(MrdEntryPoint.Y(),2)) * 100.0; // convert to cm + PenetrationDepth = PenetrationDepth*100.0; + + fMRDTrackAngle.push_back(TrackAngle); + fMRDTrackAngleError.push_back(TrackAngleError); + fMRDTrackLength.push_back(TrackLength); + fMRDPenetrationDepth.push_back(PenetrationDepth); + fMRDEntryPointRadius.push_back(EntryPointRadius); + fMRDEnergyLoss.push_back(EnergyLoss); + fMRDEnergyLossError.push_back(EnergyLossError); + fMRDTrackStartX.push_back(StartVertex.X()); + fMRDTrackStartY.push_back(StartVertex.Y()); + fMRDTrackStartZ.push_back(StartVertex.Z()); + fMRDTrackStopX.push_back(StopVertex.X()); + fMRDTrackStopY.push_back(StopVertex.Y()); + fMRDTrackStopZ.push_back(StopVertex.Z()); + fMRDStop.push_back(IsMrdStopped); + fMRDSide.push_back(IsMrdSideExit); + fMRDThrough.push_back(IsMrdPenetrating); + fMRDTrackEventID.push_back(TrackEventID); + NumClusterTracks+=1; + } + + return true; + +} + +bool SimpleReconstruction::RecoTankExitPoint(std::vector clusterid_vec){ + + bool tank_exit = true; + int trackid = -1; + + for (int i_clusterid=0; i_clusterid < (int)clusterid_vec.size(); i_clusterid++) { + + int clusterid = clusterid_vec.at(i_clusterid); + + for (int i = 0; i < (int) fMRDTrackEventID.size(); i++){ + if (fMRDTrackEventID.at(i) == clusterid) { + Log("SimpleReconstruction:RecoTankExitPoint: Found corresponding track id >>> "+std::to_string(i)+"<<< for cluster id "+std::to_string(clusterid)+"! Proceeding with extracting MRD track information...",v_message,verbosity); + trackid = i; + } + } + } + + if (trackid == -1) { + Log("SimpleReconstruction tool: Did not find corresponding track id for MRD clusterids. Abort reconstruction...",vv_debug,verbosity); + return false; + } + + //Check if track exited from the tank + double startx = fMRDTrackStartX.at(trackid); + double starty = fMRDTrackStartY.at(trackid); + double startz = fMRDTrackStartZ.at(trackid); + double stopx = fMRDTrackStopX.at(trackid); + double stopy = fMRDTrackStopY.at(trackid); + double stopz = fMRDTrackStopZ.at(trackid); + + SimpleRecoMRDStart.SetX(startx); + SimpleRecoMRDStart.SetY(starty); + SimpleRecoMRDStart.SetZ(startz); + SimpleRecoMRDStop.SetX(stopx); + SimpleRecoMRDStop.SetY(stopy); + SimpleRecoMRDStop.SetZ(stopz); + SimpleRecoTrackLengthInMRD = sqrt((stopx-startx)*(stopx-startx)+(stopy-starty)*(stopy-starty)+(stopz-startz)*(stopz-startz)); + + + //Calculate intersection point parameter t + bool hit_tank = false; + double diffx = stopx-startx; + double diffy = stopy-starty; + double diffz = stopz-startz; + double startz_c = startz-1.681; + double a = pow(diffx,2)+pow(diffz,2); + double b = -2*diffx*startx-2*diffz*startz_c; + double c = pow(startx,2)+pow(startz_c,2)-1.0*1.0; + double t1 = (-b+sqrt(b*b-4*a*c))/(2*a); + double t2 = (-b-sqrt(b*b-4*a*c))/(2*a); + double t = 0; + if (t1 < 0) t = t2; + else if (t2 < 0) t = t1; + else t = (t1 < t2)? t1 : t2; + + //Calculate exit point + exitx = startx - t*diffx; + exity = starty - t*diffy; + exitz = startz - t*diffz; + dirx = diffx/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + diry = diffy/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + dirz = diffz/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + SimpleRecoCosTheta = dirz; + + //Calculate different distances + //dist_mrd: distance traveled in MRD + //dist_air: distance traveled in air + + double dist_mrd = sqrt(pow(startx-stopx,2)+pow(starty-stopy,2)+pow(startz-stopz,2)); + double dist_air = sqrt(pow(startx-exitx,2)+pow(starty-exity,2)+pow(startz-exitz,2)); + double dist_air_x = sqrt(pow(startx-exitx,2)); + double dist_air_y = sqrt(pow(starty-exity,2)); + double dist_air_z = sqrt(pow(startz-exitz,2)); + + double ap = pow(diffx,2)+pow(diffz,2); + double bp = -2*diffx*startx-2*diffz*startz_c; + double cp = pow(startx,2)+pow(startz_c,2)-1.5*1.5; + double t1p = (-bp+sqrt(bp*bp-4*ap*cp))/(2*ap); + double t2p = (-bp-sqrt(bp*bp-4*ap*cp))/(2*ap); + double tp = 0; + if (t1p < 0) tp = t2p; + else if (t2p < 0) tp = t1p; + else tp = (t1p < t2p)? t1p : t2p; + + double exitxp = startx - tp*diffx; + double exityp = starty - tp*diffy; + double exitzp = startz - tp*diffz; + + double diff_exit_x = exitxp - exitx; + double diff_exit_y = exityp - exity; + double diff_exit_z = exitzp - exitz; + + //Cannot proceed with reconstruction for tracks which do not have a stopping track in the MRD -> set flag to false + if (fMRDStop.at(trackid) == false){ + tank_exit = false; + Log("SimpleReconstruction: Event does not have a stopping track in the MRD! Abort reconstruction",v_message,verbosity); + } + + mrd_eloss = fMRDEnergyLoss.at(trackid); + mrd_tracklength = fMRDTrackLength.at(trackid)/100; + dist_pmtvol_tank = sqrt(pow(diff_exit_x,2)+pow(diff_exit_y,2)+pow(diff_exit_z,2)); + + if (tank_exit == true){ + Log("SimpleReconstruction: Proceeding with reconstruction for event with stopping muon track in MRD. Eloss (MRD) = "+std::to_string(mrd_eloss)+" MeV, d (MRD) = "+std::to_string(mrd_tracklength)+" m, d (PMTVol - Tank) = "+std::to_string(dist_pmtvol_tank),v_message,verbosity); + + SimpleRecoStopVtx.SetX(stopx); + SimpleRecoStopVtx.SetY(stopy); + SimpleRecoStopVtx.SetZ(stopz); + SimpleRecoFlag = 1; + } + + return tank_exit; +} + +bool SimpleReconstruction::SimpleEnergyReconstruction(){ + + Log("SimpleReconstruction tool: SimpleEnergyReconstruction",v_message,verbosity); + Log("SimpleReconstruction tool: Conditions: dist (pmtvol - tank) = "+std::to_string(dist_pmtvol_tank)+" m, MRD Eloss = "+std::to_string(mrd_eloss)+" MeV, Qmax = "+std::to_string(max_pe)+" p.e.",v_message,verbosity); + + SimpleRecoEnergy = 87.3 + 200*(dist_pmtvol_tank) + mrd_eloss + max_pe*0.08534; + + Log("SimpleEnergyReconstruction: Reconstructed muon energy: "+std::to_string(SimpleRecoEnergy),v_message,verbosity); + + SimpleRecoMrdEnergyLoss = mrd_eloss; + + //Also calculate transverse muon momentum + double SimpleRecoTotalEnergy = SimpleRecoEnergy + 105.6; + SimpleRecoPt = sqrt((1-SimpleRecoCosTheta*SimpleRecoCosTheta)*(SimpleRecoTotalEnergy*SimpleRecoTotalEnergy-105.6*105.6)); + + return true; + +} + +bool SimpleReconstruction::SimpleVertexReconstruction(){ + + Log("SimpleReconstruction tool: SimpleVertexReconstruction",v_message,verbosity); + Log("Conditions: Exit Position = ("+std::to_string(exitx)+","+std::to_string(exity)+","+std::to_string(exitz)+"), Direction = ("+std::to_string(dirx)+","+std::to_string(diry)+","+std::to_string(dirz)+", Qmax = "+std::to_string(max_pe)+" p.e.",v_message,verbosity); + + double reco_vtx_x = exitx - max_pe/9/2./100.*dirx; + double reco_vtx_y = exity - max_pe/9/2./100.*diry; + double reco_vtx_z = exitz - max_pe/9/2./100.*dirz; + SimpleRecoVtx.SetX(reco_vtx_x); + SimpleRecoVtx.SetY(reco_vtx_y); + SimpleRecoVtx.SetZ(reco_vtx_z); + + 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 + if (sqrt(reco_vtx_x*reco_vtx_x+(reco_vtx_z-1.681)*(reco_vtx_z-1.681))<1.0 && fabs(reco_vtx_y)<0.5 && ((reco_vtx_z-1.681) < 0.)) SimpleRecoFV = true; + + return true; + +} diff --git a/UserTools/SimpleReconstruction/SimpleReconstruction.h b/UserTools/SimpleReconstruction/SimpleReconstruction.h new file mode 100644 index 000000000..c26c9aa5b --- /dev/null +++ b/UserTools/SimpleReconstruction/SimpleReconstruction.h @@ -0,0 +1,94 @@ +#ifndef SimpleReconstruction_H +#define SimpleReconstruction_H + +#include +#include + +#include "Tool.h" +#include "Position.h" + +/** + * \class SimpleReconstruction + * + * 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: M. Nieslony $ +* $Date: 2023/01/25 10:44:00 $ +* Contact: mnieslon@uni-mainz.de +*/ +class SimpleReconstruction: public Tool { + + + public: + + SimpleReconstruction(); ///< 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 SetDefaultValues(); ///< Set default values for SimpleReconstruction + bool SimpleEnergyReconstruction(); ///< Simple energy reconstruction for muon energy + bool SimpleVertexReconstruction(); ///< Simple vertex reconstruction for neutrino interaction vertex + bool GetANNIEEventVariables(); ////< get relevant variables from ANNIEEvent store + bool RecoTankExitPoint(std::vector clusterid); ////< Reconstruct the tank exit point of the muon + + private: + + //configuration variables + int verbosity; + + //reconstruction variables + int SimpleRecoFlag; + double SimpleRecoEnergy; + Position SimpleRecoVtx; + Position SimpleRecoStopVtx; + double SimpleRecoCosTheta; + double SimpleRecoPt; + bool SimpleRecoFV; + double SimpleRecoMrdEnergyLoss; + double SimpleRecoTrackLengthInMRD; + Position SimpleRecoMRDStart; + Position SimpleRecoMRDStop; + + //event variables + std::vector fMRDTrackAngle; + std::vector fMRDTrackAngleError; + std::vector fMRDTrackLength; + std::vector fMRDPenetrationDepth; + std::vector fMRDEntryPointRadius; + std::vector fMRDEnergyLoss; + std::vector fMRDEnergyLossError; + std::vector fMRDTrackStartX; + std::vector fMRDTrackStartY; + std::vector fMRDTrackStartZ; + std::vector fMRDTrackStopX; + std::vector fMRDTrackStopY; + std::vector fMRDTrackStopZ; + std::vector fMRDStop; + std::vector fMRDSide; + std::vector fMRDThrough; + std::vector fMRDTrackEventID; + + double dist_pmtvol_tank; + double mrd_eloss; + double max_pe; + double mrd_tracklength; + double exitx; + double exity; + double exitz; + double dirx; + double diry; + double dirz; + + //verbosity variables + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + int vv_debug=4; + + +}; + + +#endif diff --git a/UserTools/TimeClustering/TimeClustering.cpp b/UserTools/TimeClustering/TimeClustering.cpp index fdb960e6c..dd88d121a 100644 --- a/UserTools/TimeClustering/TimeClustering.cpp +++ b/UserTools/TimeClustering/TimeClustering.cpp @@ -228,7 +228,7 @@ bool TimeClustering::Execute(){ return true; } } else { - std::cout <<"TimeClustering tool: MC file: Getting TDCData object"< 0) std::cout <<"TimeClustering tool: MC file: Getting TDCData object"<Stores.at("ANNIEEvent")->Get("TDCData_mod",TDCData_MC); // a std::map>, with artificially applied efficiencies else get_ok = m_data->Stores.at("ANNIEEvent")->Get("TDCData",TDCData_MC); // a std::map>, without artifically applied efficiencies if(not get_ok){ diff --git a/UserTools/Unity.h b/UserTools/Unity.h index 6994cfab4..9e00352b5 100644 --- a/UserTools/Unity.h +++ b/UserTools/Unity.h @@ -104,7 +104,7 @@ #include "CalcClassificationVars.h" #include "StoreClassificationVars.h" #include "LoadGenieEvent.h" -//#include "PrintGenieEvent.h" +#include "PrintGenieEvent.h" #include "PlotWaveforms.h" #include "PMTDataDecoder.h" #include "ANNIEEventBuilder.h" @@ -152,6 +152,7 @@ #include "BeamDecoder.h" #include "LoadRunInfo.h" #include "ApplyMRDEff.h" +#include "SimpleReconstruction.h" #include "LAPPDnnlsPeak.h" #include "LAPPDLocateHit.h" #include "LAPPDOtherSimp.h" @@ -169,6 +170,8 @@ #include "FilterEvents.h" #include "Stage1DataBuilder.h" #include "BeamFetcherV2.h" +#include "FindNeutrons.h" +#include "NeutronMultiplicity.h" #include "PlotsTrackLengthAndEnergy.h" #include "SaveConfigInfo.h" #include "ReadConfigInfo.h" diff --git a/configfiles/NeutronMultiplicity/ClusterClassifiersConfig b/configfiles/NeutronMultiplicity/ClusterClassifiersConfig new file mode 100644 index 000000000..752200268 --- /dev/null +++ b/configfiles/NeutronMultiplicity/ClusterClassifiersConfig @@ -0,0 +1 @@ +verbosity 0 diff --git a/configfiles/NeutronMultiplicity/ClusterFinderConfig b/configfiles/NeutronMultiplicity/ClusterFinderConfig new file mode 100644 index 000000000..337d7fc2e --- /dev/null +++ b/configfiles/NeutronMultiplicity/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 100 # in ns, size of the window used to "clusterize" +AcqTimeWindow 70000 # in ns, size of the acquisition window +ClusterIntegrationWindow 100 # in ns, all hits with +/- 1/2 of this window are considered in the cluster +MinHitsPerCluster 5 # group of hits are considered clusters above this amount of hits +end_of_window_time_cut 0.95 # from o to 1, length of the window you want to loop over with respect to acq. window (1 for full window, 0.95 for 95% from the start) +Plots2D 0 #Draw 2D charge-vs-time plots? +ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat diff --git a/configfiles/NeutronMultiplicity/CreateMyList_Processed.sh b/configfiles/NeutronMultiplicity/CreateMyList_Processed.sh new file mode 100755 index 000000000..cc535e0eb --- /dev/null +++ b/configfiles/NeutronMultiplicity/CreateMyList_Processed.sh @@ -0,0 +1,20 @@ +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" + exit 1 +fi + +FILEDIR=$1 +RUN=$2 + +NUMFILES=$(ls -1q ${FILEDIR}/ProcessedRawData_TankAndMRDAndCTC_R${RUN}* | wc -l) + +echo "NUMBER OF FILES IN ${FILEDIR}: ${NUMFILES}" +((NUMFILES-=1)) + +> my_inputs.txt + +for p in $(seq 0 $NUMFILES) +do + echo "${FILEDIR}/ProcessedRawData_TankAndMRDAndCTC_R${RUN}S0p${p}" >> my_inputs.txt +done diff --git a/configfiles/NeutronMultiplicity/EventSelectorConfig b/configfiles/NeutronMultiplicity/EventSelectorConfig new file mode 100644 index 000000000..ec139f22f --- /dev/null +++ b/configfiles/NeutronMultiplicity/EventSelectorConfig @@ -0,0 +1,31 @@ +# 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 1 +PMTMRDOffset 745 +PromptTrigOnly 0 +TriggerWord 5 +SaveStatusToStore 1 +NoVeto 1 +Veto 0 +ThroughGoing 0 +IsMC 0 #MC or Data? +TriggerExtendedWindow 1 +BeamOK 1 diff --git a/configfiles/NeutronMultiplicity/FindMrdTracksConfig b/configfiles/NeutronMultiplicity/FindMrdTracksConfig new file mode 100644 index 000000000..5ba5e8f77 --- /dev/null +++ b/configfiles/NeutronMultiplicity/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/NeutronMultiplicity/FindNeutronsConfig b/configfiles/NeutronMultiplicity/FindNeutronsConfig new file mode 100644 index 000000000..ce397ceb6 --- /dev/null +++ b/configfiles/NeutronMultiplicity/FindNeutronsConfig @@ -0,0 +1,5 @@ +#FindNeutrons config file + +verbosity 1 +Method CBStrict #selection cut method for neutrons: CB, CBStrict, in the future ML techniques +EfficiencyMapPath ./configfiles/NeutronMultiplicity/NeutronEffMap_Data.txt #path to neutron efficiency map diff --git a/configfiles/NeutronMultiplicity/LoadANNIEEventConfig b/configfiles/NeutronMultiplicity/LoadANNIEEventConfig new file mode 100644 index 000000000..776fed727 --- /dev/null +++ b/configfiles/NeutronMultiplicity/LoadANNIEEventConfig @@ -0,0 +1,4 @@ +verbose 4 +FileForListOfInputs ./configfiles/NeutronMultiplicity/my_inputs.txt +EventOffset 0 +GlobalEvNr 1 diff --git a/configfiles/NeutronMultiplicity/MC/Chankey_WCSimID_v7.txt b/configfiles/NeutronMultiplicity/MC/Chankey_WCSimID_v7.txt new file mode 100644 index 000000000..62473bdf0 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/Chankey_WCSimID_v7.txt @@ -0,0 +1,132 @@ +332 1 +333 2 +334 3 +335 4 +336 5 +337 6 +338 7 +339 8 +340 9 +341 10 +342 11 +343 12 +344 13 +345 14 +346 15 +347 16 +348 17 +349 18 +350 19 +351 20 +352 21 +353 22 +354 23 +355 24 +356 25 +357 26 +358 27 +359 28 +360 29 +361 30 +362 31 +363 32 +364 33 +365 34 +366 35 +367 36 +368 37 +369 38 +370 39 +371 40 +372 41 +373 42 +374 43 +375 44 +376 45 +377 46 +378 47 +379 48 +380 49 +381 50 +382 51 +383 52 +384 53 +385 54 +386 55 +387 56 +388 57 +389 58 +390 59 +391 60 +392 61 +393 62 +394 63 +395 64 +396 65 +397 66 +398 67 +399 68 +400 69 +401 70 +402 71 +403 72 +404 73 +405 74 +406 75 +407 76 +408 77 +409 78 +410 79 +411 80 +412 81 +413 82 +414 83 +415 84 +416 85 +417 86 +418 87 +419 88 +420 89 +421 90 +422 91 +423 92 +424 93 +425 94 +426 95 +427 96 +428 97 +429 98 +430 99 +431 100 +432 101 +433 102 +434 103 +435 104 +436 105 +437 106 +438 107 +439 108 +440 109 +441 110 +442 111 +443 112 +444 113 +445 114 +446 115 +447 116 +448 117 +449 118 +450 119 +451 120 +452 121 +453 122 +454 123 +455 124 +456 125 +457 126 +458 127 +459 128 +460 129 +461 130 +462 131 +463 132 diff --git a/configfiles/NeutronMultiplicity/MC/ClusterClassifiersConfig b/configfiles/NeutronMultiplicity/MC/ClusterClassifiersConfig new file mode 100644 index 000000000..fa3939acd --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/ClusterClassifiersConfig @@ -0,0 +1,3 @@ +#ClusterClassifiers Config file +verbosity 1 +IsData 0 diff --git a/configfiles/NeutronMultiplicity/MC/ClusterFinderConfig b/configfiles/NeutronMultiplicity/MC/ClusterFinderConfig new file mode 100644 index 000000000..59ef4564a --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/ClusterFinderConfig @@ -0,0 +1,12 @@ +# ClusterFinder Config File + +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" +AcqTimeWindow 70000 # in ns, size of the acquisition window +ClusterIntegrationWindow 100 # in ns, all hits with +/- 1/2 of this window are considered in the cluster +MinHitsPerCluster 5 # group of hits are considered clusters above this amount of hits +end_of_window_time_cut 0.95 # from o to 1, length of the window you want to loop over with respect to acq. window (1 for full window, 0.95 for 95% from the start) +Plots2D 0 #Draw 2D charge-vs-time plots? +ChankeyToPMTIDMap ./configfiles/EventDisplay/Data-RecoEvent/Chankey_WCSimID.dat diff --git a/configfiles/NeutronMultiplicity/MC/DeadPMTIDs_p2v7.txt b/configfiles/NeutronMultiplicity/MC/DeadPMTIDs_p2v7.txt new file mode 100644 index 000000000..a5e258dad --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/DeadPMTIDs_p2v7.txt @@ -0,0 +1,10 @@ +2 +11 +14 +15 +18 +21 +85 +100 +113 +114 diff --git a/configfiles/NeutronMultiplicity/MC/EventSelectorConfig b/configfiles/NeutronMultiplicity/MC/EventSelectorConfig new file mode 100644 index 000000000..edbeb46a8 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/EventSelectorConfig @@ -0,0 +1,31 @@ +# 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 1 +PMTMRDOffset 0 +PromptTrigOnly 0 +TriggerWord 5 +SaveStatusToStore 1 +IsMC 1 #MC or Data? +NoVeto 1 +Veto 0 +ThroughGoing 0 +TriggerExtendedWindow 1 #We always have an extended window available in MC +BeamOK 1 #Beam is always ok in MC? diff --git a/configfiles/NeutronMultiplicity/MC/FindMrdTracksConfig b/configfiles/NeutronMultiplicity/MC/FindMrdTracksConfig new file mode 100644 index 000000000..7a9d11f7d --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/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 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/NeutronMultiplicity/MC/FindNeutronsConfig b/configfiles/NeutronMultiplicity/MC/FindNeutronsConfig new file mode 100644 index 000000000..8e1e8ce8b --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/FindNeutronsConfig @@ -0,0 +1,5 @@ +#FindNeutrons config file + +verbosity 1 +Method CB +EfficiencyMapPath ./configfiles/NeutronMultiplicity/NeutronEffMap_MC_CB.txt diff --git a/configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig b/configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig new file mode 100644 index 000000000..5d73a099f --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig @@ -0,0 +1,11 @@ +verbosity 0 +FluxVersion 0 # use 0 to load genie files based on bnb_annie_0000.root etc files + # use 1 to load files based on beammc_annie_0000.root etc files +#FileDir NA # specify "NA" for newer files: full path is saved in WCSim +FileDir /pnfs/annie/persistent/users/vfischer/genie_files/BNB_Water_10k_22-05-17 +#FileDir /pnfs/annie/persistent/users/moflaher/genie/BNB_World_10k_11-03-18_gsimpleflux +FilePattern gntp.1910.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 9900 diff --git a/configfiles/NeutronMultiplicity/MC/LoadWCSimConfig b/configfiles/NeutronMultiplicity/MC/LoadWCSimConfig new file mode 100644 index 000000000..3556a7599 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/LoadWCSimConfig @@ -0,0 +1,20 @@ +#LoadWCSim Config File +# all variables retrieved with m_variables.Get() must be defined here! +verbose 0 + +#InputFile /pnfs/annie/persistent/users/moflaher/wcsim/multipmt/tankonly/wcsim_25_04_19_ANNIEp2v6_nodigit_BNB_Water_10k_22-05-17/wcsim_0.1.9.root +#InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_ambe_port5_z0_5000_0.root +InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/pmt-files/wcsim_beam_gst_1014_99_0.1999.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 + +WCSimVersion 3 ## should reflect the WCSim version of the files being loaded +HistoricTriggeroffset 0 ## time offset of digits relative to the trigger +UseDigitSmearedTime 1 ## whether to use smeared digit time (T), or true time of first photon (F) +LappdNumStrips 60 ## num channels to construct from each LAPPD +LappdStripLength 100 ## relative x position of each LAPPD strip, for dual-sided readout [mm] +LappdStripSeparation 10 ## stripline separation, for calculating relative y position of each LAPPD strip [mm] +PMTMask configfiles/BeamClusterAnalysisMC/DeadPMTIDs_p2v7.txt ## Which PMTs should be masked out? / are dead? +ChankeyToPMTIDMap ./configfiles/BeamClusterAnalysisMC/Chankey_WCSimID_v7.txt +SplitSubTriggers 0 # should subtriggers be loaded in separate Execute steps? diff --git a/configfiles/NeutronMultiplicity/MC/LoadWCSimLAPPDConfig b/configfiles/NeutronMultiplicity/MC/LoadWCSimLAPPDConfig new file mode 100644 index 000000000..8548f52d4 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/LoadWCSimLAPPDConfig @@ -0,0 +1,14 @@ +#LoadWCSimLAPPD Config File +# 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_lappd_0.1.9.root +#InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_ambe_port5_z0_lappd_0.root +InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/lappd-files/LAPPD_wcsim_beam_gst_1046_38_0.5438.root +#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/lappd-files/LAPPD_wcsim_beam_gst_1079_9_0.9009.root +#InputFile /annie/app/users/mnieslon/WCSim_build/wcsim_michel_1000_lappd_0.root +#/pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_throughgoing/wcsim_throughgoing_muon_R2614_lappd_0.0.root + +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/NeutronMultiplicity/MC/MCParticlePropertiesConfig b/configfiles/NeutronMultiplicity/MC/MCParticlePropertiesConfig new file mode 100644 index 000000000..019526011 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/MCParticlePropertiesConfig @@ -0,0 +1,3 @@ +# MCParticleProperties configuration file + +verbosity 0 diff --git a/configfiles/NeutronMultiplicity/MC/MCRecoEventLoaderConfig b/configfiles/NeutronMultiplicity/MC/MCRecoEventLoaderConfig new file mode 100644 index 000000000..96923c44a --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/MCRecoEventLoaderConfig @@ -0,0 +1,11 @@ +# MCRecoEventLoader config file + +verbosity 0 +GetPionKaonInfo 1 +GetNRings 1 +ParticleID 13 +DoParticleSelection 0 +xshift 0.0 +yshift 14.46469 +zshift -168.1 +IsMC 1 diff --git a/configfiles/NeutronMultiplicity/MC/NeutronMultiplicityConfig b/configfiles/NeutronMultiplicity/MC/NeutronMultiplicityConfig new file mode 100644 index 000000000..1f8c71677 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/NeutronMultiplicityConfig @@ -0,0 +1,7 @@ +verbosity 5 + +SaveROOT 1 +SaveBoostStore 1 +ReadFromBoostStore None +Filename NeutronMultiplicity_MCBeam_CB_1999 +MRDTrackRestriction 1 diff --git a/configfiles/NeutronMultiplicity/MC/README.md b/configfiles/NeutronMultiplicity/MC/README.md new file mode 100644 index 000000000..930875d3b --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/README.md @@ -0,0 +1,30 @@ +# BeamClusterAnalysisMC + +*********************** +## Description +********************** + +The `BeamClusterAnalysisMC` toolchain produces a ntuple ROOT-tree from simulated events, e.g. simulated with the annie version of `WCSim`. This ntuple is created via the `PhaseIITreeMaker` tool, which generates separate trees to store the information about the trigger data, tank PMT clusters, and MRD clusters. It can be used in combination with the `EventSelector` tool to only save events to the ntuple file if they meet certain criteria. + + +************************ +## Tools +************************ + +The toolchain typically consists of the following tools: + +``` +LoadGeometry +LoadWCSim +LoadWCSimLAPPD +LoadGenieEvent +MCParticleProperties +MCRecoEventLoader +TimeClustering +FindMrdTracks +ClusterFinder +ClusterClassifiers +EventSelector +PhaseIITreeMaker +``` + diff --git a/configfiles/NeutronMultiplicity/MC/RunNeutronMultiplicityMC.sh b/configfiles/NeutronMultiplicity/MC/RunNeutronMultiplicityMC.sh new file mode 100755 index 000000000..aae61b286 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/RunNeutronMultiplicityMC.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +filelist="./pmt-files-gst_new.txt" +filelist_genie="./genie-files-gst_new.txt" +filelist_offset="./offset-gst_new.txt" + +cut=CB + +let i=0 +while read -r file && read -r filegenie <&3 && read -r offset <&6 +do + echo "$file" + echo "$filegenie" + echo "$offset" + #Change into ToolAnalysis directory + cd ../../../ + + #Change config files + sed -i "7s#.*#InputFile /pnfs/annie/persistent/users/mnieslon/wcsim/output/tankonly/wcsim_ANNIEp2v7_beam/pmt-files/${file}#" configfiles/NeutronMultiplicity/MC/LoadWCSimConfig + #sed -i "7s#.*#InputFile ${filelappd}#" configfiles/NeutronMultiplicity/MC/LoadWCSimLAPPDConfig + sed -i "6s#.*#Filename NeutronMultiplicity_MCBeam_${cut}_${i}#" configfiles/NeutronMultiplicity/MC/NeutronMultiplicityConfig + sed -i "7s#.*#FilePattern ${filegenie}#" configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig + sed -i "11s#.*#EventOffset ${offset}#" configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig + sed -i "4s#.*#Method ${cut}#" configfiles/NeutronMultiplicity/MC/FindNeutronsConfig + sed -i "5s#.*#EfficiencyMapPath ./configfiles/NeutronMultiplicity/NeutronEffMap_MC_${cut}.txt#" configfiles/NeutronMultiplicity/MC/FindNeutronsConfig + + #Run Analysis + ./Analyse ./configfiles/NeutronMultiplicity/MC/ToolChainConfig + + #Change back into original directory + cd configfiles/NeutronMultiplicity/MC + + #Increment + i=$((i+1)) + +done < $filelist 3<$filelist_genie 6<$filelist_offset + diff --git a/configfiles/NeutronMultiplicity/MC/TimeClusteringConfig b/configfiles/NeutronMultiplicity/MC/TimeClusteringConfig new file mode 100644 index 000000000..e942f7fe4 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/TimeClusteringConfig @@ -0,0 +1,13 @@ +#TimeClustering config file + +verbosity 0 +MinDigitsForTrack 3 +MaxMrdSubEventDuration 30 +MinSubeventTimeSep 30 +MakeMrdDigitTimePlot 0 +LaunchTApplication 0 +IsData 0 +#OutputROOTFile TimeClustering_MRDTest28_cluster40ns +OutputROOTFile STEC_TimeClusteringOut +MapChankey_WCSimID ./configfiles/SimpleTankEnergyCalibrator/MRD_Chankey_WCSimID.dat + diff --git a/configfiles/NeutronMultiplicity/MC/ToolChainConfig b/configfiles/NeutronMultiplicity/MC/ToolChainConfig new file mode 100644 index 000000000..03db5d3a4 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/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/NeutronMultiplicity/MC/ToolsConfig + +##### Run Type ##### +Inline -1 +Interactive 0 + diff --git a/configfiles/NeutronMultiplicity/MC/ToolsConfig b/configfiles/NeutronMultiplicity/MC/ToolsConfig new file mode 100644 index 000000000..0c6423515 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/ToolsConfig @@ -0,0 +1,14 @@ +myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +myLoadWCSim LoadWCSim ./configfiles/NeutronMultiplicity/MC/LoadWCSimConfig +#myLoadWCSimLAPPD LoadWCSimLAPPD ./configfiles/NeutronMultiplicity/MC/LoadWCSimLAPPDConfig +myLoadGenieEvent LoadGenieEvent ./configfiles/NeutronMultiplicity/MC/LoadGenieEventConfig +myMCParticleProperties MCParticleProperties ./configfiles/NeutronMultiplicity/MC/MCParticlePropertiesConfig +myMCRecoEventLoader MCRecoEventLoader ./configfiles/NeutronMultiplicity/MC/MCRecoEventLoaderConfig +myTimeClustering TimeClustering configfiles/NeutronMultiplicity/MC/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/NeutronMultiplicity/MC/FindMrdTracksConfig +myClusterFinder ClusterFinder ./configfiles/NeutronMultiplicity/MC/ClusterFinderConfig +myClusterClassifiers ClusterClassifiers ./configfiles/NeutronMultiplicity/MC/ClusterClassifiersConfig +myEventSelector EventSelector ./configfiles/NeutronMultiplicity/MC/EventSelectorConfig +mySimpleReconstruction SimpleReconstruction ./configfiles/NeutronMultiplicity/SimpleReconstructionConfig +myFindNeutrons FindNeutrons ./configfiles/NeutronMultiplicity/MC/FindNeutronsConfig +myNeutronMultiplicity NeutronMultiplicity ./configfiles/NeutronMultiplicity/MC/NeutronMultiplicityConfig diff --git a/configfiles/NeutronMultiplicity/MC/genie-files-gst.txt b/configfiles/NeutronMultiplicity/MC/genie-files-gst.txt new file mode 120000 index 000000000..d86c7a9d8 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/genie-files-gst.txt @@ -0,0 +1 @@ +/pnfs/annie/persistent/users/mnieslon/NeutronMultiplicity/file_lists/genie-files-gst_new.txt \ No newline at end of file diff --git a/configfiles/NeutronMultiplicity/MC/offset-gst.txt b/configfiles/NeutronMultiplicity/MC/offset-gst.txt new file mode 120000 index 000000000..e7e67466d --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/offset-gst.txt @@ -0,0 +1 @@ +/pnfs/annie/persistent/users/mnieslon/NeutronMultiplicity/file_lists/offset-gst_new.txt \ No newline at end of file diff --git a/configfiles/NeutronMultiplicity/MC/pmt-files-gst.txt b/configfiles/NeutronMultiplicity/MC/pmt-files-gst.txt new file mode 120000 index 000000000..75a381e52 --- /dev/null +++ b/configfiles/NeutronMultiplicity/MC/pmt-files-gst.txt @@ -0,0 +1 @@ +/pnfs/annie/persistent/users/mnieslon/NeutronMultiplicity/file_lists/pmt-files-gst_new.txt \ No newline at end of file diff --git a/configfiles/NeutronMultiplicity/NeutronEffMap_Data.txt b/configfiles/NeutronMultiplicity/NeutronEffMap_Data.txt new file mode 100644 index 000000000..b4915e5e3 --- /dev/null +++ b/configfiles/NeutronMultiplicity/NeutronEffMap_Data.txt @@ -0,0 +1,24 @@ +1 100 0 85.6 93.1 0.61 0.655 +1 50 0 35.6 93.1 0.71 0.655 +1 0 0 -14.4 93.1 0.54 0.655 +1 -50 0 -64.4 93.1 0.58 0.655 +1 -100 0 -114.4 93.1 0.57 0.655 +2 100 0 85.6 243.1 0.56 0.655 +2 50 0 35.6 243.1 0.67 0.655 +2 0 0 -14.4 243.1 0.69 0.655 +2 -50 0 -64.4 243.1 0.64 0.655 +2 -100 0 -114.4 243.1 0.58 0.655 +3 100 0 85.6 270.1 0.57 0.655 +3 50 0 35.6 270.1 0.61 0.655 +3 0 0 -14.4 270.1 0.61 0.655 +3 -50 0 -64.4 270.1 0.61 0.655 +3 -100 0 -114.4 270.1 0.54 0.655 +4 100 75 85.6 168.1 0.68 0.655 +4 50 75 35.6 168.1 0.67 0.655 +4 -50 75 -64.4 168.1 0.69 0.655 +4 -100 75 -114.4 168.1 0.67 0.655 +5 100 0 85.6 168.1 0.71 0.655 +5 50 0 35.6 168.1 0.69 0.655 +5 0 0 -14.4 168.1 0.69 0.655 +5 -50 0 -64.4 168.1 0.66 0.655 +5 -100 0 -114.4 168.1 0.65 0.655 diff --git a/configfiles/NeutronMultiplicity/NeutronEffMap_MC_CB.txt b/configfiles/NeutronMultiplicity/NeutronEffMap_MC_CB.txt new file mode 100644 index 000000000..6d6363d6d --- /dev/null +++ b/configfiles/NeutronMultiplicity/NeutronEffMap_MC_CB.txt @@ -0,0 +1,25 @@ +1 100 0 85.6 93.1 0.776274 0.65312 +1 50 0 35.6 93.1 0.841565 0.65844 +1 0 0 -14.4 93.1 0.861395 0.65048 +1 -50 0 -64.4 93.1 0.843456 0.65796 +1 -100 0 -114.4 93.1 0.756261 0.6548 +2 100 0 85.6 243.1 0.775128 0.65584 +2 50 0 35.6 243.1 0.845789 0.65832 +2 0 0 -14.4 243.1 0.864968 0.65792 +2 -50 0 -64.4 243.1 0.846539 0.6558 +2 -100 0 -114.4 243.1 0.796842 0.65604 +3 100 0 85.6 270.1 0.638479 0.63764 +3 50 0 35.6 270.1 0.723831 0.66032 +3 0 0 -14.4 270.1 0.754464 0.64512 +3 -50 0 -64.4 270.1 0.728957 0.65436 +3 -100 0 -114.4 270.1 0.671062 0.6462 +4 100 75 85.6 168.1 0.783945 0.65724 +4 50 75 35.6 168.1 0.852204 0.66064 +4 0 75 -14.4 168.1 0.863327 0.65324 +4 -50 75 -64.4 168.1 0.843649 0.65852 +4 -100 75 -114.4 168.1 0.768347 0.66116 +5 100 0 85.6 168.1 0.873564 0.65108 +5 50 0 35.6 168.1 0.928771 0.6576 +5 0 0 -14.4 168.1 0.931817 0.66116 +5 -50 0 -64.4 168.1 0.924634 0.65388 +5 -100 0 -114.4 168.1 0.888099 0.65236 diff --git a/configfiles/NeutronMultiplicity/NeutronEffMap_MC_CBStrict.txt b/configfiles/NeutronMultiplicity/NeutronEffMap_MC_CBStrict.txt new file mode 100644 index 000000000..0fda7c626 --- /dev/null +++ b/configfiles/NeutronMultiplicity/NeutronEffMap_MC_CBStrict.txt @@ -0,0 +1,25 @@ +1 100 0 85.6 93.1 0.741120 0.65312 +1 50 0 35.6 93.1 0.813620 0.65844 +1 0 0 -14.4 93.1 0.835260 0.65048 +1 -50 0 -64.4 93.1 0.818652 0.65796 +1 -100 0 -114.4 93.1 0.735186 0.6548 +2 100 0 85.6 243.1 0.753476 0.65584 +2 50 0 35.6 243.1 0.829202 0.65832 +2 0 0 -14.4 243.1 0.848857 0.65792 +2 -50 0 -64.4 243.1 0.829765 0.6558 +2 -100 0 -114.4 243.1 0.785745 0.65604 +3 100 0 85.6 270.1 0.622734 0.63764 +3 50 0 35.6 270.1 0.704446 0.66032 +3 0 0 -14.4 270.1 0.736855 0.64512 +3 -50 0 -64.4 270.1 0.708784 0.65436 +3 -100 0 -114.4 270.1 0.658372 0.6462 +4 100 75 85.6 168.1 0.761366 0.65724 +4 50 75 35.6 168.1 0.832587 0.66064 +4 0 75 -14.4 168.1 0.844100 0.65324 +4 -50 75 -64.4 168.1 0.825123 0.65852 +4 -100 75 -114.4 168.1 0.745115 0.66116 +5 100 0 85.6 168.1 0.849849 0.65108 +5 50 0 35.6 168.1 0.921655 0.6576 +5 0 0 -14.4 168.1 0.927158 0.66116 +5 -50 0 -64.4 168.1 0.919802 0.65388 +5 -100 0 -114.4 168.1 0.877981 0.65236 diff --git a/configfiles/NeutronMultiplicity/NeutronEffMap_MC_NHits10.txt b/configfiles/NeutronMultiplicity/NeutronEffMap_MC_NHits10.txt new file mode 100644 index 000000000..dd41af1e5 --- /dev/null +++ b/configfiles/NeutronMultiplicity/NeutronEffMap_MC_NHits10.txt @@ -0,0 +1,25 @@ +1 100 0 85.6 93.1 0.835804 0.65312 +1 50 0 35.6 93.1 0.870846 0.65844 +1 0 0 -14.4 93.1 0.883102 0.65048 +1 -50 0 -64.4 93.1 0.874764 0.65796 +1 -100 0 -114.4 93.1 0.811057 0.6548 +2 100 0 85.6 243.1 0.813613 0.65584 +2 50 0 35.6 243.1 0.870944 0.65832 +2 0 0 -14.4 243.1 0.874696 0.65792 +2 -50 0 -64.4 243.1 0.863312 0.6558 +2 -100 0 -114.4 243.1 0.813731 0.65604 +3 100 0 85.6 270.1 0.667963 0.63764 +3 50 0 35.6 270.1 0.768476 0.66032 +3 0 0 -14.4 270.1 0.763579 0.64512 +3 -50 0 -64.4 270.1 0.769974 0.65436 +3 -100 0 -114.4 270.1 0.677561 0.6462 +4 100 75 85.6 168.1 0.822774 0.65724 +4 50 75 35.6 168.1 0.870368 0.66064 +4 0 75 -14.4 168.1 0.880963 0.65324 +4 -50 75 -64.4 168.1 0.867278 0.65852 +4 -100 75 -114.4 168.1 0.816504 0.66116 +5 100 0 85.6 168.1 0.888001 0.65108 +5 50 0 35.6 168.1 0.912105 0.6576 +5 0 0 -14.4 168.1 0.911670 0.66116 +5 -50 0 -64.4 168.1 0.906160 0.65388 +5 -100 0 -114.4 168.1 0.882458 0.65236 diff --git a/configfiles/NeutronMultiplicity/NeutronMultiplicityConfig b/configfiles/NeutronMultiplicity/NeutronMultiplicityConfig new file mode 100644 index 000000000..38e34e869 --- /dev/null +++ b/configfiles/NeutronMultiplicity/NeutronMultiplicityConfig @@ -0,0 +1,7 @@ +verbosity 1 + +SaveROOT 1 +SaveBoostStore 1 +ReadFromBoostStore None +Filename NeutronMultiplicity_R2630_CBStrict +MRDTrackRestriction 1 diff --git a/configfiles/NeutronMultiplicity/README.md b/configfiles/NeutronMultiplicity/README.md new file mode 100644 index 000000000..e569def87 --- /dev/null +++ b/configfiles/NeutronMultiplicity/README.md @@ -0,0 +1,30 @@ +# NeutronMultiplicity toolchain + + +# Purpose + +The creation of neutron multiplicity analysis plots for ANNIE data and MC files. + +# Tools + +The following tools are present in the toolchain: + +* `LoadANNIEEvent`: Loading the event +* `LoadGeometry`: Loading the geometry +* `TimeClustering`: Looking for time clusters in the MRD +* `FindMrdTracks`: Finding MRD tracks +* `ClusterFinder`: Looking for time clusters in the tank PMTs +* `ClusterClassifiers`: Classifying those tank PMT clusters +* `EventSelector`: Apply event selection cuts +* `SimpleReconstruction`: Simple MRD-track-based reconstruction of muon properties & vertex +* `FindNeutrons`: Find neutrons by specifying a desired selection cut. New selection cuts can easily be added. +* `NeutronMultiplicity`: Combine the information about the muon and the neutrons and create the neutron multiplicity plots. + +# Usage + +The output of the toolchain is either a ROOT-file or a BoostStore file with the relevant information about the neutrons and associated reconstructed muon information. If selecting the BoostStore option, the user can then read in all the necessary information for the toolchain from these NeutronMultiplicity BoostStore files at a later stage. This is especially useful when combining multiple runs. + +The toolchain can either be used by reading in regular processed ANNIEEvent BoostStore files, by reading in filtered ANNIEEvent BoostStore files, or by reading in NeutronMultiplicity BoostStore files (as mentioned above). + +The toolchain for reading in multiple NeutronMultiplicity BoostStore files and creating an overall NeutronMultiplicity BoostStore+ROOT output file can be found at `configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolChainConfig`. + diff --git a/configfiles/NeutronMultiplicity/ReadFromBoostStore/NeutronMultiplicityConfig b/configfiles/NeutronMultiplicity/ReadFromBoostStore/NeutronMultiplicityConfig new file mode 100644 index 000000000..afa52b123 --- /dev/null +++ b/configfiles/NeutronMultiplicity/ReadFromBoostStore/NeutronMultiplicityConfig @@ -0,0 +1,10 @@ +verbosity 3 + +SaveROOT 1 +SaveBoostStore 1 +#ReadFromBoostStore None +ReadFromBoostStore ./configfiles/NeutronMultiplicity/ReadFromBoostStore/datafiles.txt +Filename NeutronMultiplicity_R2506-R2630_CBStrict +#ReadFromBoostStore ./configfiles/NeutronMultiplicity/ReadFromBoostStore/mcfiles.txt +#Filename NeutronMultiplicity_MCBeam_CB_0_2000 +MRDTrackRestriction 1 diff --git a/configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolChainConfig b/configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolChainConfig new file mode 100644 index 000000000..967a8d1fd --- /dev/null +++ b/configfiles/NeutronMultiplicity/ReadFromBoostStore/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/NeutronMultiplicity/ReadFromBoostStore/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/NeutronMultiplicity/ReadFromBoostStore/ToolsConfig b/configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolsConfig new file mode 100644 index 000000000..ca2ce9e15 --- /dev/null +++ b/configfiles/NeutronMultiplicity/ReadFromBoostStore/ToolsConfig @@ -0,0 +1 @@ +myNeutronMultiplicity NeutronMultiplicity ./configfiles/NeutronMultiplicity/ReadFromBoostStore/NeutronMultiplicityConfig diff --git a/configfiles/NeutronMultiplicity/ReadFromBoostStore/datafiles.txt b/configfiles/NeutronMultiplicity/ReadFromBoostStore/datafiles.txt new file mode 100644 index 000000000..aa6b30e99 --- /dev/null +++ b/configfiles/NeutronMultiplicity/ReadFromBoostStore/datafiles.txt @@ -0,0 +1,58 @@ +NeutronMultiplicity_R2506_CBStrict.bs +NeutronMultiplicity_R2507_CBStrict.bs +NeutronMultiplicity_R2508_CBStrict.bs +NeutronMultiplicity_R2509_CBStrict.bs +NeutronMultiplicity_R2510_CBStrict.bs +NeutronMultiplicity_R2511_CBStrict.bs +NeutronMultiplicity_R2512_CBStrict.bs +NeutronMultiplicity_R2513_CBStrict.bs +NeutronMultiplicity_R2514_CBStrict.bs +NeutronMultiplicity_R2521_CBStrict.bs +NeutronMultiplicity_R2536_CBStrict.bs +NeutronMultiplicity_R2541_CBStrict.bs +NeutronMultiplicity_R2548_CBStrict.bs +NeutronMultiplicity_R2551_CBStrict.bs +NeutronMultiplicity_R2552_CBStrict.bs +NeutronMultiplicity_R2555_CBStrict.bs +NeutronMultiplicity_R2570_CBStrict.bs +NeutronMultiplicity_R2571_CBStrict.bs +NeutronMultiplicity_R2572_CBStrict.bs +NeutronMultiplicity_R2573_CBStrict.bs +NeutronMultiplicity_R2578_CBStrict.bs +NeutronMultiplicity_R2579_CBStrict.bs +NeutronMultiplicity_R2580_CBStrict.bs +NeutronMultiplicity_R2581_CBStrict.bs +NeutronMultiplicity_R2582_CBStrict.bs +NeutronMultiplicity_R2583_CBStrict.bs +NeutronMultiplicity_R2584_CBStrict.bs +NeutronMultiplicity_R2585_CBStrict.bs +NeutronMultiplicity_R2586_CBStrict.bs +NeutronMultiplicity_R2589_CBStrict.bs +NeutronMultiplicity_R2590_CBStrict.bs +NeutronMultiplicity_R2591_CBStrict.bs +NeutronMultiplicity_R2592_CBStrict.bs +NeutronMultiplicity_R2593_CBStrict.bs +NeutronMultiplicity_R2596_CBStrict.bs +NeutronMultiplicity_R2597_CBStrict.bs +NeutronMultiplicity_R2598_CBStrict.bs +NeutronMultiplicity_R2599_CBStrict.bs +NeutronMultiplicity_R2600_CBStrict.bs +NeutronMultiplicity_R2601_CBStrict.bs +NeutronMultiplicity_R2604_CBStrict.bs +NeutronMultiplicity_R2605_CBStrict.bs +NeutronMultiplicity_R2608_CBStrict.bs +NeutronMultiplicity_R2609_CBStrict.bs +NeutronMultiplicity_R2610_CBStrict.bs +NeutronMultiplicity_R2611_CBStrict.bs +NeutronMultiplicity_R2612_CBStrict.bs +NeutronMultiplicity_R2613_CBStrict.bs +NeutronMultiplicity_R2614_CBStrict.bs +NeutronMultiplicity_R2618_CBStrict.bs +NeutronMultiplicity_R2619_CBStrict.bs +NeutronMultiplicity_R2620_CBStrict.bs +NeutronMultiplicity_R2621_CBStrict.bs +NeutronMultiplicity_R2624_CBStrict.bs +NeutronMultiplicity_R2625_CBStrict.bs +NeutronMultiplicity_R2628_CBStrict.bs +NeutronMultiplicity_R2629_CBStrict.bs +NeutronMultiplicity_R2630_CBStrict.bs diff --git a/configfiles/NeutronMultiplicity/ReadFromBoostStore/mcfiles.txt b/configfiles/NeutronMultiplicity/ReadFromBoostStore/mcfiles.txt new file mode 100644 index 000000000..99f534d47 --- /dev/null +++ b/configfiles/NeutronMultiplicity/ReadFromBoostStore/mcfiles.txt @@ -0,0 +1,101 @@ +NeutronMultiplicity_MCBeam_0.bs +NeutronMultiplicity_MCBeam_1.bs +NeutronMultiplicity_MCBeam_2.bs +NeutronMultiplicity_MCBeam_3.bs +NeutronMultiplicity_MCBeam_4.bs +NeutronMultiplicity_MCBeam_5.bs +NeutronMultiplicity_MCBeam_6.bs +NeutronMultiplicity_MCBeam_7.bs +NeutronMultiplicity_MCBeam_8.bs +NeutronMultiplicity_MCBeam_9.bs +NeutronMultiplicity_MCBeam_10.bs +NeutronMultiplicity_MCBeam_11.bs +NeutronMultiplicity_MCBeam_12.bs +NeutronMultiplicity_MCBeam_13.bs +NeutronMultiplicity_MCBeam_14.bs +NeutronMultiplicity_MCBeam_15.bs +NeutronMultiplicity_MCBeam_16.bs +NeutronMultiplicity_MCBeam_17.bs +NeutronMultiplicity_MCBeam_18.bs +NeutronMultiplicity_MCBeam_19.bs +NeutronMultiplicity_MCBeam_20.bs +NeutronMultiplicity_MCBeam_21.bs +NeutronMultiplicity_MCBeam_22.bs +NeutronMultiplicity_MCBeam_23.bs +NeutronMultiplicity_MCBeam_24.bs +NeutronMultiplicity_MCBeam_25.bs +NeutronMultiplicity_MCBeam_26.bs +NeutronMultiplicity_MCBeam_27.bs +NeutronMultiplicity_MCBeam_28.bs +NeutronMultiplicity_MCBeam_29.bs +NeutronMultiplicity_MCBeam_30.bs +NeutronMultiplicity_MCBeam_31.bs +NeutronMultiplicity_MCBeam_32.bs +NeutronMultiplicity_MCBeam_33.bs +NeutronMultiplicity_MCBeam_34.bs +NeutronMultiplicity_MCBeam_35.bs +NeutronMultiplicity_MCBeam_36.bs +NeutronMultiplicity_MCBeam_37.bs +NeutronMultiplicity_MCBeam_38.bs +NeutronMultiplicity_MCBeam_39.bs +NeutronMultiplicity_MCBeam_40.bs +NeutronMultiplicity_MCBeam_41.bs +NeutronMultiplicity_MCBeam_42.bs +NeutronMultiplicity_MCBeam_43.bs +NeutronMultiplicity_MCBeam_44.bs +NeutronMultiplicity_MCBeam_45.bs +NeutronMultiplicity_MCBeam_46.bs +NeutronMultiplicity_MCBeam_47.bs +NeutronMultiplicity_MCBeam_48.bs +NeutronMultiplicity_MCBeam_49.bs +NeutronMultiplicity_MCBeam_50.bs +NeutronMultiplicity_MCBeam_51.bs +NeutronMultiplicity_MCBeam_52.bs +NeutronMultiplicity_MCBeam_53.bs +NeutronMultiplicity_MCBeam_54.bs +NeutronMultiplicity_MCBeam_55.bs +NeutronMultiplicity_MCBeam_56.bs +NeutronMultiplicity_MCBeam_57.bs +NeutronMultiplicity_MCBeam_58.bs +NeutronMultiplicity_MCBeam_59.bs +NeutronMultiplicity_MCBeam_60.bs +NeutronMultiplicity_MCBeam_61.bs +NeutronMultiplicity_MCBeam_62.bs +NeutronMultiplicity_MCBeam_63.bs +NeutronMultiplicity_MCBeam_64.bs +NeutronMultiplicity_MCBeam_65.bs +NeutronMultiplicity_MCBeam_66.bs +NeutronMultiplicity_MCBeam_67.bs +NeutronMultiplicity_MCBeam_68.bs +NeutronMultiplicity_MCBeam_69.bs +NeutronMultiplicity_MCBeam_70.bs +NeutronMultiplicity_MCBeam_71.bs +NeutronMultiplicity_MCBeam_72.bs +NeutronMultiplicity_MCBeam_73.bs +NeutronMultiplicity_MCBeam_74.bs +NeutronMultiplicity_MCBeam_75.bs +NeutronMultiplicity_MCBeam_76.bs +NeutronMultiplicity_MCBeam_77.bs +NeutronMultiplicity_MCBeam_78.bs +NeutronMultiplicity_MCBeam_79.bs +NeutronMultiplicity_MCBeam_80.bs +NeutronMultiplicity_MCBeam_81.bs +NeutronMultiplicity_MCBeam_82.bs +NeutronMultiplicity_MCBeam_83.bs +NeutronMultiplicity_MCBeam_84.bs +NeutronMultiplicity_MCBeam_85.bs +NeutronMultiplicity_MCBeam_86.bs +NeutronMultiplicity_MCBeam_87.bs +NeutronMultiplicity_MCBeam_88.bs +NeutronMultiplicity_MCBeam_89.bs +NeutronMultiplicity_MCBeam_90.bs +NeutronMultiplicity_MCBeam_91.bs +NeutronMultiplicity_MCBeam_92.bs +NeutronMultiplicity_MCBeam_93.bs +NeutronMultiplicity_MCBeam_94.bs +NeutronMultiplicity_MCBeam_95.bs +NeutronMultiplicity_MCBeam_96.bs +NeutronMultiplicity_MCBeam_97.bs +NeutronMultiplicity_MCBeam_98.bs +NeutronMultiplicity_MCBeam_99.bs +NeutronMultiplicity_MCBeam_100.bs diff --git a/configfiles/NeutronMultiplicity/RunNeutronMultiplicity.sh b/configfiles/NeutronMultiplicity/RunNeutronMultiplicity.sh new file mode 100755 index 000000000..df0089f63 --- /dev/null +++ b/configfiles/NeutronMultiplicity/RunNeutronMultiplicity.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +if [ "$#" -ne 1 ]; then + echo "Usage: ./RunNeutronMultiplicity.sh RUNLIST" + echo "Specified input variable must contain the path to a file specifying all runs" + exit 1 +fi + +RUNLIST=$1 +cut=CBStrict + +while read -r run +do + echo "$run" + ./CreateMyList_Processed.sh /pnfs/annie/persistent/processed/processed_hits/R${run} ${run} + + #Change into the ToolAnalysis directory first + cd ../../ + + #Run analysis from here + sed -i "6s#.*#Filename NeutronMultiplicity_R${run}_${cut}#" configfiles/NeutronMultiplicity/NeutronMultiplicityConfig + sed -i "4s#.*#Method ${cut}#" configfiles/NeutronMultiplicity/FindNeutronsConfig + ./Analyse ./configfiles/NeutronMultiplicity/ToolChainConfig + + #Change back + cd configfiles/NeutronMultiplicity/ +done < $RUNLIST + diff --git a/configfiles/NeutronMultiplicity/RunNeutronMultiplicityFiltered.sh b/configfiles/NeutronMultiplicity/RunNeutronMultiplicityFiltered.sh new file mode 100755 index 000000000..390cb76b7 --- /dev/null +++ b/configfiles/NeutronMultiplicity/RunNeutronMultiplicityFiltered.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +if [ "$#" -ne 1 ]; then + echo "Usage: ./RunNeutronMultiplicityFiltered.sh RUNLIST" + echo "Specified input variable must contain the path to a file specifying all runs" + exit 1 +fi + +RUNLIST=$1 + +FILTERED_DIR=/pnfs/annie/persistent/users/mnieslon/NeutronMultiplicity/FilteredEvents + +cut=CBStrict + +while read -r run +do + echo "$run" + + #Change into TA directory + cd ../../ + + #Filtered event files need to be in the directory of ToolAnalysis + echo ${FILTERED_DIR}/FilteredEvents_R${run}_NeutrinoCandidate > my_inputs.txt + cp my_inputs.txt configfiles/NeutronMultiplicity + + #Adapt config file + sed -i "6s#.*#Filename NeutronMultiplicity_R${run}_${cut}#" configfiles/NeutronMultiplicity/NeutronMultiplicityConfig + sed -i "4s#.*#Method ${cut}#" configfiles/NeutronMultiplicity/FindNeutronsConfig + + #Run analysis + ./Analyse configfiles/NeutronMultiplicity/ToolChainConfig + + #Change back into previous directory + cd configfiles/NeutronMultiplicity/ + +done < $RUNLIST + diff --git a/configfiles/NeutronMultiplicity/SimpleReconstructionConfig b/configfiles/NeutronMultiplicity/SimpleReconstructionConfig new file mode 100644 index 000000000..0990e01a4 --- /dev/null +++ b/configfiles/NeutronMultiplicity/SimpleReconstructionConfig @@ -0,0 +1,3 @@ +# SimpleReconstruction config file + +verbosity 1 diff --git a/configfiles/NeutronMultiplicity/TimeClusteringConfig b/configfiles/NeutronMultiplicity/TimeClusteringConfig new file mode 100644 index 000000000..e778247fc --- /dev/null +++ b/configfiles/NeutronMultiplicity/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/NeutronMultiplicity/ToolChainConfig b/configfiles/NeutronMultiplicity/ToolChainConfig new file mode 100644 index 000000000..10ded5cd4 --- /dev/null +++ b/configfiles/NeutronMultiplicity/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/NeutronMultiplicity/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/NeutronMultiplicity/ToolsConfig b/configfiles/NeutronMultiplicity/ToolsConfig new file mode 100644 index 000000000..ed181d678 --- /dev/null +++ b/configfiles/NeutronMultiplicity/ToolsConfig @@ -0,0 +1,10 @@ +myLoadANNIEEvent LoadANNIEEvent ./configfiles/NeutronMultiplicity/LoadANNIEEventConfig +myLoadGeometry LoadGeometry ./configfiles/LoadGeometry/LoadGeometryConfig +myTimeClustering TimeClustering configfiles/NeutronMultiplicity/TimeClusteringConfig +myFindMrdTracks FindMrdTracks configfiles/NeutronMultiplicity/FindMrdTracksConfig +myClusterFinder ClusterFinder ./configfiles/NeutronMultiplicity/ClusterFinderConfig +myClusterClassifiers ClusterClassifiers ./configfiles/NeutronMultiplicity/ClusterClassifiersConfig +myEventSelector EventSelector ./configfiles/NeutronMultiplicity/EventSelectorConfig +mySimpleReconstruction SimpleReconstruction ./configfiles/NeutronMultiplicity/SimpleReconstructionConfig +myFindNeutrons FindNeutrons ./configfiles/NeutronMultiplicity/FindNeutronsConfig +myNeutronMultiplicity NeutronMultiplicity ./configfiles/NeutronMultiplicity/NeutronMultiplicityConfig diff --git a/configfiles/NeutronMultiplicity/my_inputs.txt b/configfiles/NeutronMultiplicity/my_inputs.txt new file mode 100644 index 000000000..6b0e2de33 --- /dev/null +++ b/configfiles/NeutronMultiplicity/my_inputs.txt @@ -0,0 +1 @@ +/pnfs/annie/persistent/users/mnieslon/NeutronMultiplicity/FilteredEvents/FilteredEvents_R2630_NeutrinoCandidate diff --git a/configfiles/NeutronMultiplicity/my_inputs_old.txt b/configfiles/NeutronMultiplicity/my_inputs_old.txt new file mode 100644 index 000000000..e58972378 --- /dev/null +++ b/configfiles/NeutronMultiplicity/my_inputs_old.txt @@ -0,0 +1,173 @@ +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p0 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p1 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p2 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p3 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p4 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p5 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p6 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p7 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p8 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p9 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p10 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p11 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p12 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p13 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p14 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p15 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p16 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p17 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p18 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p19 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p20 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p21 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p22 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p23 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p24 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p25 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p26 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p27 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p28 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p29 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p30 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p31 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p32 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p33 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p34 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p35 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p36 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p37 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p38 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p39 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p40 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p41 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p42 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p43 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p44 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p45 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p46 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p47 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p48 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p49 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p50 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p51 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p52 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p53 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p54 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p55 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p56 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p57 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p58 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p59 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p60 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p61 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p62 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p63 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p64 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p65 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p66 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p67 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p68 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p69 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p70 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p71 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p72 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p73 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p74 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p75 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p76 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p77 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p78 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p79 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p80 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p81 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p82 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p83 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p84 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p85 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p86 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p87 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p88 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p89 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p90 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p91 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p92 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p93 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p94 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p95 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p96 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p97 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p98 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p99 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p100 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p101 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p102 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p103 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p104 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p105 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p106 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p107 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p108 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p109 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p110 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p111 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p112 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p113 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p114 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p115 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p116 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p117 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p118 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p119 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p120 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p121 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p122 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p123 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p124 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p125 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p126 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p127 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p128 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p129 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p130 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p131 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p132 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p133 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p134 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p135 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p136 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p137 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p138 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p139 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p140 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p141 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p142 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p143 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p144 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p145 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p146 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p147 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p148 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p149 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p150 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p151 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p152 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p153 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p154 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p155 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p156 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p157 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p158 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p159 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p160 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p161 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p162 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p163 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p164 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p165 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p166 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p167 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p168 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p169 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p170 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p171 +/pnfs/annie/persistent/users/mnieslon/data/processed_hits_improved/R2573/ProcessedRawData_TankAndMRDAndCTC_R2573S0p172 diff --git a/configfiles/NeutronMultiplicity/root-scripts/README.md b/configfiles/NeutronMultiplicity/root-scripts/README.md new file mode 100644 index 000000000..20d82b269 --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/README.md @@ -0,0 +1,16 @@ +# ROOT scripts + +The following root scripts were used for the neutron multiplicity analysis before the ToolAnalysis implementation. The single root scripts can be executed via + +`root -l 'script_name.C("input_file.root","output_file.root",verbose_bool)'` + +in the terminal. + +The different scripts will produce different diagrams in the output files: + +* `plot_neutrons_data_beam.C`: Regular neutron multiplicity plots on data (beam events) +* `plot_neutrons_data_dirt.C`: Regular neutron multiplicity plots on data (dirt events) +* `plot_neutrons_data_mc.C`: Regular neutron multiplicity plots on MC (simulated beam events) +* `neutrino_selection.C`: Histograms which show the time and charge distributions after the various neutrino candidate selection cuts +* `reconstruction_migration.C`: Migration plots for the different reconstructed variables (energy, cos(theta)) +* `visible_energy_vertex.C`: Histograms of the visible energy as a function of the vertex coordinates diff --git a/configfiles/NeutronMultiplicity/root-scripts/RunCreateEfficiencyMC.sh b/configfiles/NeutronMultiplicity/root-scripts/RunCreateEfficiencyMC.sh new file mode 100755 index 000000000..16cd7e7e8 --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/RunCreateEfficiencyMC.sh @@ -0,0 +1,15 @@ +#/bin/bash + +portlist="./portlist.txt" +heightlist="./heightlist.txt" + +while read -r port +do + echo "Port: ${port}" + while read -r height + do + echo "Z: ${height}" + root -b -l -q "create_efficiency_mc.C(${port},${height})" + done < $heightlist +done < $portlist + diff --git a/configfiles/NeutronMultiplicity/root-scripts/create_efficiency_mc.C b/configfiles/NeutronMultiplicity/root-scripts/create_efficiency_mc.C new file mode 100644 index 000000000..6f2d6e9aa --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/create_efficiency_mc.C @@ -0,0 +1,133 @@ +void create_efficiency_mc_new(int port, int height){ + + std::stringstream file_out; + file_out <<"ambe_mc_eff_port"<Get("phaseIITankClusterTree"); + TTree *tTrigger = (TTree*) fin->Get("phaseIITriggerTree"); + + int sipm1pulses; + int sipm2pulses; + std::vector* sipmhitT = new std::vector; + std::vector* hitT = new std::vector; + std::vector* hitPE = new std::vector; + std::vector* hitChankey = new std::vector; + double clusterPE; + double clusterT; + double clusterCB; + double clusterMaxPE; + uint32_t clusterHits; + int evnumber; + int clusternumber; + + //t->SetBranchAddress("SiPM1NPulses",&sipm1pulses); + //t->SetBranchAddress("SiPM2NPulses",&sipm2pulses); + //t->SetBranchAddress("SiPMhitT",&sipmhitT); + t->SetBranchAddress("hitT",&hitT); + t->SetBranchAddress("hitPE",&hitPE); + t->SetBranchAddress("hitChankey",&hitChankey); + t->SetBranchAddress("clusterPE",&clusterPE); + t->SetBranchAddress("clusterMaxPE",&clusterMaxPE); + t->SetBranchAddress("clusterTime",&clusterT); + t->SetBranchAddress("clusterChargeBalance",&clusterCB); + t->SetBranchAddress("eventNumber",&evnumber); + t->SetBranchAddress("clusterNumber",&clusternumber); + t->SetBranchAddress("clusterHits",&clusterHits); + + int entries = t->GetEntries(); + int entriesTrigger = tTrigger->GetEntries(); + + int entries_time_range=0; + std::vector *nT = new std::vector; + tTrigger->SetBranchAddress("trueNeutCapTime",&nT); + + bool prompt = false; + bool last_event = -1; + std::vector pmt_charges; + std::vector pmt_charges_corrected; + + //std::cout <<"Tree entries: "<GetEntry(i_trigger); + for (int i_n=0; i_n< nT->size(); i_n++){ + if (nT->at(i_n) >= tmin && nT->at(i_n) <= tmax) entries_time_range++; + } + } + + for (int i_entry = 0; i_entry < entries; i_entry++){ + + t->GetEntry(i_entry); + + //std::cout <size(); + std::cout <<"sipm hits size: "<at(1)-sipmhitT->at(0); + if (fabs(delta_t)>200) { + std::cout <<"Time difference between sipm peaks > 200ns! ("< 150) continue; + + //Timing cut (standard > 10us and <67us) + //10us due to afterpulsing -> search for better discrimination in the future + //67us due to readout window + if (clusterT < tmin || clusterT > tmax) continue; + + //CB < 0.4 + if (clusterCB <= 0.4) n_candidates_CB++; + + if (clusterHits >= 10) n_candidates_NHits10++; + + if ((clusterCB <= 0.4) && (clusterCB <= (1.-clusterPE/150.)*0.5)) n_candidates_CBStrict++; + } + + fin->Close(); + delete fin; + + ofstream eff_file_nhits("ambe_eff_mc_NHits10.txt",ios_base::app); + eff_file_nhits <Get("phaseIITriggerTree"); + TTree *tMRD = (TTree*) f->Get("phaseIIMRDClusterTree"); + TTree *tPMT = (TTree*) f->Get("phaseIITankClusterTree"); + + TFile *fout = new TFile(outfile,"RECREATE"); + + int nentries_trigger = tTrigger->GetEntries(); + int nentries_mrd = tMRD->GetEntries(); + int nentries_pmt = tPMT->GetEntries(); + + std::cout << "Entries Trigger/MRD/PMT: "<* eloss = new std::vector; + std::vector* mrdstop = new std::vector; + std::vector* mrdstartx = new std::vector; + std::vector* mrdstarty = new std::vector; + std::vector* mrdstartz = new std::vector; + std::vector* mrdstopx = new std::vector; + std::vector* mrdstopy = new std::vector; + std::vector* mrdstopz = new std::vector; + + double cluster_time; + double cluster_cb; + double cluster_pe; + int extended; + int trigword; + int extended_trigger; + + int tankmrdcoinc; + int noveto; + double true_muone; + int true_pdg; + double true_vtxx; + double true_vtxy; + double true_vtxz; + + tTrigger->SetBranchAddress("runNumber",&run_trigger); + tMRD->SetBranchAddress("runNumber",&run_mrd); + tPMT->SetBranchAddress("runNumber",&run_pmt); + tTrigger->SetBranchAddress("eventNumber",&ev_trigger); + tMRD->SetBranchAddress("eventNumber",&ev_mrd); + tPMT->SetBranchAddress("eventNumber",&ev_pmt); + tTrigger->SetBranchAddress("eventTimeTank",&eventTimeTank); + tTrigger->SetBranchAddress("beam_ok",&beam_ok); + tTrigger->SetBranchAddress("trigword",&trigword); + tTrigger->SetBranchAddress("numMRDTracks",&num_mrd_tracks); + tTrigger->SetBranchAddress("MRDEnergyLoss",&eloss); + tTrigger->SetBranchAddress("MRDTrackStartX",&mrdstartx); + tTrigger->SetBranchAddress("MRDTrackStartY",&mrdstarty); + tTrigger->SetBranchAddress("MRDTrackStartZ",&mrdstartz); + tTrigger->SetBranchAddress("MRDTrackStopX",&mrdstopx); + tTrigger->SetBranchAddress("MRDTrackStopY",&mrdstopy); + tTrigger->SetBranchAddress("MRDTrackStopZ",&mrdstopz); + tTrigger->SetBranchAddress("MRDStop",&mrdstop); + tTrigger->SetBranchAddress("HasTank",&has_tank); + tPMT->SetBranchAddress("clusterTime",&cluster_time); + tPMT->SetBranchAddress("clusterPE",&cluster_pe); + tPMT->SetBranchAddress("clusterChargeBalance",&cluster_cb); + tPMT->SetBranchAddress("Extended",&extended); + tTrigger->SetBranchAddress("Extended",&extended_trigger); + tTrigger->SetBranchAddress("TankMRDCoinc",&tankmrdcoinc); + tTrigger->SetBranchAddress("NoVeto",&noveto); + tTrigger->SetBranchAddress("trueMuonEnergy",&true_muone); + tTrigger->SetBranchAddress("truePrimaryPdg",&true_pdg); + tTrigger->SetBranchAddress("trueVtxX",&true_vtxx); + tTrigger->SetBranchAddress("trueVtxY",&true_vtxy); + tTrigger->SetBranchAddress("trueVtxZ",&true_vtxz); + + TH1F *h_time_beam = new TH1F("h_time_beam","PMT Cluster time distribution (beam events)",200,0,2000); + TH1F *h_time_beam_mrdcoinc = new TH1F("h_time_beam_mrdcoinc","PMT Cluster time distribution (beam events + MRD coincidence)",200,0,2000); + TH1F *h_time_beam_mrdcoinc_noveto = new TH1F("h_time_beam_mrdcoinc_noveto","PMT Cluster time distribution (beam events + MRD coincidence + no veto)",200,0,2000); + TH1F *h_time_beam_mrdcoinc_noveto_beamok = new TH1F("h_time_beam_mrdcoinc_noveto_beamok","PMT Cluster time distribution (beam events + MRD coincidence + no veto + beam ok)",200,0,2000); + TH1F *h_time_beam_mrdcoinc_noveto_beamok_extended = new TH1F("h_time_beam_mrdcoinc_noveto_beamok_extended","PMT Cluster time distribution (beam events + MRD coincidence + no veto + beam ok + extended)",200,0,2000); + TH1F *h_charge_beam = new TH1F("h_charge_beam","PMT Cluster charge distribution (beam events)",500,0,5000); + TH1F *h_charge_beam_mrdcoinc = new TH1F("h_charge_beam_mrdcoinc","PMT Cluster charge distribution (beam events + MRD coincidence)",500,0,5000); + TH1F *h_charge_beam_mrdcoinc_noveto = new TH1F("h_charge_beam_mrdcoinc_noveto","PMT Cluster charge distribution (beam events + MRD coincidence + no veto)",500,0,5000); + TH1F *h_charge_beam_mrdcoinc_noveto_beamok = new TH1F("h_charge_beam_mrdcoinc_noveto_beamok","PMT Cluster charge distribution (beam events + MRD coincidence + no veto + beam ok)",500,0,5000); + TH1F *h_charge_beam_mrdcoinc_noveto_beamok_extended = new TH1F("h_charge_beam_mrdcoinc_noveto_beamok_extended","PMT Cluster charge distribution (beam events + MRD coincidence + no veto + beam ok + extended)",500,0,5000); + + TTree *tout = new TTree("selection_tree","Data selection tree"); + int mrdcoinc; + int no_veto; + int beamok; + int is_extended; + double clusterT; + double clusterQ; + int run_nr; + int ev_nr; + ULong64_t ev_timestamp; + tout->Branch("mrdcoinc",&mrdcoinc); + tout->Branch("no_veto",&no_veto); + tout->Branch("beamok",&beamok); + tout->Branch("is_extended",&is_extended); + tout->Branch("clusterT",&clusterT); + tout->Branch("clusterQ",&clusterQ); + tout->Branch("run_nr",&run_nr); + tout->Branch("ev_nr",&ev_nr); + tout->Branch("ev_timestamp",&ev_timestamp); + + int i_pmt=0; + for (int i_trig=0; i_trig < nentries_trigger; i_trig++){ + std::cout <<"Load trig entry "<GetEntry(i_trig); + bool found_coinc=false; + double max_pe = 0; + mrdcoinc = 0; + no_veto = 0; + beamok = 0; + is_extended = 0; + clusterT = -999; + clusterQ = -999; + run_nr = -999; + ev_nr = -999; + ev_timestamp = 0; + if (trigword != 5) continue; + + bool check_above=false; + bool check_below = false; + bool run_switch=false; + + while (i_pmt < nentries_pmt){ + tPMT->GetEntry(i_pmt); + if (verbose){ + std::cout <<"i_pmt: "< max_pe) { + max_pe = cluster_pe; + clusterT = cluster_time; + clusterQ = cluster_pe; + } + i_pmt++; + found_coinc = true; + + } else if (found_coinc) break; + + else if (ev_pmt < ev_trigger) {i_pmt++; check_below=true;} + else if (ev_pmt > ev_trigger && i_pmt > 0 && !run_switch) {i_pmt--; check_above=true;} + if (run_switch && ev_pmt > ev_trigger) break; + if (i_pmt ==0) break; + if (check_below && check_above) break; + } + else if (run_pmt < run_trigger) {i_pmt++; run_switch=true;} + else if (i_pmt > 0) break; + } + if (extended_trigger) is_extended = 1; + if (tankmrdcoinc) mrdcoinc = 1; + if (noveto) no_veto = 1; + if (beam_ok) beamok = 1; + if (tankmrdcoinc && noveto && beam_ok) { + std::cout <<"Found event that passed selection, run_trigger = "<Get("phaseIITriggerTree"); + TTree *tMRD = (TTree*) f->Get("phaseIIMRDClusterTree"); + TTree *tPMT = (TTree*) f->Get("phaseIITankClusterTree"); + + TFile *fout = new TFile(outfile,"RECREATE"); + + int nentries_trigger = tTrigger->GetEntries(); + int nentries_mrd = tMRD->GetEntries(); + int nentries_pmt = tPMT->GetEntries(); + + std::cout << "Entries Trigger/MRD/PMT: "<* eloss = new std::vector; + std::vector* tracklength = new std::vector; + std::vector* mrdstop = new std::vector; + std::vector* mrdstartx = new std::vector; + std::vector* mrdstarty = new std::vector; + std::vector* mrdstartz = new std::vector; + std::vector* mrdstopx = new std::vector; + std::vector* mrdstopy = new std::vector; + std::vector* mrdstopz = new std::vector; + + double cluster_time; + double cluster_cb; + double cluster_pe; + int extended; + int trigword; + int extended_trigger; + + int tankmrdcoinc; + int noveto; + double true_muone; + int true_pdg; + double true_vtxx; + double true_vtxy; + double true_vtxz; + + tTrigger->SetBranchAddress("runNumber",&run_trigger); + tMRD->SetBranchAddress("runNumber",&run_mrd); + tPMT->SetBranchAddress("runNumber",&run_pmt); + tTrigger->SetBranchAddress("eventNumber",&ev_trigger); + tMRD->SetBranchAddress("eventNumber",&ev_mrd); + tPMT->SetBranchAddress("eventNumber",&ev_pmt); + tTrigger->SetBranchAddress("eventTimeTank",&eventTimeTank); + tTrigger->SetBranchAddress("beam_ok",&beam_ok); + tTrigger->SetBranchAddress("trigword",&trigword); + tTrigger->SetBranchAddress("numMRDTracks",&num_mrd_tracks); + tTrigger->SetBranchAddress("MRDTrackLength",&tracklength); + tTrigger->SetBranchAddress("MRDEnergyLoss",&eloss); + tTrigger->SetBranchAddress("MRDTrackStartX",&mrdstartx); + tTrigger->SetBranchAddress("MRDTrackStartY",&mrdstarty); + tTrigger->SetBranchAddress("MRDTrackStartZ",&mrdstartz); + tTrigger->SetBranchAddress("MRDTrackStopX",&mrdstopx); + tTrigger->SetBranchAddress("MRDTrackStopY",&mrdstopy); + tTrigger->SetBranchAddress("MRDTrackStopZ",&mrdstopz); + tTrigger->SetBranchAddress("MRDStop",&mrdstop); + tTrigger->SetBranchAddress("HasTank",&has_tank); + tPMT->SetBranchAddress("clusterTime",&cluster_time); + tPMT->SetBranchAddress("clusterPE",&cluster_pe); + tPMT->SetBranchAddress("clusterChargeBalance",&cluster_cb); + tPMT->SetBranchAddress("Extended",&extended); + tTrigger->SetBranchAddress("Extended",&extended_trigger); + tTrigger->SetBranchAddress("TankMRDCoinc",&tankmrdcoinc); + tTrigger->SetBranchAddress("NoVeto",&noveto); + tTrigger->SetBranchAddress("trueMuonEnergy",&true_muone); + tTrigger->SetBranchAddress("truePrimaryPdg",&true_pdg); + tTrigger->SetBranchAddress("trueVtxX",&true_vtxx); + tTrigger->SetBranchAddress("trueVtxY",&true_vtxy); + tTrigger->SetBranchAddress("trueVtxZ",&true_vtxz); + + TH1F *h_time_neutrons = new TH1F("h_time_neutrons","Cluster time beam neutrons",200,10000,70000); + TH1F *h_time_neutrons_mrdstop = new TH1F("h_time_neutrons_mrdstop","Cluster time beam neutrons",200,10000,70000); + TH1F *h_neutrons = new TH1F("h_neutrons","Number of neutrons in beam events",10,0,10); + TH1F *h_neutrons_mrdstop = new TH1F("h_neutrons_mrdstop","Number of of neutrons in beam events (MRD stop)",10,0,10); + TH1F *h_neutrons_mrdstop_fv = new TH1F("h_neutrons_mrdstop_fv","Number of of neutrons in beam events (MRD stop, FV)",10,0,10); + TH2F *h_neutrons_energy = new TH2F("h_neutrons_energy","Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + TH2F *h_neutrons_energy_fv = new TH2F("h_neutrons_energy_fv","Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + TH2F *h_neutrons_energy_zoom = new TH2F("h_neutrons_energy_zoom","Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + TH2F *h_neutrons_energy_fv_zoom = new TH2F("h_neutrons_energy_fv_zoom","Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + TH2F *h_neutrons_costheta = new TH2F("h_neutrons_costheta","Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + TH2F *h_neutrons_costheta_fv = new TH2F("h_neutrons_costheta_fv","Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + TH1F *h_muon_energy = new TH1F("h_muon_energy","Muon energy distribution",100,0,2000); + TH1F *h_muon_energy_fv = new TH1F("h_muon_energy_fv","Muon energy distribution (FV)",100,0,2000); + TH1F *h_muon_costheta = new TH1F("h_muon_costheta","Muon cos(#theta) distribution",100,-1,1); + TH1F *h_muon_costheta_fv = new TH1F("h_muon_costheta_fv","Muon cos(#theta) distribution (FV)",100,-1,1); + TH1F *h_muon_vtx_x = new TH1F("h_muon_vtx_x","Muon vertex (x)",200,-3,3); + TH1F *h_muon_vtx_y = new TH1F("h_muon_vtx_y","Muon vertex (y)",200,-3,3); + TH1F *h_muon_vtx_z = new TH1F("h_muon_vtx_z","Muon vertex (z)",200,-3,3); + TH2F *h_muon_vtx_yz = new TH2F("h_muon_vtx_yz","Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + TH2F *h_muon_vtx_xz = new TH2F("h_muon_vtx_xz","Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + + double Emu; + double Enu; + double vtxX; + double vtxY; + double vtxZ; + std::vector *clusterCB = new std::vector; + std::vector *clusterTime = new std::vector; + std::vector *clusterPE = new std::vector; + std::vector *nCandCB = new std::vector; + std::vector *nCandTime = new std::vector; + std::vector *nCandPE = new std::vector; + double mrdTrackLength; + double mrdEnergyLoss; + int tankMRDCoinc; + int clusters; + int nCandidates; + double RecoVtxX; + double RecoVtxY; + double RecoVtxZ; + int FV; + double cosTheta; + + TTree *tout = new TTree("neutron_tree","Neutron tree"); + tout->Branch("TankMRDCoinc",&tankMRDCoinc); + tout->Branch("nCandidates",&nCandidates); + tout->Branch("Emu",&Emu); + tout->Branch("Enu",&Enu); + tout->Branch("RecoVtxX",&RecoVtxX); + tout->Branch("RecoVtxY",&RecoVtxY); + tout->Branch("RecoVtxZ",&RecoVtxZ); + tout->Branch("FV",&FV); + tout->Branch("Clusters",&clusters); + tout->Branch("ClusterCB",&clusterCB); + tout->Branch("ClusterTime",&clusterTime); + tout->Branch("ClusterPE",&clusterPE); + tout->Branch("nCandCB",&nCandCB); + tout->Branch("nCandTime",&nCandTime); + tout->Branch("nCandPE",&nCandPE); + tout->Branch("mrdTrackLength",&mrdTrackLength); + tout->Branch("mrdEnergyLoss",&mrdEnergyLoss); + tout->Branch("cosTheta",&cosTheta); + + int i_pmt=0; + for (int i_trig=0; i_trig < nentries_trigger; i_trig++){ + std::cout <<"Load trig entry "<GetEntry(i_trig); + if (!tankmrdcoinc) continue; + if (!noveto) continue; + if (trigword != 5) continue; + bool found_coinc=false; + bool is_extended = false; + int n_neutrons=0; + double max_pe = 0; + std::vector n_times; + std::vector n_times_alt; + Emu = 0.; + Enu = 0.; + mrdTrackLength = 0; + mrdEnergyLoss = 0; + clusterCB->clear(); + clusterTime->clear(); + clusterPE->clear(); + nCandCB->clear(); + nCandTime->clear(); + nCandPE->clear(); + clusters = 0; + nCandidates = 0; + RecoVtxX = -999; + RecoVtxY = -999; + RecoVtxZ = -999; + cosTheta = -999; + FV = 0; + + bool check_above=false; + bool check_below = false; + bool run_switch=false; + + while (i_pmt < nentries_pmt){ + tPMT->GetEntry(i_pmt); + if (verbose){ + std::cout <<"i_pmt: "< max_pe) max_pe = cluster_pe; + if (cluster_time > 10000 && extended > 0 && beam_ok == 1 && cluster_pe < 120 && cluster_cb < 0.4){ + if (cluster_cb <= (1.-cluster_pe/150.)*0.5) { + n_neutrons++; + nCandCB->push_back(cluster_cb); + nCandTime->push_back(cluster_time); + nCandPE->push_back(cluster_pe); + n_times.push_back(cluster_time); + nCandidates ++; + } + } + i_pmt++; + found_coinc = true; + if (extended) is_extended = true; + clusters++; + clusterCB->push_back(cluster_cb); + clusterTime->push_back(cluster_time); + clusterPE->push_back(cluster_pe); + + } else if (found_coinc) break; + else if (ev_pmt < ev_trigger) {i_pmt++; check_below=true;} + else if (ev_pmt > ev_trigger && i_pmt > 0 && !run_switch) {i_pmt--; check_above=true;} + if (run_switch && ev_pmt > ev_trigger) break; + if (i_pmt ==0) break; + if (check_below && check_above) break; + } + else if (run_pmt < run_trigger) {i_pmt++; run_switch=true;} + else if (i_pmt > 0) break; + } + if (found_coinc && is_extended && num_mrd_tracks == 1) { + h_neutrons->Fill(n_neutrons); + for (int i_t = 0; i_t < (int) n_times.size(); i_t++){ + h_time_neutrons->Fill(n_times.at(i_t)); + } + if (mrdstop->at(0)){ + for (int i_t = 0; i_t < (int) n_times.size(); i_t++){ + h_time_neutrons_mrdstop->Fill(n_times.at(i_t)); + } + h_neutrons_mrdstop->Fill(n_neutrons); + + //Energy reconstruction + double muon_eloss = eloss->at(0); + double mrdTrackLength = tracklength->at(0); + double reco_muon_energy = muon_eloss + max_pe*0.08534; + + //Direction information (from MRD) + double startx = mrdstartx->at(0); + double starty = mrdstarty->at(0); + double startz = mrdstartz->at(0); + double stopx = mrdstopx->at(0); + double stopy = mrdstopy->at(0); + double stopz = mrdstopz->at(0); + double diffx = stopx-startx; + double diffy = stopy-starty; + double diffz = stopz-startz; + double startz_c = startz-1.681; + bool hit_tank = false; + double a = pow(diffx,2)+pow(diffz,2); + double b = -2*diffx*startx-2*diffz*startz_c; + double c = pow(startx,2)+pow(startz_c,2)-1.0*1.0; + double t1 = (-b+sqrt(b*b-4*a*c))/(2*a); + double t2 = (-b-sqrt(b*b-4*a*c))/(2*a); + double t = 0; + if (t1 < 0) t = t2; + else if (t2 < 0) t = t1; + else t = (t1 < t2)? t1 : t2; + double exitx = startx - t*diffx; + double exity = starty - t*diffy; + double exitz = startz - t*diffz; + double dirx = diffx/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double diry = diffy/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double dirz = diffz/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + cosTheta = dirz; + + double dist_mrd = sqrt(pow(startx-stopx,2)+pow(starty-stopy,2)+pow(startz-stopz,2)); + double dist_air = sqrt(pow(startx-exitx,2)+pow(starty-exity,2)+pow(startz-exitz,2)); + double dist_air_x = sqrt(pow(startx-exitx,2)); + double dist_air_y = sqrt(pow(starty-exity,2)); + double dist_air_z = sqrt(pow(startz-exitz,2)); + + double ap = pow(diffx,2)+pow(diffz,2); + double bp = -2*diffx*startx-2*diffz*startz_c; + double cp = pow(startx,2)+pow(startz_c,2)-1.5*1.5; + double t1p = (-bp+sqrt(bp*bp-4*ap*cp))/(2*ap); + double t2p = (-bp-sqrt(bp*bp-4*ap*cp))/(2*ap); + std::cout <<"t1, t2: "<Fill(reco_muon_energy,n_neutrons); + h_neutrons_energy_zoom->Fill(reco_muon_energy,n_neutrons); + h_muon_energy->Fill(reco_muon_energy); + h_neutrons_costheta->Fill(cosTheta,n_neutrons); + h_muon_costheta->Fill(cosTheta); + + double reco_vtxx = exitx - max_pe/9/2./100.*dirx; + double reco_vtxy = exity - max_pe/9/2./100.*diry; + double reco_vtxz = exitz - max_pe/9/2./100.*dirz; + + h_muon_vtx_x->Fill(reco_vtxx); + h_muon_vtx_y->Fill(reco_vtxy); + h_muon_vtx_z->Fill(reco_vtxz); + h_muon_vtx_yz->Fill(reco_vtxz,reco_vtxy); + h_muon_vtx_xz->Fill(reco_vtxz,reco_vtxx); + + FV = 0; + + if (sqrt(reco_vtxx*reco_vtxx+(reco_vtxz-1.681)*(reco_vtxz-1.681))<1.0 && fabs(reco_vtxy)<0.5 && ((reco_vtxz-1.681) < 0.)) { + h_neutrons_energy_fv->Fill(reco_muon_energy,n_neutrons); + h_neutrons_energy_fv_zoom->Fill(reco_muon_energy,n_neutrons); + h_muon_energy_fv->Fill(reco_muon_energy); + h_muon_costheta_fv->Fill(cosTheta); + h_neutrons_mrdstop_fv->Fill(n_neutrons); + h_neutrons_costheta_fv->Fill(cosTheta,n_neutrons); + FV = 1; + } + + Emu = reco_muon_energy; + RecoVtxX = reco_vtxx; + RecoVtxY = reco_vtxy; + RecoVtxZ = reco_vtxz; + mrdEnergyLoss = muon_eloss; + tankMRDCoinc = tankmrdcoinc; + tout->Fill(); + } + } + } + + + + h_neutrons->SetLineWidth(2); + h_neutrons->SetStats(0); + h_neutrons->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop->SetLineWidth(2); + h_neutrons_mrdstop->SetLineColor(kBlack); + h_neutrons_mrdstop->SetStats(0); + h_neutrons_mrdstop->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop_fv->SetLineWidth(2); + h_neutrons_mrdstop_fv->SetStats(0); + h_neutrons_mrdstop_fv->SetLineColor(kRed); + h_neutrons_mrdstop_fv->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop_fv->GetYaxis()->SetTitle("#"); + + h_neutrons_energy->SetStats(0); + h_neutrons_energy->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_zoom->SetStats(0); + h_neutrons_energy_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_zoom->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv->SetStats(0); + h_neutrons_energy_fv->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv_zoom->SetStats(0); + h_neutrons_energy_fv_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv_zoom->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"); + + h_neutrons_costheta_fv->SetStats(0); + h_neutrons_costheta_fv->GetXaxis()->SetTitle("cos(#theta)"); + h_neutrons_costheta_fv->GetYaxis()->SetTitle("Number of neutrons"); + + TGraphErrors *gr_neutrons_muon = new TGraphErrors(); + TGraphErrors *gr_neutrons_muon_fv = new TGraphErrors(); + TGraphErrors *gr_neutrons_neutrino = new TGraphErrors(); + TGraphErrors *gr_neutrons_neutrino_fv = new TGraphErrors(); + + int i_graph = 0; + int n_bins_x = 10; + int n_bins_y = 20; + for (int i=0; iGetBinContent(i+1,j+1); + mean_n+= (j*nentries); + n_n += nentries; + } + if (n_n>0){ + mean_n /= n_n; + gr_neutrons_muon->SetPoint(i_graph,(i+0.5)*200,mean_n); + std::cout <<"Setting point (X/Y): "<<(i+0.5)*200<<" / "<GetBinContent(i+1,j+1); + std_dev+=(nentries*(j-mean_n)*(j-mean_n)); + } + if (n_n>1) std_dev/=(n_n-1); + std_dev = sqrt(std_dev); + if (n_n>0) std_dev/=sqrt(n_n); + gr_neutrons_muon->SetPointError(i_graph,100,std_dev); + std::cout <<"Setting error (X/Y): "<<100<<" / "<GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_muon_energy->GetYaxis()->SetTitle("#"); + h_muon_energy->SetStats(0); + h_muon_energy->SetLineWidth(2); + h_muon_energy_fv->SetStats(0); + h_muon_energy_fv->SetLineColor(kRed); + h_muon_energy_fv->SetLineWidth(2); + + + i_graph = 0; + for (int i=0; iGetBinContent(i+1,j+1); + mean_n+= (j*nentries); + n_n += nentries; + } + if (n_n>0){ + mean_n /= n_n; + gr_neutrons_muon_fv->SetPoint(i_graph,(i+0.5)*200,mean_n); + std::cout <<"Setting point (X/Y): "<<(i+0.5)*200<<" / "<GetBinContent(i+1,j+1); + std_dev+=(nentries*(j-mean_n)*(j-mean_n)); + } + if (n_n>1) std_dev/=(n_n-1); + std_dev = sqrt(std_dev); + if (n_n>0) std_dev/=sqrt(n_n); + gr_neutrons_muon_fv->SetPointError(i_graph,100,std_dev); + std::cout <<"Setting error (X/Y): "<<100<<" / "<GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_yz->GetYaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_yz->SetStats(0); + h_muon_vtx_xz->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_xz->GetYaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_xz->SetStats(0); + + h_muon_vtx_x->GetXaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_x->GetYaxis()->SetTitle("#"); + h_muon_vtx_y->GetXaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_y->GetYaxis()->SetTitle("#"); + h_muon_vtx_z->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_z->GetYaxis()->SetTitle("#"); + + + fout->Write(); + + gr_neutrons_muon->Write("gr_neutrons_muon"); + gr_neutrons_muon_fv->Write("gr_neutrons_muon_fv"); + + fout->Close(); + +} diff --git a/configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_data_dirt.C b/configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_data_dirt.C new file mode 100644 index 000000000..b676b541e --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_data_dirt.C @@ -0,0 +1,483 @@ +void plot_neutrons_data_dirt(const char* infile, const char* outfile, bool verbose = false){ + + TFile *f = new TFile(infile,"READ"); + TTree *tTrigger = (TTree*) f->Get("phaseIITriggerTree"); + TTree *tMRD = (TTree*) f->Get("phaseIIMRDClusterTree"); + TTree *tPMT = (TTree*) f->Get("phaseIITankClusterTree"); + + TFile *fout = new TFile(outfile,"RECREATE"); + + int nentries_trigger = tTrigger->GetEntries(); + int nentries_mrd = tMRD->GetEntries(); + int nentries_pmt = tPMT->GetEntries(); + + std::cout << "Entries Trigger/MRD/PMT: "<* eloss = new std::vector; + std::vector* tracklength = new std::vector; + std::vector* mrdstop = new std::vector; + std::vector* mrdstartx = new std::vector; + std::vector* mrdstarty = new std::vector; + std::vector* mrdstartz = new std::vector; + std::vector* mrdstopx = new std::vector; + std::vector* mrdstopy = new std::vector; + std::vector* mrdstopz = new std::vector; + + double cluster_time; + double cluster_cb; + double cluster_pe; + int extended; + int trigword; + int extended_trigger; + + int tankmrdcoinc; + int noveto; + double true_muone; + int true_pdg; + double true_vtxx; + double true_vtxy; + double true_vtxz; + + tTrigger->SetBranchAddress("runNumber",&run_trigger); + tMRD->SetBranchAddress("runNumber",&run_mrd); + tPMT->SetBranchAddress("runNumber",&run_pmt); + tTrigger->SetBranchAddress("eventNumber",&ev_trigger); + tMRD->SetBranchAddress("eventNumber",&ev_mrd); + tPMT->SetBranchAddress("eventNumber",&ev_pmt); + tTrigger->SetBranchAddress("eventTimeTank",&eventTimeTank); + tTrigger->SetBranchAddress("beam_ok",&beam_ok); + tTrigger->SetBranchAddress("trigword",&trigword); + tTrigger->SetBranchAddress("numMRDTracks",&num_mrd_tracks); + tTrigger->SetBranchAddress("MRDTrackLength",&tracklength); + tTrigger->SetBranchAddress("MRDEnergyLoss",&eloss); + tTrigger->SetBranchAddress("MRDTrackStartX",&mrdstartx); + tTrigger->SetBranchAddress("MRDTrackStartY",&mrdstarty); + tTrigger->SetBranchAddress("MRDTrackStartZ",&mrdstartz); + tTrigger->SetBranchAddress("MRDTrackStopX",&mrdstopx); + tTrigger->SetBranchAddress("MRDTrackStopY",&mrdstopy); + tTrigger->SetBranchAddress("MRDTrackStopZ",&mrdstopz); + tTrigger->SetBranchAddress("MRDStop",&mrdstop); + tTrigger->SetBranchAddress("HasTank",&has_tank); + tPMT->SetBranchAddress("clusterTime",&cluster_time); + tPMT->SetBranchAddress("clusterPE",&cluster_pe); + tPMT->SetBranchAddress("clusterChargeBalance",&cluster_cb); + tPMT->SetBranchAddress("Extended",&extended); + tTrigger->SetBranchAddress("Extended",&extended_trigger); + tTrigger->SetBranchAddress("TankMRDCoinc",&tankmrdcoinc); + tTrigger->SetBranchAddress("NoVeto",&noveto); + tTrigger->SetBranchAddress("trueMuonEnergy",&true_muone); + tTrigger->SetBranchAddress("truePrimaryPdg",&true_pdg); + tTrigger->SetBranchAddress("trueVtxX",&true_vtxx); + tTrigger->SetBranchAddress("trueVtxY",&true_vtxy); + tTrigger->SetBranchAddress("trueVtxZ",&true_vtxz); + + TH1F *h_time_neutrons = new TH1F("h_time_neutrons","Cluster time beam neutrons",200,10000,70000); + TH1F *h_time_neutrons_mrdstop = new TH1F("h_time_neutrons_mrdstop","Cluster time beam neutrons",200,10000,70000); + TH1F *h_neutrons = new TH1F("h_neutrons","Number of neutrons in beam events",10,0,10); + TH1F *h_neutrons_mrdstop = new TH1F("h_neutrons_mrdstop","Number of of neutrons in beam events (MRD stop)",10,0,10); + TH1F *h_neutrons_mrdstop_fv = new TH1F("h_neutrons_mrdstop_fv","Number of of neutrons in beam events (MRD stop, FV)",10,0,10); + TH2F *h_neutrons_energy = new TH2F("h_neutrons_energy","Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + TH2F *h_neutrons_energy_fv = new TH2F("h_neutrons_energy_fv","Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + TH2F *h_neutrons_energy_zoom = new TH2F("h_neutrons_energy_zoom","Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + TH2F *h_neutrons_energy_fv_zoom = new TH2F("h_neutrons_energy_fv_zoom","Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + TH2F *h_neutrons_costheta = new TH2F("h_neutrons_costheta","Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + TH2F *h_neutrons_costheta_fv = new TH2F("h_neutrons_costheta_fv","Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + TH1F *h_muon_energy = new TH1F("h_muon_energy","Muon energy distribution",100,0,2000); + TH1F *h_muon_energy_fv = new TH1F("h_muon_energy_fv","Muon energy distribution (FV)",100,0,2000); + TH1F *h_muon_costheta = new TH1F("h_muon_costheta","Muon cos(#theta) distribution",100,-1,1); + TH1F *h_muon_costheta_fv = new TH1F("h_muon_costheta_fv","Muon cos(#theta) distribution (FV)",100,-1,1); + TH1F *h_muon_vtx_x = new TH1F("h_muon_vtx_x","Muon vertex (x)",200,-3,3); + TH1F *h_muon_vtx_y = new TH1F("h_muon_vtx_y","Muon vertex (y)",200,-3,3); + TH1F *h_muon_vtx_z = new TH1F("h_muon_vtx_z","Muon vertex (z)",200,-3,3); + TH2F *h_muon_vtx_yz = new TH2F("h_muon_vtx_yz","Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + TH2F *h_muon_vtx_xz = new TH2F("h_muon_vtx_xz","Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + + double Emu; + double Enu; + double vtxX; + double vtxY; + double vtxZ; + std::vector *clusterCB = new std::vector; + std::vector *clusterTime = new std::vector; + std::vector *clusterPE = new std::vector; + std::vector *nCandCB = new std::vector; + std::vector *nCandTime = new std::vector; + std::vector *nCandPE = new std::vector; + double mrdTrackLength; + double mrdEnergyLoss; + int tankMRDCoinc; + int clusters; + int nCandidates; + double RecoVtxX; + double RecoVtxY; + double RecoVtxZ; + int FV; + double cosTheta; + + TTree *tout = new TTree("neutron_tree","Neutron tree"); + tout->Branch("TankMRDCoinc",&tankMRDCoinc); + tout->Branch("nCandidates",&nCandidates); + tout->Branch("Emu",&Emu); + tout->Branch("Enu",&Enu); + tout->Branch("RecoVtxX",&RecoVtxX); + tout->Branch("RecoVtxY",&RecoVtxY); + tout->Branch("RecoVtxZ",&RecoVtxZ); + tout->Branch("FV",&FV); + tout->Branch("Clusters",&clusters); + tout->Branch("ClusterCB",&clusterCB); + tout->Branch("ClusterTime",&clusterTime); + tout->Branch("ClusterPE",&clusterPE); + tout->Branch("nCandCB",&nCandCB); + tout->Branch("nCandTime",&nCandTime); + tout->Branch("nCandPE",&nCandPE); + tout->Branch("mrdTrackLength",&mrdTrackLength); + tout->Branch("mrdEnergyLoss",&mrdEnergyLoss); + tout->Branch("cosTheta",&cosTheta); + + int i_pmt=0; + for (int i_trig=0; i_trig < nentries_trigger; i_trig++){ + std::cout <<"Load trig entry "<GetEntry(i_trig); + if (!tankmrdcoinc) continue; + if (noveto) continue; + if (trigword != 5) continue; + bool found_coinc=false; + bool is_extended = false; + int n_neutrons=0; + double max_pe = 0; + std::vector n_times; + std::vector n_times_alt; + Emu = 0.; + Enu = 0.; + mrdTrackLength = 0; + mrdEnergyLoss = 0; + clusterCB->clear(); + clusterTime->clear(); + clusterPE->clear(); + nCandCB->clear(); + nCandTime->clear(); + nCandPE->clear(); + clusters = 0; + nCandidates = 0; + RecoVtxX = -999; + RecoVtxY = -999; + RecoVtxZ = -999; + cosTheta = -999; + FV = 0; + + bool check_above=false; + bool check_below = false; + bool run_switch=false; + + while (i_pmt < nentries_pmt){ + tPMT->GetEntry(i_pmt); + if (verbose){ + std::cout <<"i_pmt: "< max_pe) max_pe = cluster_pe; + if (cluster_time > 10000 && extended > 0 && beam_ok == 1 && cluster_pe < 120 && cluster_cb < 0.4){ + if (cluster_cb <= (1.-cluster_pe/150.)*0.5) { + n_neutrons++; + nCandCB->push_back(cluster_cb); + nCandTime->push_back(cluster_time); + nCandPE->push_back(cluster_pe); + n_times.push_back(cluster_time); + nCandidates ++; + } + } + i_pmt++; + found_coinc = true; + if (extended) is_extended = true; + clusters++; + clusterCB->push_back(cluster_cb); + clusterTime->push_back(cluster_time); + clusterPE->push_back(cluster_pe); + + } else if (found_coinc) break; + else if (ev_pmt < ev_trigger) {i_pmt++; check_below=true;} + else if (ev_pmt > ev_trigger && i_pmt > 0 && !run_switch) {i_pmt--; check_above=true;} + if (run_switch && ev_pmt > ev_trigger) break; + if (i_pmt ==0) break; + if (check_below && check_above) break; + } + else if (run_pmt < run_trigger) {i_pmt++; run_switch=true;} + else if (i_pmt > 0) break; + } + if (found_coinc && is_extended && num_mrd_tracks == 1) { + h_neutrons->Fill(n_neutrons); + for (int i_t = 0; i_t < (int) n_times.size(); i_t++){ + h_time_neutrons->Fill(n_times.at(i_t)); + } + if (mrdstop->at(0)){ + for (int i_t = 0; i_t < (int) n_times.size(); i_t++){ + h_time_neutrons_mrdstop->Fill(n_times.at(i_t)); + } + h_neutrons_mrdstop->Fill(n_neutrons); + + //Energy reconstruction + double muon_eloss = eloss->at(0); + double mrdTrackLength = tracklength->at(0); + double reco_muon_energy = muon_eloss + max_pe*0.08534; + + //Direction information (from MRD) + double startx = mrdstartx->at(0); + double starty = mrdstarty->at(0); + double startz = mrdstartz->at(0); + double stopx = mrdstopx->at(0); + double stopy = mrdstopy->at(0); + double stopz = mrdstopz->at(0); + double diffx = stopx-startx; + double diffy = stopy-starty; + double diffz = stopz-startz; + double startz_c = startz-1.681; + bool hit_tank = false; + double a = pow(diffx,2)+pow(diffz,2); + double b = -2*diffx*startx-2*diffz*startz_c; + double c = pow(startx,2)+pow(startz_c,2)-1.0*1.0; + double t1 = (-b+sqrt(b*b-4*a*c))/(2*a); + double t2 = (-b-sqrt(b*b-4*a*c))/(2*a); + double t = 0; + if (t1 < 0) t = t2; + else if (t2 < 0) t = t1; + else t = (t1 < t2)? t1 : t2; + double exitx = startx - t*diffx; + double exity = starty - t*diffy; + double exitz = startz - t*diffz; + double dirx = diffx/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double diry = diffy/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double dirz = diffz/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + cosTheta = dirz; + + double dist_mrd = sqrt(pow(startx-stopx,2)+pow(starty-stopy,2)+pow(startz-stopz,2)); + double dist_air = sqrt(pow(startx-exitx,2)+pow(starty-exity,2)+pow(startz-exitz,2)); + double dist_air_x = sqrt(pow(startx-exitx,2)); + double dist_air_y = sqrt(pow(starty-exity,2)); + double dist_air_z = sqrt(pow(startz-exitz,2)); + + double ap = pow(diffx,2)+pow(diffz,2); + double bp = -2*diffx*startx-2*diffz*startz_c; + double cp = pow(startx,2)+pow(startz_c,2)-1.5*1.5; + double t1p = (-bp+sqrt(bp*bp-4*ap*cp))/(2*ap); + double t2p = (-bp-sqrt(bp*bp-4*ap*cp))/(2*ap); + std::cout <<"t1, t2: "<Fill(reco_muon_energy,n_neutrons); + h_neutrons_energy_zoom->Fill(reco_muon_energy,n_neutrons); + h_muon_energy->Fill(reco_muon_energy); + h_neutrons_costheta->Fill(cosTheta,n_neutrons); + h_muon_costheta->Fill(cosTheta); + + //Neutrino energy reconstruction (with direction from MRD) + //double reco_neutrino_energy = calculate_neutrino(reco_muon_energy,diffz); + //Vertex reconstruction + + double reco_vtxx = exitx - max_pe/9/2./100.*dirx; + double reco_vtxy = exity - max_pe/9/2./100.*diry; + double reco_vtxz = exitz - max_pe/9/2./100.*dirz; + + h_muon_vtx_x->Fill(reco_vtxx); + h_muon_vtx_y->Fill(reco_vtxy); + h_muon_vtx_z->Fill(reco_vtxz); + h_muon_vtx_yz->Fill(reco_vtxz,reco_vtxy); + h_muon_vtx_xz->Fill(reco_vtxz,reco_vtxx); + + FV = 0; + + if (sqrt(reco_vtxx*reco_vtxx+(reco_vtxz-1.681)*(reco_vtxz-1.681))<1.0 && fabs(reco_vtxy)<0.5 && ((reco_vtxz-1.681) < 0.)) { + h_neutrons_energy_fv->Fill(reco_muon_energy,n_neutrons); + h_neutrons_energy_fv_zoom->Fill(reco_muon_energy,n_neutrons); + h_muon_energy_fv->Fill(reco_muon_energy); + h_muon_costheta_fv->Fill(cosTheta); + h_neutrons_mrdstop_fv->Fill(n_neutrons); + h_neutrons_costheta_fv->Fill(cosTheta,n_neutrons); + FV = 1; + } + + Emu = reco_muon_energy; + RecoVtxX = reco_vtxx; + RecoVtxY = reco_vtxy; + RecoVtxZ = reco_vtxz; + mrdEnergyLoss = muon_eloss; + tankMRDCoinc = tankmrdcoinc; + tout->Fill(); + } + } + } + + + + h_neutrons->SetLineWidth(2); + h_neutrons->SetStats(0); + h_neutrons->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop->SetLineWidth(2); + h_neutrons_mrdstop->SetLineColor(kBlack); + h_neutrons_mrdstop->SetStats(0); + h_neutrons_mrdstop->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop_fv->SetLineWidth(2); + h_neutrons_mrdstop_fv->SetStats(0); + h_neutrons_mrdstop_fv->SetLineColor(kRed); + h_neutrons_mrdstop_fv->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop_fv->GetYaxis()->SetTitle("#"); + + h_neutrons_energy->SetStats(0); + h_neutrons_energy->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_zoom->SetStats(0); + h_neutrons_energy_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_zoom->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv->SetStats(0); + h_neutrons_energy_fv->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv_zoom->SetStats(0); + h_neutrons_energy_fv_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv_zoom->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"); + + h_neutrons_costheta_fv->SetStats(0); + h_neutrons_costheta_fv->GetXaxis()->SetTitle("cos(#theta)"); + h_neutrons_costheta_fv->GetYaxis()->SetTitle("Number of neutrons"); + + TGraphErrors *gr_neutrons_muon = new TGraphErrors(); + TGraphErrors *gr_neutrons_muon_fv = new TGraphErrors(); + TGraphErrors *gr_neutrons_neutrino = new TGraphErrors(); + TGraphErrors *gr_neutrons_neutrino_fv = new TGraphErrors(); + + int i_graph = 0; + int n_bins_x = 10; + int n_bins_y = 20; + for (int i=0; iGetBinContent(i+1,j+1); + mean_n+= (j*nentries); + n_n += nentries; + } + if (n_n>0){ + mean_n /= n_n; + gr_neutrons_muon->SetPoint(i_graph,(i+0.5)*200,mean_n); + std::cout <<"Setting point (X/Y): "<<(i+0.5)*200<<" / "<GetBinContent(i+1,j+1); + std_dev+=(nentries*(j-mean_n)*(j-mean_n)); + } + if (n_n>1) std_dev/=(n_n-1); + std_dev = sqrt(std_dev); + if (n_n>0) std_dev/=sqrt(n_n); + gr_neutrons_muon->SetPointError(i_graph,100,std_dev); + std::cout <<"Setting error (X/Y): "<<100<<" / "<GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_muon_energy->GetYaxis()->SetTitle("#"); + h_muon_energy->SetStats(0); + h_muon_energy->SetLineWidth(2); + h_muon_energy_fv->SetStats(0); + h_muon_energy_fv->SetLineColor(kRed); + h_muon_energy_fv->SetLineWidth(2); + + + i_graph = 0; + for (int i=0; iGetBinContent(i+1,j+1); + mean_n+= (j*nentries); + n_n += nentries; + } + if (n_n>0){ + mean_n /= n_n; + gr_neutrons_muon_fv->SetPoint(i_graph,(i+0.5)*200,mean_n); + std::cout <<"Setting point (X/Y): "<<(i+0.5)*200<<" / "<GetBinContent(i+1,j+1); + std_dev+=(nentries*(j-mean_n)*(j-mean_n)); + } + if (n_n>1) std_dev/=(n_n-1); + std_dev = sqrt(std_dev); + if (n_n>0) std_dev/=sqrt(n_n); + gr_neutrons_muon_fv->SetPointError(i_graph,100,std_dev); + std::cout <<"Setting error (X/Y): "<<100<<" / "<GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_yz->GetYaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_yz->SetStats(0); + h_muon_vtx_xz->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_xz->GetYaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_xz->SetStats(0); + + h_muon_vtx_x->GetXaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_x->GetYaxis()->SetTitle("#"); + h_muon_vtx_y->GetXaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_y->GetYaxis()->SetTitle("#"); + h_muon_vtx_z->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_z->GetYaxis()->SetTitle("#"); + + + fout->Write(); + + gr_neutrons_muon->Write("gr_neutrons_muon"); + gr_neutrons_muon_fv->Write("gr_neutrons_muon_fv"); + + fout->Close(); + +} diff --git a/configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_mc.C b/configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_mc.C new file mode 100644 index 000000000..1a40b87af --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/plot_neutrons_mc.C @@ -0,0 +1,582 @@ +void plot_neutrons_mc(const char* infile, const char* outfile, bool verbose = false){ + + TFile *f = new TFile(infile,"READ"); + TTree *tTrigger = (TTree*) f->Get("phaseIITriggerTree"); + TTree *tMRD = (TTree*) f->Get("phaseIIMRDClusterTree"); + TTree *tPMT = (TTree*) f->Get("phaseIITankClusterTree"); + + TFile *fout = new TFile(outfile,"RECREATE"); + + int nentries_trigger = tTrigger->GetEntries(); + int nentries_mrd = tMRD->GetEntries(); + int nentries_pmt = tPMT->GetEntries(); + + std::cout << "Entries Trigger/MRD/PMT: "<* eloss = new std::vector; + std::vector* tracklength = new std::vector; + std::vector* mrdstop = new std::vector; + std::vector* mrdstartx = new std::vector; + std::vector* mrdstarty = new std::vector; + std::vector* mrdstartz = new std::vector; + std::vector* mrdstopx = new std::vector; + std::vector* mrdstopy = new std::vector; + std::vector* mrdstopz = new std::vector; + + double cluster_time; + double cluster_cb; + double cluster_pe; + int extended; + + int tankmrdcoinc; + int noveto; + double true_muone; + int true_pdg; + double true_vtxx; + double true_vtxy; + double true_vtxz; + + int true_neutrons; + int true_protons; + int true_mec; + int true_dis; + int true_res; + int true_qel; + int true_cc; + double true_q2; + double true_neutrino_energy; + std::vector *true_neut_cap_e = new std::vector; + std::vector *true_neut_cap_time = new std::vector; + std::vector *true_neut_cap_nucl = new std::vector; + std::vector *true_neut_cap_vtxx = new std::vector; + std::vector *true_neut_cap_vtxy = new std::vector; + std::vector *true_neut_cap_vtxz = new std::vector; + std::vector *true_neut_cap_gammas = new std::vector; + std::vector *true_primary_pdgs = new std::vector; + int trueMultiRing; + + tTrigger->SetBranchAddress("runNumber",&run_trigger); + tMRD->SetBranchAddress("runNumber",&run_mrd); + tPMT->SetBranchAddress("runNumber",&run_pmt); + tTrigger->SetBranchAddress("eventNumber",&ev_trigger); + tMRD->SetBranchAddress("eventNumber",&ev_mrd); + tPMT->SetBranchAddress("eventNumber",&ev_pmt); + tTrigger->SetBranchAddress("beam_ok",&beam_ok); + tTrigger->SetBranchAddress("numMRDTracks",&num_mrd_tracks); + tTrigger->SetBranchAddress("MRDTrackLength",&tracklength); + tTrigger->SetBranchAddress("MRDEnergyLoss",&eloss); + tTrigger->SetBranchAddress("MRDTrackStartX",&mrdstartx); + tTrigger->SetBranchAddress("MRDTrackStartY",&mrdstarty); + tTrigger->SetBranchAddress("MRDTrackStartZ",&mrdstartz); + tTrigger->SetBranchAddress("MRDTrackStopX",&mrdstopx); + tTrigger->SetBranchAddress("MRDTrackStopY",&mrdstopy); + tTrigger->SetBranchAddress("MRDTrackStopZ",&mrdstopz); + tTrigger->SetBranchAddress("MRDStop",&mrdstop); + tTrigger->SetBranchAddress("HasTank",&has_tank); + tPMT->SetBranchAddress("clusterTime",&cluster_time); + tPMT->SetBranchAddress("clusterPE",&cluster_pe); + tPMT->SetBranchAddress("clusterChargeBalance",&cluster_cb); + tPMT->SetBranchAddress("Extended",&extended); + tTrigger->SetBranchAddress("TankMRDCoinc",&tankmrdcoinc); + tTrigger->SetBranchAddress("NoVeto",&noveto); + tTrigger->SetBranchAddress("trueMuonEnergy",&true_muone); + tTrigger->SetBranchAddress("truePrimaryPdg",&true_pdg); + tTrigger->SetBranchAddress("trueVtxX",&true_vtxx); + tTrigger->SetBranchAddress("trueVtxY",&true_vtxy); + tTrigger->SetBranchAddress("trueVtxZ",&true_vtxz); + tTrigger->SetBranchAddress("truePrimaryPdgs",&true_primary_pdgs); + tTrigger->SetBranchAddress("trueNeutCapVtxX",&true_neut_cap_vtxx); + tTrigger->SetBranchAddress("trueNeutCapVtxY",&true_neut_cap_vtxy); + tTrigger->SetBranchAddress("trueNeutCapVtxZ",&true_neut_cap_vtxz); + tTrigger->SetBranchAddress("trueNeutCapNucleus",&true_neut_cap_nucl); + tTrigger->SetBranchAddress("trueNeutCapTime",&true_neut_cap_time); + tTrigger->SetBranchAddress("trueNeutCapGammas",&true_neut_cap_gammas); + tTrigger->SetBranchAddress("trueNeutCapE",&true_neut_cap_e); + tTrigger->SetBranchAddress("trueNeutrinoEnergy",&true_neutrino_energy); + tTrigger->SetBranchAddress("trueQ2",&true_q2); + tTrigger->SetBranchAddress("trueCC",&true_cc); + tTrigger->SetBranchAddress("trueQEL",&true_qel); + tTrigger->SetBranchAddress("trueRES",&true_res); + tTrigger->SetBranchAddress("trueDIS",&true_dis); + tTrigger->SetBranchAddress("trueMEC",&true_mec); + tTrigger->SetBranchAddress("trueNeutrons",&true_neutrons); + tTrigger->SetBranchAddress("trueProtons",&true_protons); + tTrigger->SetBranchAddress("trueMultiRing",&trueMultiRing); + + TH1F *h_time_neutrons = new TH1F("h_time_neutrons","Cluster time beam neutrons",200,10000,70000); + TH1F *h_time_neutrons_mrdstop = new TH1F("h_time_neutrons_mrdstop","Cluster time beam neutrons",200,10000,70000); + TH1F *h_neutrons = new TH1F("h_neutrons","Number of neutrons in beam events",10,0,10); + TH1F *h_neutrons_mrdstop = new TH1F("h_neutrons_mrdstop","Number of of neutrons in beam events (MRD stop)",10,0,10); + TH1F *h_neutrons_mrdstop_fv = new TH1F("h_neutrons_mrdstop_fv","Number of of neutrons in beam events (MRD stop, FV)",10,0,10); + TH2F *h_neutrons_energy = new TH2F("h_neutrons_energy","Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + TH2F *h_neutrons_energy_fv = new TH2F("h_neutrons_energy_fv","Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + TH2F *h_neutrons_energy_zoom = new TH2F("h_neutrons_energy_zoom","Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + TH2F *h_neutrons_energy_fv_zoom = new TH2F("h_neutrons_energy_fv_zoom","Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + TH2F *h_primneutrons_energy = new TH2F("h_primneutrons_energy","Primary Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + TH2F *h_primneutrons_energy_fv = new TH2F("h_primneutrons_energy_fv","Primary Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + TH2F *h_primneutrons_energy_zoom = new TH2F("h_primneutrons_energy_zoom","Primary Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + TH2F *h_primneutrons_energy_fv_zoom = new TH2F("h_primneutrons_energy_fv_zoom","Primary Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + TH2F *h_totalneutrons_energy = new TH2F("h_totalneutrons_energy","Total Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + TH2F *h_totalneutrons_energy_fv = new TH2F("h_totalneutrons_energy_fv","Total Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + TH2F *h_totalneutrons_energy_zoom = new TH2F("h_totalneutrons_energy_zoom","Total Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + TH2F *h_totalneutrons_energy_fv_zoom = new TH2F("h_totalneutrons_energy_fv_zoom","Total Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + TH2F *h_pmtvolneutrons_energy = new TH2F("h_pmtvolneutrons_energy","PMTVol Neutron multiplicity vs muon energy",10,0,2000,20,0,20); + TH2F *h_pmtvolneutrons_energy_fv = new TH2F("h_pmtvolneutrons_energy_fv","PMTVol Neutron multiplicity vs muon energy (FV)",10,0,2000,20,0,20); + TH2F *h_pmtvolneutrons_energy_zoom = new TH2F("h_pmtvolneutrons_energy_zoom","PMTVol Neutron multiplicity vs muon energy",8,400,1200,20,0,20); + TH2F *h_pmtvolneutrons_energy_fv_zoom = new TH2F("h_pmtvolneutrons_energy_fv_zoom","PMTVol Neutron multiplicity vs muon energy (FV)",6,600,1200,20,0,20); + TH2F *h_neutrons_costheta = new TH2F("h_neutrons_costheta","Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + TH2F *h_neutrons_costheta_fv = new TH2F("h_neutrons_costheta_fv","Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + TH2F *h_primneutrons_costheta = new TH2F("h_primneutrons_costheta","Primary Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + TH2F *h_primneutrons_costheta_fv = new TH2F("h_primvolneutrons_costheta_fv","Primary Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + TH2F *h_totalneutrons_costheta = new TH2F("h_totalneutrons_costheta","Total Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + TH2F *h_totalneutrons_costheta_fv = new TH2F("h_totalneutrons_costheta_fv","Total Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + TH2F *h_pmtvolneutrons_costheta = new TH2F("h_pmtvolneutrons_costheta","PMTVol Neutron multiplicity vs muon angle",6,0.7,1.0,20,0,20); + TH2F *h_pmtvolneutrons_costheta_fv = new TH2F("h_pmtvolneutrons_costheta_fv","PMTVol Neutron multiplicity vs muon angle (FV)",6,0.7,1.0,20,0,20); + + TH1F *h_muon_energy = new TH1F("h_muon_energy","Muon energy distribution",100,0,2000); + TH1F *h_muon_energy_fv = new TH1F("h_muon_energy_fv","Muon energy distribution (FV)",100,0,2000); + TH2F *h_muon_vtx_yz = new TH2F("h_muon_vtx_yz","Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + TH2F *h_muon_vtx_xz = new TH2F("h_muon_vtx_xz","Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + TH1F *h_muon_costheta = new TH1F("h_muon_costheta","Muon cos(#theta) distribution",100,-1,1); + TH1F *h_muon_costheta_fv = new TH1F("h_muon_costheta_fv","Muon cos(#theta) distribution (FV)",100,-1,1); + TH1F *h_muon_vtx_x = new TH1F("h_muon_vtx_x","Muon vertex (x)",200,-3,3); + TH1F *h_muon_vtx_y = new TH1F("h_muon_vtx_y","Muon vertex (y)",200,-3,3); + TH1F *h_muon_vtx_z = new TH1F("h_muon_vtx_z","Muon vertex (z)",200,-3,3); + + int nPrimNeut; + int nPrimProt; + int nCaptures; + int nCapturesPMTVol; + double Emu; + double Enu; + double Q2; + double vtxX; + double vtxY; + double vtxZ; + std::vector *clusterCB = new std::vector; + std::vector *clusterTime = new std::vector; + std::vector *clusterPE = new std::vector; + std::vector *nCandCB = new std::vector; + std::vector *nCandTime = new std::vector; + std::vector *nCandPE = new std::vector; + double mrdEnergyLoss; + std::vector *neutVtxX = new std::vector; + std::vector *neutVtxY = new std::vector; + std::vector *neutVtxZ = new std::vector; + std::vector *neutCapNucl = new std::vector; + std::vector *neutCapTime = new std::vector; + std::vector *neutCapETotal = new std::vector; + std::vector *neutCapNGamma = new std::vector; + std::vector *neutCapPrimary = new std::vector; + int isCC; + int isQEL; + int isDIS; + int isRES; + int isCOH; + int isMEC; + int tankMRDCoinc; + int multiRing; + int clusters; + int nCandidates; + double RecoVtxX; + double RecoVtxY; + double RecoVtxZ; + int FV; + double cosTheta; + std::vector *primaryPdgs = new std::vector; + + TTree *tout = new TTree("neutron_tree","Neutron tree"); + tout->Branch("TankMRDCoinc",&tankMRDCoinc); + tout->Branch("nPrimNeut",&nPrimNeut); + tout->Branch("nPrimProt",&nPrimProt); + tout->Branch("nCaptures",&nCaptures); + tout->Branch("nCapturesPMTVol",&nCapturesPMTVol); + tout->Branch("nCandidates",&nCandidates); + tout->Branch("Emu",&Emu); + tout->Branch("Enu",&Enu); + tout->Branch("Q2",&Q2); + tout->Branch("vtxX",&vtxX); + tout->Branch("vtxY",&vtxY); + tout->Branch("vtxZ",&vtxZ); + tout->Branch("RecoVtxX",&RecoVtxX); + tout->Branch("RecoVtxY",&RecoVtxY); + tout->Branch("RecoVtxZ",&RecoVtxZ); + tout->Branch("FV",&FV); + tout->Branch("cosTheta",&cosTheta); + tout->Branch("Clusters",&clusters); + tout->Branch("ClusterCB",&clusterCB); + tout->Branch("ClusterTime",&clusterTime); + tout->Branch("ClusterPE",&clusterPE); + tout->Branch("nCandCB",&nCandCB); + tout->Branch("nCandTime",&nCandTime); + tout->Branch("nCandPE",&nCandPE); + tout->Branch("mrdEnergyLoss",&mrdEnergyLoss); + tout->Branch("neutVtxX",&neutVtxX); + tout->Branch("neutVtxY",&neutVtxY); + tout->Branch("neutVtxZ",&neutVtxZ); + tout->Branch("neutCapNucl",&neutCapNucl); + tout->Branch("neutCapTime",&neutCapTime); + tout->Branch("neutCapETotal",&neutCapETotal); + tout->Branch("neutCapNGamma",&neutCapNGamma); + tout->Branch("neutCapPrimary",&neutCapPrimary); + tout->Branch("isCC",&isCC); + tout->Branch("isQEL",&isQEL); + tout->Branch("isDIS",&isDIS); + tout->Branch("isRES",&isRES); + tout->Branch("isMEC",&isMEC); + tout->Branch("isCOH",&isCOH); + tout->Branch("multiRing",&multiRing); + tout->Branch("primaryPdgs",&primaryPdgs); + + int i_pmt=0; + for (int i_trig=0; i_trig < nentries_trigger; i_trig++){ + std::cout <<"Load trig entry "<GetEntry(i_trig); + if (!noveto) continue; + if (!tankmrdcoinc) continue; + bool found_coinc=false; + bool is_extended = false; + int n_neutrons=0; + double max_pe = 0; + std::vector n_times; + Emu = 0.; + Enu = 0.; + Q2 = 0.; + nPrimNeut = 0; + nPrimProt = 0; + nCaptures = 0; + nCapturesPMTVol = 0; + mrdEnergyLoss = 0; + clusterCB->clear(); + clusterTime->clear(); + clusterPE->clear(); + nCandCB->clear(); + nCandTime->clear(); + nCandPE->clear(); + primaryPdgs->clear(); + neutVtxX->clear(); + neutVtxY->clear(); + neutVtxZ->clear(); + neutCapNucl->clear(); + neutCapETotal->clear(); + neutCapNGamma->clear(); + isCC = 0; + isQEL = 0; + isDIS = 0; + isRES = 0; + isMEC = 0; + isCOH = 0; + multiRing = 0; + clusters = 0; + nCandidates = 0; + RecoVtxX = -999; + RecoVtxY = -999; + RecoVtxZ = -999; + cosTheta = -999; + FV = 0; + + bool check_above=false; + bool check_below = false; + bool run_switch=false; + + while (i_pmt < nentries_pmt){ + tPMT->GetEntry(i_pmt); + if (verbose){ + std::cout <<"i_pmt: "< max_pe) max_pe = cluster_pe; + if (cluster_time > 10000 && extended > 0 && beam_ok == 1 && cluster_pe < 120 && cluster_cb < 0.4){ + if (cluster_cb <= (1.-cluster_pe/150.)*0.5) { + + n_times.push_back(cluster_time); + n_neutrons++; + nCandCB->push_back(cluster_cb); + nCandTime->push_back(cluster_time); + nCandPE->push_back(cluster_pe); + } + } + i_pmt++; + found_coinc = true; + if (extended) is_extended = true; + clusters++; + clusterCB->push_back(cluster_cb); + clusterTime->push_back(cluster_time); + clusterPE->push_back(cluster_pe); + + } else if (found_coinc) break; + /*else if (ev_pmt < ev_trigger) i_pmt++; + else if (ev_pmt > ev_trigger) { + //i_pmt--; //Data case + break; //MC case + }*/ + else if (ev_pmt < ev_trigger) {i_pmt++; check_below=true;} + else if (ev_pmt > ev_trigger && i_pmt > 0 && !run_switch) {i_pmt--; check_above=true;} + if (run_switch && ev_pmt > ev_trigger) break; + if (i_pmt ==0) break; + if (check_below && check_above) break; + } + else if (run_pmt < run_trigger) {i_pmt++; run_switch = true;} + else if (i_pmt > 0) break; + } + if (found_coinc && is_extended && num_mrd_tracks == 1){ + h_neutrons->Fill(n_neutrons); + for (int i_t = 0; i_t < (int) n_times.size(); i_t++){ + h_time_neutrons->Fill(n_times.at(i_t)); + } + if (mrdstop->at(0)){ + for (int i_t = 0; i_t < (int) n_times.size(); i_t++){ + h_time_neutrons_mrdstop->Fill(n_times.at(i_t)); + } + h_neutrons_mrdstop->Fill(n_neutrons); + + //Energy reconstruction + double muon_eloss = eloss->at(0); + double mrdTrackLength = tracklength->at(0); + double reco_muon_energy = muon_eloss + max_pe*0.08534; + //Direction information (from MRD) + double startx = mrdstartx->at(0); + double starty = mrdstarty->at(0); + double startz = mrdstartz->at(0); + double stopx = mrdstopx->at(0); + double stopy = mrdstopy->at(0); + double stopz = mrdstopz->at(0); + double diffx = stopx-startx; + double diffy = stopy-starty; + double diffz = stopz-startz; + double startz_c = startz-1.681; + bool hit_tank = false; + double a = pow(diffx,2)+pow(diffz,2); + double b = -2*diffx*startx-2*diffz*startz_c; + double c = pow(startx,2)+pow(startz_c,2)-1.0*1.0; + double t1 = (-b+sqrt(b*b-4*a*c))/(2*a); + double t2 = (-b-sqrt(b*b-4*a*c))/(2*a); + double t = 0; + if (t1 < 0) t = t2; + else if (t2 < 0) t = t1; + else t = (t1 < t2)? t1 : t2; + double exitx = startx - t*diffx; + double exity = starty - t*diffy; + double exitz = startz - t*diffz; + double dirx = diffx/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double diry = diffy/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double dirz = diffz/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + cosTheta = dirz; + + double dist_mrd = sqrt(pow(startx-stopx,2)+pow(starty-stopy,2)+pow(startz-stopz,2)); + double dist_air = sqrt(pow(startx-exitx,2)+pow(starty-exity,2)+pow(startz-exitz,2)); + double dist_air_x = sqrt(pow(startx-exitx,2)); + double dist_air_y = sqrt(pow(starty-exity,2)); + double dist_air_z = sqrt(pow(startz-exitz,2)); + + double ap = pow(diffx,2)+pow(diffz,2); + double bp = -2*diffx*startx-2*diffz*startz_c; + double cp = pow(startx,2)+pow(startz_c,2)-1.5*1.5; + double t1p = (-bp+sqrt(bp*bp-4*ap*cp))/(2*ap); + double t2p = (-bp-sqrt(bp*bp-4*ap*cp))/(2*ap); + std::cout <<"t1, t2: "<Fill(reco_muon_energy,n_neutrons); + h_neutrons_energy_zoom->Fill(reco_muon_energy,n_neutrons); + h_muon_energy->Fill(reco_muon_energy); + h_neutrons_costheta->Fill(cosTheta,n_neutrons); + h_muon_costheta->Fill(cosTheta); + + //Vertex reconstruction + double reco_vtxx = exitx - max_pe/9/2./100.*dirx; + double reco_vtxy = exity - max_pe/9/2./100.*diry; + double reco_vtxz = exitz - max_pe/9/2./100.*dirz; + + h_muon_vtx_x->Fill(reco_vtxx); + h_muon_vtx_y->Fill(reco_vtxy); + h_muon_vtx_z->Fill(reco_vtxz); + h_muon_vtx_yz->Fill(reco_vtxz,reco_vtxy); + h_muon_vtx_xz->Fill(reco_vtxz,reco_vtxx); + + FV = 0; + + if (sqrt(reco_vtxx*reco_vtxx+(reco_vtxz-1.681)*(reco_vtxz-1.681))<1.0 && fabs(reco_vtxy)<0.5 && ((reco_vtxz-1.681) < 0.)) { + h_neutrons_energy_fv->Fill(reco_muon_energy,n_neutrons); + h_neutrons_energy_fv_zoom->Fill(reco_muon_energy,n_neutrons); + h_muon_energy_fv->Fill(reco_muon_energy); + h_muon_costheta_fv->Fill(cosTheta); + h_neutrons_mrdstop_fv->Fill(n_neutrons); + h_neutrons_costheta_fv->Fill(cosTheta,n_neutrons); + FV = 1; + } + + //MC version of vtx x/y/z + double vtxx = true_vtxx/100.; + double vtxy = true_vtxy/100.; + double vtxz = true_vtxz/100.; + vtxX = vtxx; + vtxY = vtxy; + vtxZ = vtxz; + Emu = reco_muon_energy; + RecoVtxX = reco_vtxx; + RecoVtxY = reco_vtxy; + RecoVtxZ = reco_vtxz; + mrdEnergyLoss = muon_eloss; + tankMRDCoinc = tankmrdcoinc; + nPrimNeut = true_neutrons; + isMEC = true_mec; + isDIS = true_dis; + isRES = true_res; + isQEL = true_qel; + isCC = true_cc; + Q2 = -true_q2; //For some reason Q2 in Genie is saved with negative sign + nPrimProt = true_protons; + multiRing = trueMultiRing; + nCaptures = true_neut_cap_vtxx->size(); + nCandidates = n_neutrons; + nCapturesPMTVol = 0; + for (int i_neut= 0; i_neut < (int) true_neut_cap_vtxx->size(); i_neut++){ + neutVtxX->push_back(true_neut_cap_vtxx->at(i_neut)); + neutVtxY->push_back(true_neut_cap_vtxy->at(i_neut)); + neutVtxZ->push_back(true_neut_cap_vtxz->at(i_neut)); + neutCapNucl->push_back(true_neut_cap_nucl->at(i_neut)); + neutCapTime->push_back(true_neut_cap_time->at(i_neut)); + neutCapETotal->push_back(true_neut_cap_e->at(i_neut)); + neutCapNGamma->push_back(true_neut_cap_gammas->at(i_neut)); + //PMT volume cut + double zcorr = true_neut_cap_vtxz->at(i_neut)/100.-1.681; + double ycorr = true_neut_cap_vtxy->at(i_neut)/100.+0.144; + double xcorr = true_neut_cap_vtxx->at(i_neut)/100.; + double rad = sqrt(xcorr*xcorr+zcorr*zcorr); + if (rad < 1.0 && fabs(ycorr)<1.5) nCapturesPMTVol++; + } + h_primneutrons_energy->Fill(reco_muon_energy,nPrimNeut); + h_primneutrons_energy_zoom->Fill(reco_muon_energy,nPrimNeut); + h_totalneutrons_energy->Fill(reco_muon_energy,nCaptures); + h_totalneutrons_energy_zoom->Fill(reco_muon_energy,nCaptures); + h_pmtvolneutrons_energy->Fill(reco_muon_energy,nCapturesPMTVol); + h_pmtvolneutrons_energy_zoom->Fill(reco_muon_energy,nCapturesPMTVol); + h_primneutrons_costheta->Fill(cosTheta,nPrimNeut); + h_totalneutrons_costheta->Fill(cosTheta,nCaptures); + h_pmtvolneutrons_costheta->Fill(cosTheta,nCapturesPMTVol); + if (FV){ + h_primneutrons_energy_fv->Fill(reco_muon_energy,nPrimNeut); + h_primneutrons_energy_fv_zoom->Fill(reco_muon_energy,nPrimNeut); + h_totalneutrons_energy_fv->Fill(reco_muon_energy,nCaptures); + h_totalneutrons_energy_fv_zoom->Fill(reco_muon_energy,nCaptures); + h_pmtvolneutrons_energy_fv->Fill(reco_muon_energy,nCapturesPMTVol); + h_pmtvolneutrons_energy_fv_zoom->Fill(reco_muon_energy,nCapturesPMTVol); + h_primneutrons_costheta_fv->Fill(cosTheta,nPrimNeut); + h_totalneutrons_costheta_fv->Fill(cosTheta,nCaptures); + h_pmtvolneutrons_costheta_fv->Fill(cosTheta,nCapturesPMTVol); + + } + for (int i_part = 0; i_part < (int) true_primary_pdgs->size(); i_part++){ + primaryPdgs->push_back(true_primary_pdgs->at(i_part)); + } + tout->Fill(); + + } + } + } + + h_neutrons->SetLineWidth(2); + h_neutrons->SetStats(0); + h_neutrons->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop->SetLineWidth(2); + h_neutrons_mrdstop->SetLineColor(kBlack); + h_neutrons_mrdstop->SetStats(0); + h_neutrons_mrdstop->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop->GetYaxis()->SetTitle("#"); + + h_neutrons_mrdstop_fv->SetLineWidth(2); + h_neutrons_mrdstop_fv->SetStats(0); + h_neutrons_mrdstop_fv->SetLineColor(kRed); + h_neutrons_mrdstop_fv->GetXaxis()->SetTitle("Number of neutrons"); + h_neutrons_mrdstop_fv->GetYaxis()->SetTitle("#"); + + h_neutrons_energy->SetStats(0); + h_neutrons_energy->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_zoom->SetStats(0); + h_neutrons_energy_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_zoom->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv->SetStats(0); + h_neutrons_energy_fv->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv->GetYaxis()->SetTitle("Number of neutrons"); + + h_neutrons_energy_fv_zoom->SetStats(0); + h_neutrons_energy_fv_zoom->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_neutrons_energy_fv_zoom->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"); + + h_neutrons_costheta_fv->SetStats(0); + h_neutrons_costheta_fv->GetXaxis()->SetTitle("cos(#theta)"); + h_neutrons_costheta_fv->GetYaxis()->SetTitle("Number of neutrons"); + + + h_muon_energy->GetXaxis()->SetTitle("E_{#mu} [MeV]"); + h_muon_energy->GetYaxis()->SetTitle("#"); + h_muon_energy->SetStats(0); + h_muon_energy->SetLineWidth(2); + h_muon_energy_fv->SetStats(0); + h_muon_energy_fv->SetLineColor(kRed); + h_muon_energy_fv->SetLineWidth(2); + + + h_muon_vtx_yz->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_yz->GetYaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_yz->SetStats(0); + h_muon_vtx_xz->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_xz->GetYaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_xz->SetStats(0); + + h_muon_vtx_x->GetXaxis()->SetTitle("Vertex X [m]"); + h_muon_vtx_x->GetYaxis()->SetTitle("#"); + h_muon_vtx_y->GetXaxis()->SetTitle("Vertex Y [m]"); + h_muon_vtx_y->GetYaxis()->SetTitle("#"); + h_muon_vtx_z->GetXaxis()->SetTitle("Vertex Z [m]"); + h_muon_vtx_z->GetYaxis()->SetTitle("#"); + + fout->Write(); + + fout->Close(); + +} diff --git a/configfiles/NeutronMultiplicity/root-scripts/portlist.txt b/configfiles/NeutronMultiplicity/root-scripts/portlist.txt new file mode 100644 index 000000000..8a1218a10 --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/portlist.txt @@ -0,0 +1,5 @@ +1 +2 +3 +4 +5 diff --git a/configfiles/NeutronMultiplicity/root-scripts/reconstruction_migration.C b/configfiles/NeutronMultiplicity/root-scripts/reconstruction_migration.C new file mode 100644 index 000000000..70abd42b0 --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/reconstruction_migration.C @@ -0,0 +1,655 @@ +double calculate_neutrino(double Emu, double cosT){ + + double Ev = 0; + double Mp = 938.272; + double Mn = 939.565; + double Eb = 26; + double Mmu = 105.658; + 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: "<Get("phaseIITriggerTree"); + TTree *tMRD = (TTree*) f->Get("phaseIIMRDClusterTree"); + TTree *tPMT = (TTree*) f->Get("phaseIITankClusterTree"); + + TFile *fout = new TFile(outfile,"RECREATE"); + + int nentries_trigger = tTrigger->GetEntries(); + int nentries_mrd = tMRD->GetEntries(); + int nentries_pmt = tPMT->GetEntries(); + + std::cout << "Entries Trigger/MRD/PMT: "<* eloss = new std::vector; + std::vector* tracklength = new std::vector; + std::vector* mrdstop = new std::vector; + std::vector* mrdstartx = new std::vector; + std::vector* mrdstarty = new std::vector; + std::vector* mrdstartz = new std::vector; + std::vector* mrdstopx = new std::vector; + std::vector* mrdstopy = new std::vector; + std::vector* mrdstopz = new std::vector; + + double cluster_time; + double cluster_cb; + double cluster_pe; + int extended; + + int tankmrdcoinc; + int noveto; + double true_muone; + int true_pdg; + double true_vtxx; + double true_vtxy; + double true_vtxz; + double true_dirx; + double true_diry; + double true_dirz; + + int true_neutrons; + int true_protons; + int true_mec; + int true_dis; + int true_res; + int true_qel; + int true_cc; + double true_q2; + double true_neutrino_energy; + std::vector *true_neut_cap_e = new std::vector; + std::vector *true_neut_cap_time = new std::vector; + std::vector *true_neut_cap_nucl = new std::vector; + std::vector *true_neut_cap_vtxx = new std::vector; + std::vector *true_neut_cap_vtxy = new std::vector; + std::vector *true_neut_cap_vtxz = new std::vector; + std::vector *true_neut_cap_gammas = new std::vector; + std::vector *true_primary_pdgs = new std::vector; + int trueMultiRing; + + tTrigger->SetBranchAddress("runNumber",&run_trigger); + tMRD->SetBranchAddress("runNumber",&run_mrd); + tPMT->SetBranchAddress("runNumber",&run_pmt); + tTrigger->SetBranchAddress("eventNumber",&ev_trigger); + tMRD->SetBranchAddress("eventNumber",&ev_mrd); + tPMT->SetBranchAddress("eventNumber",&ev_pmt); + tTrigger->SetBranchAddress("beam_ok",&beam_ok); + tTrigger->SetBranchAddress("numMRDTracks",&num_mrd_tracks); + tTrigger->SetBranchAddress("MRDTrackLength",&tracklength); + tTrigger->SetBranchAddress("MRDEnergyLoss",&eloss); + tTrigger->SetBranchAddress("MRDTrackStartX",&mrdstartx); + tTrigger->SetBranchAddress("MRDTrackStartY",&mrdstarty); + tTrigger->SetBranchAddress("MRDTrackStartZ",&mrdstartz); + tTrigger->SetBranchAddress("MRDTrackStopX",&mrdstopx); + tTrigger->SetBranchAddress("MRDTrackStopY",&mrdstopy); + tTrigger->SetBranchAddress("MRDTrackStopZ",&mrdstopz); + tTrigger->SetBranchAddress("MRDStop",&mrdstop); + tTrigger->SetBranchAddress("HasTank",&has_tank); + tPMT->SetBranchAddress("clusterTime",&cluster_time); + tPMT->SetBranchAddress("clusterPE",&cluster_pe); + tPMT->SetBranchAddress("clusterChargeBalance",&cluster_cb); + tPMT->SetBranchAddress("Extended",&extended); + tTrigger->SetBranchAddress("TankMRDCoinc",&tankmrdcoinc); + tTrigger->SetBranchAddress("NoVeto",&noveto); + tTrigger->SetBranchAddress("trueMuonEnergy",&true_muone); + tTrigger->SetBranchAddress("truePrimaryPdg",&true_pdg); + tTrigger->SetBranchAddress("trueVtxX",&true_vtxx); + tTrigger->SetBranchAddress("trueVtxY",&true_vtxy); + tTrigger->SetBranchAddress("trueVtxZ",&true_vtxz); + tTrigger->SetBranchAddress("truePrimaryPdgs",&true_primary_pdgs); + tTrigger->SetBranchAddress("trueNeutCapVtxX",&true_neut_cap_vtxx); + tTrigger->SetBranchAddress("trueNeutCapVtxY",&true_neut_cap_vtxy); + tTrigger->SetBranchAddress("trueNeutCapVtxZ",&true_neut_cap_vtxz); + tTrigger->SetBranchAddress("trueNeutCapNucleus",&true_neut_cap_nucl); + tTrigger->SetBranchAddress("trueNeutCapTime",&true_neut_cap_time); + tTrigger->SetBranchAddress("trueNeutCapGammas",&true_neut_cap_gammas); + tTrigger->SetBranchAddress("trueNeutCapE",&true_neut_cap_e); + tTrigger->SetBranchAddress("trueNeutrinoEnergy",&true_neutrino_energy); + tTrigger->SetBranchAddress("trueQ2",&true_q2); + tTrigger->SetBranchAddress("trueCC",&true_cc); + tTrigger->SetBranchAddress("trueQEL",&true_qel); + tTrigger->SetBranchAddress("trueRES",&true_res); + tTrigger->SetBranchAddress("trueDIS",&true_dis); + tTrigger->SetBranchAddress("trueMEC",&true_mec); + tTrigger->SetBranchAddress("trueNeutrons",&true_neutrons); + tTrigger->SetBranchAddress("trueProtons",&true_protons); + tTrigger->SetBranchAddress("trueMultiRing",&trueMultiRing); + tTrigger->SetBranchAddress("trueDirX",&true_dirx); + tTrigger->SetBranchAddress("trueDirY",&true_diry); + tTrigger->SetBranchAddress("trueDirZ",&true_dirz); + + TH1F *h_muon_energy = new TH1F("h_muon_energy","Muon energy distribution",100,0,2000); + TH1F *h_muon_energy_fv = new TH1F("h_muon_energy_fv","Muon energy distribution (FV)",100,0,2000); + TH1F *h_neutrino_energy = new TH1F("h_neutrino_energy","Neutrino energy distribution",100,0,2000); + TH1F *h_neutrino_energy_fv = new TH1F("h_neutrino_energy_fv","Neutrino energy distribution (FV)",100,0,2000); + TH1F *h_muon_vtx_x = new TH1F("h_muon_vtx_x","Muon vertex (x)",200,-3,3); + TH1F *h_muon_vtx_y = new TH1F("h_muon_vtx_y","Muon vertex (y)",200,-3,3); + TH1F *h_muon_vtx_z = new TH1F("h_muon_vtx_z","Muon vertex (z)",200,-3,3); + TH2F *h_muon_vtx_yz = new TH2F("h_muon_vtx_yz","Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + TH2F *h_muon_vtx_xz = new TH2F("h_muon_vtx_xz","Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + + TH1F *h_true_muon_energy = new TH1F("h_true_muon_energy","True Muon energy distribution",100,0,2000); + TH1F *h_true_muon_energy_fv = new TH1F("h_true_muon_energy_fv","True Muon energy distribution (FV)",100,0,2000); + TH1F *h_true_neutrino_energy = new TH1F("h_true_neutrino_energy","True Neutrino energy distribution",100,0,2000); + TH1F *h_true_neutrino_energy_fv = new TH1F("h_true_neutrino_energy_fv","True Neutrino energy distribution (FV)",100,0,2000); + TH1F *h_true_muon_vtx_x = new TH1F("h_true_muon_vtx_x","True Muon vertex (x)",200,-3,3); + TH1F *h_true_muon_vtx_y = new TH1F("h_true_muon_vtx_y","True Muon vertex (y)",200,-3,3); + TH1F *h_true_muon_vtx_z = new TH1F("h_true_muon_vtx_z","True Muon vertex (z)",200,-3,3); + TH2F *h_true_muon_vtx_yz = new TH2F("h_true_muon_vtx_yz","True Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + TH2F *h_true_muon_vtx_xz = new TH2F("h_true_muon_vtx_xz","True Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + + TH1F *h_diff_muon_energy = new TH1F("h_diff_muon_energy","Difference Muon energy distribution",100,-1000,1000); + TH1F *h_diff_muon_energy_fv = new TH1F("h_diff_muon_energy_fv","Difference Muon energy distribution (FV)",100,-1000,1000); + TH1F *h_diff_neutrino_energy = new TH1F("h_diff_neutrino_energy","Difference Neutrino energy distribution",100,-1000,1000); + TH1F *h_diff_neutrino_energy_fv = new TH1F("h_diff_neutrino_energy_fv","Difference Neutrino energy distribution (FV)",100,-1000,1000); + TH1F *h_diff_muon_vtx_x = new TH1F("h_diff_muon_vtx_x","Difference Muon vertex (x)",200,-3,3); + TH1F *h_diff_muon_vtx_y = new TH1F("h_diff_muon_vtx_y","Difference Muon vertex (y)",200,-3,3); + TH1F *h_diff_muon_vtx_z = new TH1F("h_diff_muon_vtx_z","Difference Muon vertex (z)",200,-3,3); + TH2F *h_diff_muon_vtx_yz = new TH2F("h_diff_muon_vtx_yz","Difference Muon vertex (tank) Y-Z",200,-3,3,200,-3,3); + TH2F *h_diff_muon_vtx_xz = new TH2F("h_diff_muon_vtx_xz","Difference Muon vertex (tank) X-Z",200,-2.5,2.5,200,-2.5,2.5); + + TH2F *h_Etank_Q = new TH2F("h_Etank_Q","Muon energy (tank) vs. charge",200,0,5000,200,-300,1000); + + TH1F *h_diff_dirz = new TH1F("h_diff_dirz","Difference muon direction (z)",100,-2,2); + + TH2F *h_migration_energy = new TH2F("h_migration_energy","Migration matrix muon energy",8,400,1200,8,400,1200); + TH2F *h_migration_angle = new TH2F("h_migration_angle","Migration matrix cos(#theta)",6,0.7,1.,6,0.7,1.); + + int nPrimNeut; + int nPrimProt; + int nCaptures; + int nCapturesPMTVol; + double Emu; + double Enu; + double Q2; + double vtxX; + double vtxY; + double vtxZ; + std::vector *clusterCB = new std::vector; + std::vector *clusterTime = new std::vector; + std::vector *clusterPE = new std::vector; + std::vector *nCandCB = new std::vector; + std::vector *nCandTime = new std::vector; + std::vector *nCandPE = new std::vector; + double mrdTrackLength; + double mrdEnergyLoss; + std::vector *neutVtxX = new std::vector; + std::vector *neutVtxY = new std::vector; + std::vector *neutVtxZ = new std::vector; + std::vector *neutCapNucl = new std::vector; + std::vector *neutCapTime = new std::vector; + std::vector *neutCapETotal = new std::vector; + std::vector *neutCapNGamma = new std::vector; + int isCC; + int isQEL; + int isDIS; + int isRES; + int isCOH; + int isMEC; + int tankMRDCoinc; + int multiRing; + int clusters; + int nCandidates; + std::vector *primaryPdgs = new std::vector; + + TTree *tout = new TTree("neutron_tree","Neutron tree"); + tout->Branch("TankMRDCoinc",&tankMRDCoinc); + tout->Branch("nPrimNeut",&nPrimNeut); + tout->Branch("nPrimProt",&nPrimProt); + tout->Branch("nCaptures",&nCaptures); + tout->Branch("nCapturesPMTVol",&nCapturesPMTVol); + tout->Branch("nCandidates",&nCandidates); + tout->Branch("Emu",&Emu); + tout->Branch("Enu",&Enu); + tout->Branch("Q2",&Q2); + tout->Branch("vtxX",&vtxX); + tout->Branch("vtxY",&vtxY); + tout->Branch("vtxZ",&vtxZ); + tout->Branch("Clusters",&clusters); + tout->Branch("ClusterCB",&clusterCB); + tout->Branch("ClusterTime",&clusterTime); + tout->Branch("ClusterPE",&clusterPE); + tout->Branch("nCandCB",&nCandCB); + tout->Branch("nCandTime",&nCandTime); + tout->Branch("nCandPE",&nCandPE); + tout->Branch("mrdTrackLength",&mrdTrackLength); + tout->Branch("mrdEnergyLoss",&mrdEnergyLoss); + tout->Branch("neutVtxX",&neutVtxX); + tout->Branch("neutVtxY",&neutVtxY); + tout->Branch("neutVtxZ",&neutVtxZ); + tout->Branch("neutCapNucl",&neutCapNucl); + tout->Branch("neutCapTime",&neutCapTime); + tout->Branch("neutCapETotal",&neutCapETotal); + tout->Branch("neutCapNGamma",&neutCapNGamma); + tout->Branch("isCC",&isCC); + tout->Branch("isQEL",&isQEL); + tout->Branch("isDIS",&isDIS); + tout->Branch("isRES",&isRES); + tout->Branch("isMEC",&isMEC); + tout->Branch("isCOH",&isCOH); + tout->Branch("multiRing",&multiRing); + tout->Branch("primaryPdgs",&primaryPdgs); + + double ChargeTank; + double TrueVtxX; + double TrueVtxY; + double TrueVtxZ; + double TrueMuonE; + double TrueNeutrinoE; + int TrueFV; + int FV; + double RecoMuonE; + double RecoNeutrinoE; + double RecoVtxX; + double RecoVtxY; + double RecoVtxZ; + double DWater; + double DAir; + double DMRD; + double RecoMuonEMRD; + double RecoTheta; + double RecoMuonEWater; + double MRDStartX; + double MRDStartY; + double MRDStartZ; + double MRDStopX; + double MRDStopY; + double MRDStopZ; + double TankExitX; + double TankExitY; + double TankExitZ; + double PMTVolExitX; + double PMTVolExitY; + double PMTVolExitZ; + double DirX; + double DirY; + double DirZ; + + TTree *tout_reco = new TTree("tout_reco","Reco tree"); + tout_reco->Branch("ChargeTank",&ChargeTank); + tout_reco->Branch("TrueVtxX",&TrueVtxX); + tout_reco->Branch("TrueVtxY",&TrueVtxY); + tout_reco->Branch("TrueVtxZ",&TrueVtxZ); + tout_reco->Branch("TrueMuonE",&TrueMuonE); + tout_reco->Branch("TrueNeutrinoE",&TrueNeutrinoE); + tout_reco->Branch("TrueFV",&TrueFV); + + tout_reco->Branch("RecoMuonE",&RecoMuonE); + tout_reco->Branch("RecoNeutrinoE",&RecoNeutrinoE); + tout_reco->Branch("RecoVtxX",&RecoVtxX); + tout_reco->Branch("RecoVtxY",&RecoVtxY); + tout_reco->Branch("RecoVtxZ",&RecoVtxZ); + tout_reco->Branch("FV",&FV); + + tout_reco->Branch("DWater",&DWater); + tout_reco->Branch("DAir",&DAir); + tout_reco->Branch("DMRD",&DMRD); + tout_reco->Branch("RecoMuonEMRD",&RecoMuonEMRD); + tout_reco->Branch("RecoTheta",&RecoTheta); + tout_reco->Branch("RecoMuonEWater",&RecoMuonEWater); + tout_reco->Branch("MRDStartX",&MRDStartX); + tout_reco->Branch("MRDStartY",&MRDStartY); + tout_reco->Branch("MRDStartZ",&MRDStartZ); + tout_reco->Branch("MRDStopX",&MRDStopX); + tout_reco->Branch("MRDStopY",&MRDStopY); + tout_reco->Branch("MRDStopZ",&MRDStopZ); + tout_reco->Branch("TankExitX",&TankExitX); + tout_reco->Branch("TankExitY",&TankExitY); + tout_reco->Branch("TankExitZ",&TankExitZ); + tout_reco->Branch("PMTVolExitX",&PMTVolExitX); + tout_reco->Branch("PMTVolExitY",&PMTVolExitY); + tout_reco->Branch("PMTVolExitZ",&PMTVolExitZ); + tout_reco->Branch("DirX",&DirX); + tout_reco->Branch("DirY",&DirY); + tout_reco->Branch("DirZ",&DirZ); + + int i_pmt=0; + for (int i_trig=0; i_trig < nentries_trigger; i_trig++){ + std::cout <<"Load trig entry "<GetEntry(i_trig); + if (!noveto) continue; + if (fabs(true_pdg) != 13) continue; + bool found_coinc=false; + bool is_extended = false; + int n_neutrons=0; + double max_pe = 0; + std::vector n_times; + Emu = 0.; + Enu = 0.; + Q2 = 0.; + nPrimNeut = 0; + nPrimProt = 0; + nCaptures = 0; + nCapturesPMTVol = 0; + mrdTrackLength = 0; + mrdEnergyLoss = 0; + clusterCB->clear(); + clusterTime->clear(); + clusterPE->clear(); + nCandCB->clear(); + nCandTime->clear(); + nCandPE->clear(); + primaryPdgs->clear(); + neutVtxX->clear(); + neutVtxY->clear(); + neutVtxZ->clear(); + neutCapNucl->clear(); + neutCapETotal->clear(); + neutCapNGamma->clear(); + isCC = 0; + isQEL = 0; + isDIS = 0; + isRES = 0; + isMEC = 0; + isCOH = 0; + multiRing = 0; + clusters = 0; + nCandidates = 0; + + + ChargeTank = -999; + TrueVtxX = -999; + TrueVtxY = -999; + TrueVtxZ = -999; + TrueMuonE = -999; + TrueNeutrinoE = -999; + TrueFV = 0; + FV = 0; + RecoMuonE = -999; + RecoNeutrinoE = -999; + RecoVtxX = -999; + RecoVtxY = -999; + RecoVtxZ = -999; + DWater = -999; + DAir = -999; + DMRD = -999; + RecoMuonEMRD = -999; + RecoTheta = -999; + RecoMuonEWater = -999; + MRDStartX = -999; + MRDStartY = -999; + MRDStartZ = -999; + MRDStopX = -999; + MRDStopY = -999; + MRDStopZ = -999; + TankExitX = -999; + TankExitY = -999; + TankExitZ = -999; + PMTVolExitX = -999; + PMTVolExitY = -999; + PMTVolExitZ = -999; + DirX = -999; + DirY = -999; + DirZ = -999; + + while (i_pmt < nentries_pmt){ + tPMT->GetEntry(i_pmt); + if (verbose){ + std::cout <<"i_pmt: "< max_pe) max_pe = cluster_pe; + if (cluster_time > 10000 && extended > 0 && beam_ok == 1 && cluster_pe < 120 && cluster_cb < 0.4){ + n_times.push_back(cluster_time); + n_neutrons++; + nCandCB->push_back(cluster_cb); + nCandTime->push_back(cluster_time); + nCandPE->push_back(cluster_pe); + } + i_pmt++; + found_coinc = true; + if (extended) is_extended = true; + clusters++; + clusterCB->push_back(cluster_cb); + clusterTime->push_back(cluster_time); + clusterPE->push_back(cluster_pe); + + } else if (found_coinc) break; + else if (ev_pmt < ev_trigger) i_pmt++; + else if (ev_pmt > ev_trigger) { + //i_pmt--; //Data case + break; //MC case + } + } + else if (run_pmt < run_trigger) i_pmt++; + else if (i_pmt > 0) break; + } + if (found_coinc){ + if (is_extended && num_mrd_tracks == 1) { + if (mrdstop->at(0)){ + std::cout <<"cuts passed!"<at(0); + mrdTrackLength = tracklength->at(0); + //double reco_muon_energy = muon_eloss + max_pe/12; //Data version + double reco_muon_energy = muon_eloss + max_pe*0.08534; //Data version + double true_muon_energy = true_muone-105.66; + + //Direction information (from MRD) + double startx = mrdstartx->at(0); + double starty = mrdstarty->at(0); + double startz = mrdstartz->at(0); + double stopx = mrdstopx->at(0); + double stopy = mrdstopy->at(0); + double stopz = mrdstopz->at(0); + double diffx = stopx-startx; + double diffy = stopy-starty; + double diffz = stopz-startz; + double startz_c = startz-1.681; + bool hit_tank = false; + double a = pow(diffx,2)+pow(diffz,2); + double b = -2*diffx*startx-2*diffz*startz_c; + double c = pow(startx,2)+pow(startz_c,2)-1.0*1.0; + double t1 = (-b+sqrt(b*b-4*a*c))/(2*a); + double t2 = (-b-sqrt(b*b-4*a*c))/(2*a); + double t = 0; + if (t1 < 0) t = t2; + else if (t2 < 0) t = t1; + else t = (t1 < t2)? t1 : t2; + double exitx = startx - t*diffx; + double exity = starty - t*diffy; + double exitz = startz - t*diffz; + double dirx = diffx/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double diry = diffy/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + double dirz = diffz/(sqrt(diffx*diffx+diffy*diffy+diffz*diffz)); + + double dist_mrd = sqrt(pow(startx-stopx,2)+pow(starty-stopy,2)+pow(startz-stopz,2)); + double dist_air = sqrt(pow(startx-exitx,2)+pow(starty-exity,2)+pow(startz-exitz,2)); + double dist_air_x = sqrt(pow(startx-exitx,2)); + double dist_air_y = sqrt(pow(starty-exity,2)); + double dist_air_z = sqrt(pow(startz-exitz,2)); + + double ap = pow(diffx,2)+pow(diffz,2); + double bp = -2*diffx*startx-2*diffz*startz_c; + double cp = pow(startx,2)+pow(startz_c,2)-1.5*1.5; + double t1p = (-bp+sqrt(bp*bp-4*ap*cp))/(2*ap); + double t2p = (-bp-sqrt(bp*bp-4*ap*cp))/(2*ap); + std::cout <<"t1, t2: "<size(); + nCandidates = n_neutrons; + nCapturesPMTVol = 0; + for (int i_neut= 0; i_neut < (int) true_neut_cap_vtxx->size(); i_neut++){ + neutVtxX->push_back(true_neut_cap_vtxx->at(i_neut)); + neutVtxY->push_back(true_neut_cap_vtxy->at(i_neut)); + neutVtxZ->push_back(true_neut_cap_vtxz->at(i_neut)); + neutCapNucl->push_back(true_neut_cap_nucl->at(i_neut)); + neutCapTime->push_back(true_neut_cap_time->at(i_neut)); + neutCapETotal->push_back(true_neut_cap_e->at(i_neut)); + neutCapNGamma->push_back(true_neut_cap_gammas->at(i_neut)); + //PMT volume cut + double zcorr = true_neut_cap_vtxz->at(i_neut)/100.-1.681; + double ycorr = true_neut_cap_vtxy->at(i_neut)/100.+0.144; + double xcorr = true_neut_cap_vtxx->at(i_neut)/100.; + double rad = sqrt(xcorr*xcorr+zcorr*zcorr); + if (rad < 1.0 && fabs(ycorr)<1.5) nCapturesPMTVol++; + } + for (int i_part = 0; i_part < (int) true_primary_pdgs->size(); i_part++){ + primaryPdgs->push_back(true_primary_pdgs->at(i_part)); + } + tout->Fill(); + + if (tankmrdcoinc){ + + //Fill reconstruction parameters to tree + ChargeTank = max_pe; + TrueVtxX = truevtxx; + TrueVtxY = truevtxy; + TrueVtxZ = truevtxz; + TrueMuonE = true_muon_energy; + TrueNeutrinoE = true_neutrino_energy*1000; + + RecoMuonE = reco_muon_energy; + RecoNeutrinoE = reco_neutrino_energy; + RecoVtxX = reco_vtxx; + RecoVtxY = reco_vtxy; + RecoVtxZ = reco_vtxz; + DWater = diff_pmtvol_tank; + DAir = dist_air; + DMRD = dist_mrd; + RecoMuonEMRD = muon_eloss; + RecoTheta = diffz; //this is actually cos(theta), not theta + RecoMuonEWater = true_muon_energy - muon_eloss - 200.*DWater; + MRDStartX = startx; + MRDStartY = starty; + MRDStartZ = startz; + MRDStopX = stopx; + MRDStopY = stopy; + MRDStopZ = stopz; + TankExitX = exitx; + TankExitY = exity; + TankExitZ = exitz; + PMTVolExitX = exitxp; + PMTVolExitY = exityp; + PMTVolExitZ = exitzp; + DirX = dirx; + DirY = diry; + DirZ = dirz; + + h_Etank_Q->Fill(ChargeTank,RecoMuonEWater); + + //Fill reconstruction-specific histograms + + h_neutrino_energy->Fill(reco_neutrino_energy); + h_true_neutrino_energy->Fill(1000.*true_neutrino_energy); + h_diff_neutrino_energy->Fill(reco_neutrino_energy-1000.*true_neutrino_energy); + + h_muon_energy->Fill(reco_muon_energy); + h_true_muon_energy->Fill(true_muon_energy); + h_diff_muon_energy->Fill(reco_muon_energy-true_muon_energy); + + h_diff_dirz->Fill(dirz - true_dirz); + h_migration_angle->Fill(true_dirz,dirz); + h_migration_energy->Fill(true_muon_energy,reco_muon_energy); + + h_muon_vtx_x->Fill(reco_vtxx); + h_muon_vtx_y->Fill(reco_vtxy); + h_muon_vtx_z->Fill(reco_vtxz); + h_true_muon_vtx_x->Fill(truevtxx); + h_true_muon_vtx_y->Fill(truevtxy); + h_true_muon_vtx_z->Fill(truevtxz); + h_diff_muon_vtx_x->Fill(reco_vtxx-truevtxx); + h_diff_muon_vtx_y->Fill(reco_vtxy-truevtxy); + h_diff_muon_vtx_z->Fill(reco_vtxz-truevtxz); + + h_muon_vtx_yz->Fill(reco_vtxz-1.681,reco_vtxy+0.144); + h_muon_vtx_xz->Fill(reco_vtxz-1.681,reco_vtxx); + h_true_muon_vtx_yz->Fill(truevtxz-1.681,truevtxy+0.144); + h_true_muon_vtx_xz->Fill(truevtxz-1.681,truevtxx); + h_diff_muon_vtx_yz->Fill(reco_vtxz-truevtxz,reco_vtxy-truevtxy); + h_diff_muon_vtx_xz->Fill(reco_vtxz-truevtxz,reco_vtxx-truevtxx); + + if (sqrt(reco_vtxx*reco_vtxx+(reco_vtxz-1.681)*(reco_vtxz-1.681))<1.0 && fabs(reco_vtxy+0.144)<0.5 && ((reco_vtxz-1.681) < 0.)) { + h_muon_energy_fv->Fill(reco_muon_energy); + h_neutrino_energy_fv->Fill(reco_neutrino_energy); + FV = 1; + } + if (sqrt(truevtxx*truevtxx+(truevtxz-1.681)*(truevtxz-1.681))<1.0 && fabs(truevtxy+0.144)<0.5 && ((truevtxz-1.681) < 0.)) { + h_true_muon_energy_fv->Fill(true_muon_energy); + h_true_neutrino_energy_fv->Fill(1000.*true_neutrino_energy); + TrueFV = 1; + } + tout_reco->Fill(); + } + } + } + } + } + + + fout->Write(); + fout->Close(); + +} diff --git a/configfiles/NeutronMultiplicity/root-scripts/visible_energy_vertex.C b/configfiles/NeutronMultiplicity/root-scripts/visible_energy_vertex.C new file mode 100644 index 000000000..73b2dbc6f --- /dev/null +++ b/configfiles/NeutronMultiplicity/root-scripts/visible_energy_vertex.C @@ -0,0 +1,367 @@ +void visible_energy_vertex(const char* infile, const char* outfile, bool IsMC = true, bool verbose = false){ + + TFile *f = new TFile(infile,"READ"); + TTree *tTrigger = (TTree*) f->Get("phaseIITriggerTree"); + TTree *tMRD = (TTree*) f->Get("phaseIIMRDClusterTree"); + TTree *tPMT = (TTree*) f->Get("phaseIITankClusterTree"); + + TFile *fout = new TFile(outfile,"RECREATE"); + + int nentries_trigger = tTrigger->GetEntries(); + int nentries_mrd = tMRD->GetEntries(); + int nentries_pmt = tPMT->GetEntries(); + + std::cout << "Entries Trigger/MRD/PMT: "<* eloss = new std::vector; + std::vector* tracklength = new std::vector; + std::vector* mrdstop = new std::vector; + std::vector* mrdstartx = new std::vector; + std::vector* mrdstarty = new std::vector; + std::vector* mrdstartz = new std::vector; + std::vector* mrdstopx = new std::vector; + std::vector* mrdstopy = new std::vector; + std::vector* mrdstopz = new std::vector; + + double cluster_time; + double cluster_cb; + double cluster_pe; + int extended; + + int tankmrdcoinc; + int noveto; + double true_muone; + int true_pdg; + double true_vtxx; + double true_vtxy; + double true_vtxz; + + int true_neutrons; + int true_protons; + int true_mec; + int true_dis; + int true_res; + int true_qel; + int true_cc; + double true_q2; + double true_neutrino_energy; + std::vector *true_neut_cap_e = new std::vector; + std::vector *true_neut_cap_time = new std::vector; + std::vector *true_neut_cap_nucl = new std::vector; + std::vector *true_neut_cap_vtxx = new std::vector; + std::vector *true_neut_cap_vtxy = new std::vector; + std::vector *true_neut_cap_vtxz = new std::vector; + std::vector *true_neut_cap_gammas = new std::vector; + std::vector *true_primary_pdgs = new std::vector; + int trueMultiRing; + + tTrigger->SetBranchAddress("runNumber",&run_trigger); + tMRD->SetBranchAddress("runNumber",&run_mrd); + tPMT->SetBranchAddress("runNumber",&run_pmt); + tTrigger->SetBranchAddress("eventNumber",&ev_trigger); + tMRD->SetBranchAddress("eventNumber",&ev_mrd); + tPMT->SetBranchAddress("eventNumber",&ev_pmt); + tTrigger->SetBranchAddress("beam_ok",&beam_ok); + tTrigger->SetBranchAddress("numMRDTracks",&num_mrd_tracks); + tTrigger->SetBranchAddress("MRDTrackLength",&tracklength); + tTrigger->SetBranchAddress("MRDEnergyLoss",&eloss); + tTrigger->SetBranchAddress("MRDTrackStartX",&mrdstartx); + tTrigger->SetBranchAddress("MRDTrackStartY",&mrdstarty); + tTrigger->SetBranchAddress("MRDTrackStartZ",&mrdstartz); + tTrigger->SetBranchAddress("MRDTrackStopX",&mrdstopx); + tTrigger->SetBranchAddress("MRDTrackStopY",&mrdstopy); + tTrigger->SetBranchAddress("MRDTrackStopZ",&mrdstopz); + tTrigger->SetBranchAddress("MRDStop",&mrdstop); + tTrigger->SetBranchAddress("HasTank",&has_tank); + tPMT->SetBranchAddress("clusterTime",&cluster_time); + tPMT->SetBranchAddress("clusterPE",&cluster_pe); + tPMT->SetBranchAddress("clusterChargeBalance",&cluster_cb); + tPMT->SetBranchAddress("Extended",&extended); + tTrigger->SetBranchAddress("TankMRDCoinc",&tankmrdcoinc); + tTrigger->SetBranchAddress("NoVeto",&noveto); + tTrigger->SetBranchAddress("trueMuonEnergy",&true_muone); + tTrigger->SetBranchAddress("truePrimaryPdg",&true_pdg); + tTrigger->SetBranchAddress("trueVtxX",&true_vtxx); + tTrigger->SetBranchAddress("trueVtxY",&true_vtxy); + tTrigger->SetBranchAddress("trueVtxZ",&true_vtxz); + tTrigger->SetBranchAddress("truePrimaryPdgs",&true_primary_pdgs); + tTrigger->SetBranchAddress("trueNeutCapVtxX",&true_neut_cap_vtxx); + tTrigger->SetBranchAddress("trueNeutCapVtxY",&true_neut_cap_vtxy); + tTrigger->SetBranchAddress("trueNeutCapVtxZ",&true_neut_cap_vtxz); + tTrigger->SetBranchAddress("trueNeutCapNucleus",&true_neut_cap_nucl); + tTrigger->SetBranchAddress("trueNeutCapTime",&true_neut_cap_time); + tTrigger->SetBranchAddress("trueNeutCapGammas",&true_neut_cap_gammas); + tTrigger->SetBranchAddress("trueNeutCapE",&true_neut_cap_e); + tTrigger->SetBranchAddress("trueNeutrinoEnergy",&true_neutrino_energy); + tTrigger->SetBranchAddress("trueQ2",&true_q2); + tTrigger->SetBranchAddress("trueCC",&true_cc); + tTrigger->SetBranchAddress("trueQEL",&true_qel); + tTrigger->SetBranchAddress("trueRES",&true_res); + tTrigger->SetBranchAddress("trueDIS",&true_dis); + tTrigger->SetBranchAddress("trueMEC",&true_mec); + tTrigger->SetBranchAddress("trueNeutrons",&true_neutrons); + tTrigger->SetBranchAddress("trueProtons",&true_protons); + tTrigger->SetBranchAddress("trueMultiRing",&trueMultiRing); + + TH2F *h_visible_rho = new TH2F("h_visible_rho","Visible energy vs. #rho",200,0,4,400,0,4000); + TH2F *h_visible_zrho = new TH2F("h_visible_zrho","Visible energy vs. |z| #rho",400,-4,4,400,0,4000); + TH2F *h_visible_y = new TH2F("h_visible_y","Visible energy vs. y",200,-2,2,400,0,4000); + TH2F *h_visible_y_zrho_0_100 = new TH2F("h_visible_y_zrho_0_100","Vertex y vs |z| #rho (0-100p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_100_200 = new TH2F("h_visible_y_zrho_100_200","Vertex y vs |z| #rho (100-200p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_200_300 = new TH2F("h_visible_y_zrho_200_300","Vertex y vs |z| #rho (200-300p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_300_400 = new TH2F("h_visible_y_zrho_300_400","Vertex y vs |z| #rho (300-400p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_400_500 = new TH2F("h_visible_y_zrho_400_500","Vertex y vs |z| #rho (400-500p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_500_600 = new TH2F("h_visible_y_zrho_500_600","Vertex y vs |z| #rho (500-600p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_600_700 = new TH2F("h_visible_y_zrho_600_700","Vertex y vs |z| #rho (600-700p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_700_800 = new TH2F("h_visible_y_zrho_700_800","Vertex y vs |z| #rho (700-800p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_800_900 = new TH2F("h_visible_y_zrho_800_900","Vertex y vs |z| #rho (800-900p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_900_1000 = new TH2F("h_visible_y_zrho_900_1000","Vertex y vs |z| #rho (900-1000p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_1000_1500 = new TH2F("h_visible_y_zrho_1000_1500","Vertex y vs |z| #rho (1000-1500p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_1500_2000 = new TH2F("h_visible_y_zrho_1500_2000","Vertex y vs |z| #rho (1500-2000p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_2000_2500 = new TH2F("h_visible_y_zrho_2000_2500","Vertex y vs |z| #rho (2000-2500p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_2500_3000 = new TH2F("h_visible_y_zrho_2500_3000","Vertex y vs |z| #rho (2500-3000p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_3000_3500 = new TH2F("h_visible_y_zrho_3000_3500","Vertex y vs |z| #rho (3000-3500p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_3500_4000 = new TH2F("h_visible_y_zrho_3500_4000","Vertex y vs |z| #rho (3500-4000p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_4000_4500 = new TH2F("h_visible_y_zrho_4000_4500","Vertex y vs |z| #rho (4000-4500p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_4500_5000 = new TH2F("h_visible_y_zrho_4500_5000","Vertex y vs |z| #rho (4500-5000p.e.)",200,0,2,200,-2,2); + TH2F *h_visible_y_zrho_5000_plus = new TH2F("h_visible_y_zrho_5000_plus","Vertex y vs |z| #rho (> 5000p.e.)",200,0,2,200,-2,2); + + TH2F *h_Etank_Q = new TH2F("h_Etank_Q","Muon energy (tank) vs. charge",200,0,5000,200,-300,1000); + + int nPrimNeut; + int nPrimProt; + int nCaptures; + int nCapturesPMTVol; + double Emu; + double Enu; + double Q2; + double vtxX; + double vtxY; + double vtxZ; + std::vector *clusterCB = new std::vector; + std::vector *clusterTime = new std::vector; + std::vector *clusterPE = new std::vector; + std::vector *nCandCB = new std::vector; + std::vector *nCandTime = new std::vector; + std::vector *nCandPE = new std::vector; + double mrdTrackLength; + double mrdEnergyLoss; + std::vector *neutVtxX = new std::vector; + std::vector *neutVtxY = new std::vector; + std::vector *neutVtxZ = new std::vector; + std::vector *neutCapNucl = new std::vector; + std::vector *neutCapTime = new std::vector; + std::vector *neutCapETotal = new std::vector; + std::vector *neutCapNGamma = new std::vector; + int isCC; + int isQEL; + int isDIS; + int isRES; + int isCOH; + int isMEC; + int tankMRDCoinc; + int multiRing; + int clusters; + int nCandidates; + std::vector *primaryPdgs = new std::vector; + + double ChargeTank; + double TrueVtxX; + double TrueVtxY; + double TrueVtxZ; + double TrueMuonE; + double TrueNeutrinoE; + int TrueFV; + int FV; + double RecoMuonE; + double RecoNeutrinoE; + double RecoVtxX; + double RecoVtxY; + double RecoVtxZ; + double DWater; + double DAir; + double DMRD; + double RecoMuonEMRD; + double RecoTheta; + double RecoMuonEWater; + double MRDStartX; + double MRDStartY; + double MRDStartZ; + double MRDStopX; + double MRDStopY; + double MRDStopZ; + double TankExitX; + double TankExitY; + double TankExitZ; + double PMTVolExitX; + double PMTVolExitY; + double PMTVolExitZ; + double DirX; + double DirY; + double DirZ; + + int i_pmt=0; + for (int i_trig=0; i_trig < nentries_trigger; i_trig++){ + std::cout <<"Load trig entry "<GetEntry(i_trig); + if (!noveto) continue; + if (fabs(true_pdg) != 13) continue; + bool found_coinc=false; + bool is_extended = false; + int n_neutrons=0; + double max_pe = 0; + std::vector n_times; + Emu = 0.; + Enu = 0.; + Q2 = 0.; + nPrimNeut = 0; + nPrimProt = 0; + nCaptures = 0; + nCapturesPMTVol = 0; + mrdTrackLength = 0; + mrdEnergyLoss = 0; + clusterCB->clear(); + clusterTime->clear(); + clusterPE->clear(); + nCandCB->clear(); + nCandTime->clear(); + nCandPE->clear(); + primaryPdgs->clear(); + neutVtxX->clear(); + neutVtxY->clear(); + neutVtxZ->clear(); + neutCapNucl->clear(); + neutCapETotal->clear(); + neutCapNGamma->clear(); + isCC = 0; + isQEL = 0; + isDIS = 0; + isRES = 0; + isMEC = 0; + isCOH = 0; + multiRing = 0; + clusters = 0; + nCandidates = 0; + + + ChargeTank = -999; + TrueVtxX = -999; + TrueVtxY = -999; + TrueVtxZ = -999; + TrueMuonE = -999; + TrueNeutrinoE = -999; + TrueFV = 0; + FV = 0; + RecoMuonE = -999; + RecoNeutrinoE = -999; + RecoVtxX = -999; + RecoVtxY = -999; + RecoVtxZ = -999; + DWater = -999; + DAir = -999; + DMRD = -999; + RecoMuonEMRD = -999; + RecoTheta = -999; + RecoMuonEWater = -999; + MRDStartX = -999; + MRDStartY = -999; + MRDStartZ = -999; + MRDStopX = -999; + MRDStopY = -999; + MRDStopZ = -999; + TankExitX = -999; + TankExitY = -999; + TankExitZ = -999; + PMTVolExitX = -999; + PMTVolExitY = -999; + PMTVolExitZ = -999; + DirX = -999; + DirY = -999; + DirZ = -999; + + while (i_pmt < nentries_pmt){ + tPMT->GetEntry(i_pmt); + if (verbose){ + std::cout <<"i_pmt: "< max_pe) max_pe = cluster_pe; + if (cluster_time > 10000 && extended > 0 && beam_ok == 1 && cluster_pe < 120 && cluster_cb < 0.4){ + n_times.push_back(cluster_time); + n_neutrons++; + nCandCB->push_back(cluster_cb); + nCandTime->push_back(cluster_time); + nCandPE->push_back(cluster_pe); + } + i_pmt++; + found_coinc = true; + if (extended) is_extended = true; + clusters++; + clusterCB->push_back(cluster_cb); + clusterTime->push_back(cluster_time); + clusterPE->push_back(cluster_pe); + + } else if (found_coinc) break; + else if (ev_pmt < ev_trigger) i_pmt++; + else if (ev_pmt > ev_trigger) { + if (IsMC) break; //MC case + else i_pmt--; //Data case + } + } + else if (run_pmt < run_trigger) i_pmt++; + else if (i_pmt > 0) break; + } + if (found_coinc){ + + double truevtxx = true_vtxx/100.; + double truevtxy = true_vtxy/100.; + double truevtxz = true_vtxz/100.; + + double rho = sqrt(truevtxx*truevtxx+truevtxz*truevtxz); + double zrho = rho; + if (truevtxz < 0) zrho *= -1; + + //Fill histograms + h_visible_rho->Fill(rho,max_pe); + h_visible_zrho->Fill(zrho,max_pe); + h_visible_y->Fill(truevtxy,max_pe); + if (max_pe > 5000) h_visible_y_zrho_5000_plus->Fill(zrho,truevtxy); + else if (max_pe > 4500) h_visible_y_zrho_4500_5000->Fill(zrho,truevtxy); + else if (max_pe > 4000) h_visible_y_zrho_4000_4500->Fill(zrho,truevtxy); + else if (max_pe > 3500) h_visible_y_zrho_3500_4000->Fill(zrho,truevtxy); + else if (max_pe > 3000) h_visible_y_zrho_3000_3500->Fill(zrho,truevtxy); + else if (max_pe > 2500) h_visible_y_zrho_2500_3000->Fill(zrho,truevtxy); + else if (max_pe > 2000) h_visible_y_zrho_2000_2500->Fill(zrho,truevtxy); + else if (max_pe > 1500) h_visible_y_zrho_1500_2000->Fill(zrho,truevtxy); + else if (max_pe > 1000) h_visible_y_zrho_1000_1500->Fill(zrho,truevtxy); + else if (max_pe > 900) h_visible_y_zrho_900_1000->Fill(zrho,truevtxy); + else if (max_pe > 800) h_visible_y_zrho_800_900->Fill(zrho,truevtxy); + else if (max_pe > 700) h_visible_y_zrho_700_800->Fill(zrho,truevtxy); + else if (max_pe > 600) h_visible_y_zrho_600_700->Fill(zrho,truevtxy); + else if (max_pe > 500) h_visible_y_zrho_500_600->Fill(zrho,truevtxy); + else if (max_pe > 400) h_visible_y_zrho_400_500->Fill(zrho,truevtxy); + else if (max_pe > 300) h_visible_y_zrho_300_400->Fill(zrho,truevtxy); + else if (max_pe > 200) h_visible_y_zrho_200_300->Fill(zrho,truevtxy); + else if (max_pe > 100) h_visible_y_zrho_100_200->Fill(zrho,truevtxy); + else if (max_pe > 0) h_visible_y_zrho_0_100->Fill(zrho,truevtxy); + } + } + + + fout->Write(); + fout->Close(); + +} diff --git a/configfiles/NeutronMultiplicity/runlist_r2506-r2630.txt b/configfiles/NeutronMultiplicity/runlist_r2506-r2630.txt new file mode 100644 index 000000000..84846c580 --- /dev/null +++ b/configfiles/NeutronMultiplicity/runlist_r2506-r2630.txt @@ -0,0 +1,58 @@ +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2521 +2536 +2541 +2548 +2551 +2552 +2555 +2570 +2571 +2572 +2573 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2589 +2590 +2591 +2592 +2593 +2596 +2597 +2598 +2599 +2600 +2601 +2604 +2605 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2618 +2619 +2620 +2621 +2624 +2625 +2628 +2629 +2630