diff --git a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp index 673fdbd39..a821d6685 100644 --- a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp +++ b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.cpp @@ -17,6 +17,7 @@ bool AssignBunchTimingMC::Initialise(std::string configfile, DataModel &data){ bool got_count = m_variables.Get("bunchcount", fbunchcount); bool got_sample = m_variables.Get("sampletype", fsample); bool got_trigger = m_variables.Get("prompttriggertime", ftriggertime); + bool got_waveform = m_variables.Get("PMTWaveformSim", fPMTWaveformSim); if (!got_verbosity) { verbosity = 0; @@ -62,6 +63,13 @@ bool AssignBunchTimingMC::Initialise(std::string configfile, DataModel &data){ Log(logmessage, v_warning, verbosity); } + if (!got_waveform) { + fPMTWaveformSim = false; // assume they are using the standard, parametric MC Hits + logmessage = ("Warning (AssignBunchTimingMC): \"PMTWaveformSim\" not " + "set in the config file. Using default MC Hits instead of waveform hits"); + Log(logmessage, v_warning, verbosity); + } + if (verbosity >= v_message) { std::cout<<"------------------------------------"<<"\n"; @@ -70,6 +78,7 @@ bool AssignBunchTimingMC::Initialise(std::string configfile, DataModel &data){ std::cout<<"bunch width = "<Stores["ANNIEEvent"]->Get("SkipExecute", skip); + if (got_skip_status && skip) { + Log("AssignBunchTimingMC: An upstream tool told me to skip this event.",v_warning,verbosity); + return true; + } + if (!LoadStores()) // Load info from store return false; if (verbosity >= v_debug) { @@ -103,15 +122,35 @@ bool AssignBunchTimingMC::Execute() std::cout << "AssignBunchTimingMC: BNB timing successful" << std::endl; } - for (std::pair>&& apair : *fClusterMapMC) { - double totalHitTime = 0; - int hitCount = 0; - int totalHits = apair.second.size(); + if (fPMTWaveformSim) { // PMTWaveformSim data-like clusters (read from ClusterMap) + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Reading from ClusterMap (PMTWaveformSim)" << std::endl; + } + for (std::pair>&& apair : *fClusterMap) { + double totalHitTime = 0; + int hitCount = 0; + int totalHits = apair.second.size(); + + CalculateClusterAndBunchTimesPMTWaveformSim(apair.second, totalHitTime, hitCount, totalHits); + + // store the cluster time in a map (e.g., keyed by cluster identifier) + fbunchTimes->emplace(apair.first, bunchTime); + } + + } else { // otherwise default to reading the ClusterMapMC + if (verbosity >= v_debug) { + std::cout << "AssignBunchTimingMC: Reading from ClusterMapMC (default MCHits)" << std::endl; + } + for (std::pair>&& apair : *fClusterMapMC) { + double totalHitTime = 0; + int hitCount = 0; + int totalHits = apair.second.size(); - CalculateClusterAndBunchTimes(apair.second, totalHitTime, hitCount, totalHits); + CalculateClusterAndBunchTimes(apair.second, totalHitTime, hitCount, totalHits); - // store the cluster time in a map (e.g., keyed by cluster identifier) - fbunchTimes->emplace(apair.first, bunchTime); + // store the cluster time in a map (e.g., keyed by cluster identifier) + fbunchTimes->emplace(apair.first, bunchTime); + } } if (verbosity >= v_debug) { @@ -142,10 +181,18 @@ bool AssignBunchTimingMC::LoadStores() { // grab necessary information from Stores - bool get_MCClusters = m_data->CStore.Get("ClusterMapMC", fClusterMapMC); - if (!get_MCClusters) { - Log("AssignBunchTimingMC: no ClusterMapMC in the CStore! Are you sure you ran the ClusterFinder tool?", v_error, verbosity); - return false; + if (fPMTWaveformSim) { + bool get_Clusters = m_data->CStore.Get("ClusterMap", fClusterMap); + if (!get_Clusters) { + Log("AssignBunchTimingMC: no ClusterMap in the CStore! Are you sure you ran the ClusterFinder (and the PMTWaveformSim) tool?", v_error, verbosity); + return false; + } + } else { + bool get_MCClusters = m_data->CStore.Get("ClusterMapMC", fClusterMapMC); + if (!get_MCClusters) { + Log("AssignBunchTimingMC: no ClusterMapMC in the CStore! Are you sure you ran the ClusterFinder tool?", v_error, verbosity); + return false; + } } bool get_AnnieEvent = m_data->Stores.count("ANNIEEvent"); @@ -153,12 +200,6 @@ bool AssignBunchTimingMC::LoadStores() Log("AssignBunchTimingMC: no ANNIEEvent store!", v_error, verbosity); return false; } - - bool get_MCHits = m_data->Stores.at("ANNIEEvent")->Get("MCHits", fMCHitsMap); - if (!get_MCHits) { - Log("AssignBunchTimingMC: no MCHits in the ANNIEEvent!", v_error, verbosity); - return false; - } bool get_neutrino_vtxt = m_data->Stores["GenieInfo"]->Get("NuIntxVtx_T",TrueNuIntxVtx_T); // grab neutrino interaction time if (!get_neutrino_vtxt) { @@ -177,7 +218,7 @@ void AssignBunchTimingMC::BNBtiming() { // Determined from GENIE samples (as of Dec 2024) const double tank_time = 33.0; // Tank neutrino arrival time: 33ns - const double world_time = 33.0; // WORLD neutrino arrival time: 33ns (As of Dec 2024, World samples have not yet been re-produced fully) + const double world_time = 33.0; // WORLD neutrino arrival time: 33ns if (ftriggertime == 0) { new_nu_time = (fsample == 0) ? (TrueNuIntxVtx_T - tank_time) : (TrueNuIntxVtx_T - world_time); @@ -240,6 +281,37 @@ void AssignBunchTimingMC::CalculateClusterAndBunchTimes(std::vector const } +void AssignBunchTimingMC::CalculateClusterAndBunchTimesPMTWaveformSim(std::vector const &hits, double &totalHitTime, int &hitCount, int &totalHits) +{ + + // loop over the hits to get their times + for (auto hit : hits) { + double hitTime = hit.GetTime(); + totalHitTime += hitTime; + hitCount++; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: (" + std::to_string(hitCount) + "/" + std::to_string(totalHits) + ") PMTWaveformSim Hit time = " + std::to_string(hitTime); + Log(logmessage, v_debug, verbosity); + } + } + + // find nominal cluster time (average hit time) + double clusterTime = (hitCount > 0) ? totalHitTime / hitCount : -9999; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: ClusterTime = " + std::to_string(clusterTime); + Log(logmessage, v_debug, verbosity); + } + + // calculate BunchTime + bunchTime = fbunchinterval * bunchNumber + clusterTime + jitter + new_nu_time ; + if (verbosity >= v_debug) { + std::string logmessage = "AssignBunchTimingMC: bunchTime = " + std::to_string(bunchTime); + Log(logmessage, v_debug, verbosity); + } + +} + + //------------------------------------------------------------------------------ // done diff --git a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h index 69373d644..5058923a5 100644 --- a/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h +++ b/UserTools/AssignBunchTimingMC/AssignBunchTimingMC.h @@ -30,11 +30,12 @@ class AssignBunchTimingMC: public Tool { bool LoadStores(); ///< Loads all relevant information from the store, away from the Execute function void BNBtiming(); ///< Calculates the appropriate BNB timing to apply to the clusters void CalculateClusterAndBunchTimes(std::vector const &mchits, double &totalHitTime, int &hitCount, int &totalHits); ///< Loops through the MCHits, finds the cluster times (avg hit time), and calculates the new bunch timing + void CalculateClusterAndBunchTimesPMTWaveformSim(std::vector const &hits, double &totalHitTime, int &hitCount, int &totalHits); ///< Same as above but for the data-like PMTWaveformSim clusters and hits private: - std::map> *fMCHitsMap = nullptr; ///< All of the MCHits keyed by channel number std::map> *fClusterMapMC = nullptr; ///< All MC clusters + std::map> *fClusterMap = nullptr; ///< All MC clusters (data-like hits from the PMTWaveformSim tool) double TrueNuIntxVtx_T; ///< true neutrino interaction time in ns, from GenieInfo store std::map *fbunchTimes = nullptr; ///< Bunch-realistic timing from the cluster times; @@ -47,6 +48,7 @@ class AssignBunchTimingMC: public Tool { int fbunchcount; ///< number of BNB bunches per spill int fsample; ///< GENIE Tank or WORLD samples int ftriggertime; ///< whether the samples used the default WCSim prompt trigger = 0 (when particles enter the volume), or the adjusted prompt trigger based on the start of the beam dump + bool fPMTWaveformSim; ///< whether to use the PMTWaveform data-like hits or the defaul MCHits double new_nu_time; ///< offset needed to make the cluster times beam realistic int bunchNumber; ///< randomly assigned bunch number diff --git a/UserTools/AssignBunchTimingMC/README.md b/UserTools/AssignBunchTimingMC/README.md index ff1dab79f..f4f84943a 100644 --- a/UserTools/AssignBunchTimingMC/README.md +++ b/UserTools/AssignBunchTimingMC/README.md @@ -15,12 +15,14 @@ verbosity 0 +PMTWaveformSim 1 # Whether we're using the data-like hits output from PMTWaveformSim + # BNB properties taken from: MicroBooNE https://doi.org/10.1103/PhysRevD.108.052010 bunchwidth 1.308 # BNB instrinic bunch spread [ns] bunchinterval 18.936 # BNB bunch spacings [ns] bunchcount 81 # number of BNB bunches per spill -sampletype 0 # Tank (0) or World (1) genie samples you are running over +sampletype 1 # Tank (0) or World (1) genie samples you are running over prompttriggertime 1 # WCSim prompt trigger settings: (0 = default, t0 = 0 when a particle enters the volume) # (1 = modified, t0 = 0 when the neutrino beam dump begins) ``` diff --git a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp index 2120db005..3480e8cea 100644 --- a/UserTools/ClusterClassifiers/ClusterClassifiers.cpp +++ b/UserTools/ClusterClassifiers/ClusterClassifiers.cpp @@ -36,6 +36,14 @@ bool ClusterClassifiers::Initialise(std::string configfile, DataModel &data){ bool ClusterClassifiers::Execute(){ //We're gonna make ourselves a couple cluster classifier maps boyeeee + bool skip = false; + bool goodSkipStatus = m_data->Stores.at("ANNIEEvent")->Get("SkipExecute", skip); + if (goodSkipStatus && skip) { + logmessage = "ClusterClassifier: An upstream tool told me to skip this event."; + Log(logmessage, v_warning, verbosity); + return true; + } + if(verbosity>4) std::cout << "ClusterClassifiers tool: Accessing cluster map in CStore" << std::endl; bool get_clusters = false; m_data->CStore.Get("ClusterMap",m_all_clusters); diff --git a/UserTools/ClusterFinder/ClusterFinder.cpp b/UserTools/ClusterFinder/ClusterFinder.cpp index 5c002b119..8ce1966b8 100644 --- a/UserTools/ClusterFinder/ClusterFinder.cpp +++ b/UserTools/ClusterFinder/ClusterFinder.cpp @@ -164,6 +164,16 @@ bool ClusterFinder::Execute(){ //---------------------------------------------------------------------------- //---------------get the members of the ANNIEEvent---------------------------- //---------------------------------------------------------------------------- + + // An upstream tool may opt to skip this execution stage + // For example the PMTWaveformSim tool will skip events with no MCHits or if + // no waveforms are produced. + bool skip = false; + bool got_skip_status = m_data->Stores["ANNIEEvent"]->Get("SkipExecute", skip); + if (got_skip_status && skip) { + Log("ClusterFinder: An upstream tool told me to skip this event.",v_warning,verbose); + return true; + } m_data->Stores["ANNIEEvent"]->Get("EventNumber", evnum); //m_data->Stores["ANNIEEvent"]->Get("BeamStatus", BeamStatus); diff --git a/UserTools/Factory/Factory.cpp b/UserTools/Factory/Factory.cpp index e1b8b30c7..7d1366c60 100644 --- a/UserTools/Factory/Factory.cpp +++ b/UserTools/Factory/Factory.cpp @@ -174,6 +174,7 @@ if (tool=="BackTracker") ret=new BackTracker; if (tool=="PrintDQ") ret=new PrintDQ; if (tool=="AssignBunchTimingMC") ret=new AssignBunchTimingMC; if (tool=="FitRWMWaveform") ret=new FitRWMWaveform; +if (tool=="PMTWaveformSim") ret=new PMTWaveformSim; if (tool=="LAPPDWaveformDisplay") ret=new LAPPDWaveformDisplay; return ret; } diff --git a/UserTools/LoadGeometry/LoadGeometry.cpp b/UserTools/LoadGeometry/LoadGeometry.cpp index de93f7e7b..d30bbc97e 100644 --- a/UserTools/LoadGeometry/LoadGeometry.cpp +++ b/UserTools/LoadGeometry/LoadGeometry.cpp @@ -77,6 +77,7 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ TankPMTCrateSpaceToChannelNumMap = new std::map,int>; ChannelNumToTankPMTSPEChargeMap = new std::map; ChannelNumToTankPMTTimingOffsetMap = new std::map; + ChannelNumToTankPMTTimingSigmaMap = new std::map; ChannelNumToTankPMTCrateSpaceMap = new std::map>; AuxCrateSpaceToChannelNumMap = new std::map,int>; AuxChannelNumToTypeMap = new std::map; @@ -112,6 +113,7 @@ bool LoadGeometry::Initialise(std::string configfile, DataModel &data){ m_data->CStore.Set("ChannelNumToTankPMTCrateSpaceMap",ChannelNumToTankPMTCrateSpaceMap); m_data->CStore.Set("ChannelNumToTankPMTSPEChargeMap",ChannelNumToTankPMTSPEChargeMap); m_data->CStore.Set("ChannelNumToTankPMTTimingOffsetMap",ChannelNumToTankPMTTimingOffsetMap); + m_data->CStore.Set("ChannelNumToTankPMTTimingSigmaMap",ChannelNumToTankPMTTimingSigmaMap); m_data->CStore.Set("AuxCrateSpaceToChannelNumMap",AuxCrateSpaceToChannelNumMap); m_data->CStore.Set("AuxChannelNumToCrateSpaceMap",AuxChannelNumToCrateSpaceMap); m_data->CStore.Set("AuxChannelNumToTypeMap",AuxChannelNumToTypeMap); @@ -919,21 +921,25 @@ void LoadGeometry::LoadTankPMTGains(){ return; } +// load in both the timing offsets and uncertainties from the 2023 laser campaign void LoadGeometry::LoadTankPMTTimingOffsets(){ ifstream myfile(fTankPMTTimingOffsetFile.c_str()); std::string line; if (myfile.is_open()){ - //Loop over lines, collect all detector data (should only be one line here) + // Timing offset file has columns: [0] chankey [1] PMT_location [2] offset value (ns) [3] sigma (ns) [4] notes while(getline(myfile,line)){ if(verbosity>3) std::cout << line << std::endl; //has our stuff; if(line.find("#")!=std::string::npos) continue; std::vector DataEntries; boost::split(DataEntries,line, boost::is_any_of(","), boost::token_compress_on); int channelkey = -9999; - double TimingOffset = -9999.; + double TimingOffset = -9999; + double TimingSigma = -9999; channelkey = std::stoul(DataEntries.at(0)); TimingOffset= std::stod(DataEntries.at(2)); + TimingSigma = std::stod(DataEntries.at(3)); ChannelNumToTankPMTTimingOffsetMap->emplace(channelkey,TimingOffset); + ChannelNumToTankPMTTimingSigmaMap->emplace(channelkey,TimingSigma); } } return; diff --git a/UserTools/LoadGeometry/LoadGeometry.h b/UserTools/LoadGeometry/LoadGeometry.h index 9f4e2210a..8841ad510 100644 --- a/UserTools/LoadGeometry/LoadGeometry.h +++ b/UserTools/LoadGeometry/LoadGeometry.h @@ -69,6 +69,7 @@ class LoadGeometry: public Tool { std::map>* AuxChannelNumToCrateSpaceMap; std::map* ChannelNumToTankPMTSPEChargeMap; std::map* ChannelNumToTankPMTTimingOffsetMap; + std::map* ChannelNumToTankPMTTimingSigmaMap; std::map* AuxChannelNumToTypeMap; std::map,int>* LAPPDCrateSpaceToChannelNumMap; diff --git a/UserTools/PMTWaveformSim/PMTWaveformSim.cpp b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp new file mode 100644 index 000000000..d5789e354 --- /dev/null +++ b/UserTools/PMTWaveformSim/PMTWaveformSim.cpp @@ -0,0 +1,536 @@ +#include +#include +#include + +// ANNIE includes +#include "ANNIEconstants.h" +#include "PMTWaveformSim.h" + +// ROOT includes +#include "TGraph.h" + +PMTWaveformSim::PMTWaveformSim():Tool(){} + + +bool PMTWaveformSim::Initialise(std::string configfile, DataModel &data) +{ + + /////////////////// Useful header /////////////////////// + if(configfile!="") m_variables.Initialise(configfile); // loading config file + //m_variables.Print(); + + m_data= &data; //assigning transient data pointer + ///////////////////////////////////////////////////////////////// + + // get config variables + bool gotVerbosity = m_variables.Get("verbosity", verbosity); + if (!gotVerbosity) verbosity = 1; + + bool gotPMTParamFile = m_variables.Get("PMTParameterFile", fPMTParameterFile); + if (!gotPMTParamFile) { + logmessage = "PMTWaveformSim: No PMTParameterFile specified! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + if (!LoadPMTParameters()) + return false; + + bool got_sigmamap = m_variables.Get("useTimeSmearing", fuseTimeSmearing); + if (!got_sigmamap) { + logmessage = "PMTWaveformSim: No useTimeSmearing specified! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + bool gotPrewindow = m_variables.Get("Prewindow", fPrewindow); + if (!gotPrewindow) { + logmessage = "PMTWaveformSim: Prewindow not defined. Using default of 10."; + Log(logmessage, v_warning, verbosity); + fPrewindow = 10; + } + + bool gotReadoutWindow = m_variables.Get("ReadoutWindow", fReadoutWindow); + if (!gotReadoutWindow) { + logmessage = "PMTWaveformSim: ReadoutWindow not defined. Using default of 35."; + Log(logmessage, v_warning, verbosity); + fReadoutWindow = 35; + } + + bool gotT0Offset = m_variables.Get("T0Offset", fT0Offset); + if (!gotT0Offset) { + logmessage = "PMTWaveformSim: T0Offset not defined. Using default of 25."; + Log(logmessage, v_warning, verbosity); + fT0Offset = 25; + } + + bool gotShiftTimes = m_variables.Get("TimeShift", fTimeShift); + if (!gotShiftTimes) { + logmessage = "PMTWaveformSim: TimeShift not defined. Using default of 0."; + Log(logmessage, v_warning, verbosity); + fTimeShift = 0.0; + } else { + logmessage = "PMTWaveformSim: TimeShift = " + std::to_string(fTimeShift) + "ns will be applied to ALL MCHits."; + Log(logmessage, v_warning, verbosity); + } + + bool gotDebug = m_variables.Get("MakeDebugFile", fDebug); + if (!gotDebug) fDebug = 0; + if (fDebug) + fOutFile = new TFile("PMTWaveforms.root", "RECREATE"); + + bool gotGeometry = m_data->Stores.at("ANNIEEvent")->Header->Get("AnnieGeometry", fGeo); + if(!gotGeometry){ + logmessage = "PMTWaveformSim: Error retrieving Geometry from ANNIEEvent! Aborting!"; + Log(logmessage, v_error, verbosity); + return false; + } + + // random seed is grabbed from the system clock + fRandom.SetSeed(0); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::Execute() +{ + int load_status = LoadFromStores(); + + + // The container for the data that we'll put into the ANNIEEvent + std::map> > RawADCDataMC; + std::map> > CalADCDataMC; + + for (auto mcHitsIt : *fMCHits) { // Loop over the hit PMTs + int PMTID = mcHitsIt.first; + + std::vector mcHits = mcHitsIt.second; + + // Generate waveform samples from the MC hits + // samples from hits that are close in time will be added together + // key is hit time in clock ticks, value is amplitude + std::map sample_map; + for (const auto& mcHit : mcHits) {// Loop through each MCHit in the vector + + // skip negative hit times, what does that even mean if we're not using the smeared digit time? + // skip hit times past 70 us since that's our longest readout + if (mcHit.GetTime() < 0) continue; + if (mcHit.GetTime() > 70000) continue; + + // Grab the hit time (also converted to clock ticks) and the charge + double hit_t0 = mcHit.GetTime() + fTimeShift; + double hit_charge = mcHit.GetCharge(); + + logmessage = "PMTWaveformSim:\n hit charge = " + std::to_string(hit_charge) + " p.e., hit time = " + std::to_string(hit_t0) + " for PMTID " + std::to_string(PMTID); + Log(logmessage, v_message, verbosity); + + // before "digitizing", add smearing based on the uncertainty extracted in the laser analysis + if (fuseTimeSmearing) { + double timesmear = TimeSmearing(PMTID); + hit_t0 += timesmear; + } + + // now convert to clock ticks + uint16_t t0_ticks = uint16_t(hit_t0 / NS_PER_ADC_SAMPLE); + + // Set the readout window in clock ticks, but don't allow negative times + uint16_t start_clocktick = (t0_ticks > fPrewindow)? t0_ticks - fPrewindow : 0; + uint16_t end_clocktick = start_clocktick + fReadoutWindow; + + // Randomly Sample the PMT parameters for each MCHit + SampleFitParameters(PMTID); + + // loop over clock ticks + for (uint16_t clocktick = start_clocktick; clocktick <= end_clocktick; clocktick += 1) { + uint16_t sample = CustomLogNormalPulse(hit_t0, clocktick, hit_charge); + + std::stringstream logmessage; + logmessage << " --> clocktick = " << clocktick << ", sample = " << sample; + Log(logmessage.str(), v_message, verbosity); + + // check if this hit time has been recorded + // either set it or add to it + if (sample_map.find(clocktick) == sample_map.end()) + sample_map[clocktick] = sample; + else + sample_map[clocktick] += sample; + }// end loop over clock ticks + }// end loop over mcHits + + // If there are no samples for this PMT then no need to do the rest + if (sample_map.empty()) continue; + + + // Set the noise envelope and baseline for this PMT + // The noise std dev appears to be normally distributed around 1 with sigma 0.25 + // TODO: set accurate baseline and noise profiles for all PMTs individually (noise should be fine, baselines will vary) + double noiseSigma = fRandom.Gaus(1, 0.25); + int basline = fRandom.Uniform(300, 350); + + // convert the sample map into a vector of Waveforms and put them into the container + std::vector> rawWaveforms; + std::vector> calWaveforms; + ConvertMapToWaveforms(sample_map, rawWaveforms, calWaveforms, noiseSigma, basline); + + RawADCDataMC.emplace(PMTID, rawWaveforms); + CalADCDataMC.emplace(PMTID, calWaveforms); + }// end loop over PMTs + + // Publish the waveforms to the ANNIEEvent store if we have them + if (RawADCDataMC.size()) { + m_data->Stores.at("ANNIEEvent")->Set("RawADCDataMC", RawADCDataMC); + m_data->Stores.at("ANNIEEvent")->Set("CalibratedADCData", CalADCDataMC); + } else { + logmessage = "PMTWaveformSim: No waveforms produced. Skipping!"; + Log(logmessage, v_warning, verbosity); + m_data->Stores.at("ANNIEEvent")->Set("SkipExecute", true); + return true; + } + + + if (fDebug) + FillDebugGraphs(RawADCDataMC); + + m_data->Stores.at("ANNIEEvent")->Set("SkipExecute", false); + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::Finalise() +{ + if (fDebug) + fOutFile->Close(); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::LoadPMTParameters() +{ + + std::ifstream infile(fPMTParameterFile); + if (!infile.is_open()) { + logmessage = "PMTWaveformSim: Error opening CSV file: "; + logmessage += fPMTParameterFile + "!"; + Log(logmessage, v_error, verbosity); + return false; + } + + if (fuseTimeSmearing) { + // load timing offsets from the laser calibration to use as our timing uncertainty / smearing + bool got_offset = m_data->CStore.Get("ChannelNumToTankPMTTimingSigmaMap",ChannelKeyToTimingSigmaMap); + if (!got_offset) { + logmessage = "PMTWaveformSim: Error retrieving PMT timing uncertainty... double check LoadGeometry maybe?"; + Log(logmessage, v_error, verbosity); + return false; + } + } + + int pmtid; + // Stored fit parameters. + // p0, p1, and p2 are the mean values of the lognorm + // T1 and T2 are the reflection spacings + // r1 and r2 are the reflection amplitudes (relative to the main peak amplitude) + // the uncertainties (u*) are the sq(diagonal elements) of the fitted covariance matrix + double p0, p1, p2, T1, T2, R1, R2, + up0, up1, up2, uT1, uT2, uR1, uR2; + + std::string comma; + std::string line; + while (std::getline(infile, line)) { + if (infile.fail()) { + logmessage = "PMTWaveformSim: Error using CSV file: "; + logmessage += fPMTParameterFile + "!"; + Log(logmessage, v_error, verbosity); + + return false; + } + + // Skip the header line + if (line.find("PMT") != std::string::npos) continue; + + // Skip any commented lines + if(line.rfind("#",0) != std::string::npos) continue; + + // Turn the line into a stringstream to extract the values + std::stringstream ss(line); + ss >> pmtid >> comma >> p0 >> comma >> p1 >> comma >> p2 >> comma >> T1 >> comma >> T2 >> comma >> R1 >> comma >> R2 >> comma + >> up0 >> comma >> up1 >> comma >> up2 >> comma >> uT1 >> comma >> uT2 >> comma >> uR1 >> comma >> uR2; + + fPMTParamMap[pmtid] = {p0, p1, p2, T1, T2, R1, R2, up0, up1, up2, uT1, uT2, uR1, uR2}; + + logmessage = "PMTWaveformSim: Loaded parameters for PMTID " + std::to_string(pmtid) + ": "; + logmessage += "p0 = " + std::to_string(p0); + logmessage += " p1 = " + std::to_string(p1); + logmessage += " p2 = " + std::to_string(p2); + logmessage += " T1 = " + std::to_string(T1); + logmessage += " T2 = " + std::to_string(T2); + logmessage += " R1 = " + std::to_string(R1); + logmessage += " R2 = " + std::to_string(R2); + logmessage += " uncertainty_p0 = " + std::to_string(p0); + logmessage += " uncertainty_p1 = " + std::to_string(p1); + logmessage += " uncertainty_p2 = " + std::to_string(p2); + logmessage += " uncertainty_T1 = " + std::to_string(T1); + logmessage += " uncertainty_T2 = " + std::to_string(T2); + logmessage += " uncertainty_R1 = " + std::to_string(R1); + logmessage += " uncertainty_R2 = " + std::to_string(R2); + Log(logmessage, v_message, verbosity); + } + + infile.close(); + + return true; +} + +//------------------------------------------------------------------------------ +bool PMTWaveformSim::SampleFitParameters(int pmtid) +{ + PMTFitParams pmtParams; + if (fPMTParamMap.find(pmtid) != fPMTParamMap.end()) { + pmtParams = fPMTParamMap[pmtid]; + } else { + logmessage = "PMTWaveformSim: PMTParameters not found for " + std::to_string(pmtid); + logmessage += ", using defaults (exemplary fit: PMT 403 Hamamatsu): p0 = 16.876, p1 = 65.448, p2 = 0.032, T1 = 6.593, T2 = 6.975, r1 = 0.174, r2 = 0.049"; + Log(logmessage, v_warning, verbosity); + + // TODO make this a random sample as well + // TODO make the default the parameters of the *total* fit + fP0 = 16.876; + fP1 = 65.448; + fP2 = 0.032; + fT1 = 6.593; + fT2 = 6.975; + fR1 = 0.174; + fR2 = 0.049; + + return true; + } + + // First sample a Gaussian with mean 0 and deviation 1 + double rr0 = fRandom.Gaus(); // p0 + double rr1 = fRandom.Gaus(); // p1 + double rr2 = fRandom.Gaus(); // p2 + + // Randomly sample parameters with their associated uncertainties + fP0 = rr0*pmtParams.up0 + pmtParams.p0; + fP1 = rr1*pmtParams.up1 + pmtParams.p1; + fP2 = rr2*pmtParams.up2 + pmtParams.p2; + + // for the reflection coefficients, we know they must be positive (or else its nonsense) + double rr3, rr4, rr5, rr6; + do { + rr3 = fRandom.Gaus(); // T1 + rr4 = fRandom.Gaus(); // T2 + rr5 = fRandom.Gaus(); // r1 + rr6 = fRandom.Gaus(); // r2 + + fT1 = rr3*pmtParams.uT1 + pmtParams.T1; + fT2 = rr4*pmtParams.uT2 + pmtParams.T2; + fR1 = rr5*pmtParams.uR1 + pmtParams.R1; + fR2 = rr6*pmtParams.uR2 + pmtParams.R2; + + if (fT1 < 0.0 || fT2 < 0.0 || fR1 < 0.0 || fR2 < 0.0) { + std::stringstream debug_msg_random; + debug_msg_random << "PMTWaveformSim: Resampling due to negative value(s): " + << "fT1 = " << fT1 << ", " + << "fT2 = " << fT2 << ", " + << "fR1 = " << fR1 << ", " + << "fR2 = " << fR2 << std::endl; + Log(debug_msg_random.str(), v_warning, verbosity); + } + + } while (fT1 < 0.0 || fT2 < 0.0 || fR1 < 0.0 || fR2 < 0.0); + + + std::stringstream debug_msg; + debug_msg << "PMTWaveformSim::SampleFitParameters final sampled parameters:" + << "\n random p0 = " << fP0 + << "\n random p1 = " << fP1 + << "\n random p2 = " << fP2 + << "\n random T1 = " << fT1 + << "\n random T2 = " << fT2 + << "\n random R1 = " << fR1 + << "\n random R2 = " << fR2; + Log(debug_msg.str(), v_warning, verbosity); + + return true; +} + +//------------------------------------------------------------------------------ +uint16_t PMTWaveformSim::CustomLogNormalPulse(double hit_t0, uint16_t clocktick, double hit_charge) +{ + //p0*exp( -0.5 * (log(x/p1)/p2)^2) (main peak) + sum_{i = 1}^{3}[(pi*p0)*exp( -0.5 * (log(x - (i * Ti)/p1)/p2)^2)] (3 reflections) + + // The fit was performed in time units of ns, but we pass samples in clock ticks + double x = (clocktick + fT0Offset) * NS_PER_ADC_SAMPLE - hit_t0; + + // debug + double logarg_main = x / fP1; + double logarg_r1 = (x - fT1) / fP1; + double logarg_r2 = (x - 2*fT2) / fP1; + std::stringstream debug_msg; + debug_msg << "PMTWaveformSim::CustomLogNormalPulse debug:" + << "\n clocktick = " << clocktick + << "\n hit_t0 = " << hit_t0 + << "\n x = " << x + << "\n logarg_main = " << logarg_main + << "\n logarg_r1 = " << logarg_r1 + << "\n logarg_r2 = " << logarg_r2 + << "\n fP0 = " << fP0 + << ", fP1 = " << fP1 + << ", fP2 = " << fP2 + << ", fT1 = " << fT1 + << ", fT2 = " << fT2 + << ", fR1 = " << fR1 + << ", fR2 = " << fR2 + << ", hit_charge = " << hit_charge; + Log(debug_msg.str(), v_warning, verbosity); + + // main peak parameters + double numerator = log(x/fP1); + numerator = numerator * numerator; + double denom = fP2 * fP2; // main peak shape + width is used for all reflection peaks; only calculate once + double amplitude = fP0 * exp(-0.5 * numerator/denom) * hit_charge; + + // reflection 1 parameters + double numerator_r1 = log((x - fT1)/fP1); + numerator_r1 = numerator_r1 * numerator_r1; + amplitude += (fP0 * fR1) * exp(-0.5 * numerator_r1/denom) * hit_charge; + + // reflection 2 parameters + double numerator_r2 = log((x - (2*fT2))/fP1); + numerator_r2 = numerator_r2 * numerator_r2; + amplitude += (fP0 * fR2) * exp(-0.5 * numerator_r2/denom) * hit_charge; + + // Clip at 4095 and digitize to an integer + return uint16_t((amplitude > 4095) ? 4095 : amplitude); +} + +//------------------------------------------------------------------------------ +void PMTWaveformSim::ConvertMapToWaveforms(const std::map &sample_map, + std::vector> &rawWaveforms, + std::vector> &calWaveforms, + double noiseSigma, int baseline) +{ + // Clear the output waveforms just in case + rawWaveforms.clear(); + calWaveforms.clear(); + + // All MC has extended readout, but it's time consuming to draw 35000 noise samples + // Instead, only sample up to the maximum tick time. Then start with all baseline and + // add noise only to relevant ticks. The intermediate space between pulses will have no noise + + uint16_t maxTick = sample_map.rbegin()->first; + std::vector rawSamples(maxTick+1, baseline); + std::vector calSamples(maxTick+1, 0); + for (auto sample_pair : sample_map) { + uint16_t tick = sample_pair.first; + + // Generate noise for each sample based on the std dev of the noise envelope + double noise = fRandom.Gaus(0, noiseSigma); + int sample = std::round(noise + baseline); + + sample += sample_pair.second; + + rawSamples[tick] = (sample > 4095) ? 4095 : sample; + calSamples[tick] = (rawSamples[tick] - baseline) * ADC_TO_VOLT; + } + + // The start time in data is a trigger timestamp. Don't have that for MC so just set to 0. + rawWaveforms.emplace_back(0, rawSamples); + calWaveforms.emplace_back(0, calSamples, baseline, noiseSigma); +} + +//------------------------------------------------------------------------------ +int PMTWaveformSim::LoadFromStores() +{ + bool goodAnnieEvent = m_data->Stores.count("ANNIEEvent"); + if (!goodAnnieEvent) { + logmessage = "PMTWaveformSim: no ANNIEEvent store!"; + Log(logmessage, v_error, verbosity); + return 0; + } + + bool goodMCHits = m_data->Stores.at("ANNIEEvent")->Get("MCHits", fMCHits); + if (!goodMCHits) { + logmessage = "PMTWaveformSim: no MCHits in the ANNIEEvent! "; + Log(logmessage, v_error, verbosity); + return 0; + } + + if (fMCHits->empty()) { + logmessage = "PMTWaveformSim: The MCHits map is empty! Skipping!"; + Log(logmessage, v_warning, verbosity); + return 2; + } + + + return 1; +} + +//------------------------------------------------------------------------------ +void PMTWaveformSim::FillDebugGraphs(const std::map> > &RawADCDataMC) +{ + for (auto itpair : RawADCDataMC) { + std::string chanString = std::to_string(itpair.first); + + // Get/make the directory for this PMT + TDirectory* dir = fOutFile->GetDirectory(chanString.c_str()); + if (!dir) + dir = fOutFile->mkdir(chanString.c_str()); + + // Hop into that directory and save the graph + dir->cd(); + + // loop over waveforms and make graphs + for (uint wfIdx = 0; wfIdx < itpair.second.size(); ++wfIdx) { + auto waveform = itpair.second.at(wfIdx); + + uint32_t evtNum = 0; + m_data->Stores.at("ANNIEEvent")->Get("EventNumber",evtNum); + std::string grName = ("wf_" + std::to_string(evtNum) + "_" + std::to_string(wfIdx)); + + // Make the graph + std::vector samples = waveform.Samples(); + TGraph grTemp = TGraph(); + double sampleX = waveform.GetStartTime(); + for(auto sample : samples) { + grTemp.AddPoint(sampleX, sample); + ++sampleX; + } + + grTemp.Write(grName.c_str()); + }// end loop over waveforms + }// end loop over PMTs +} + +double PMTWaveformSim::TimeSmearing(int pmtid) +{ + // fetch uncertainty using PMT id + auto it = ChannelKeyToTimingSigmaMap->find(pmtid); + double timing_sigma; + if (it != ChannelKeyToTimingSigmaMap->end()) { + timing_sigma = it->second; + if (verbosity > v_debug) { + std::cout << "PMTWaveformSim: Found timing uncertainty for PMT " << pmtid + << " -> " << timing_sigma << " ns" << std::endl; + } + } else { + timing_sigma = 1.0; // default to 1 ns if not found + if (verbosity > v_error) { + std::cout << "PMTWaveformSim: Didn't find timing uncertainty for PMT " << pmtid + << ", setting timing uncertainty to " << timing_sigma << " ns" + << std::endl; + } + } + + // apply time smearing by sampling normal centered at 0 with std = timing_sigma + double time_smearing = fRandom.Gaus(0, timing_sigma); + return time_smearing; +} + + + + + diff --git a/UserTools/PMTWaveformSim/PMTWaveformSim.h b/UserTools/PMTWaveformSim/PMTWaveformSim.h new file mode 100644 index 000000000..8ca705ae1 --- /dev/null +++ b/UserTools/PMTWaveformSim/PMTWaveformSim.h @@ -0,0 +1,93 @@ +#ifndef PMTWaveformSim_H +#define PMTWaveformSim_H + +#include +#include + +// ANNIE includes +#include "Tool.h" +#include "CalibratedADCWaveform.h" +#include "Waveform.h" + +// ROOT includes +#include "TFile.h" +#include "TRandom3.h" + +struct PMTFitParams +{ + double p0, p1, p2, T1, T2, R1, R2; + double up0, up1, up2, uT1, uT2, uR1, uR2; +}; + + +/** + * \class PMTWaveformSim + * + * This is a blank template for a Tool used by the script to generate a new custom tool. Please fill out the description and author information. +* +* $Author: A.Sutton, S.Doran, and D. Ajana $ +* $Date: 2024/11/05 10:44:00 $ +* Contact: doran@iastate.edu +*/ +class PMTWaveformSim: public Tool { + + + public: + + PMTWaveformSim(); ///< Simple constructor + bool Initialise(std::string configfile,DataModel &data); ///< Initialise Function for setting up Tool resources. @param configfile The path and name of the dynamic configuration file to read in. @param data A reference to the transient data class used to pass information between Tools. + bool Execute(); ///< Execute function used to perform Tool purpose. + bool Finalise(); ///< Finalise function used to clean up resources. + int LoadFromStores(); ///< Fetch all necessary info from the CStore + + bool LoadPMTParameters(); ///< load in: 1. lognorm fit information from the csv file and 2. PMT timing uncertainties from laser analysis + bool SampleFitParameters(int pmtid); ///< sample fit parameters in a way that preserves covariance + uint16_t CustomLogNormalPulse(double hit_t0, uint16_t t0_clocktick, double hit_charge); //< construct simulated ADC pulses using sampled fit values + void ConvertMapToWaveforms(const std::map &sample_map, ///< construct a waveform with the simulated pulse + baseline modulation, to feed into the PhaseIIADCHitFinder + std::vector> &rawWaveforms, + std::vector> &calWaveforms, + double noiseSigma, int baseline); + + void FillDebugGraphs(const std::map> > &RawADCDataMC); ///< debugging + double TimeSmearing(int pmtid); ///< prior to sampling the fits, we can add realistic time smearing (instead of relying on WCSim's time smearing) to the MCHit (true) time + + private: + + // To load from the ANNIEEvent + std::map> *fMCHits = nullptr; + + Geometry *fGeo = nullptr; + + // Config variables + uint16_t fPrewindow; // number of clock ticks before the MC hit time to begin sampling the fit function + uint16_t fReadoutWindow; // number of clock ticks around the MC hit time over which waveforms are sampled + int fT0Offset; // a timing offset (in clock ticks) that can be used to align the pulse start time (can be positive or negative) + bool fuseTimeSmearing; // whether to implement time smearing based on the uncertainties extracted from the PMT laser timing analysis + // (this should be used in place of the standard WCSim time smearing) + double fTimeShift; // [ns] to shift MC hit times by - if generating WCSim particles, there is often a pileup at t = 0. When doing the hit integration, + // this can artificially shorten the "pre"-pulse integration (doesn't typically happen in data). + + std::string fPMTParameterFile; + + TRandom3 fRandom; + + std::map fPMTParamMap; + double fP0, fP1, fP2; // main peak parameters + double fT1, fT2, fR1, fR2; // reflection amplitudes and time spacings + + // timing uncertainty map + std::map* ChannelKeyToTimingSigmaMap; + + bool fDebug; + TFile *fOutFile; + + int verbosity; + int v_error=0; + int v_warning=1; + int v_message=2; + int v_debug=3; + std::string logmessage; +}; + + +#endif diff --git a/UserTools/PMTWaveformSim/README.md b/UserTools/PMTWaveformSim/README.md new file mode 100644 index 000000000..a31230d80 --- /dev/null +++ b/UserTools/PMTWaveformSim/README.md @@ -0,0 +1,37 @@ +# PMTWaveformSim + +PMTWaveformSim generates PMT waveforms based on the simulated PMT hits. For each MCHit a lognorm waveform is sampled based on fit parameters extracted from SPE waveforms in data. The fit functions are taken from Daya Bay and are used to model a main peak and two reflections. The fit parameters are sampled using the associated fit errors, and captures the random behavior of a PMT's response. A full extended readout window (70 us) is sampled and waveforms from overlapping hits are added. A random baseline between 300 and 350 ADC is added. Random noise is applied, where the noise sigma is sampled from a gaussian with mean 1 and std dev of 0.25. The baseline and noise envelope values are hardcoded at the moment. Finally, any ADC counts above 4095 are clipped to mimic saturation. The resulting MC waveform hits look like Data hits, and can be passed to tools downstream as if they are Data hits (so long as the configuration is set for those tools). + +The implementation of this tool and details on the waveform simulation can be found here: https://annie-docdb.fnal.gov/cgi-bin/sso/RetrieveFile?docid=5962&filename=MC%20Tuning%20and%20Validation%20_%20March%202025%20Collab%20Meeting%20_%20Steven%20Doran.pdf&version=1 + +Details on the fits used can be found here: https://github.com/S81D/PMTPulseFit + +## Data + +**RawADCDataMC** `std::map> >` +* The raw simulated waveforms. The key is PMT channel number, then inner vector should always have size == 1 + +**CalibratedADCData** `std::map> >` +* The "calibrated" simulated waveforms. The baseline and sigma are the true, randomly-generated values. The key is PMT channel number, then inner vector should always have size == 1 + + +## Configuration + +`PMTWaveformSim` uses a fit file with SPE fits extracted from the data for each PMT. Any toolchain using this tool must have a `PMTWaveformLognormFit.csv` file in that toolchain directory. + +``` +verbosity 0 +PMTParameterFile configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv # file containing the fit parameters and uncertainties +useTimeSmearing 0 # instead of the default WCSim time smearing, add in realistic time smearing based on the PMT laser analysis +Prewindow 80 # number of clock ticks before the MC hit time to begin sampling the fit function +ReadoutWindow 200 # number of clock ticks around the MC hit time over which waveforms are sampled +T0Offset 25 # A timing offset (in clock ticks) that can be used to vary the pulse start times + # (it is primarily used to ensure the lognorm fits on the main peak avoid NaNs when sampling the fit params) + # (The T0offset set to 25 shifts the sampling to avoid fit blowups, then the code shifts it back by 25. 25 is therefore the "default" and is recommended.) +TimeShift 0 # This is an artificial time shift to the MC Hits [ns] + # (as WCSim simulates particles from t0 = 0, this can be used as a toggle on the "trigger time") +MakeDebugFile 0 # Produce a root file containing all the simulated waveforms +``` + +## Other notes +#### CAUTION: In line 90, the RNG seed is set in Initialization based on the clock time. If any other downstream tools are also setting a random seed, there may be unexpected behavior as a result of this tool. diff --git a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp index e80800af8..da2cfcb8a 100755 --- a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp +++ b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.cpp @@ -36,6 +36,7 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat m_variables.Get("PulseWindowEnd", pulse_window_end_shift); m_variables.Get("WindowIntegrationDB", adc_window_db); m_variables.Get("EventBuilding",eventbuilding_mode); + m_variables.Get("MCWaveforms",mc_waveforms); if ((pulse_window_start_shift > 0) || (pulse_window_end_shift) < 0){ Log("PhaseIIADCHitFinder Tool: WARNING... trigger threshold crossing will not be inside pulse window. Threshold" @@ -65,6 +66,11 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat eventbuilding_mode = false; } + if (mc_waveforms && (eventbuilding_mode || use_led_waveforms)) { + Log("PhaseIIADCCalibrator: Cannot use MCWaveforms in EventBuilding mode or while using LED waveforms. Aborting!", v_error, verbosity); + return false; + } + //Set in CStore for tools to know and log this later m_data->CStore.Set("ADCThreshold",default_adc_threshold); @@ -72,7 +78,8 @@ bool PhaseIIADCHitFinder::Initialise(std::string config_filename, DataModel& dat m_data->CStore.Get("AuxChannelNumToTypeMap",AuxChannelNumToTypeMap); // Get the timing offsets - m_data->CStore.Get("ChannelNumToTankPMTTimingOffsetMap",ChannelKeyToTimingOffsetMap); + if (!mc_waveforms) // (don't need them for MC) + m_data->CStore.Get("ChannelNumToTankPMTTimingOffsetMap",ChannelKeyToTimingOffsetMap); //Recreate maps that were deleted with ANNIEEvent->Delete() ANNIEEventBuilder tool hit_map = new std::map>; @@ -129,6 +136,25 @@ bool PhaseIIADCHitFinder::Execute() { } else { got_raw_data = annie_event->Get("RawADCData", raw_waveform_map); got_rawaux_data = annie_event->Get("RawADCAuxData", raw_aux_waveform_map); + + if (mc_waveforms) { + got_raw_data = annie_event->Get("RawADCDataMC", raw_waveform_map); + + // Some executes are skipped if there are no MCHits or waveforms produced + // Put the cleared maps into the ANNIEEvent to ensure that a downstream + // tool doesn't grab a map from a previous event + bool skip = false; + bool got_skip_status = annie_event->Get("SkipExecute", skip); + if (got_skip_status && skip) { + Log("PhaseIIADCHitFinder: An upstream tool told me to skip this event.",v_warning,verbosity); + + m_data->Stores.at("ANNIEEvent")->Set("RecoADCHits", pulse_map); + m_data->Stores.at("ANNIEEvent")->Set("RecoADCAuxHits", aux_pulse_map); + + return true; + } + }// end if mc_waveforms + } // Check for problems if ( !got_raw_data ) { @@ -136,7 +162,7 @@ bool PhaseIIADCHitFinder::Execute() { verbosity); return false; } - if ( !got_rawaux_data ) { + if ( !got_rawaux_data && !(use_led_waveforms || mc_waveforms)) { Log("Error: The PhaseIIADCHitFinder tool could not find the RawADCAuxData entry", v_error, verbosity); return false; @@ -165,7 +191,7 @@ bool PhaseIIADCHitFinder::Execute() { " entry", v_error, verbosity); return false; } - if ( !got_calibratedaux_data ) { + if ( !got_calibratedaux_data && !(use_led_waveforms || mc_waveforms)) { Log("Error: The PhaseIIADCHitFinder tool could not find the CalibratedADCAuxData" " entry", v_error, verbosity); return false; @@ -666,6 +692,10 @@ std::vector PhaseIIADCHitFinder::find_pulses_bywindow( double charge = 0.; unsigned long raw_area = 0; // ADC * samples + unsigned short baseline_plus_one_sigma = static_cast( + std::round( calibrated_minibuffer_data.GetBaseline() + + calibrated_minibuffer_data.GetSigmaBaseline() )); + if(MaxHeightPulseOnly){ // From that peak sample, sum up to either side until finding a // sample that's 10% of the max height @@ -675,23 +705,57 @@ std::vector PhaseIIADCHitFinder::find_pulses_bywindow( size_t pulsewinright = peak_sample + 1; bool integrated_leftward = false; bool integrated_rightward = false; + + size_t extra_pulsewinleft = 0; + bool extra_winleft = false; + size_t extra_pulsewinright = 0; + bool extra_winright = false; + while (!integrated_leftward && peak_sample!=wmin){ double sample_height = calibrated_minibuffer_data.GetSample(pulsewinleft); - if (sample_height > (0.1 * calibrated_amplitude) && (pulsewinleft>wmin)){ + double raw_sample_height = raw_minibuffer_data.GetSample(pulsewinleft); + + if (raw_sample_height <= (baseline_plus_one_sigma)) extra_winleft = true; + + if (pulsewinleft<=wmin) {integrated_leftward = true;} + + else if (raw_sample_height > (baseline_plus_one_sigma) && (pulsewinleft>wmin) && !extra_winleft ){ raw_area += raw_minibuffer_data.GetSample(pulsewinleft); charge += sample_height; pulsewinleft-=1; } - else integrated_leftward = true; + + else if (extra_winleft && pulsewinleft>wmin) { + raw_area += raw_minibuffer_data.GetSample(pulsewinleft); + charge += sample_height; + pulsewinleft-=1; + extra_pulsewinleft += 1; + if(extra_pulsewinleft == 5) integrated_leftward = true; + } + } while (!integrated_rightward && peak_sample!=wmax){ double sample_height = calibrated_minibuffer_data.GetSample(pulsewinright); - if (sample_height > (0.1 * calibrated_amplitude) && (pulsewinright < wmax)){ + double raw_sample_height = raw_minibuffer_data.GetSample(pulsewinright); + + if (raw_sample_height <= (baseline_plus_one_sigma)) extra_winright = true; + + if (pulsewinright>=wmax) {integrated_rightward = true;} + + else if (raw_sample_height > (baseline_plus_one_sigma) && (pulsewinright PhaseIIADCHitFinder::find_pulses_bywindow( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>2){ + if(verbosity>2 && !mc_waveforms){ std::cout << "Didn't find Timing offset for channel " << channel_key << std::endl; } } @@ -826,7 +890,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>v_error){ + if(verbosity>v_error && !mc_waveforms){ std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel... setting this channel's offset to 0ns" << channel_key << std::endl; } } @@ -954,7 +1018,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>v_error){ + if(verbosity>v_error && !mc_waveforms){ std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel " << channel_key << "... setting this channel's offset to 0ns" << std::endl; } } @@ -1076,7 +1140,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( if(it != ChannelKeyToTimingOffsetMap.end()){ //Timing offset is available timing_offset = ChannelKeyToTimingOffsetMap.at(channel_key); } else { - if(verbosity>v_error){ + if(verbosity>v_error && !mc_waveforms){ std::cout << "PhaseIIADCHitFinder: Didn't find Timing offset for channel... setting this channel's offset to 0ns" << channel_key << std::endl; } } @@ -1110,16 +1174,16 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( } } - if(verbosity>v_debug) { - - std::cout << "Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; - - if (hit_time < 0.0) { + if (hit_time < 0.0) { // If for some reason the interpolation finds a negative time value (if the pulse is extremely early in the buffer), // default to the peak time (maximum ADC value of the pulse) std::cout << "Hit time is negative! Defaulting to peak time" << std::endl; hit_time = peak_sample; - } + } + + if(verbosity>v_debug) { + + std::cout << "Hit time [ns] " << hit_time * NS_PER_ADC_SAMPLE << std::endl; std::cout << "Pulse properties: " << std::endl; std::cout << " chanID: " << channel_key << std::endl; @@ -1143,7 +1207,7 @@ std::vector PhaseIIADCHitFinder::find_pulses_bythreshold( } } else { if(verbosity > v_error){ - std::cout << "PhaseIIADCHitFinder Tool error: Pulse window type not recognized. Please pick fixed or dynamic" << std::endl; + std::cout << "PhaseIIADCHitFinder Tool error: Pulse window type not recognized. Please pick fixed, dynamic, or Fixed_2023_Gains" << std::endl; } } if(verbosity > v_debug) std::cout << "Number of pulses in channels pulse vector: " << pulses.size() << std::endl; diff --git a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h index b3471d58e..ef3c10907 100755 --- a/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h +++ b/UserTools/PhaseIIADCHitFinder/PhaseIIADCHitFinder.h @@ -59,6 +59,7 @@ class PhaseIIADCHitFinder : public Tool { std::map channel_threshold_map; std::map>> channel_window_map; bool eventbuilding_mode; + bool mc_waveforms; std::map ChannelKeyToTimingOffsetMap; diff --git a/UserTools/Unity.h b/UserTools/Unity.h index f95bb5c8d..ea9fdd96d 100644 --- a/UserTools/Unity.h +++ b/UserTools/Unity.h @@ -182,4 +182,5 @@ #include "PrintDQ.h" #include "AssignBunchTimingMC.h" #include "FitRWMWaveform.h" +#include "PMTWaveformSim.h" #include "LAPPDWaveformDisplay.h" diff --git a/configfiles/PMTWaveformSim/ClusterClassifiersConfig b/configfiles/PMTWaveformSim/ClusterClassifiersConfig new file mode 100644 index 000000000..f079d9b8a --- /dev/null +++ b/configfiles/PMTWaveformSim/ClusterClassifiersConfig @@ -0,0 +1,3 @@ +#ClusterClassifiers Config file +verbosity 0 +IsData 1 diff --git a/configfiles/PMTWaveformSim/ClusterFinderConfig b/configfiles/PMTWaveformSim/ClusterFinderConfig new file mode 100644 index 000000000..ded568144 --- /dev/null +++ b/configfiles/PMTWaveformSim/ClusterFinderConfig @@ -0,0 +1,12 @@ +# ClusterFinder Config File + +verbosity 0 +HitStore Hits #Either MCHits or Hits (accessed in ANNIEEvent store) +OutputFile BeamRun_ClusterFinder_DefaultOutput #Output root prefix name for the current run +ClusterFindingWindow 40 # in ns, size of the window used to "clusterize" +AcqTimeWindow 70000 # in ns, size of the acquisition window +ClusterIntegrationWindow 40 # in ns, all hits with +/- 1/2 of this window are considered in the cluster +MinHitsPerCluster 5 # group of hits are considered clusters above this amount of hits +end_of_window_time_cut 0.95 # from o to 1, length of the window you want to loop over with respect to acq. window (1 for full window, 0.95 for 95% from the start) +Plots2D 0 #Draw 2D charge-vs-time plots? +MC_pulse_width 35 # width of MC "pulse" in which to integrate true photon hits - all true photon hits on a single PMT will be combined into a "pulse" of this width diff --git a/configfiles/PMTWaveformSim/LoadGeometryConfig b/configfiles/PMTWaveformSim/LoadGeometryConfig new file mode 100644 index 000000000..b52737aa4 --- /dev/null +++ b/configfiles/PMTWaveformSim/LoadGeometryConfig @@ -0,0 +1,9 @@ +verbosity 0 +LAPPDChannelCount 60 +FACCMRDGeoFile ./configfiles/LoadGeometry/FullMRDGeometry.csv +DetectorGeoFile ./configfiles/LoadGeometry/DetectorGeometrySpecs.csv +LAPPDGeoFile ./configfiles/LoadGeometry/LAPPDGeometry.csv +TankPMTGeoFile ./configfiles/LoadGeometry/FullTankPMTGeometry.csv +TankPMTGainFile ./configfiles/LoadGeometry/ChannelSPEGains_BeamRun20192020.csv +AuxiliaryChannelFile ./configfiles/LoadGeometry/AuxChannels.csv +TankPMTTimingOffsetFile ./configfiles/LoadGeometry/TankPMTTimingOffsets.csv \ No newline at end of file diff --git a/configfiles/PMTWaveformSim/LoadWCSimConfig b/configfiles/PMTWaveformSim/LoadWCSimConfig new file mode 100644 index 000000000..810e60949 --- /dev/null +++ b/configfiles/PMTWaveformSim/LoadWCSimConfig @@ -0,0 +1,13 @@ +verbose 1 +InputFile wcsim_0.root + +WCSimVersion 3 +HistoricTriggeroffset 0 +UseDigitSmearedTime 0 +LappdNumStrips 56 +LappdStripLength 100 +LappdStripSeparation 10 +PMTMask ./configfiles/LoadWCSim/DeadPMTIDs_p2v7.txt +ChankeyToPMTIDMap ./configfiles/LoadWCSim/Chankey_WCSimID_v7.txt +ChankeyToMRDIDMap ./configfiles/LoadWCSim/MRD_Chankey_WCSimID.dat +ChankeyToFMVIDMap ./configfiles/LoadWCSim/FMV_Chankey_WCSimID.dat diff --git a/configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv b/configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv new file mode 100644 index 000000000..4106d8905 --- /dev/null +++ b/configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv @@ -0,0 +1,119 @@ +PMT, p0, p1, p2, T1, T2, r1, r2, uncertainty_p0, uncertainty_p1, uncertainty_p2, uncertainty_T1, uncertainty_T2, uncertainty_r1, uncertainty_r2 +332, 20.357853978341936, 65.90384439721554, 0.0340967744115092, 7.557160702639488, 6.585655917219643, 0.1503852922643872, 0.0283262902553479, 1.5006784011077394, 0.1821045576494313, 0.0020383848858524, 0.8183581423499159, 1.3294537012359884, 0.0319670913492465, 0.0212107330727452 +334, 6.292263691717479, 66.17529055087431, 0.0479550421907901, 7.028760743259689, 6.708418856643082, 1.2999999999999998, 0.8831324340336038, 0.754961760469793, 0.5060144651618599, 0.0047079405839556, 0.5494404969709311, 0.3931356265396093, 0.2227145854675353, 0.262187622488554 +335, 15.790696448010278, 66.7984345406303, 0.0421359716208697, 8.681214051550992, 8.406762885569735, 0.1665020833218284, 0.0798274099045134, 1.4366601798060934, 0.2926699462545326, 0.0025504882574863, 0.9806570759481033, 0.5682558594952786, 0.0388617629341706, 0.020493300267404 +336, 14.383511954753358, 66.3345096634602, 0.0402961636208563, 9.030202858813963, 8.12502775564912, 0.2018161494205744, 0.1099581127595617, 0.7312133475898853, 0.1505907674866848, 0.0015810733327726, 0.6038714965494124, 0.3897435593647128, 0.0284952802199744, 0.0213485284430556 +338, 9.751203657255116, 66.09204333811005, 0.0417688718421429, 7.870905656037526, 7.48408716940295, 0.8793499987261487, 0.3813396934209984, 0.6291471368220871, 0.1842806521392485, 0.0017302975245936, 0.2386304454804918, 0.2398935612948264, 0.0695339006141688, 0.0506630520223418 +339, 12.297137860654884, 66.25433439234966, 0.0410039389624383, 8.712815893450685, 9.078555383381486, 0.287588600092208, 0.1860505124675845, 0.9699956938398736, 0.2237270945022526, 0.0024822126317048, 0.7725603832311662, 0.5379861371461777, 0.0611103629288461, 0.0494593533475276 +340, 13.236372335808973, 66.6125305674671, 0.0426244102502171, 9.341517097309929, 9.341753844982414, 0.2787903874544818, 0.1298472064798972, 0.9722414439332344, 0.197676827031285, 0.0020950128178821, 0.5415375345441487, 0.5358072131451369, 0.0395040903759332, 0.0343961868646554 +341, 19.671767926618845, 66.57659829699266, 0.0392724761439105, 8.66492442594544, 7.823086748074368, 0.1733782616419335, 0.0251066508853136, 0.8609250064152121, 0.117863382297257, 0.0012647868135769, 0.4943269882416702, 1.105360575091787, 0.0199459893319272, 0.013031301380743 +344, 12.2135404235275, 66.21814185876319, 0.0402443983589074, 9.999999999999998, 9.999999999999998, 0.4583938774896324, 0.327458807747422, 3.271092049037668, 0.6677256037508603, 0.0052553814226796, 0.9418292192490556, 0.6611275022340305, 0.1554458296742829, 0.1270203810499398 +347, 17.237522282606196, 66.88819719304713, 0.041863701801471, 7.054668116607341, 7.904142341113217, 0.2386773215632731, 0.0525338860923424, 1.0016354950146786, 0.2279784361981261, 0.0021616698215719, 0.7097112099875018, 0.8459998117959165, 0.0545083704982428, 0.0215464687425428 +348, 19.330360090339248, 66.71209409634614, 0.0398160824347048, 8.850519058543316, 9.357958326080697, 0.1643832828586765, 0.0631286738890893, 1.0058583214126628, 0.1409381082663351, 0.0014471801848537, 0.4954874299763987, 0.3541299315363446, 0.0210955720887048, 0.0119934424997495 +350, 19.050897037557963, 66.06911930633586, 0.0349696973891647, 7.771461656171925, 7.385219746743812, 0.1361972160753289, 0.0283486293661057, 0.959697403682776, 0.1300662540797689, 0.0013681710052555, 0.5474234625525469, 0.7528051678346602, 0.0219350406831112, 0.0118744913643624 +351, 20.46018688687866, 66.28463751212165, 0.0356813804674755, 7.949883842739932, 7.924394777152569, 0.1433122937248124, 0.0151484017212938, 0.8684720810861236, 0.1107167474626796, 0.0011120124103089, 0.3853890130351099, 0.898701255137052, 0.016464840588247, 0.0070669185445902 +353, 7.538493076099391, 64.90405391519464, 0.033709862211958, 7.147215216338458, 7.387082838850287, 0.2740162858771454, 0.0279572647798352, 0.385700571206148, 0.144271104398858, 0.0019475881695673, 0.46593025700815, 2.0866025789857123, 0.0452298134623492, 0.0363609431824052 +354, 17.811456970786526, 67.46145611134042, 0.0448806473551208, 8.364787449091981, 9.365560244850483, 0.2884148127179849, 0.0841552346104563, 1.0550132433996708, 0.1871692339128528, 0.0017231848649593, 0.3858520847309457, 0.3692117386846541, 0.0334737210055136, 0.015474857709283 +355, 11.008456595647305, 67.4326306929489, 0.050884817029899, 9.098796385195598, 9.954330813147434, 0.271961217862843, 0.0785939358749361, 0.497947186364587, 0.1775190810225733, 0.0018378629024142, 0.4393889369072745, 0.5048889587521092, 0.0300373539886787, 0.015456706806295 +356, 8.266511790339552, 64.90421719919337, 0.0362584188783418, 7.296051860387467, 7.936996736221687, 0.3119339831842557, 0.1065571987204909, 0.7747643827392147, 0.2278143488689185, 0.0025563167861311, 0.4831649049641118, 0.607733953959011, 0.047786977324938, 0.0411330394082787 +357, 16.83827719845519, 67.98649737338961, 0.0488589063764169, 8.715776607463875, 9.686373080102197, 0.317360105169386, 0.1091658092760097, 1.47255133189011, 0.3058130787158061, 0.0027411885052504, 0.5468664172609529, 0.437332187025368, 0.0571768798045901, 0.0218602903508639 +358, 10.588611200775787, 65.55145501058198, 0.0375302199806138, 7.032609490880665, 7.382789294556115, 0.395240092652954, 0.0821026238510351, 0.7166051123354304, 0.1959985392242673, 0.0020450892586263, 0.3602105518180945, 0.5735352663913568, 0.0480789232970733, 0.0241669289931063 +360, 12.989523387362754, 67.43889722954187, 0.0490778437418347, 9.178232884799996, 9.999999999999998, 0.2838452583454555, 0.0790984645918084, 0.611297868773257, 0.1789603734389225, 0.0017966225547267, 0.440223444369138, 0.5150740343162961, 0.0318429640634362, 0.016963149224655 +361, 9.152541649643704, 65.19848920697314, 0.0355782101555033, 5.754350987206749, 6.240737091825019, 0.4882725615755737, 0.1921702513822433, 0.9039223425346138, 0.3169800739912223, 0.0033503817235365, 0.5195944812474874, 0.4262150700328748, 0.1067108748039876, 0.055461481172022 +362, 14.257330335978208, 67.25062803286859, 0.0455298878788364, 8.785319479913118, 9.544639360492388, 0.2372920619753069, 0.0662136604169978, 0.6248513845555664, 0.1407506162089925, 0.001330056292391, 0.2913950619337741, 0.3149709085760995, 0.0218185539178776, 0.009425473245432 +363, 14.37440551348584, 66.99281218787614, 0.0441690641032088, 8.162230183905065, 9.328589221880376, 0.2791999479399347, 0.071630276694176, 0.7955827329506822, 0.1743714143274772, 0.0017276221333635, 0.4042614793689724, 0.4629478891129285, 0.0350566328301072, 0.0151883879792555 +364, 11.209341886338796, 67.5298345924113, 0.0505583268434526, 8.589305269459647, 9.361193322478924, 0.3083212753213922, 0.0652203603825681, 0.5024802349597685, 0.2071002609469198, 0.0020526916892498, 0.4983360964235795, 0.7692829232687812, 0.0419311772303984, 0.0197042258068616 +365, 10.466342200724522, 67.01549260673573, 0.0490357604131224, 8.703495741380584, 9.5413216467255, 0.2901998987673181, 0.0695586495138962, 0.4811489426909944, 0.1889924442762473, 0.0019915926052866, 0.4574497254291375, 0.6446410926555026, 0.03496492394386, 0.0179338200887867 +366, 8.238963208355255, 65.31371086437863, 0.037826453042094, 6.9440160033602645, 7.083326382024604, 0.3404063954596296, 0.0848594805349115, 0.4225362793625691, 0.165471263411407, 0.0018784814058399, 0.3947423550768326, 0.5990073974407618, 0.0396755579772224, 0.0270374337457129 +367, 17.221447145341997, 67.38180136856019, 0.0463019190587128, 9.261792583194069, 8.910818909916847, 0.2647917364447043, 0.0688395476615478, 1.1122327907666834, 0.2083636694046652, 0.0021228996696989, 0.4957113399827973, 0.5918826537798941, 0.0326279028697975, 0.0177669028319231 +368, 16.055617970932637, 67.6045562971837, 0.048645952971135, 8.668428731726522, 9.397754566149544, 0.3177199305298535, 0.0875385610776006, 0.8087785725388428, 0.1903535750972179, 0.001858743137012, 0.4110759187780123, 0.4443929993361959, 0.0377975861469125, 0.016091114671514 +369, 8.235514483612029, 65.39845991622674, 0.0379919780567145, 5.195837313213686, 5.841392431189012, 0.4633905603219343, 0.218082652995764, 0.6753439039520601, 0.3058374607984611, 0.0027808731333128, 0.5093918536723553, 0.3062621394095709, 0.1260503074233654, 0.0513733019244091 +370, 9.827913801926622, 66.0029553149226, 0.0408463267695314, 4.670733303673959, 5.530465872066271, 0.5330036879159584, 0.2881785488445582, 1.4064672968668608, 0.5336943438568987, 0.0038190146827619, 0.7204958564658008, 0.3638948806595114, 0.2616106607633683, 0.0898330223648199 +371, 15.536924107906126, 67.31011301676995, 0.0460609945752772, 8.170689499542611, 8.776286477487787, 0.3358923530971972, 0.090995966096718, 0.8326839920806605, 0.1914391963734649, 0.0018055048426144, 0.3863461541721553, 0.4212820655693525, 0.0385778283500794, 0.0173991403126674 +372, 20.265801207087076, 66.26643798500443, 0.037625758884311, 7.691365477704399, 7.934860337473662, 0.2062905507564349, 0.1099545604410246, 1.7323620620757134, 0.2165536486686666, 0.00208843117146, 0.6060900699060611, 0.3691399059204142, 0.040189979210692, 0.0216112090271472 +373, 18.47144696591243, 66.10843510828055, 0.0368250562553195, 7.37889451927354, 7.926558542135284, 0.1780689923412876, 0.0992824526972676, 1.0386260204178026, 0.1465209405415157, 0.001423639726641, 0.4960782919123777, 0.2651544908150366, 0.0266197166251409, 0.0151614616280693 +374, 18.733450625202543, 66.03714395896549, 0.0357466721532745, 6.821980748374166, 7.42455753358584, 0.2004897248381177, 0.0967446905983924, 1.3117159659263418, 0.181747766583614, 0.0018190688074595, 0.593356767971712, 0.349141087276101, 0.0431702972880477, 0.0196726485958993 +375, 18.29964101164197, 65.99041546078678, 0.0360924681726434, 6.788350534514889, 6.9933261635974935, 0.1890352464355826, 0.0883206877550451, 1.2398531836790057, 0.1838388338187482, 0.0018043317084514, 0.5978804693061366, 0.3329718257885954, 0.0387644050824806, 0.0169542976112072 +376, 18.27003660075122, 65.93388119788045, 0.0349124830899537, 6.324933649949538, 7.154945500990409, 0.2517633898831827, 0.1143958038629183, 1.2831597386108702, 0.1882514192308142, 0.0017213712270112, 0.4547619440641796, 0.2994235057762209, 0.0459274076706117, 0.0204626135754265 +377, 18.025089963105607, 66.2495254397634, 0.0371680236705387, 7.892418019437722, 7.9585813233008444, 0.18547839075243, 0.0807544808460221, 1.3576058819403294, 0.1899875859611221, 0.0017963602647972, 0.5574188200868234, 0.3787728361010564, 0.0337894783102483, 0.0171747233015483 +378, 17.988837317346352, 66.08187729182039, 0.0364098975116126, 6.894381296547095, 7.301397539820902, 0.1992731803776769, 0.0956253533013246, 1.2081798572278206, 0.1780396826276052, 0.0017803965463349, 0.5626408446382771, 0.3369999517809889, 0.0386051086745962, 0.0165434939462849 +379, 21.50877185750913, 65.96737726011403, 0.0343135506346025, 7.7513648710468575, 7.45351379507988, 0.1989535915872935, 0.151952869094528, 2.5981886395246474, 0.2677781707724807, 0.0023178437891173, 0.5574264198249208, 0.2757627249010551, 0.0390261909252865, 0.0274969121020276 +380, 19.20067503080077, 65.96608849830523, 0.0348164848817087, 6.751549684509847, 7.549526260525422, 0.1536762714722039, 0.0472637374182467, 0.8116528840617694, 0.1141492539432269, 0.00116861811166, 0.4411194763191918, 0.3812347749849946, 0.025121907803883, 0.0103321410468936 +381, 17.373081367523614, 66.24625742254646, 0.0378614207286974, 7.058499878398702, 7.805230215675485, 0.2074217019099125, 0.1071282800626527, 1.2767576312163291, 0.212589811996142, 0.0020290076265826, 0.6642612060123632, 0.3525885463695034, 0.0463197718986886, 0.0208680968948524 +382, 12.035449884160748, 66.9814753401914, 0.0495179853093072, 9.898642200418037, 9.78068460991484, 0.2455030398469793, 0.1076958517097385, 0.842790170414863, 0.2292453179005805, 0.0024749354189114, 0.6673103138889279, 0.589306878409522, 0.0360797354574715, 0.0254876370478119 +383, 18.02803411091742, 65.99957975522472, 0.0359672818202815, 7.347588346388168, 7.888858554124166, 0.2282692590779507, 0.1407724686399679, 2.246573357275466, 0.2930788517603523, 0.0027350351938541, 0.7700762746189261, 0.3939793257977521, 0.0614681340090239, 0.03697267174153 +384, 19.990891339914636, 66.19086992380423, 0.0366187702093468, 6.60064475992842, 7.56601411210285, 0.2066197181833559, 0.1057978101114609, 1.369998565897189, 0.1858096285376867, 0.0017348413420067, 0.5352162951737549, 0.2617819434580249, 0.0443216182342138, 0.0163303533071465 +385, 18.523793279834774, 65.84651142599436, 0.0347846700196521, 7.292703282789168, 7.606764018496365, 0.1965404832383936, 0.1220467410511367, 2.744299821033251, 0.3331344789498712, 0.0033851060567715, 0.9950885779911394, 0.584952402765698, 0.063760657983406, 0.0446504329813765 +386, 19.07726440643801, 66.91110115728442, 0.0404877968005175, 9.3457389261798, 8.801588388186175, 0.1413111184631165, 0.0668636614954617, 1.5547918021830218, 0.2076457843813306, 0.0020459811188574, 0.6471765125686321, 0.4491016927395748, 0.0255891247621286, 0.0146109756918254 +387, 19.698840619318755, 66.51687876007263, 0.037732742430993, 6.877548622374473, 8.090376674361364, 0.2390210913944661, 0.1244593890144124, 1.805196123494598, 0.2411285469294603, 0.0020875042942138, 0.5231229274062029, 0.2489240884588758, 0.0467137601036716, 0.0186004012257697 +388, 16.976419363727093, 66.0691858132698, 0.0374432826384177, 7.1985994097835295, 7.501018713933011, 0.1802775935228593, 0.1045309384955463, 1.1414698962373522, 0.189256076969585, 0.0018847684596867, 0.6651225124034182, 0.3378953313385421, 0.0367934612419309, 0.0182629608387061 +389, 20.69153184363912, 66.28230965465572, 0.0366506428225253, 7.009714867797686, 7.749748176725212, 0.196747081733372, 0.0917180855550247, 1.4397651841289492, 0.1776323801606303, 0.0016986888604135, 0.4911473343227802, 0.2976906425874857, 0.0343977488673439, 0.0160849546142348 +390, 18.29513190531393, 65.75895717472372, 0.0339468262737206, 7.454371556179617, 7.554554244355689, 0.1732254815092535, 0.1174627447756332, 1.896160982875436, 0.2368148607245767, 0.0022655554252346, 0.5632723891929925, 0.299523491895407, 0.0354989337738146, 0.0229176746212104 +391, 16.446869331081242, 66.12979926977948, 0.0379419994523057, 7.181182541211345, 7.737013516212239, 0.188169166484076, 0.0892611930713792, 1.0828882227404226, 0.1801285397128989, 0.0018446786702973, 0.5544571989296538, 0.3474597031348681, 0.0365686292085394, 0.0162268388532557 +392, 18.10037597973357, 66.13110631031017, 0.0369513369809789, 7.181066931323182, 7.597669687683862, 0.1855849996470122, 0.0888038209476141, 1.3108869397795335, 0.1960559898989754, 0.0019157971481176, 0.6198250315927314, 0.3853619860733604, 0.0394935834185836, 0.0193155083754942 +393, 16.907142155837317, 66.31821105893007, 0.0393941877499777, 7.22108876162418, 7.616071759503668, 0.2477481744276517, 0.1294502016635013, 2.087445457543301, 0.3689872815921458, 0.0035304151531983, 0.9065999618407272, 0.4876294236433435, 0.0721352880383473, 0.0338746014782778 +394, 19.918159041001275, 66.40899554102111, 0.0370423668487652, 7.028823815234155, 7.665309813485248, 0.2007470307506836, 0.0573860631176127, 2.448833765127851, 0.329798413164323, 0.0032356005433289, 0.7850040130046321, 0.7141855934938324, 0.0597276635543796, 0.022486123157187 +395, 22.343993034188436, 66.11378217453917, 0.0350021638642662, 7.376000768588432, 7.550235367490872, 0.2151184784793641, 0.0899018126299405, 1.696670091023725, 0.1781860799542669, 0.0016955259313657, 0.4958129017597347, 0.3012811840362435, 0.0362693058451072, 0.0158272495985619 +396, 20.074373764845888, 66.35473559924681, 0.0371498495984742, 7.901628568055258, 7.942950347545157, 0.213036869473744, 0.0938528219108705, 1.369997194613913, 0.1686054439967259, 0.0016140387613863, 0.5057755114094593, 0.3471847000569977, 0.0332788667573514, 0.0197874051426945 +397, 19.56498509234194, 66.26312491775246, 0.0373598600055074, 7.454663270906445, 7.526250758930758, 0.1927075193053785, 0.1063612683328234, 2.1170098543862808, 0.284643908560572, 0.0025944113675331, 0.7144890504946412, 0.3770123507902998, 0.0469995263907288, 0.0245167190502662 +398, 17.874340661390136, 66.14173415188586, 0.0366365596025424, 7.5141582372027695, 7.571126562390608, 0.1985528544549165, 0.0794684999890907, 1.1155494983032366, 0.1615435276086761, 0.0015543412293081, 0.4939204021857534, 0.327086003197535, 0.0300156034087383, 0.0149868305270727 +399, 19.81292933880471, 65.70681528941532, 0.0330754115381455, 6.323241851889453, 7.867137817361507, 0.1986768171798851, 0.1320660242018618, 1.7298469588978902, 0.2094210384991726, 0.0019879310642329, 0.5623427739862503, 0.2125323903904961, 0.0447672279504401, 0.0185065880069016 +400, 20.887858398591177, 65.59317125645961, 0.0318375922629219, 6.672196043752917, 6.838505228232379, 0.1934165499816758, 0.071791704460624, 1.729900593608972, 0.1929097789831603, 0.0018975641536606, 0.4774939654930509, 0.3591248213297429, 0.0350835093783025, 0.0167991232698852 +401, 17.95262429630529, 66.0343636467792, 0.0352484340615266, 5.658319455056447, 6.271911382371345, 0.2047087958044494, 0.1135588305890174, 1.3369287934995924, 0.2360756261147048, 0.0021439371524606, 0.7430200616472216, 0.286489960913077, 0.0678092197290203, 0.020580582081731 +402, 20.214258672155527, 65.44467074338986, 0.0305942978562151, 6.68275307724832, 7.378976500481007, 0.1886627849334542, 0.0756526265145536, 1.423133773549715, 0.1480722317004907, 0.0015422718175544, 0.3744930234299622, 0.2530772864300156, 0.0282201012205183, 0.0130827003446219 +403, 16.876453295867062, 65.44778665291958, 0.0318506579313678, 6.59334206721106, 6.974529059279896, 0.1744721725129299, 0.0491263152042068, 1.1831808923244895, 0.162596385119135, 0.0017088080969836, 0.4877049034391983, 0.4658885581070544, 0.0313896668521573, 0.0144426616503463 +404, 12.989420341666008, 67.55584133302663, 0.0516572581158946, 9.999999999999998, 9.999999999999936, 0.2659266958541229, 0.1208655630877946, 1.3064324358560242, 0.348932648847728, 0.0036007108908314, 0.89994197288172, 0.6448582917030454, 0.0506801803205766, 0.0309956473185391 +405, 8.841391133850305, 66.22175520396388, 0.0435373695959395, 7.349773567034183, 7.756711847442749, 0.3211131726274235, 0.1803268511455277, 0.6501942966146254, 0.2866537737821133, 0.0028640509950068, 0.6740589707544311, 0.3970773490903765, 0.0679234041859579, 0.0364547511944473 +406, 17.984188875454638, 66.43931296078893, 0.0388031951030341, 7.679776801181958, 8.155260395469567, 0.2068254080408273, 0.1180313658362269, 1.765932045716578, 0.2602285783654933, 0.0025602021559334, 0.757136851188016, 0.4759856942968204, 0.0455822966261769, 0.0300367510429369 +407, 20.8296242850307, 65.64040208689386, 0.0322871298909452, 6.316102512553846, 6.938889498533984, 0.1622260423769429, 0.0660045713901145, 2.067644337653926, 0.2372656455541333, 0.0023471024640966, 0.6746761716343133, 0.4228472602578131, 0.0435734519040125, 0.0182603664581294 +409, 18.895808965616013, 66.22305369407037, 0.0366970452803449, 8.099697776569181, 8.074330081289373, 0.1725348967635966, 0.0779833605254992, 1.8204582625445416, 0.2223096740041255, 0.0021561933765174, 0.5739942013597409, 0.4161988922452162, 0.03381159648897, 0.018662097561366 +410, 18.13919532189455, 66.60061478521499, 0.0382288171995885, 7.415356811400521, 7.829234957111108, 0.2744352418286567, 0.1143439314648725, 1.9603491202503245, 0.2891398733392141, 0.0026025021404837, 0.551903889459659, 0.388289587219339, 0.0500010687185159, 0.0239531754068601 +411, 16.03974453728752, 65.86826762267665, 0.035710675303522, 6.556466247020019, 7.756976915833579, 0.2438999223848733, 0.1130114318371147, 0.9939515061505104, 0.1634237044308242, 0.0015917200655788, 0.4213552808280931, 0.2575274238070944, 0.0413234508732263, 0.017592846028183 +412, 18.73468089354676, 65.8525864266488, 0.0355683511526484, 7.070978202725093, 7.66267825815321, 0.2034514127772492, 0.084354220004157, 1.1546446325467312, 0.1513512007595489, 0.0015077755681148, 0.4271728423001572, 0.2981863503737384, 0.0307904191437006, 0.0144229395726077 +413, 19.091261597873693, 66.24084541673696, 0.0370946250482944, 7.517795429792926, 7.925008939428284, 0.1722666465599524, 0.092381588500136, 1.4014225539381793, 0.1962555069510597, 0.0019292771137502, 0.6996854378297949, 0.3717898547401424, 0.0378710683765004, 0.01899087352699 +414, 20.18183630297641, 66.02304138191256, 0.034930391498557, 7.488876310797508, 7.734832100414675, 0.1947943088818413, 0.0865410032708088, 1.415621792217299, 0.1619893616855036, 0.0015848590877043, 0.495056587763702, 0.319698335967824, 0.0313571812826614, 0.0161071160080269 +415, 20.386408427244948, 65.34484423951572, 0.0295689310069173, 6.861031189018985, 7.881622563464948, 0.1692531394734677, 0.0935458253415347, 1.894535123529596, 0.1956957008164354, 0.0021012019522695, 0.5456810028481168, 0.328004390569142, 0.0338156986279808, 0.0225849153359102 +417, 21.65346959270596, 65.6451643731617, 0.031202239742052, 7.840525760175249, 8.214419556728744, 0.274076244420219, 0.0844083937534889, 1.1853794137382527, 0.1246519648013942, 0.0011933666997029, 0.2838262121653028, 0.1982446711254029, 0.0284934232635238, 0.0122368631342197 +418, 20.789177585513368, 65.9638696231725, 0.033803258903743, 8.153834151130688, 8.5496869065135, 0.2600622822340173, 0.0783336317470313, 0.801090418618431, 0.089926797962843, 0.0008553869566324, 0.2293466133491089, 0.2196531561393827, 0.0198480831420829, 0.0110987302680096 +419, 16.736511851590315, 65.7704723944457, 0.0342444717447583, 7.745275162859688, 8.450251577276843, 0.2598808230607848, 0.0786207636349865, 0.5581733374254342, 0.0832504232240767, 0.0007884204160615, 0.208716291388075, 0.2152281549386959, 0.0177637896515609, 0.0116606677945402 +420, 17.822321737523325, 65.445969110379, 0.0321217930476515, 8.083072120116062, 7.485415477090315, 0.6843770683240785, 0.3195479042031249, 1.3769214244885952, 0.1600133321908912, 0.0014284050114644, 0.2700999423263581, 0.1914797763097361, 0.0730765582989, 0.0391252362965674 +421, 19.2409954338793, 65.87331944092587, 0.0337603917929127, 8.043721913248069, 8.521911504840208, 0.2535238366396616, 0.0743047083221945, 1.231163429800794, 0.1446691015870124, 0.0014018015306112, 0.3541129435998789, 0.3028417938999865, 0.0312785743826359, 0.0142954664919282 +422, 20.3457623623276, 65.62510135233299, 0.0319024763686103, 7.806965810900566, 8.086127620908186, 0.2940513123569279, 0.1008223530338031, 1.7010953235011872, 0.1873262759664873, 0.0017773376064251, 0.4150922842885959, 0.3043101492319108, 0.0437065540788175, 0.0216862163593942 +423, 20.727229324095724, 65.60427763366253, 0.0312668130855889, 7.835699547944687, 8.033141040562358, 0.2607588541252869, 0.0600276015918915, 1.0654014686370352, 0.1109814117988401, 0.0010930238936029, 0.2745264569675429, 0.2951530569236021, 0.0253013749326926, 0.012659067541964 +424, 21.064234246040453, 66.19993084081977, 0.034428183687201, 8.438406330494141, 8.81163611146005, 0.2452094698771383, 0.0794181065099458, 1.1130351172886823, 0.1294766320814448, 0.0011574343752242, 0.2849636017415481, 0.2646098532366801, 0.023697776622307, 0.0141279849500886 +425, 17.32379650305197, 66.23711709845979, 0.0369409934039274, 7.883360992653102, 8.421182771179392, 0.3234191829726071, 0.1218464346473362, 0.988813893361572, 0.1423235065873731, 0.001255544812004, 0.2879400064110314, 0.1746076199063987, 0.0313401358206672, 0.0126721228492435 +426, 19.676408549677543, 65.6019741040735, 0.0320935264621533, 8.045569275791959, 8.261193852516683, 0.2092446426936531, 0.0843378189830445, 1.0561706590349569, 0.1261778977291271, 0.0012004207885413, 0.3688369671783133, 0.2913125798018823, 0.027092161290261, 0.0173444726615215 +427, 18.931327713830598, 65.72046441709304, 0.0328857951294851, 8.38358366471532, 8.284176711815778, 0.2038443331332205, 0.0975119724184071, 0.7899064344799026, 0.0966000642632132, 0.0009430010991718, 0.2793010899289433, 0.2269185598610383, 0.0191086562594229, 0.0176587899464906 +428, 18.8428709142582, 66.3178751310621, 0.0355361226821072, 8.385430986970228, 8.77198680380445, 0.2575823232687283, 0.0701379979233186, 1.0058079860800564, 0.1377671649095061, 0.0012913257826597, 0.3023324876885616, 0.3024495554309677, 0.0263265422468645, 0.0122580873654274 +429, 18.60395056738597, 65.80293591432954, 0.0329687675543597, 8.361217179715945, 8.47008030662252, 0.229383190897102, 0.0916630463832661, 0.8387471513608692, 0.1025484486237376, 0.0009937035713919, 0.2772545546841503, 0.2705469464995127, 0.0216314485263755, 0.0158846903022361 +430, 18.01501353412002, 66.23060957849347, 0.0364507654272159, 8.220695094159039, 8.775390744540426, 0.289226629323711, 0.1175522347079003, 1.6304590802052283, 0.220955013694321, 0.0020352321585428, 0.5013362200712546, 0.3723838259451199, 0.0490104018349032, 0.0275011263161908 +432, 17.50310932710253, 65.81046577097354, 0.0345844742576821, 7.94062644945325, 8.483832297126815, 0.2873095312785791, 0.090199696490066, 0.8227433165779013, 0.1098181086994381, 0.0010902968507599, 0.2706055286267805, 0.2786378313003572, 0.0249250240647009, 0.015116726841983 +433, 20.34139152083189, 65.61537246706635, 0.0318335911460926, 8.209073898280089, 8.154158929947496, 0.184936468778572, 0.0502758596090779, 0.8507955538360962, 0.0995229223780767, 0.0009872420477397, 0.316362223711494, 0.4384408033859829, 0.0198550564240856, 0.0154409959500234 +434, 16.93680068907594, 65.96340732429614, 0.0349959384534805, 7.842666696584803, 8.359046609088988, 0.2902541470418494, 0.0951409046237551, 0.842341521857461, 0.1239265757102382, 0.0011682064754019, 0.2927515112513859, 0.2504492568775668, 0.028562187488646, 0.0147933040772646 +435, 20.460542714162383, 66.20300863582169, 0.0340557894928244, 8.439241154046266, 9.377191121474372, 0.2100677884866865, 0.0590973313544583, 2.367162370170629, 0.2753744441590828, 0.0025960475796094, 0.63875795435106, 0.6637682513147795, 0.0494351301520202, 0.0248660689436474 +436, 21.261446244641316, 65.84254903624077, 0.0325829888822235, 8.723049208886982, 8.704078327282467, 0.2021549254471222, 0.0758684531215836, 0.8914967026871833, 0.0977470506009845, 0.0009372929729155, 0.2783268605616823, 0.3080094008806317, 0.0187587506392808, 0.0155422015543724 +437, 24.835155807915577, 65.69078354061978, 0.0304931587241177, 8.337810885750056, 8.530229978726432, 0.1856802519431378, 0.0696724392427746, 1.2403135990928689, 0.1112315864183901, 0.0010426280003629, 0.284552329375029, 0.229741605003026, 0.0186299687664994, 0.0127606662712546 +438, 20.568601463733376, 65.72886058621853, 0.0326922206153394, 8.102501120684007, 8.716521493243379, 0.224000176717178, 0.0598075975406976, 1.08301456412506, 0.1269462454308264, 0.0012546684626599, 0.3222177399849242, 0.3235798524595886, 0.0246562548372528, 0.0136318947119127 +439, 20.93785685157656, 65.93113652729623, 0.0322441076269637, 8.218843502143404, 8.497221012995727, 0.2532835312860731, 0.089376909808957, 1.3757170566318744, 0.1520032937933028, 0.0013886851253614, 0.3278451782433996, 0.2475402794058355, 0.0294701900140717, 0.0151638725870107 +440, 19.52782256493223, 66.0510773177615, 0.0355230303065688, 8.122334923508763, 8.832968695264174, 0.2669774744745575, 0.0832092351568731, 0.8610970424254204, 0.1100153381809537, 0.0010879861812948, 0.270431304349643, 0.2764968006167488, 0.0228727693816378, 0.012986674056354 +441, 18.73975532269145, 65.90148380887688, 0.0345523870453647, 7.842589090219954, 8.516367453929854, 0.2645666581189351, 0.0819017193034798, 1.120119892359901, 0.1458830338980886, 0.0013460399838721, 0.3469815618414059, 0.2870738230158016, 0.0302535685063239, 0.0150391072475234 +442, 19.82417702271372, 65.64195425033728, 0.0321834587810454, 8.34991236918498, 8.415152429545298, 0.2104877536190419, 0.1022213322845603, 1.1253904215859043, 0.1225542997472593, 0.0012157248385016, 0.3791955434962882, 0.3743172752864463, 0.0264228825989434, 0.0245977659502914 +443, 17.63017098277628, 65.83674204196093, 0.0342535656684394, 7.773766164335162, 8.573401421344306, 0.2769845488159174, 0.0952904466700415, 0.9348620335365484, 0.1237269087959292, 0.0011870092132544, 0.3094996083536473, 0.2811382048898285, 0.0298152876541073, 0.016404881110685 +446, 21.21005864070331, 65.85765505064813, 0.0332423860311022, 7.950067619386306, 8.411151169707017, 0.2610163519856194, 0.0705570143204864, 1.4327822256743246, 0.1574899211822774, 0.0014649094544818, 0.3638104782525744, 0.3134131947080908, 0.0318846490366453, 0.0144681991556606 +447, 18.024962359993005, 66.1203525344101, 0.034833596648156, 7.926579541604622, 8.448753872052244, 0.2916463678722938, 0.0797666433143335, 0.8681703337409233, 0.1120879817856488, 0.0010693388858398, 0.2594507816288838, 0.253643348872702, 0.0249488717716234, 0.0121191920886137 +448, 21.229410789693503, 65.86958829929925, 0.0329611810699021, 8.486385133628673, 8.56142562240672, 0.2035053775593352, 0.0789764517803622, 1.0261216363608503, 0.1076851362782755, 0.0010547785624211, 0.3142421063177205, 0.2980255718589237, 0.0207276847276626, 0.0161827131168983 +449, 19.36204538837964, 65.83115929187589, 0.0330160826253947, 8.285036241700993, 8.393143605453032, 0.2309219389151962, 0.086827790885734, 0.9085196940086974, 0.1018088683497137, 0.000964274046825, 0.2825709615773661, 0.2466787149573407, 0.0227731867985071, 0.0136402836241971 +450, 15.605930224141211, 65.7262746628475, 0.0365130339275594, 9.27911272142386, 8.97112782240633, 0.3181293853785584, 0.3084125773926113, 1.4420689002609757, 0.2041582818049802, 0.0021147924526227, 0.5063844638679416, 0.2815362646048324, 0.0513824519396528, 0.0571438253845317 +451, 17.892296774529324, 65.92977876948336, 0.0334040666481763, 8.18306123417763, 9.049839199837038, 0.2649877475923062, 0.1001244132073916, 0.7906046523803519, 0.0979924240890918, 0.0009227768376427, 0.2368062163066847, 0.227378339025932, 0.0215607607129154, 0.0167124027636894 +452, 21.45289724271045, 65.71360431346936, 0.0320911908769673, 7.797039056244331, 7.890168075828954, 0.3097835679665351, 0.1086531038883223, 2.136407676593817, 0.2153108864492142, 0.0019390946733159, 0.4324791057442891, 0.2975928500602989, 0.048979712575082, 0.0233862952875551 +453, 23.70092560857747, 65.5720639607955, 0.0299784733843956, 8.991747798421404, 8.637276663340929, 0.1891142318609101, 0.0703114974034916, 1.7967228300196925, 0.1723302614156794, 0.0016387429236658, 0.3840045749262791, 0.3821228417360033, 0.0263945086269092, 0.0216646555640289 +454, 18.66578105930316, 65.69283409314251, 0.0324265394534018, 8.340798954111703, 8.274189917993427, 0.1989739792863297, 0.067515862823484, 1.011444593547323, 0.1284391537398137, 0.0012249784137876, 0.3878277212452012, 0.4046428190587978, 0.0254083551720694, 0.0169926450163182 +455, 20.864152263473716, 65.88070481069025, 0.0334423108504933, 8.307775718023986, 8.806212941796938, 0.2219791413073081, 0.0845146441681902, 1.2629369207527668, 0.1384193990412489, 0.0013411893988092, 0.3700314905022108, 0.3321642343456721, 0.0277409967329666, 0.0183921949054767 +456, 24.04758277915513, 65.88902367573554, 0.03265420682809, 8.113147110547649, 8.285686062206084, 0.2057632940986345, 0.0816611742248908, 1.429430422822425, 0.1336346776109253, 0.0012649548465252, 0.3692014206487338, 0.3336590976834644, 0.0268653835485691, 0.0192432687414581 +457, 22.524337089712034, 66.40272251545233, 0.0350583423054751, 8.152381713001738, 8.809750603715884, 0.2370252900644747, 0.0722123891113932, 1.8262320742723184, 0.1935442843590715, 0.001783977123646, 0.4395306806182772, 0.3430382852587487, 0.0369322559756491, 0.0150512306695985 +458, 19.04410189843947, 66.1513604684099, 0.0358942855799551, 8.380945399861085, 8.940382669492662, 0.2698886308905548, 0.09269746519517, 0.8466125248970239, 0.1115465863327161, 0.0010272317084075, 0.2662552989499304, 0.2337500138267207, 0.0235177585996511, 0.0141074921940522 +459, 18.78974591666449, 65.96462651578425, 0.0350990416778611, 7.961221812121976, 8.60373213249672, 0.266761349861109, 0.0851341625206457, 0.8767675996046631, 0.1114317573269102, 0.0010565716094747, 0.2570958316324297, 0.24117720547176, 0.022943195421895, 0.0119338821678387 +460, 19.408156932454204, 65.93524288343467, 0.0348306099805193, 7.769343162341361, 8.612247046731538, 0.2813242136473392, 0.0839646550775433, 0.9504377039750032, 0.1184544330738325, 0.0011460882301083, 0.2922765249395898, 0.3371088567439712, 0.0272394973249799, 0.0181051599699306 +461, 20.020743112335285, 65.89707625032543, 0.0335736791603121, 7.7842799261141185, 8.47354946421575, 0.2479320527499865, 0.0585432137944318, 1.007261124249476, 0.1255715800898394, 0.0011355648564087, 0.2979597576017224, 0.3018134455319902, 0.0243841238803686, 0.0117222329761243 +462, 20.375573178806075, 65.73169167301837, 0.032519640610326, 7.831248736233272, 8.065557711517458, 0.2906815786616215, 0.0974104825449875, 1.0728886191070537, 0.1196039761422414, 0.0010995272015496, 0.2509817827705711, 0.1834693401171643, 0.0254244700399541, 0.0120713588091314 +463, 19.16083120620851, 65.89760300409763, 0.0338505749224141, 8.019163343422518, 8.637498150193235, 0.2420626085004077, 0.0617444885717428, 0.7583045097495793, 0.0934682873505771, 0.0009009392559887, 0.2468982277841892, 0.3152915630889853, 0.0198917517496276, 0.0122472565898517 diff --git a/configfiles/PMTWaveformSim/PMTWaveformSimConfig b/configfiles/PMTWaveformSim/PMTWaveformSimConfig new file mode 100644 index 000000000..4233a2a9c --- /dev/null +++ b/configfiles/PMTWaveformSim/PMTWaveformSimConfig @@ -0,0 +1,8 @@ +verbosity 0 +PMTParameterFile configfiles/PMTWaveformSim/PMTWaveformLognormFit.csv +useTimeSmearing 0 +Prewindow 80 +ReadoutWindow 200 +T0Offset 25 +TimeShift 0 +MakeDebugFile 0 diff --git a/configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig b/configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig new file mode 100644 index 000000000..d7df3353e --- /dev/null +++ b/configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig @@ -0,0 +1,11 @@ +verbosity 0 + +UseLEDWaveforms 0 + +PulseFindingApproach threshold +PulseWindowType Fixed_2023_Gains +DefaultADCThreshold 7 +DefaultThresholdType relative + +EventBuilding 0 +MCWaveforms 1 diff --git a/configfiles/PMTWaveformSim/README.md b/configfiles/PMTWaveformSim/README.md new file mode 100644 index 000000000..c54af24b0 --- /dev/null +++ b/configfiles/PMTWaveformSim/README.md @@ -0,0 +1,22 @@ +# Configure files + +*********************** +#Description +********************** + +`PMTWaveformSim` toolchain. + + +************************ +#Usage +************************ + +The toolchain requires the following tools to be run beforehand: + +``` +LoadGeometry +LoadWCSim +``` + +It also requires the presence of a `PMTWaveformLognormFit.csv` with fits from the SPE data. + diff --git a/configfiles/PMTWaveformSim/ToolChainConfig b/configfiles/PMTWaveformSim/ToolChainConfig new file mode 100644 index 000000000..499818543 --- /dev/null +++ b/configfiles/PMTWaveformSim/ToolChainConfig @@ -0,0 +1,26 @@ +#ToolChain dynamic setup file + +##### Runtime Parameters ##### +verbose 0 ## Verbosity level of ToolChain +error_level 0 # 0= do not exit, 1= exit on unhandled errors only, 2= exit on unhandled errors and handled errors +attempt_recover 1 ## 1= will attempt to finalise if an execute fails +remote_port 24002 +IO_Threads 1 ## Number of threads for network traffic (~ 1/Gbps) + +###### Logging ##### +log_mode Interactive # Interactive=cout , Remote= remote logging system "serservice_name Remote_Logging" , Local = local file log; +log_local_path ./log +log_service LogStore + + +###### Service discovery ##### Ignore these settings for local analysis +service_publish_sec -1 +service_kick_sec -1 + +##### Tools To Add ##### +Tools_File configfiles/PMTWaveformSim/ToolsConfig ## list of tools to run and their config files + +##### Run Type ##### +Inline -1 ## number of Execute steps in program, -1 infinite loop that is ended by user +Interactive 0 ## set to 1 if you want to run the code interactively + diff --git a/configfiles/PMTWaveformSim/ToolsConfig b/configfiles/PMTWaveformSim/ToolsConfig new file mode 100644 index 000000000..782b19507 --- /dev/null +++ b/configfiles/PMTWaveformSim/ToolsConfig @@ -0,0 +1,5 @@ +LoadGeometry LoadGeometry configfiles/LoadGeometry/LoadGeometryConfig +LoadWCSim LoadWCSim configfiles/PMTWaveformSim/LoadWCSimConfig +PMTWaveformSim PMTWaveformSim configfiles/PMTWaveformSim/PMTWaveformSimConfig +PhaseIIADCHitFinder PhaseIIADCHitFinder configfiles/PMTWaveformSim/PhaseIIADCHitFinderConfig +ClusterFinder ClusterFinder configfiles/PMTWaveformSim/ClusterFinderConfig \ No newline at end of file